|
|
@@ -1,53 +1,97 @@
|
|
|
-# Capture Convention (wie die `.scm` Queries an CodeGraph andocken)
|
|
|
+# Capture Convention: Wie Pascal/Delphi an CodeGraph andockt
|
|
|
|
|
|
-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**.
|
|
|
+## Architektur-Übersicht
|
|
|
|
|
|
-## Vorgehen
|
|
|
+CodeGraph verwendet **keine** `.scm`-Query-Dateien für die Extraktion. Stattdessen wird die Logik über ein `LanguageExtractor`-Objekt in `src/extraction/tree-sitter.ts` definiert. Dieses Objekt mappt tree-sitter AST-Knotentypen auf die interne Verarbeitungslogik.
|
|
|
|
|
|
-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.
|
|
|
+### Zentrale Dateien für die Integration
|
|
|
|
|
|
-## Empfohlene semantische Einteilung
|
|
|
+| Datei | Änderung |
|
|
|
+|---|---|
|
|
|
+| `src/extraction/grammars.ts` | Grammar-Loader, Extension-Mapping, Display-Name |
|
|
|
+| `src/types.ts` | `Language`-Union-Type, `DEFAULT_CONFIG.include` Patterns |
|
|
|
+| `src/extraction/tree-sitter.ts` | `EXTRACTORS`-Map mit `LanguageExtractor`-Konfiguration |
|
|
|
|
|
|
-Unabhängig von den konkreten Capture-Namen sollte jedes Query-Match folgende Informationen liefern:
|
|
|
+## LanguageExtractor-Interface
|
|
|
|
|
|
-### 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)
|
|
|
+Die Konfiguration definiert, welche AST-Knotentypen welcher Semantik entsprechen:
|
|
|
|
|
|
-### 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)
|
|
|
+```typescript
|
|
|
+interface LanguageExtractor {
|
|
|
+ functionTypes: string[]; // Top-Level Funktionen/Prozeduren
|
|
|
+ classTypes: string[]; // Klassen, Records, Objects
|
|
|
+ methodTypes: string[]; // Methoden, Konstruktoren, Destruktoren
|
|
|
+ interfaceTypes: string[]; // Interfaces
|
|
|
+ structTypes: string[]; // Structs (in Delphi: leer)
|
|
|
+ enumTypes: string[]; // Enums
|
|
|
+ typeAliasTypes: string[]; // Type-Aliase
|
|
|
+ importTypes: string[]; // uses-Klauseln
|
|
|
+ callTypes: string[]; // Funktionsaufrufe
|
|
|
+ variableTypes: string[]; // Variable/Feld-Deklarationen
|
|
|
+ nameField: string; // AST-Feld für den Namen
|
|
|
+ bodyField: string; // AST-Feld für den Body
|
|
|
+ paramsField: string; // AST-Feld für Parameter
|
|
|
+ returnField?: string; // AST-Feld für Rückgabetyp
|
|
|
+ getSignature?: (node, source) => string | undefined;
|
|
|
+ getVisibility?: (node) => 'public' | 'private' | 'protected' | 'internal' | undefined;
|
|
|
+ isExported?: (node, source) => boolean;
|
|
|
+ isStatic?: (node) => boolean;
|
|
|
+ isConst?: (node) => boolean;
|
|
|
+}
|
|
|
+```
|
|
|
|
|
|
-## Minimaler Capture-Satz (Pseudo)
|
|
|
+## Konkrete Zuordnung für Pascal/Delphi
|
|
|
|
|
|
-> **Wichtig:** Diese Namen sind **Platzhalter**. Bitte auf das CodeGraph-interne Schema mappen.
|
|
|
+| LanguageExtractor-Feld | tree-sitter-pascal Typ(en) | Anmerkung |
|
|
|
+|---|---|---|
|
|
|
+| `functionTypes` | `['declProc']` | Top-Level, gefiltert nach Kontext (kein Parent `declClass`) |
|
|
|
+| `classTypes` | `['declClass']` | Enthält class, record, object |
|
|
|
+| `methodTypes` | `['declProc']` | Innerhalb `declClass`, inkl. constructor/destructor |
|
|
|
+| `interfaceTypes` | `['declIntf']` | interface, dispinterface |
|
|
|
+| `structTypes` | `[]` | Records werden über `declClass` (mit `kRecord`) abgedeckt |
|
|
|
+| `enumTypes` | `['declEnum']` | Innerhalb von `declType` |
|
|
|
+| `typeAliasTypes` | `['declType']` | Einfache `type X = Y` Deklarationen |
|
|
|
+| `importTypes` | `['declUses']` | `uses`-Klauseln |
|
|
|
+| `callTypes` | `['exprCall']` | Funktions-/Methodenaufrufe |
|
|
|
+| `variableTypes` | `['declField', 'declConst']` | Felder und Konstanten |
|
|
|
+| `nameField` | `'name'` | `declProc`, `declConst`, `declField`, `declEnumValue` haben `name`-Feld |
|
|
|
+| `bodyField` | `'body'` | Nur bei `defProc` (Implementierungen) |
|
|
|
+| `paramsField` | `'args'` | `declProc` hat `args`-Feld (`declArgs`) |
|
|
|
+| `returnField` | `'type'` | `declProc` hat optionales `type`-Feld |
|
|
|
|
|
|
-- `@cg.node` mit Properties:
|
|
|
- - `(#set! cg.kind "class")`
|
|
|
- - `(#set! cg.name @nameCapture)` oder per separate captures
|
|
|
+## Delphi-spezifische Herausforderungen
|
|
|
|
|
|
-- `@cg.edge` mit Properties:
|
|
|
- - `(#set! cg.kind "calls")`
|
|
|
- - Zielsymbol als Capture: `@cg.target`
|
|
|
+### declProc: Funktion oder Methode?
|
|
|
|
|
|
-Wenn CodeGraph statt `#set!` eine feste Capture-Nomenklatur nutzt (z.B. `@definition.function`), dann übernimm exakt diese.
|
|
|
+`declProc` wird sowohl für Top-Level-Funktionen als auch für Methoden verwendet. Die Unterscheidung erfolgt über den Kontext:
|
|
|
+- **Top-Level**: Parent ist `interface` (der Unit-interface-Abschnitt) oder `implementation`
|
|
|
+- **Methode**: Parent ist `declClass` oder `declIntf`
|
|
|
+- **Kind-Unterscheidung**: Enthält `kProcedure`, `kFunction`, `kConstructor`, oder `kDestructor`
|
|
|
|
|
|
-## Delphi-spezifische Stolperfallen
|
|
|
+### Sichtbarkeit über declSection
|
|
|
|
|
|
-- `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`
|
|
|
+Delphi gruppiert Mitglieder in Sichtbarkeitsbereichen:
|
|
|
+```
|
|
|
+declClass → declSection (kPublic) → declProc, declField, declProp
|
|
|
+ → declSection (kPrivate) → declField
|
|
|
+```
|
|
|
+Die `getVisibility`-Funktion muss den nächsten `declSection`-Vorfahren inspizieren.
|
|
|
|
|
|
-Für MVP: **nicht perfekt auflösen**, aber **zuverlässig extrahieren**.
|
|
|
+### Vererbung und Interface-Implementierung
|
|
|
+
|
|
|
+`declClass` hat ein `parent`-Feld mit einer Liste von `typeref`-Knoten:
|
|
|
+- Der **erste** `typeref` ist typischerweise die Basisklasse (`extends`)
|
|
|
+- Weitere `typeref`s sind implementierte Interfaces (`implements`)
|
|
|
+
|
|
|
+### `with`-Statements (Phase 2)
|
|
|
+
|
|
|
+`with`-Statements erzeugen einen impliziten Scope, der Call-Qualifier verschleiert:
|
|
|
+```delphi
|
|
|
+with MyObj do
|
|
|
+ DoSomething; // ist eigentlich MyObj.DoSomething
|
|
|
+```
|
|
|
+Im MVP wird dies **nicht** aufgelöst – Calls innerhalb von `with` werden ohne Qualifier extrahiert.
|
|
|
+
|
|
|
+### Namespaces
|
|
|
+
|
|
|
+Delphi-Unit-Namen können Punkte enthalten (`System.SysUtils`). Der `moduleName`-Knoten enthält den vollständigen Namen. Die Resolution muss sowohl exakte Matches als auch Suffix-Matches unterstützen.
|