Delphi concept
This commit is contained in:
@@ -0,0 +1,72 @@
|
|||||||
|
# Implementation Plan: Pascal/Delphi in CodeGraph
|
||||||
|
|
||||||
|
## 0) Prämissen
|
||||||
|
|
||||||
|
- CodeGraph extrahiert **Nodes** und **Edges** über **tree-sitter** und language-spezifische **Queries (`.scm`)**.
|
||||||
|
- Danach folgt **Reference Resolution** (Calls → Definitionen, imports → Dateien, inheritance, framework patterns).
|
||||||
|
|
||||||
|
## 1) Parser / Grammar
|
||||||
|
|
||||||
|
Empfohlen: `tree-sitter-pascal` (unterstützt Delphi + FreePascal).
|
||||||
|
|
||||||
|
**Tasks:**
|
||||||
|
- Dependency hinzufügen (wie bei bestehenden Sprachen).
|
||||||
|
- Language-Loader/Registry erweitern: `languageId = "pascal"` (oder `"delphi"`, aber konsistent).
|
||||||
|
|
||||||
|
## 2) File-Erkennung
|
||||||
|
|
||||||
|
Extensions (MVP):
|
||||||
|
- `.pas` (Units)
|
||||||
|
- `.dpr` (Program)
|
||||||
|
- `.dpk` (Package)
|
||||||
|
- `.lpr` (Lazarus Program)
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
- `.inc` (Include-Fragmente) – erst später oder nur, wenn Parser tolerant genug ist.
|
||||||
|
|
||||||
|
## 3) Queries (MVP)
|
||||||
|
|
||||||
|
### 3.1 Nodes
|
||||||
|
Extrahiere mindestens:
|
||||||
|
- Unit/Program/Package Name
|
||||||
|
- Klassen / Interfaces / Records
|
||||||
|
- Procedures/Functions
|
||||||
|
- Methoden (class/instance)
|
||||||
|
|
||||||
|
### 3.2 Edges
|
||||||
|
Extrahiere mindestens:
|
||||||
|
- `uses` (import/dependency)
|
||||||
|
- `extends` (Basisklasse)
|
||||||
|
- `implements` (Interface-Implementierungen)
|
||||||
|
- `calls` (Identifier + optional Qualifier)
|
||||||
|
|
||||||
|
## 4) Reference Resolution (MVP)
|
||||||
|
|
||||||
|
### 4.1 Unit-Auflösung (`uses`)
|
||||||
|
- Index-Phase: Map `UnitName -> fileId` (aus Units/Programs/Packages)
|
||||||
|
- Resolution: Bei `uses Foo, Bar;` Edges auf Ziel-Units setzen.
|
||||||
|
- Spezialfälle (später): `Foo in 'path\Foo.pas'` (DPR/DPK), Namespaces (`System.SysUtils`).
|
||||||
|
|
||||||
|
### 4.2 Call-Auflösung (best effort)
|
||||||
|
- Extraktion: `callName`, optional `qualifier` (`Obj.DoIt`, `TMyClass.DoIt`)
|
||||||
|
- Heuristik-Reihenfolge:
|
||||||
|
1. lokale Procs/Funcs in der gleichen Unit
|
||||||
|
2. Methoden in der gleichen Klasse
|
||||||
|
3. Units aus `uses`
|
||||||
|
4. globaler Fallback nach Name
|
||||||
|
|
||||||
|
## 5) Tests
|
||||||
|
|
||||||
|
- Fixtures aus `fixtures/` in die Test-Suite aufnehmen
|
||||||
|
- Assertions:
|
||||||
|
- Node-Anzahl + zentrale Namen
|
||||||
|
- `uses`-Edges
|
||||||
|
- `extends`/`implements`-Edges
|
||||||
|
- einfache Call-Edges
|
||||||
|
|
||||||
|
## 6) Definition of Done
|
||||||
|
|
||||||
|
- `codegraph index` indexiert Delphi/ Pascal-Dateien ohne Crash
|
||||||
|
- `codegraph_search` findet Klassen/Methoden
|
||||||
|
- `codegraph_callers/callees` liefert sinnvolle Ergebnisse für einfache Fälle
|
||||||
|
- `uses`-Graph stimmt (Unit-Abhängigkeiten)
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# Capture Convention (wie die `.scm` Queries an CodeGraph andocken)
|
||||||
|
|
||||||
|
Da wir hier nur ein ZIP-Konzept liefern (ohne den CodeGraph-Source lokal auszulesen), ist das wichtigste: **du musst die Captures so benennen, wie CodeGraph sie in den bestehenden Sprachen bereits erwartet**.
|
||||||
|
|
||||||
|
## Vorgehen
|
||||||
|
|
||||||
|
1. Öffne im CodeGraph-Repo eine bestehende Sprache (z.B. Go/Rust/Java).
|
||||||
|
2. Suche nach `.scm` Dateien und schaue:
|
||||||
|
- welche Capture-Namen verwendet werden
|
||||||
|
- wie Node-Kind/Edge-Kind gesetzt werden (oft via `#set!`)
|
||||||
|
3. Übertrage exakt dieses Schema auf Pascal.
|
||||||
|
|
||||||
|
## Empfohlene semantische Einteilung
|
||||||
|
|
||||||
|
Unabhängig von den konkreten Capture-Namen sollte jedes Query-Match folgende Informationen liefern:
|
||||||
|
|
||||||
|
### Für Nodes
|
||||||
|
- **kind**: `unit | program | package | class | interface | record | function | procedure | method | property | field | type | enum | variable`
|
||||||
|
- **name**: Symbolname
|
||||||
|
- **container** (optional): z.B. Klassenname für Methoden
|
||||||
|
- **signature** (optional): Parameter/Returntype, falls leicht verfügbar
|
||||||
|
- **range**: Start/Ende im File (Line/Column)
|
||||||
|
|
||||||
|
### Für Edges
|
||||||
|
- **kind**: `imports | calls | extends | implements | contains | returns_type`
|
||||||
|
- **from**: Node-ID der Quelle (oder "current scope")
|
||||||
|
- **to**: Zielsymbol (Name) oder Ziel-Node-ID, wenn schon auflösbar
|
||||||
|
- **raw**: Originaltext (hilft Resolvern)
|
||||||
|
|
||||||
|
## Minimaler Capture-Satz (Pseudo)
|
||||||
|
|
||||||
|
> **Wichtig:** Diese Namen sind **Platzhalter**. Bitte auf das CodeGraph-interne Schema mappen.
|
||||||
|
|
||||||
|
- `@cg.node` mit Properties:
|
||||||
|
- `(#set! cg.kind "class")`
|
||||||
|
- `(#set! cg.name @nameCapture)` oder per separate captures
|
||||||
|
|
||||||
|
- `@cg.edge` mit Properties:
|
||||||
|
- `(#set! cg.kind "calls")`
|
||||||
|
- Zielsymbol als Capture: `@cg.target`
|
||||||
|
|
||||||
|
Wenn CodeGraph statt `#set!` eine feste Capture-Nomenklatur nutzt (z.B. `@definition.function`), dann übernimm exakt diese.
|
||||||
|
|
||||||
|
## Delphi-spezifische Stolperfallen
|
||||||
|
|
||||||
|
- `procedure Foo;` vs `function Foo: Integer;`
|
||||||
|
- `class procedure` / `class function`
|
||||||
|
- `constructor` / `destructor`
|
||||||
|
- `property` (kann wie Feld wirken, ist aber call-ähnlich)
|
||||||
|
- `with`-Statements (Call-Qualifier wird verschleiert)
|
||||||
|
- Namespaces: `System.SysUtils`
|
||||||
|
|
||||||
|
Für MVP: **nicht perfekt auflösen**, aber **zuverlässig extrahieren**.
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
# Tree-sitter Query Skizzen (Pascal/Delphi)
|
||||||
|
|
||||||
|
Diese Skizzen sind bewusst so geschrieben, dass du sie schnell an die **konkreten Node-Namen** von `tree-sitter-pascal` und die **Capture-Konvention** von CodeGraph anpassen kannst.
|
||||||
|
|
||||||
|
> Praxis-Tipp: Nutze `tree-sitter parse` bzw. Editor-Tools (z.B. Neovim `:InspectTree`) um die exakten Node-Typen im AST zu sehen.
|
||||||
|
|
||||||
|
## A) Nodes
|
||||||
|
|
||||||
|
### 1) Unit / Program / Package
|
||||||
|
|
||||||
|
- Match: `unit`/`program`/`library`/`package` header
|
||||||
|
- Extrahiere Name
|
||||||
|
|
||||||
|
Skizze:
|
||||||
|
|
||||||
|
```scm
|
||||||
|
; (unit_header name: (identifier) @NAME) @NODE
|
||||||
|
; (#set! "kind" "unit")
|
||||||
|
|
||||||
|
; (program_header name: (identifier) @NAME) @NODE
|
||||||
|
; (#set! "kind" "program")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2) Klassen / Interfaces / Records
|
||||||
|
|
||||||
|
Skizze:
|
||||||
|
|
||||||
|
```scm
|
||||||
|
; (type_declaration
|
||||||
|
; (type_definition
|
||||||
|
; name: (identifier) @TYPE_NAME
|
||||||
|
; value: (class_type) @CLASS
|
||||||
|
; )
|
||||||
|
; )
|
||||||
|
|
||||||
|
; (type_definition name: (identifier) @TYPE_NAME value: (interface_type) @IFACE)
|
||||||
|
; (type_definition name: (identifier) @TYPE_NAME value: (record_type) @REC)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3) Procs/Funcs (top-level)
|
||||||
|
|
||||||
|
```scm
|
||||||
|
; (procedure_declaration name: (identifier) @NAME) @NODE
|
||||||
|
; (#set! "kind" "procedure")
|
||||||
|
|
||||||
|
; (function_declaration name: (identifier) @NAME) @NODE
|
||||||
|
; (#set! "kind" "function")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4) Methoden
|
||||||
|
|
||||||
|
Je nach Grammar sind Methoden oft als procedure/function nodes innerhalb eines `class_body` oder `visibility_section` enthalten.
|
||||||
|
|
||||||
|
```scm
|
||||||
|
; (method_declaration name: (identifier) @NAME) @NODE
|
||||||
|
; (#set! "kind" "method")
|
||||||
|
; optional: capture class name via ancestor match (wenn CodeGraph das unterstützt)
|
||||||
|
```
|
||||||
|
|
||||||
|
## B) Edges
|
||||||
|
|
||||||
|
### 1) uses (imports/dependencies)
|
||||||
|
|
||||||
|
```scm
|
||||||
|
; (uses_clause (qualified_identifier) @UNIT_NAME) @EDGE
|
||||||
|
; (#set! "kind" "imports")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2) extends (Basisklasse)
|
||||||
|
|
||||||
|
```scm
|
||||||
|
; (class_type
|
||||||
|
; base_class: (qualified_identifier) @BASE
|
||||||
|
; ) @EDGE
|
||||||
|
; (#set! "kind" "extends")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3) implements (Interfaces)
|
||||||
|
|
||||||
|
```scm
|
||||||
|
; (class_type
|
||||||
|
; implements: (interface_list (qualified_identifier) @IFACE)
|
||||||
|
; ) @EDGE
|
||||||
|
; (#set! "kind" "implements")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4) calls (Call-Graph)
|
||||||
|
|
||||||
|
Du willst in Delphi mindestens folgende Formen sehen:
|
||||||
|
- `Foo()`
|
||||||
|
- `Obj.Foo()`
|
||||||
|
- `TMyClass.Foo()`
|
||||||
|
|
||||||
|
Skizze:
|
||||||
|
|
||||||
|
```scm
|
||||||
|
; (call_expression
|
||||||
|
; function: (identifier) @CALLEE
|
||||||
|
; ) @EDGE
|
||||||
|
; (#set! "kind" "calls")
|
||||||
|
|
||||||
|
; (call_expression
|
||||||
|
; function: (qualified_identifier
|
||||||
|
; qualifier: (identifier) @QUAL
|
||||||
|
; name: (identifier) @CALLEE)
|
||||||
|
; ) @EDGE
|
||||||
|
; (#set! "kind" "calls")
|
||||||
|
```
|
||||||
|
|
||||||
|
## C) MVP: „Contains“-Edges
|
||||||
|
|
||||||
|
Optional, aber oft sehr nützlich: Datei/Unit enthält Klassen/Procs.
|
||||||
|
|
||||||
|
```scm
|
||||||
|
; (type_definition name: (identifier) @CHILD) @EDGE
|
||||||
|
; (#set! "kind" "contains")
|
||||||
|
```
|
||||||
|
|
||||||
|
Das ist abhängig davon, wie CodeGraph containment modelliert.
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# Checklist: Pascal/Delphi Support in CodeGraph
|
||||||
|
|
||||||
|
## A) Plumbing
|
||||||
|
- [ ] tree-sitter grammar dependency (Pascal)
|
||||||
|
- [ ] Language registry: `pascal` hinzufügen
|
||||||
|
- [ ] Extension mapping: `.pas .dpr .dpk .lpr` (optional `.inc`)
|
||||||
|
- [ ] Queries laden (nodes + edges)
|
||||||
|
|
||||||
|
## B) Extraction
|
||||||
|
- [ ] Unit/Program/Package Nodes
|
||||||
|
- [ ] Class/Interface/Record Nodes
|
||||||
|
- [ ] Procedure/Function Nodes
|
||||||
|
- [ ] Method Nodes
|
||||||
|
- [ ] uses -> imports edges
|
||||||
|
- [ ] extends edges
|
||||||
|
- [ ] implements edges
|
||||||
|
- [ ] calls edges (best-effort)
|
||||||
|
|
||||||
|
## C) Resolution
|
||||||
|
- [ ] unitName -> file/node mapping
|
||||||
|
- [ ] resolve `uses X;` to unit node
|
||||||
|
- [ ] resolve `X in 'path'` (DPR/DPK) (Phase 2)
|
||||||
|
- [ ] call resolution baseline (same file + class)
|
||||||
|
|
||||||
|
## D) Testing
|
||||||
|
- [ ] add fixtures to tests
|
||||||
|
- [ ] assert extracted nodes
|
||||||
|
- [ ] assert imports/extends/implements/calls
|
||||||
|
|
||||||
|
## E) Polishing
|
||||||
|
- [ ] expose language in `Supported Languages` docs
|
||||||
|
- [ ] update CLI help / config validation
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# CodeGraph Pascal/Delphi Support (Fork-Konzept)
|
||||||
|
|
||||||
|
Dieses ZIP ist **kein fertiger CodeGraph-Fork**, sondern ein **umsetzbarer Bauplan** inklusive Query-Skizzen, Scaffold-Dateistruktur, Test-Fixtures und einer Checkliste.
|
||||||
|
|
||||||
|
Ziel: CodeGraph soll **Pascal/Delphi**-Dateien indexieren und daraus **Nodes** (Units, Klassen, Methoden, …) sowie **Edges** (uses/imports, calls, extends, implements, …) extrahieren.
|
||||||
|
|
||||||
|
## Inhalt
|
||||||
|
|
||||||
|
- `Docs/` – Konzept, Capture-Konventionen, Implementations-Schritte
|
||||||
|
- `Scaffold/` – vorgeschlagene Ordner/Dateien für `src/languages/pascal/` inkl. `.scm` Queries
|
||||||
|
- `fixtures/` – kleine Delphi-Beispieldateien zum Testen der Extraktion
|
||||||
|
- `resolution/` – Resolver-Heuristiken (Unit-Mapping, Call-Resolution)
|
||||||
|
|
||||||
|
## Wie du damit arbeitest
|
||||||
|
|
||||||
|
1. **Im CodeGraph-Repo** die bestehende Struktur für eine Sprache ansehen (z.B. `src/languages/go` oder `src/languages/java`).
|
||||||
|
2. Dieses ZIP als Vorlage nehmen und **1:1** in deinen Fork übertragen:
|
||||||
|
- `src/languages/pascal/**`
|
||||||
|
- Extension-Mapping (`.pas`, `.dpr`, `.dpk`, `.lpr`, optional `.inc`)
|
||||||
|
- Language-Registry erweitern
|
||||||
|
3. Queries (`.scm`) auf die **Capture-Namen** mappen, die CodeGraph intern erwartet.
|
||||||
|
4. Resolver erweitern (mindestens `uses` → Unit-File, einfache Call-Auflösung).
|
||||||
|
5. Fixtures in die Tests aufnehmen.
|
||||||
|
|
||||||
|
> Hinweis: Tree-sitter ist die Grundlage. Für Pascal/Delphi bietet sich `tree-sitter-pascal` an (Delphi + FreePascal).
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# Pascal / Delphi Language Module (Scaffold)
|
||||||
|
|
||||||
|
Diese Dateien sind als **Startpunkt** für einen CodeGraph-Fork gedacht.
|
||||||
|
|
||||||
|
## Strukturvorschlag
|
||||||
|
|
||||||
|
- `language.ts` – registriert Parser, Extensions, Query-Files
|
||||||
|
- `queries/nodes.scm` – Node-Extraktion
|
||||||
|
- `queries/edges.scm` – Edge-Extraktion
|
||||||
|
- `queries/comments.scm` (optional) – Docstrings/Kommentare
|
||||||
|
|
||||||
|
## Wichtig
|
||||||
|
|
||||||
|
Die Capture-Namen in den `.scm` Dateien sind **Platzhalter**.
|
||||||
|
Passe sie so an, dass sie zum internen Schema von CodeGraph passen (siehe `Docs/02-Capture-Convention.md`).
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Pascal / Delphi language registration scaffold for CodeGraph.
|
||||||
|
*
|
||||||
|
* NOTE: This is intentionally pseudo-code / a template.
|
||||||
|
* You must adapt it to the actual CodeGraph codebase structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const pascalLanguage = {
|
||||||
|
id: 'pascal',
|
||||||
|
displayName: 'Pascal / Delphi',
|
||||||
|
|
||||||
|
// MVP extensions
|
||||||
|
extensions: ['.pas', '.dpr', '.dpk', '.lpr'],
|
||||||
|
|
||||||
|
// Suggested tree-sitter grammar package name (verify in your fork)
|
||||||
|
// parser: require('tree-sitter-pascal'),
|
||||||
|
|
||||||
|
// Queries used by the extractor
|
||||||
|
queries: {
|
||||||
|
nodes: __dirname + '/queries/nodes.scm',
|
||||||
|
edges: __dirname + '/queries/edges.scm',
|
||||||
|
// comments: __dirname + '/queries/comments.scm',
|
||||||
|
},
|
||||||
|
|
||||||
|
// Optional language-specific settings
|
||||||
|
options: {
|
||||||
|
// includeFiles: ['**/*.inc'] // only if you decide to support includes
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
; Pascal/Delphi edge extraction queries (SCAFFOLD)
|
||||||
|
; -----------------------------------------------
|
||||||
|
; IMPORTANT: Replace capture names with the exact ones CodeGraph expects.
|
||||||
|
|
||||||
|
; === uses (imports) ===
|
||||||
|
|
||||||
|
; (uses_clause (qualified_identifier) @cg.target) @cg.edge
|
||||||
|
; (#set! cg.kind "imports")
|
||||||
|
|
||||||
|
|
||||||
|
; === class inheritance ===
|
||||||
|
|
||||||
|
; (class_type
|
||||||
|
; base_class: (qualified_identifier) @cg.target
|
||||||
|
; ) @cg.edge
|
||||||
|
; (#set! cg.kind "extends")
|
||||||
|
|
||||||
|
|
||||||
|
; === implements interfaces ===
|
||||||
|
|
||||||
|
; (class_type
|
||||||
|
; implements: (interface_list (qualified_identifier) @cg.target)
|
||||||
|
; ) @cg.edge
|
||||||
|
; (#set! cg.kind "implements")
|
||||||
|
|
||||||
|
|
||||||
|
; === call graph (best-effort) ===
|
||||||
|
|
||||||
|
; (call_expression function: (identifier) @cg.target) @cg.edge
|
||||||
|
; (#set! cg.kind "calls")
|
||||||
|
|
||||||
|
; Qualified calls: Obj.Foo(), TMyClass.Bar()
|
||||||
|
; (call_expression
|
||||||
|
; function: (qualified_identifier
|
||||||
|
; qualifier: (identifier) @cg.qualifier
|
||||||
|
; name: (identifier) @cg.target)
|
||||||
|
; ) @cg.edge
|
||||||
|
; (#set! cg.kind "calls")
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
; Pascal/Delphi node extraction queries (SCAFFOLD)
|
||||||
|
; -------------------------------------------------
|
||||||
|
; IMPORTANT: Replace capture names with the exact ones CodeGraph expects.
|
||||||
|
; Use existing languages as reference.
|
||||||
|
|
||||||
|
; === Unit / Program / Library / Package ===
|
||||||
|
|
||||||
|
; (unit_header name: (identifier) @cg.name) @cg.node
|
||||||
|
; (#set! cg.kind "unit")
|
||||||
|
|
||||||
|
; (program_header name: (identifier) @cg.name) @cg.node
|
||||||
|
; (#set! cg.kind "program")
|
||||||
|
|
||||||
|
; (library_header name: (identifier) @cg.name) @cg.node
|
||||||
|
; (#set! cg.kind "library")
|
||||||
|
|
||||||
|
; (package_header name: (identifier) @cg.name) @cg.node
|
||||||
|
; (#set! cg.kind "package")
|
||||||
|
|
||||||
|
|
||||||
|
; === Types: class / interface / record ===
|
||||||
|
|
||||||
|
; (type_definition
|
||||||
|
; name: (identifier) @cg.name
|
||||||
|
; value: (class_type)
|
||||||
|
; ) @cg.node
|
||||||
|
; (#set! cg.kind "class")
|
||||||
|
|
||||||
|
; (type_definition
|
||||||
|
; name: (identifier) @cg.name
|
||||||
|
; value: (interface_type)
|
||||||
|
; ) @cg.node
|
||||||
|
; (#set! cg.kind "interface")
|
||||||
|
|
||||||
|
; (type_definition
|
||||||
|
; name: (identifier) @cg.name
|
||||||
|
; value: (record_type)
|
||||||
|
; ) @cg.node
|
||||||
|
; (#set! cg.kind "record")
|
||||||
|
|
||||||
|
|
||||||
|
; === Top-level procedures/functions ===
|
||||||
|
|
||||||
|
; (procedure_declaration name: (identifier) @cg.name) @cg.node
|
||||||
|
; (#set! cg.kind "procedure")
|
||||||
|
|
||||||
|
; (function_declaration name: (identifier) @cg.name) @cg.node
|
||||||
|
; (#set! cg.kind "function")
|
||||||
|
|
||||||
|
|
||||||
|
; === Methods (depending on grammar) ===
|
||||||
|
|
||||||
|
; (method_declaration name: (identifier) @cg.name) @cg.node
|
||||||
|
; (#set! cg.kind "method")
|
||||||
|
|
||||||
|
; Constructors / Destructors (optional)
|
||||||
|
; (constructor_declaration name: (identifier) @cg.name) @cg.node
|
||||||
|
; (#set! cg.kind "constructor")
|
||||||
|
;
|
||||||
|
; (destructor_declaration name: (identifier) @cg.name) @cg.node
|
||||||
|
; (#set! cg.kind "destructor")
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
program App;
|
||||||
|
|
||||||
|
{$APPTYPE CONSOLE}
|
||||||
|
|
||||||
|
uses
|
||||||
|
System.SysUtils,
|
||||||
|
UAuth in 'UAuth.pas';
|
||||||
|
|
||||||
|
var
|
||||||
|
Svc: TAuthService;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Svc := TAuthService.Create;
|
||||||
|
try
|
||||||
|
Writeln(Svc.Login('olaf', 'secret'));
|
||||||
|
finally
|
||||||
|
Svc.Free;
|
||||||
|
end;
|
||||||
|
end.
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
unit UAuth;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
System.SysUtils,
|
||||||
|
System.Classes;
|
||||||
|
|
||||||
|
type
|
||||||
|
ITokenValidator = interface
|
||||||
|
['{11111111-1111-1111-1111-111111111111}']
|
||||||
|
function Validate(const AToken: string): Boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TAuthService = class(TInterfacedObject, ITokenValidator)
|
||||||
|
public
|
||||||
|
function Validate(const AToken: string): Boolean;
|
||||||
|
function Login(const AUser, APass: string): string;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
function TAuthService.Validate(const AToken: string): Boolean;
|
||||||
|
begin
|
||||||
|
Result := AToken <> '';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TAuthService.Login(const AUser, APass: string): string;
|
||||||
|
begin
|
||||||
|
if Validate(AUser + ':' + APass) then
|
||||||
|
Result := 'ok'
|
||||||
|
else
|
||||||
|
Result := '';
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Unit Resolution Heuristics (uses → File)
|
||||||
|
|
||||||
|
## Input
|
||||||
|
|
||||||
|
- Extracted edges of kind `imports` from `uses` clauses.
|
||||||
|
- Extracted nodes of kind `unit|program|package|library` with their names.
|
||||||
|
|
||||||
|
## MVP Algorithm
|
||||||
|
|
||||||
|
1. Build `unitName -> nodeId` map for all indexed files.
|
||||||
|
2. For each `imports` edge with target name `X`:
|
||||||
|
- try exact match `X`
|
||||||
|
- try case-insensitive match
|
||||||
|
- try namespace normalization:
|
||||||
|
- `System.SysUtils` may correspond to unit `SysUtils` (optional heuristic)
|
||||||
|
3. If resolved: store `edge.to_node_id = targetNodeId`.
|
||||||
|
4. If not resolved: keep `edge.to_symbol = X` so search still works.
|
||||||
|
|
||||||
|
## DPR/DPK "in 'path'" cases (Phase 2)
|
||||||
|
|
||||||
|
In Delphi project files you can have:
|
||||||
|
|
||||||
|
```
|
||||||
|
uses
|
||||||
|
Foo in 'src/Foo.pas',
|
||||||
|
Bar in 'Bar.pas';
|
||||||
|
```
|
||||||
|
|
||||||
|
Enhancement:
|
||||||
|
- Parse optional path literal and resolve directly to file.
|
||||||
Reference in New Issue
Block a user