- Alle Docs auf verifizierte AST-Knotentypen aktualisiert (declClass, declIntf, declProc, etc.) - Scaffold/ entfernt und durch konkreten Integration Guide ersetzt (06-Integration-Guide.md) - Neue Docs: AST-Referenz (03), NodeKind-Mapping (05), Integration Guide (06) - Checklist um bekannte Einschränkungen erweitert (with-Statements, .dfm/.fmx, Generics) - UAuth.pas erweitert: Sichtbarkeitsbereiche, Felder, Properties, Constructor/Destructor - UTypes.pas neu: Enums, Records, Type-Aliase, Konstanten, Class Methods, verschachtelte Typen - UnitResolution.md mit konkreten AST-Strukturen aktualisiert - README.md an neue Architektur-Beschreibung angepasst
4.5 KiB
Capture Convention: Wie Pascal/Delphi an CodeGraph andockt
Architektur-Übersicht
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.
Zentrale Dateien für die Integration
| 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 |
LanguageExtractor-Interface
Die Konfiguration definiert, welche AST-Knotentypen welcher Semantik entsprechen:
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;
}
Konkrete Zuordnung für Pascal/Delphi
| 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 |
Delphi-spezifische Herausforderungen
declProc: Funktion oder Methode?
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) oderimplementation - Methode: Parent ist
declClassoderdeclIntf - Kind-Unterscheidung: Enthält
kProcedure,kFunction,kConstructor, oderkDestructor
Sichtbarkeit über declSection
Delphi gruppiert Mitglieder in Sichtbarkeitsbereichen:
declClass → declSection (kPublic) → declProc, declField, declProp
→ declSection (kPrivate) → declField
Die getVisibility-Funktion muss den nächsten declSection-Vorfahren inspizieren.
Vererbung und Interface-Implementierung
declClass hat ein parent-Feld mit einer Liste von typeref-Knoten:
- Der erste
typerefist typischerweise die Basisklasse (extends) - Weitere
typerefs sind implementierte Interfaces (implements)
with-Statements (Phase 2)
with-Statements erzeugen einen impliziten Scope, der Call-Qualifier verschleiert:
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.