@mduenas/codegraph 0.5.6 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/bin/codegraph.js +16 -15
- package/dist/bin/codegraph.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +3 -3
- package/dist/context/index.js.map +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +10 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +11 -12
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/queries.d.ts +8 -0
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +51 -10
- package/dist/db/queries.js.map +1 -1
- package/dist/db/schema.sql +4 -0
- package/dist/extraction/index.d.ts.map +1 -1
- package/dist/extraction/index.js +104 -7
- package/dist/extraction/index.js.map +1 -1
- package/dist/extraction/tree-sitter.d.ts +76 -4
- package/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.js +627 -20
- package/dist/extraction/tree-sitter.js.map +1 -1
- package/dist/graph/traversal.d.ts.map +1 -1
- package/dist/graph/traversal.js +6 -2
- package/dist/graph/traversal.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -18
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +4 -0
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/tools.d.ts +13 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +70 -37
- package/dist/mcp/tools.js.map +1 -1
- package/dist/resolution/import-resolver.d.ts.map +1 -1
- package/dist/resolution/import-resolver.js +3 -4
- package/dist/resolution/import-resolver.js.map +1 -1
- package/dist/resolution/index.d.ts +21 -0
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +139 -24
- package/dist/resolution/index.js.map +1 -1
- package/dist/resolution/name-matcher.d.ts.map +1 -1
- package/dist/resolution/name-matcher.js +7 -20
- package/dist/resolution/name-matcher.js.map +1 -1
- package/dist/resolution/types.d.ts +4 -0
- package/dist/resolution/types.d.ts.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +42 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +111 -1
- package/dist/utils.js.map +1 -1
- package/dist/vectors/embedder.js +1 -1
- package/dist/vectors/embedder.js.map +1 -1
- package/dist/vectors/search.d.ts.map +1 -1
- package/dist/vectors/search.js +8 -7
- package/dist/vectors/search.js.map +1 -1
- package/package.json +1 -1
|
@@ -158,6 +158,116 @@ function isKotlinEnum(node) {
|
|
|
158
158
|
function isKotlinAbstractClass(node) {
|
|
159
159
|
return kotlinHasModifier(node, 'abstract');
|
|
160
160
|
}
|
|
161
|
+
// =============================================================================
|
|
162
|
+
// Swift-specific Helper Functions
|
|
163
|
+
// =============================================================================
|
|
164
|
+
/**
|
|
165
|
+
* Check if a Swift node has a specific modifier
|
|
166
|
+
*/
|
|
167
|
+
function swiftHasModifier(node, modifier) {
|
|
168
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
169
|
+
const child = node.child(i);
|
|
170
|
+
if (child?.type === 'modifiers' && child.text.includes(modifier)) {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Get the declaration kind from a Swift class_declaration
|
|
178
|
+
* Returns: 'class' | 'struct' | 'actor' | 'extension' | 'enum' | null
|
|
179
|
+
*/
|
|
180
|
+
function getSwiftDeclarationKind(node) {
|
|
181
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
182
|
+
const child = node.child(i);
|
|
183
|
+
if (child) {
|
|
184
|
+
if (child.type === 'class')
|
|
185
|
+
return 'class';
|
|
186
|
+
if (child.type === 'struct')
|
|
187
|
+
return 'struct';
|
|
188
|
+
if (child.type === 'actor')
|
|
189
|
+
return 'actor';
|
|
190
|
+
if (child.type === 'extension')
|
|
191
|
+
return 'extension';
|
|
192
|
+
if (child.type === 'enum')
|
|
193
|
+
return 'enum';
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Extract property wrapper attributes (e.g., @State, @Published)
|
|
200
|
+
*/
|
|
201
|
+
function getSwiftPropertyWrappers(node, source) {
|
|
202
|
+
const wrappers = [];
|
|
203
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
204
|
+
const child = node.child(i);
|
|
205
|
+
if (child?.type === 'attribute') {
|
|
206
|
+
const text = getNodeText(child, source);
|
|
207
|
+
wrappers.push(text);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return wrappers;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Get the name from a Swift class_declaration
|
|
214
|
+
* For extensions, returns the extended type name
|
|
215
|
+
*/
|
|
216
|
+
function getSwiftClassName(node, source) {
|
|
217
|
+
let name = '<unknown>';
|
|
218
|
+
let constraints = '';
|
|
219
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
220
|
+
const child = node.namedChild(i);
|
|
221
|
+
if (child?.type === 'type_identifier') {
|
|
222
|
+
name = getNodeText(child, source);
|
|
223
|
+
}
|
|
224
|
+
// For extensions, the name is in a user_type
|
|
225
|
+
if (child?.type === 'user_type') {
|
|
226
|
+
name = getNodeText(child, source);
|
|
227
|
+
}
|
|
228
|
+
// Capture type_constraints for extensions with where clauses
|
|
229
|
+
if (child?.type === 'type_constraints') {
|
|
230
|
+
constraints = ' ' + getNodeText(child, source);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return name + constraints;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Get the name from a Swift property_declaration
|
|
237
|
+
*/
|
|
238
|
+
function getSwiftPropertyName(node, source) {
|
|
239
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
240
|
+
const child = node.namedChild(i);
|
|
241
|
+
if (child?.type === 'pattern') {
|
|
242
|
+
// The simple_identifier is inside the pattern
|
|
243
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
244
|
+
const patternChild = child.namedChild(j);
|
|
245
|
+
if (patternChild?.type === 'simple_identifier') {
|
|
246
|
+
return getNodeText(patternChild, source);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return '<unknown>';
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Check if a Swift property is a constant (let vs var)
|
|
255
|
+
*/
|
|
256
|
+
function isSwiftConstant(node) {
|
|
257
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
258
|
+
const child = node.namedChild(i);
|
|
259
|
+
if (child?.type === 'value_binding_pattern') {
|
|
260
|
+
// Check for 'let' child
|
|
261
|
+
for (let j = 0; j < child.childCount; j++) {
|
|
262
|
+
const bindingChild = child.child(j);
|
|
263
|
+
if (bindingChild?.type === 'let') {
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
161
271
|
/**
|
|
162
272
|
* Language-specific extractors
|
|
163
273
|
*/
|
|
@@ -627,8 +737,13 @@ const EXTRACTORS = {
|
|
|
627
737
|
return false;
|
|
628
738
|
},
|
|
629
739
|
isAsync: (node) => {
|
|
740
|
+
// In Swift, async is a direct child node, not inside modifiers
|
|
630
741
|
for (let i = 0; i < node.childCount; i++) {
|
|
631
742
|
const child = node.child(i);
|
|
743
|
+
if (child?.type === 'async') {
|
|
744
|
+
return true;
|
|
745
|
+
}
|
|
746
|
+
// Also check modifiers for cases where it might be there
|
|
632
747
|
if (child?.type === 'modifiers' && child.text.includes('async')) {
|
|
633
748
|
return true;
|
|
634
749
|
}
|
|
@@ -821,13 +936,9 @@ class TreeSitterExtractor {
|
|
|
821
936
|
}
|
|
822
937
|
// Check for class declarations
|
|
823
938
|
else if (this.extractor.classTypes.includes(nodeType)) {
|
|
824
|
-
// Swift uses class_declaration for
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
this.extractStruct(node);
|
|
828
|
-
}
|
|
829
|
-
else if (this.language === 'swift' && this.hasChildOfType(node, 'enum')) {
|
|
830
|
-
this.extractEnum(node);
|
|
939
|
+
// Swift uses class_declaration for class, struct, actor, extension, enum
|
|
940
|
+
if (this.language === 'swift' && nodeType === 'class_declaration') {
|
|
941
|
+
this.extractSwiftClassDeclaration(node);
|
|
831
942
|
}
|
|
832
943
|
// Kotlin uses class_declaration for classes, interfaces, and enums
|
|
833
944
|
else if (this.language === 'kotlin' && nodeType === 'class_declaration') {
|
|
@@ -863,6 +974,37 @@ class TreeSitterExtractor {
|
|
|
863
974
|
else if (this.language === 'kotlin' && nodeType === 'type_alias') {
|
|
864
975
|
this.extractKotlinTypeAlias(node);
|
|
865
976
|
}
|
|
977
|
+
// Swift property_declaration (top-level or inside protocols)
|
|
978
|
+
else if (this.language === 'swift' && nodeType === 'property_declaration') {
|
|
979
|
+
this.extractSwiftProperty(node);
|
|
980
|
+
}
|
|
981
|
+
// Swift protocol_property_declaration
|
|
982
|
+
else if (this.language === 'swift' && nodeType === 'protocol_property_declaration') {
|
|
983
|
+
this.extractSwiftProperty(node);
|
|
984
|
+
}
|
|
985
|
+
// Swift subscript_declaration
|
|
986
|
+
else if (this.language === 'swift' && nodeType === 'subscript_declaration') {
|
|
987
|
+
this.extractSwiftSubscript(node);
|
|
988
|
+
skipChildren = true;
|
|
989
|
+
}
|
|
990
|
+
// Swift typealias_declaration
|
|
991
|
+
else if (this.language === 'swift' && nodeType === 'typealias_declaration') {
|
|
992
|
+
this.extractSwiftTypealias(node);
|
|
993
|
+
}
|
|
994
|
+
// Swift associatedtype_declaration
|
|
995
|
+
else if (this.language === 'swift' && nodeType === 'associatedtype_declaration') {
|
|
996
|
+
this.extractSwiftAssociatedType(node);
|
|
997
|
+
}
|
|
998
|
+
// Swift init_declaration
|
|
999
|
+
else if (this.language === 'swift' && nodeType === 'init_declaration') {
|
|
1000
|
+
this.extractSwiftInit(node);
|
|
1001
|
+
skipChildren = true;
|
|
1002
|
+
}
|
|
1003
|
+
// Swift deinit_declaration
|
|
1004
|
+
else if (this.language === 'swift' && nodeType === 'deinit_declaration') {
|
|
1005
|
+
this.extractSwiftDeinit(node);
|
|
1006
|
+
skipChildren = true;
|
|
1007
|
+
}
|
|
866
1008
|
// Check for method declarations (only if not already handled by functionTypes)
|
|
867
1009
|
else if (this.extractor.methodTypes.includes(nodeType)) {
|
|
868
1010
|
this.extractMethod(node);
|
|
@@ -870,7 +1012,13 @@ class TreeSitterExtractor {
|
|
|
870
1012
|
}
|
|
871
1013
|
// Check for interface/protocol/trait declarations
|
|
872
1014
|
else if (this.extractor.interfaceTypes.includes(nodeType)) {
|
|
873
|
-
|
|
1015
|
+
// Swift protocols need special handling for associated types
|
|
1016
|
+
if (this.language === 'swift' && nodeType === 'protocol_declaration') {
|
|
1017
|
+
this.extractSwiftProtocol(node);
|
|
1018
|
+
}
|
|
1019
|
+
else {
|
|
1020
|
+
this.extractInterface(node);
|
|
1021
|
+
}
|
|
874
1022
|
skipChildren = true; // extractInterface visits body children
|
|
875
1023
|
}
|
|
876
1024
|
// Check for struct declarations
|
|
@@ -949,18 +1097,6 @@ class TreeSitterExtractor {
|
|
|
949
1097
|
parts.push(name);
|
|
950
1098
|
return parts.join('::');
|
|
951
1099
|
}
|
|
952
|
-
/**
|
|
953
|
-
* Check if a node has a child of a specific type
|
|
954
|
-
*/
|
|
955
|
-
hasChildOfType(node, type) {
|
|
956
|
-
for (let i = 0; i < node.childCount; i++) {
|
|
957
|
-
const child = node.child(i);
|
|
958
|
-
if (child?.type === type) {
|
|
959
|
-
return true;
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
return false;
|
|
963
|
-
}
|
|
964
1100
|
/**
|
|
965
1101
|
* Extract a function
|
|
966
1102
|
*/
|
|
@@ -1522,6 +1658,477 @@ class TreeSitterExtractor {
|
|
|
1522
1658
|
}
|
|
1523
1659
|
}
|
|
1524
1660
|
}
|
|
1661
|
+
// =============================================================================
|
|
1662
|
+
// Swift-specific Extraction Methods
|
|
1663
|
+
// =============================================================================
|
|
1664
|
+
/**
|
|
1665
|
+
* Extract a Swift class declaration (handles class, struct, actor, extension, enum)
|
|
1666
|
+
*/
|
|
1667
|
+
extractSwiftClassDeclaration(node) {
|
|
1668
|
+
const declKind = getSwiftDeclarationKind(node);
|
|
1669
|
+
switch (declKind) {
|
|
1670
|
+
case 'extension':
|
|
1671
|
+
this.extractSwiftExtension(node);
|
|
1672
|
+
break;
|
|
1673
|
+
case 'actor':
|
|
1674
|
+
this.extractSwiftActor(node);
|
|
1675
|
+
break;
|
|
1676
|
+
case 'enum':
|
|
1677
|
+
this.extractSwiftEnum(node);
|
|
1678
|
+
break;
|
|
1679
|
+
case 'struct':
|
|
1680
|
+
this.extractSwiftStruct(node);
|
|
1681
|
+
break;
|
|
1682
|
+
default:
|
|
1683
|
+
this.extractSwiftClass(node);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
/**
|
|
1687
|
+
* Extract a Swift class
|
|
1688
|
+
*/
|
|
1689
|
+
extractSwiftClass(node) {
|
|
1690
|
+
if (!this.extractor)
|
|
1691
|
+
return;
|
|
1692
|
+
const name = getSwiftClassName(node, this.source);
|
|
1693
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
1694
|
+
const visibility = this.extractor.getVisibility?.(node);
|
|
1695
|
+
const isAbstract = swiftHasModifier(node, 'abstract');
|
|
1696
|
+
const classNode = this.createNode('class', name, node, {
|
|
1697
|
+
docstring,
|
|
1698
|
+
visibility,
|
|
1699
|
+
isAbstract,
|
|
1700
|
+
});
|
|
1701
|
+
// Extract inheritance
|
|
1702
|
+
this.extractSwiftInheritance(node, classNode.id);
|
|
1703
|
+
// Push to stack and visit body
|
|
1704
|
+
this.nodeStack.push(classNode.id);
|
|
1705
|
+
this.visitSwiftClassBody(node);
|
|
1706
|
+
this.nodeStack.pop();
|
|
1707
|
+
}
|
|
1708
|
+
/**
|
|
1709
|
+
* Extract a Swift struct
|
|
1710
|
+
*/
|
|
1711
|
+
extractSwiftStruct(node) {
|
|
1712
|
+
if (!this.extractor)
|
|
1713
|
+
return;
|
|
1714
|
+
const name = getSwiftClassName(node, this.source);
|
|
1715
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
1716
|
+
const visibility = this.extractor.getVisibility?.(node);
|
|
1717
|
+
const structNode = this.createNode('struct', name, node, {
|
|
1718
|
+
docstring,
|
|
1719
|
+
visibility,
|
|
1720
|
+
});
|
|
1721
|
+
// Extract protocol conformance
|
|
1722
|
+
this.extractSwiftInheritance(node, structNode.id);
|
|
1723
|
+
// Push to stack and visit body
|
|
1724
|
+
this.nodeStack.push(structNode.id);
|
|
1725
|
+
this.visitSwiftClassBody(node);
|
|
1726
|
+
this.nodeStack.pop();
|
|
1727
|
+
}
|
|
1728
|
+
/**
|
|
1729
|
+
* Extract a Swift actor declaration
|
|
1730
|
+
*/
|
|
1731
|
+
extractSwiftActor(node) {
|
|
1732
|
+
if (!this.extractor)
|
|
1733
|
+
return;
|
|
1734
|
+
const name = getSwiftClassName(node, this.source);
|
|
1735
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
1736
|
+
const visibility = this.extractor.getVisibility?.(node);
|
|
1737
|
+
// Actors are similar to classes but with built-in synchronization
|
|
1738
|
+
const actorNode = this.createNode('class', name, node, {
|
|
1739
|
+
docstring,
|
|
1740
|
+
visibility,
|
|
1741
|
+
});
|
|
1742
|
+
// Extract protocol conformance
|
|
1743
|
+
this.extractSwiftInheritance(node, actorNode.id);
|
|
1744
|
+
// Push to stack and visit body
|
|
1745
|
+
this.nodeStack.push(actorNode.id);
|
|
1746
|
+
this.visitSwiftClassBody(node);
|
|
1747
|
+
this.nodeStack.pop();
|
|
1748
|
+
}
|
|
1749
|
+
/**
|
|
1750
|
+
* Extract a Swift extension declaration
|
|
1751
|
+
*/
|
|
1752
|
+
extractSwiftExtension(node) {
|
|
1753
|
+
if (!this.extractor)
|
|
1754
|
+
return;
|
|
1755
|
+
// For extensions, the name is the extended type
|
|
1756
|
+
const name = getSwiftClassName(node, this.source);
|
|
1757
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
1758
|
+
const visibility = this.extractor.getVisibility?.(node);
|
|
1759
|
+
// Extensions are treated as classes extending the original type
|
|
1760
|
+
const extNode = this.createNode('class', name, node, {
|
|
1761
|
+
docstring,
|
|
1762
|
+
visibility,
|
|
1763
|
+
});
|
|
1764
|
+
// Extract protocol conformance added by the extension
|
|
1765
|
+
this.extractSwiftInheritance(node, extNode.id);
|
|
1766
|
+
// Push to stack and visit body
|
|
1767
|
+
this.nodeStack.push(extNode.id);
|
|
1768
|
+
this.visitSwiftClassBody(node);
|
|
1769
|
+
this.nodeStack.pop();
|
|
1770
|
+
}
|
|
1771
|
+
/**
|
|
1772
|
+
* Extract a Swift enum
|
|
1773
|
+
*/
|
|
1774
|
+
extractSwiftEnum(node) {
|
|
1775
|
+
if (!this.extractor)
|
|
1776
|
+
return;
|
|
1777
|
+
const name = getSwiftClassName(node, this.source);
|
|
1778
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
1779
|
+
const visibility = this.extractor.getVisibility?.(node);
|
|
1780
|
+
const enumNode = this.createNode('enum', name, node, {
|
|
1781
|
+
docstring,
|
|
1782
|
+
visibility,
|
|
1783
|
+
});
|
|
1784
|
+
// Extract protocol conformance
|
|
1785
|
+
this.extractSwiftInheritance(node, enumNode.id);
|
|
1786
|
+
// Push to stack and visit body (enum_class_body)
|
|
1787
|
+
this.nodeStack.push(enumNode.id);
|
|
1788
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
1789
|
+
const child = node.namedChild(i);
|
|
1790
|
+
if (child?.type === 'enum_class_body') {
|
|
1791
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
1792
|
+
const bodyChild = child.namedChild(j);
|
|
1793
|
+
if (bodyChild) {
|
|
1794
|
+
if (bodyChild.type === 'enum_entry') {
|
|
1795
|
+
this.extractSwiftEnumCase(bodyChild);
|
|
1796
|
+
}
|
|
1797
|
+
else {
|
|
1798
|
+
this.visitNode(bodyChild);
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
this.nodeStack.pop();
|
|
1805
|
+
}
|
|
1806
|
+
/**
|
|
1807
|
+
* Extract a Swift enum case
|
|
1808
|
+
*/
|
|
1809
|
+
extractSwiftEnumCase(node) {
|
|
1810
|
+
// Find the simple_identifier for the case name
|
|
1811
|
+
let name = '<unknown>';
|
|
1812
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
1813
|
+
const child = node.namedChild(i);
|
|
1814
|
+
if (child?.type === 'simple_identifier') {
|
|
1815
|
+
name = getNodeText(child, this.source);
|
|
1816
|
+
break;
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
this.createNode('enum_member', name, node, {});
|
|
1820
|
+
}
|
|
1821
|
+
/**
|
|
1822
|
+
* Extract a Swift property (stored or computed)
|
|
1823
|
+
*/
|
|
1824
|
+
extractSwiftProperty(node) {
|
|
1825
|
+
if (!this.extractor)
|
|
1826
|
+
return;
|
|
1827
|
+
const name = getSwiftPropertyName(node, this.source);
|
|
1828
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
1829
|
+
const visibility = this.extractor.getVisibility?.(node);
|
|
1830
|
+
const isConst = isSwiftConstant(node);
|
|
1831
|
+
const isStatic = this.extractor.isStatic?.(node);
|
|
1832
|
+
// Get property wrappers (decorators)
|
|
1833
|
+
const wrappers = getSwiftPropertyWrappers(node, this.source);
|
|
1834
|
+
const decorators = wrappers.length > 0 ? wrappers : undefined;
|
|
1835
|
+
// Use 'constant' for let, 'property' for var
|
|
1836
|
+
const kind = isConst && this.nodeStack.length === 0 ? 'constant' : 'property';
|
|
1837
|
+
this.createNode(kind, name, node, {
|
|
1838
|
+
docstring,
|
|
1839
|
+
visibility,
|
|
1840
|
+
isStatic,
|
|
1841
|
+
decorators,
|
|
1842
|
+
});
|
|
1843
|
+
}
|
|
1844
|
+
/**
|
|
1845
|
+
* Extract a Swift subscript declaration
|
|
1846
|
+
*/
|
|
1847
|
+
extractSwiftSubscript(node) {
|
|
1848
|
+
if (!this.extractor)
|
|
1849
|
+
return;
|
|
1850
|
+
// Subscripts are treated as methods
|
|
1851
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
1852
|
+
const visibility = this.extractor.getVisibility?.(node);
|
|
1853
|
+
const isStatic = this.extractor.isStatic?.(node);
|
|
1854
|
+
// Build signature from parameters and return type
|
|
1855
|
+
let signature = '';
|
|
1856
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
1857
|
+
const child = node.namedChild(i);
|
|
1858
|
+
if (child?.type === 'parameter') {
|
|
1859
|
+
if (signature)
|
|
1860
|
+
signature += ', ';
|
|
1861
|
+
signature += getNodeText(child, this.source);
|
|
1862
|
+
}
|
|
1863
|
+
else if (child?.type === 'user_type') {
|
|
1864
|
+
signature += ' -> ' + getNodeText(child, this.source);
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
this.createNode('method', 'subscript', node, {
|
|
1868
|
+
docstring,
|
|
1869
|
+
visibility,
|
|
1870
|
+
isStatic,
|
|
1871
|
+
signature: signature || undefined,
|
|
1872
|
+
});
|
|
1873
|
+
}
|
|
1874
|
+
/**
|
|
1875
|
+
* Extract a Swift typealias declaration
|
|
1876
|
+
*/
|
|
1877
|
+
extractSwiftTypealias(node) {
|
|
1878
|
+
// Find the type_identifier for the alias name
|
|
1879
|
+
let name = '<unknown>';
|
|
1880
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
1881
|
+
const child = node.namedChild(i);
|
|
1882
|
+
if (child?.type === 'type_identifier') {
|
|
1883
|
+
name = getNodeText(child, this.source);
|
|
1884
|
+
break;
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
1888
|
+
const visibility = this.extractor?.getVisibility?.(node);
|
|
1889
|
+
this.createNode('type_alias', name, node, {
|
|
1890
|
+
docstring,
|
|
1891
|
+
visibility,
|
|
1892
|
+
});
|
|
1893
|
+
}
|
|
1894
|
+
/**
|
|
1895
|
+
* Extract a Swift associated type declaration (in protocols)
|
|
1896
|
+
*/
|
|
1897
|
+
extractSwiftAssociatedType(node) {
|
|
1898
|
+
// Find the type_identifier for the associated type name
|
|
1899
|
+
let name = '<unknown>';
|
|
1900
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
1901
|
+
const child = node.namedChild(i);
|
|
1902
|
+
if (child?.type === 'type_identifier') {
|
|
1903
|
+
name = getNodeText(child, this.source);
|
|
1904
|
+
break;
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
1908
|
+
this.createNode('type_alias', name, node, {
|
|
1909
|
+
docstring,
|
|
1910
|
+
});
|
|
1911
|
+
}
|
|
1912
|
+
/**
|
|
1913
|
+
* Extract a Swift init declaration
|
|
1914
|
+
*/
|
|
1915
|
+
extractSwiftInit(node) {
|
|
1916
|
+
if (!this.extractor)
|
|
1917
|
+
return;
|
|
1918
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
1919
|
+
const visibility = this.extractor.getVisibility?.(node);
|
|
1920
|
+
const isAsync = this.extractor.isAsync?.(node);
|
|
1921
|
+
// Build signature from parameters
|
|
1922
|
+
let signature = '';
|
|
1923
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
1924
|
+
const child = node.namedChild(i);
|
|
1925
|
+
if (child?.type === 'parameter') {
|
|
1926
|
+
if (signature)
|
|
1927
|
+
signature += ', ';
|
|
1928
|
+
signature += getNodeText(child, this.source);
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
const initNode = this.createNode('method', 'init', node, {
|
|
1932
|
+
docstring,
|
|
1933
|
+
visibility,
|
|
1934
|
+
isAsync,
|
|
1935
|
+
signature: signature ? `(${signature})` : '()',
|
|
1936
|
+
});
|
|
1937
|
+
// Visit function body for calls
|
|
1938
|
+
this.nodeStack.push(initNode.id);
|
|
1939
|
+
this.visitSwiftFunctionBody(node);
|
|
1940
|
+
this.nodeStack.pop();
|
|
1941
|
+
}
|
|
1942
|
+
/**
|
|
1943
|
+
* Extract a Swift deinit declaration
|
|
1944
|
+
*/
|
|
1945
|
+
extractSwiftDeinit(node) {
|
|
1946
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
1947
|
+
const deinitNode = this.createNode('method', 'deinit', node, {
|
|
1948
|
+
docstring,
|
|
1949
|
+
});
|
|
1950
|
+
// Visit function body for calls
|
|
1951
|
+
this.nodeStack.push(deinitNode.id);
|
|
1952
|
+
this.visitSwiftFunctionBody(node);
|
|
1953
|
+
this.nodeStack.pop();
|
|
1954
|
+
}
|
|
1955
|
+
/**
|
|
1956
|
+
* Extract Swift inheritance (protocol conformance, superclass)
|
|
1957
|
+
*/
|
|
1958
|
+
extractSwiftInheritance(node, classId) {
|
|
1959
|
+
let isFirst = true;
|
|
1960
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
1961
|
+
const child = node.namedChild(i);
|
|
1962
|
+
if (child?.type === 'inheritance_specifier') {
|
|
1963
|
+
// Get the user_type inside inheritance_specifier
|
|
1964
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
1965
|
+
const specChild = child.namedChild(j);
|
|
1966
|
+
if (specChild?.type === 'user_type') {
|
|
1967
|
+
const typeName = getNodeText(specChild, this.source);
|
|
1968
|
+
// First inheritance is usually extends (for classes), rest are implements
|
|
1969
|
+
this.unresolvedReferences.push({
|
|
1970
|
+
fromNodeId: classId,
|
|
1971
|
+
referenceName: typeName,
|
|
1972
|
+
referenceKind: isFirst ? 'extends' : 'implements',
|
|
1973
|
+
line: specChild.startPosition.row + 1,
|
|
1974
|
+
column: specChild.startPosition.column,
|
|
1975
|
+
});
|
|
1976
|
+
isFirst = false;
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
/**
|
|
1983
|
+
* Extract a Swift protocol declaration
|
|
1984
|
+
*/
|
|
1985
|
+
extractSwiftProtocol(node) {
|
|
1986
|
+
if (!this.extractor)
|
|
1987
|
+
return;
|
|
1988
|
+
// Get protocol name
|
|
1989
|
+
let name = '<unknown>';
|
|
1990
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
1991
|
+
const child = node.namedChild(i);
|
|
1992
|
+
if (child?.type === 'type_identifier') {
|
|
1993
|
+
name = getNodeText(child, this.source);
|
|
1994
|
+
break;
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
1998
|
+
const visibility = this.extractor.getVisibility?.(node);
|
|
1999
|
+
const protocolNode = this.createNode('interface', name, node, {
|
|
2000
|
+
docstring,
|
|
2001
|
+
visibility,
|
|
2002
|
+
});
|
|
2003
|
+
// Extract protocol inheritance
|
|
2004
|
+
this.extractSwiftInheritance(node, protocolNode.id);
|
|
2005
|
+
// Push to stack and visit protocol body
|
|
2006
|
+
this.nodeStack.push(protocolNode.id);
|
|
2007
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
2008
|
+
const child = node.namedChild(i);
|
|
2009
|
+
if (child?.type === 'protocol_body') {
|
|
2010
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
2011
|
+
const bodyChild = child.namedChild(j);
|
|
2012
|
+
if (bodyChild) {
|
|
2013
|
+
if (bodyChild.type === 'associatedtype_declaration') {
|
|
2014
|
+
this.extractSwiftAssociatedType(bodyChild);
|
|
2015
|
+
}
|
|
2016
|
+
else if (bodyChild.type === 'protocol_property_declaration') {
|
|
2017
|
+
this.extractSwiftProtocolProperty(bodyChild);
|
|
2018
|
+
}
|
|
2019
|
+
else if (bodyChild.type === 'protocol_function_declaration') {
|
|
2020
|
+
this.extractSwiftProtocolFunction(bodyChild);
|
|
2021
|
+
}
|
|
2022
|
+
else {
|
|
2023
|
+
this.visitNode(bodyChild);
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
this.nodeStack.pop();
|
|
2030
|
+
}
|
|
2031
|
+
/**
|
|
2032
|
+
* Extract a Swift protocol property declaration
|
|
2033
|
+
*/
|
|
2034
|
+
extractSwiftProtocolProperty(node) {
|
|
2035
|
+
// Find the simple_identifier for the property name
|
|
2036
|
+
let name = '<unknown>';
|
|
2037
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
2038
|
+
const child = node.namedChild(i);
|
|
2039
|
+
if (child?.type === 'pattern') {
|
|
2040
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
2041
|
+
const patternChild = child.namedChild(j);
|
|
2042
|
+
if (patternChild?.type === 'simple_identifier') {
|
|
2043
|
+
name = getNodeText(patternChild, this.source);
|
|
2044
|
+
break;
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
}
|
|
2049
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
2050
|
+
this.createNode('property', name, node, {
|
|
2051
|
+
docstring,
|
|
2052
|
+
});
|
|
2053
|
+
}
|
|
2054
|
+
/**
|
|
2055
|
+
* Extract a Swift protocol function declaration
|
|
2056
|
+
*/
|
|
2057
|
+
extractSwiftProtocolFunction(node) {
|
|
2058
|
+
// Find the simple_identifier for the function name
|
|
2059
|
+
let name = '<unknown>';
|
|
2060
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
2061
|
+
const child = node.namedChild(i);
|
|
2062
|
+
if (child?.type === 'simple_identifier') {
|
|
2063
|
+
name = getNodeText(child, this.source);
|
|
2064
|
+
break;
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
const docstring = getPrecedingDocstring(node, this.source);
|
|
2068
|
+
// Build signature
|
|
2069
|
+
let signature = '';
|
|
2070
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
2071
|
+
const child = node.namedChild(i);
|
|
2072
|
+
if (child?.type === 'user_type') {
|
|
2073
|
+
signature = ' -> ' + getNodeText(child, this.source);
|
|
2074
|
+
break;
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
this.createNode('method', name, node, {
|
|
2078
|
+
docstring,
|
|
2079
|
+
signature: signature || undefined,
|
|
2080
|
+
});
|
|
2081
|
+
}
|
|
2082
|
+
/**
|
|
2083
|
+
* Visit a Swift class/struct/actor body and extract members
|
|
2084
|
+
*/
|
|
2085
|
+
visitSwiftClassBody(node) {
|
|
2086
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
2087
|
+
const child = node.namedChild(i);
|
|
2088
|
+
if (child?.type === 'class_body') {
|
|
2089
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
2090
|
+
const bodyChild = child.namedChild(j);
|
|
2091
|
+
if (bodyChild) {
|
|
2092
|
+
// Handle Swift-specific node types
|
|
2093
|
+
if (bodyChild.type === 'property_declaration') {
|
|
2094
|
+
this.extractSwiftProperty(bodyChild);
|
|
2095
|
+
}
|
|
2096
|
+
else if (bodyChild.type === 'subscript_declaration') {
|
|
2097
|
+
this.extractSwiftSubscript(bodyChild);
|
|
2098
|
+
}
|
|
2099
|
+
else if (bodyChild.type === 'init_declaration') {
|
|
2100
|
+
this.extractSwiftInit(bodyChild);
|
|
2101
|
+
}
|
|
2102
|
+
else if (bodyChild.type === 'deinit_declaration') {
|
|
2103
|
+
this.extractSwiftDeinit(bodyChild);
|
|
2104
|
+
}
|
|
2105
|
+
else if (bodyChild.type === 'typealias_declaration') {
|
|
2106
|
+
this.extractSwiftTypealias(bodyChild);
|
|
2107
|
+
}
|
|
2108
|
+
else {
|
|
2109
|
+
this.visitNode(bodyChild);
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
/**
|
|
2117
|
+
* Visit a Swift function body to extract calls
|
|
2118
|
+
*/
|
|
2119
|
+
visitSwiftFunctionBody(node) {
|
|
2120
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
2121
|
+
const child = node.namedChild(i);
|
|
2122
|
+
if (child?.type === 'function_body') {
|
|
2123
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
2124
|
+
const bodyChild = child.namedChild(j);
|
|
2125
|
+
if (bodyChild) {
|
|
2126
|
+
this.visitNode(bodyChild);
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
1525
2132
|
}
|
|
1526
2133
|
exports.TreeSitterExtractor = TreeSitterExtractor;
|
|
1527
2134
|
/**
|