driftdetect-core 0.1.2 → 0.3.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.
Files changed (193) hide show
  1. package/dist/boundaries/boundary-store.d.ts +92 -0
  2. package/dist/boundaries/boundary-store.d.ts.map +1 -0
  3. package/dist/boundaries/boundary-store.js +458 -0
  4. package/dist/boundaries/boundary-store.js.map +1 -0
  5. package/dist/boundaries/index.d.ts +8 -0
  6. package/dist/boundaries/index.d.ts.map +1 -0
  7. package/dist/boundaries/index.js +8 -0
  8. package/dist/boundaries/index.js.map +1 -0
  9. package/dist/boundaries/types.d.ts +237 -0
  10. package/dist/boundaries/types.d.ts.map +1 -0
  11. package/dist/boundaries/types.js +8 -0
  12. package/dist/boundaries/types.js.map +1 -0
  13. package/dist/dna/ai-context.d.ts +10 -0
  14. package/dist/dna/ai-context.d.ts.map +1 -0
  15. package/dist/dna/ai-context.js +46 -0
  16. package/dist/dna/ai-context.js.map +1 -0
  17. package/dist/dna/dna-analyzer.d.ts +34 -0
  18. package/dist/dna/dna-analyzer.d.ts.map +1 -0
  19. package/dist/dna/dna-analyzer.js +110 -0
  20. package/dist/dna/dna-analyzer.js.map +1 -0
  21. package/dist/dna/dna-store.d.ts +13 -0
  22. package/dist/dna/dna-store.d.ts.map +1 -0
  23. package/dist/dna/dna-store.js +43 -0
  24. package/dist/dna/dna-store.js.map +1 -0
  25. package/dist/dna/gene-extractors/animation-approach.d.ts +15 -0
  26. package/dist/dna/gene-extractors/animation-approach.d.ts.map +1 -0
  27. package/dist/dna/gene-extractors/animation-approach.js +97 -0
  28. package/dist/dna/gene-extractors/animation-approach.js.map +1 -0
  29. package/dist/dna/gene-extractors/base-extractor.d.ts +53 -0
  30. package/dist/dna/gene-extractors/base-extractor.d.ts.map +1 -0
  31. package/dist/dna/gene-extractors/base-extractor.js +76 -0
  32. package/dist/dna/gene-extractors/base-extractor.js.map +1 -0
  33. package/dist/dna/gene-extractors/index.d.ts +16 -0
  34. package/dist/dna/gene-extractors/index.d.ts.map +1 -0
  35. package/dist/dna/gene-extractors/index.js +38 -0
  36. package/dist/dna/gene-extractors/index.js.map +1 -0
  37. package/dist/dna/gene-extractors/responsive-approach.d.ts +10 -0
  38. package/dist/dna/gene-extractors/responsive-approach.d.ts.map +1 -0
  39. package/dist/dna/gene-extractors/responsive-approach.js +30 -0
  40. package/dist/dna/gene-extractors/responsive-approach.js.map +1 -0
  41. package/dist/dna/gene-extractors/spacing-philosophy.d.ts +10 -0
  42. package/dist/dna/gene-extractors/spacing-philosophy.d.ts.map +1 -0
  43. package/dist/dna/gene-extractors/spacing-philosophy.js +30 -0
  44. package/dist/dna/gene-extractors/spacing-philosophy.js.map +1 -0
  45. package/dist/dna/gene-extractors/state-styling.d.ts +10 -0
  46. package/dist/dna/gene-extractors/state-styling.d.ts.map +1 -0
  47. package/dist/dna/gene-extractors/state-styling.js +29 -0
  48. package/dist/dna/gene-extractors/state-styling.js.map +1 -0
  49. package/dist/dna/gene-extractors/theming.d.ts +10 -0
  50. package/dist/dna/gene-extractors/theming.d.ts.map +1 -0
  51. package/dist/dna/gene-extractors/theming.js +30 -0
  52. package/dist/dna/gene-extractors/theming.js.map +1 -0
  53. package/dist/dna/gene-extractors/variant-handling.d.ts +13 -0
  54. package/dist/dna/gene-extractors/variant-handling.d.ts.map +1 -0
  55. package/dist/dna/gene-extractors/variant-handling.js +38 -0
  56. package/dist/dna/gene-extractors/variant-handling.js.map +1 -0
  57. package/dist/dna/health-calculator.d.ts +21 -0
  58. package/dist/dna/health-calculator.d.ts.map +1 -0
  59. package/dist/dna/health-calculator.js +113 -0
  60. package/dist/dna/health-calculator.js.map +1 -0
  61. package/dist/dna/index.d.ts +21 -0
  62. package/dist/dna/index.d.ts.map +1 -0
  63. package/dist/dna/index.js +19 -0
  64. package/dist/dna/index.js.map +1 -0
  65. package/dist/dna/mutation-detector.d.ts +10 -0
  66. package/dist/dna/mutation-detector.d.ts.map +1 -0
  67. package/dist/dna/mutation-detector.js +39 -0
  68. package/dist/dna/mutation-detector.js.map +1 -0
  69. package/dist/dna/playbook-generator.d.ts +6 -0
  70. package/dist/dna/playbook-generator.d.ts.map +1 -0
  71. package/dist/dna/playbook-generator.js +53 -0
  72. package/dist/dna/playbook-generator.js.map +1 -0
  73. package/dist/dna/types.d.ts +95 -0
  74. package/dist/dna/types.d.ts.map +1 -0
  75. package/dist/dna/types.js +8 -0
  76. package/dist/dna/types.js.map +1 -0
  77. package/dist/index.d.ts +7 -0
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +10 -0
  80. package/dist/index.js.map +1 -1
  81. package/dist/parsers/parser-manager.d.ts.map +1 -1
  82. package/dist/parsers/parser-manager.js +2 -0
  83. package/dist/parsers/parser-manager.js.map +1 -1
  84. package/dist/parsers/tree-sitter/config.d.ts +82 -0
  85. package/dist/parsers/tree-sitter/config.d.ts.map +1 -0
  86. package/dist/parsers/tree-sitter/config.js +200 -0
  87. package/dist/parsers/tree-sitter/config.js.map +1 -0
  88. package/dist/parsers/tree-sitter/csharp-ast-converter.d.ts +64 -0
  89. package/dist/parsers/tree-sitter/csharp-ast-converter.d.ts.map +1 -0
  90. package/dist/parsers/tree-sitter/csharp-ast-converter.js +271 -0
  91. package/dist/parsers/tree-sitter/csharp-ast-converter.js.map +1 -0
  92. package/dist/parsers/tree-sitter/csharp-loader.d.ts +43 -0
  93. package/dist/parsers/tree-sitter/csharp-loader.d.ts.map +1 -0
  94. package/dist/parsers/tree-sitter/csharp-loader.js +146 -0
  95. package/dist/parsers/tree-sitter/csharp-loader.js.map +1 -0
  96. package/dist/parsers/tree-sitter/index.d.ts +26 -0
  97. package/dist/parsers/tree-sitter/index.d.ts.map +1 -0
  98. package/dist/parsers/tree-sitter/index.js +47 -0
  99. package/dist/parsers/tree-sitter/index.js.map +1 -0
  100. package/dist/parsers/tree-sitter/java/annotation-extractor.d.ts +79 -0
  101. package/dist/parsers/tree-sitter/java/annotation-extractor.d.ts.map +1 -0
  102. package/dist/parsers/tree-sitter/java/annotation-extractor.js +540 -0
  103. package/dist/parsers/tree-sitter/java/annotation-extractor.js.map +1 -0
  104. package/dist/parsers/tree-sitter/java/class-extractor.d.ts +40 -0
  105. package/dist/parsers/tree-sitter/java/class-extractor.d.ts.map +1 -0
  106. package/dist/parsers/tree-sitter/java/class-extractor.js +770 -0
  107. package/dist/parsers/tree-sitter/java/class-extractor.js.map +1 -0
  108. package/dist/parsers/tree-sitter/java/index.d.ts +14 -0
  109. package/dist/parsers/tree-sitter/java/index.d.ts.map +1 -0
  110. package/dist/parsers/tree-sitter/java/index.js +25 -0
  111. package/dist/parsers/tree-sitter/java/index.js.map +1 -0
  112. package/dist/parsers/tree-sitter/java/method-extractor.d.ts +88 -0
  113. package/dist/parsers/tree-sitter/java/method-extractor.d.ts.map +1 -0
  114. package/dist/parsers/tree-sitter/java/method-extractor.js +551 -0
  115. package/dist/parsers/tree-sitter/java/method-extractor.js.map +1 -0
  116. package/dist/parsers/tree-sitter/java/types.d.ts +545 -0
  117. package/dist/parsers/tree-sitter/java/types.d.ts.map +1 -0
  118. package/dist/parsers/tree-sitter/java/types.js +81 -0
  119. package/dist/parsers/tree-sitter/java/types.js.map +1 -0
  120. package/dist/parsers/tree-sitter/loader.d.ts +50 -0
  121. package/dist/parsers/tree-sitter/loader.d.ts.map +1 -0
  122. package/dist/parsers/tree-sitter/loader.js +156 -0
  123. package/dist/parsers/tree-sitter/loader.js.map +1 -0
  124. package/dist/parsers/tree-sitter/pydantic/config-extractor.d.ts +78 -0
  125. package/dist/parsers/tree-sitter/pydantic/config-extractor.d.ts.map +1 -0
  126. package/dist/parsers/tree-sitter/pydantic/config-extractor.js +278 -0
  127. package/dist/parsers/tree-sitter/pydantic/config-extractor.js.map +1 -0
  128. package/dist/parsers/tree-sitter/pydantic/constraint-parser.d.ts +84 -0
  129. package/dist/parsers/tree-sitter/pydantic/constraint-parser.d.ts.map +1 -0
  130. package/dist/parsers/tree-sitter/pydantic/constraint-parser.js +321 -0
  131. package/dist/parsers/tree-sitter/pydantic/constraint-parser.js.map +1 -0
  132. package/dist/parsers/tree-sitter/pydantic/field-extractor.d.ts +74 -0
  133. package/dist/parsers/tree-sitter/pydantic/field-extractor.d.ts.map +1 -0
  134. package/dist/parsers/tree-sitter/pydantic/field-extractor.js +285 -0
  135. package/dist/parsers/tree-sitter/pydantic/field-extractor.js.map +1 -0
  136. package/dist/parsers/tree-sitter/pydantic/index.d.ts +18 -0
  137. package/dist/parsers/tree-sitter/pydantic/index.d.ts.map +1 -0
  138. package/dist/parsers/tree-sitter/pydantic/index.js +23 -0
  139. package/dist/parsers/tree-sitter/pydantic/index.js.map +1 -0
  140. package/dist/parsers/tree-sitter/pydantic/inheritance-resolver.d.ts +70 -0
  141. package/dist/parsers/tree-sitter/pydantic/inheritance-resolver.d.ts.map +1 -0
  142. package/dist/parsers/tree-sitter/pydantic/inheritance-resolver.js +251 -0
  143. package/dist/parsers/tree-sitter/pydantic/inheritance-resolver.js.map +1 -0
  144. package/dist/parsers/tree-sitter/pydantic/pydantic-extractor.d.ts +102 -0
  145. package/dist/parsers/tree-sitter/pydantic/pydantic-extractor.d.ts.map +1 -0
  146. package/dist/parsers/tree-sitter/pydantic/pydantic-extractor.js +399 -0
  147. package/dist/parsers/tree-sitter/pydantic/pydantic-extractor.js.map +1 -0
  148. package/dist/parsers/tree-sitter/pydantic/type-resolver.d.ts +89 -0
  149. package/dist/parsers/tree-sitter/pydantic/type-resolver.d.ts.map +1 -0
  150. package/dist/parsers/tree-sitter/pydantic/type-resolver.js +426 -0
  151. package/dist/parsers/tree-sitter/pydantic/type-resolver.js.map +1 -0
  152. package/dist/parsers/tree-sitter/pydantic/types.d.ts +177 -0
  153. package/dist/parsers/tree-sitter/pydantic/types.d.ts.map +1 -0
  154. package/dist/parsers/tree-sitter/pydantic/types.js +139 -0
  155. package/dist/parsers/tree-sitter/pydantic/types.js.map +1 -0
  156. package/dist/parsers/tree-sitter/pydantic/validator-extractor.d.ts +88 -0
  157. package/dist/parsers/tree-sitter/pydantic/validator-extractor.d.ts.map +1 -0
  158. package/dist/parsers/tree-sitter/pydantic/validator-extractor.js +315 -0
  159. package/dist/parsers/tree-sitter/pydantic/validator-extractor.js.map +1 -0
  160. package/dist/parsers/tree-sitter/python-ast-converter.d.ts +140 -0
  161. package/dist/parsers/tree-sitter/python-ast-converter.d.ts.map +1 -0
  162. package/dist/parsers/tree-sitter/python-ast-converter.js +360 -0
  163. package/dist/parsers/tree-sitter/python-ast-converter.js.map +1 -0
  164. package/dist/parsers/tree-sitter/tree-sitter-csharp-parser.d.ts +465 -0
  165. package/dist/parsers/tree-sitter/tree-sitter-csharp-parser.d.ts.map +1 -0
  166. package/dist/parsers/tree-sitter/tree-sitter-csharp-parser.js +1146 -0
  167. package/dist/parsers/tree-sitter/tree-sitter-csharp-parser.js.map +1 -0
  168. package/dist/parsers/tree-sitter/tree-sitter-python-parser.d.ts +86 -0
  169. package/dist/parsers/tree-sitter/tree-sitter-python-parser.d.ts.map +1 -0
  170. package/dist/parsers/tree-sitter/tree-sitter-python-parser.js +177 -0
  171. package/dist/parsers/tree-sitter/tree-sitter-python-parser.js.map +1 -0
  172. package/dist/parsers/tree-sitter/types.d.ts +399 -0
  173. package/dist/parsers/tree-sitter/types.d.ts.map +1 -0
  174. package/dist/parsers/tree-sitter/types.js +20 -0
  175. package/dist/parsers/tree-sitter/types.js.map +1 -0
  176. package/dist/parsers/types.d.ts +1 -1
  177. package/dist/parsers/types.d.ts.map +1 -1
  178. package/dist/scanner/file-walker.d.ts.map +1 -1
  179. package/dist/scanner/file-walker.js +5 -0
  180. package/dist/scanner/file-walker.js.map +1 -1
  181. package/dist/store/history-store.d.ts +85 -269
  182. package/dist/store/history-store.d.ts.map +1 -1
  183. package/dist/store/history-store.js +272 -624
  184. package/dist/store/history-store.js.map +1 -1
  185. package/dist/types/index.d.ts +1 -0
  186. package/dist/types/index.d.ts.map +1 -1
  187. package/dist/types/index.js +2 -0
  188. package/dist/types/index.js.map +1 -1
  189. package/dist/types/java-type-mapping.d.ts +79 -0
  190. package/dist/types/java-type-mapping.d.ts.map +1 -0
  191. package/dist/types/java-type-mapping.js +290 -0
  192. package/dist/types/java-type-mapping.js.map +1 -0
  193. package/package.json +8 -3
@@ -0,0 +1,1146 @@
1
+ /**
2
+ * Tree-sitter C# Parser
3
+ *
4
+ * C# parsing using tree-sitter-c-sharp with semantic extraction.
5
+ * Extracts usings, namespaces, classes, records, structs, interfaces,
6
+ * methods, properties, fields, and attributes.
7
+ *
8
+ * @requirements 3.2 - Support C# language
9
+ */
10
+ import { BaseParser } from '../base-parser.js';
11
+ import { isCSharpTreeSitterAvailable, createCSharpParser, getCSharpLoadingError } from './csharp-loader.js';
12
+ import { CSharpASTConverter } from './csharp-ast-converter.js';
13
+ // ============================================
14
+ // Parser Implementation
15
+ // ============================================
16
+ /**
17
+ * Tree-sitter C# Parser
18
+ *
19
+ * Parses C# source code using tree-sitter-c-sharp and extracts
20
+ * semantic information including classes, records, methods, etc.
21
+ */
22
+ export class TreeSitterCSharpParser extends BaseParser {
23
+ language = 'csharp';
24
+ extensions = ['.cs'];
25
+ parser = null;
26
+ converter;
27
+ currentNamespace = null;
28
+ constructor() {
29
+ super();
30
+ this.converter = new CSharpASTConverter();
31
+ }
32
+ /**
33
+ * Check if tree-sitter-c-sharp is available.
34
+ */
35
+ static isAvailable() {
36
+ return isCSharpTreeSitterAvailable();
37
+ }
38
+ /**
39
+ * Get the loading error if tree-sitter-c-sharp failed to load.
40
+ */
41
+ static getLoadingError() {
42
+ return getCSharpLoadingError();
43
+ }
44
+ /**
45
+ * Initialize the parser (lazy loading).
46
+ */
47
+ ensureParser() {
48
+ if (!this.parser) {
49
+ if (!isCSharpTreeSitterAvailable()) {
50
+ throw new Error(`C# parser not available: ${getCSharpLoadingError() ?? 'unknown error'}`);
51
+ }
52
+ this.parser = createCSharpParser();
53
+ }
54
+ return this.parser;
55
+ }
56
+ /**
57
+ * Parse C# source code.
58
+ */
59
+ parse(source, _filePath) {
60
+ try {
61
+ const parser = this.ensureParser();
62
+ const tree = parser.parse(source);
63
+ // Convert to drift AST
64
+ const rootNode = this.converter.convert(tree.rootNode);
65
+ const ast = {
66
+ rootNode,
67
+ text: source,
68
+ };
69
+ // Reset namespace tracking
70
+ this.currentNamespace = null;
71
+ // Extract semantic information
72
+ const usings = this.extractUsings(tree.rootNode);
73
+ const globalUsings = usings.filter(u => u.isGlobal);
74
+ const namespaces = this.extractNamespaces(tree.rootNode);
75
+ const classes = this.extractClasses(tree.rootNode);
76
+ const records = this.extractRecords(tree.rootNode);
77
+ const structs = this.extractStructs(tree.rootNode);
78
+ const interfaces = this.extractInterfaces(tree.rootNode);
79
+ const enums = this.extractEnums(tree.rootNode);
80
+ const topLevelStatements = this.hasTopLevelStatements(tree.rootNode);
81
+ return {
82
+ ast,
83
+ language: 'csharp',
84
+ errors: [],
85
+ success: true,
86
+ usings,
87
+ globalUsings,
88
+ namespaces,
89
+ classes,
90
+ records,
91
+ structs,
92
+ interfaces,
93
+ enums,
94
+ topLevelStatements,
95
+ };
96
+ }
97
+ catch (error) {
98
+ const errorMessage = error instanceof Error ? error.message : 'Unknown parse error';
99
+ return {
100
+ ast: null,
101
+ language: 'csharp',
102
+ errors: [{ message: errorMessage, position: { row: 0, column: 0 } }],
103
+ success: false,
104
+ usings: [],
105
+ globalUsings: [],
106
+ namespaces: [],
107
+ classes: [],
108
+ records: [],
109
+ structs: [],
110
+ interfaces: [],
111
+ enums: [],
112
+ topLevelStatements: false,
113
+ };
114
+ }
115
+ }
116
+ /**
117
+ * Query the AST for nodes matching a pattern.
118
+ */
119
+ query(ast, pattern) {
120
+ return this.findNodesByType(ast, pattern);
121
+ }
122
+ // ============================================
123
+ // Extraction Methods
124
+ // ============================================
125
+ extractUsings(root) {
126
+ const usings = [];
127
+ for (const child of root.children) {
128
+ if (child.type === 'using_directive') {
129
+ usings.push(this.parseUsingDirective(child));
130
+ }
131
+ else if (child.type === 'global_statement') {
132
+ // Check for global using
133
+ const usingChild = child.children.find(c => c.type === 'using_directive');
134
+ if (usingChild) {
135
+ const using = this.parseUsingDirective(usingChild);
136
+ using.isGlobal = true;
137
+ usings.push(using);
138
+ }
139
+ }
140
+ }
141
+ return usings;
142
+ }
143
+ parseUsingDirective(node) {
144
+ let namespace = '';
145
+ let alias = null;
146
+ let isStatic = false;
147
+ let isGlobal = false;
148
+ for (const child of node.children) {
149
+ if (child.type === 'identifier' || child.type === 'qualified_name') {
150
+ namespace = child.text;
151
+ }
152
+ else if (child.type === 'name_equals') {
153
+ alias = child.children.find(c => c.type === 'identifier')?.text ?? null;
154
+ }
155
+ else if (child.text === 'static') {
156
+ isStatic = true;
157
+ }
158
+ else if (child.text === 'global') {
159
+ isGlobal = true;
160
+ }
161
+ }
162
+ return {
163
+ namespace,
164
+ alias,
165
+ isStatic,
166
+ isGlobal,
167
+ startPosition: { row: node.startPosition.row, column: node.startPosition.column },
168
+ endPosition: { row: node.endPosition.row, column: node.endPosition.column },
169
+ };
170
+ }
171
+ extractNamespaces(root) {
172
+ const namespaces = [];
173
+ for (const child of root.children) {
174
+ if (child.type === 'namespace_declaration') {
175
+ namespaces.push(this.parseNamespace(child, false));
176
+ }
177
+ else if (child.type === 'file_scoped_namespace_declaration') {
178
+ namespaces.push(this.parseNamespace(child, true));
179
+ }
180
+ }
181
+ return namespaces;
182
+ }
183
+ parseNamespace(node, isFileScoped) {
184
+ let name = '';
185
+ for (const child of node.children) {
186
+ if (child.type === 'identifier' || child.type === 'qualified_name') {
187
+ name = child.text;
188
+ this.currentNamespace = name;
189
+ break;
190
+ }
191
+ }
192
+ return {
193
+ name,
194
+ isFileScoped,
195
+ startPosition: { row: node.startPosition.row, column: node.startPosition.column },
196
+ endPosition: { row: node.endPosition.row, column: node.endPosition.column },
197
+ };
198
+ }
199
+ extractClasses(root) {
200
+ const classes = [];
201
+ this.findNodesOfType(root, 'class_declaration', (node) => {
202
+ classes.push(this.parseClass(node));
203
+ });
204
+ return classes;
205
+ }
206
+ parseClass(node) {
207
+ const info = {
208
+ name: '',
209
+ namespace: this.currentNamespace,
210
+ baseClass: null,
211
+ interfaces: [],
212
+ genericParameters: [],
213
+ attributes: [],
214
+ methods: [],
215
+ properties: [],
216
+ fields: [],
217
+ constructors: [],
218
+ nestedTypes: [],
219
+ accessibility: 'internal',
220
+ isStatic: false,
221
+ isAbstract: false,
222
+ isSealed: false,
223
+ isPartial: false,
224
+ startPosition: { row: node.startPosition.row, column: node.startPosition.column },
225
+ endPosition: { row: node.endPosition.row, column: node.endPosition.column },
226
+ };
227
+ for (const child of node.children) {
228
+ switch (child.type) {
229
+ case 'identifier':
230
+ info.name = child.text;
231
+ break;
232
+ case 'attribute_list':
233
+ info.attributes.push(...this.parseAttributeList(child));
234
+ break;
235
+ case 'modifier':
236
+ this.applyModifier(info, child.text);
237
+ break;
238
+ case 'type_parameter_list':
239
+ info.genericParameters = this.parseTypeParameters(child);
240
+ break;
241
+ case 'base_list':
242
+ const bases = this.parseBaseList(child);
243
+ if (bases.length > 0) {
244
+ // First non-interface is base class
245
+ const firstBase = bases[0];
246
+ if (!firstBase.startsWith('I') || firstBase.length === 1 || !this.isUpperCase(firstBase[1])) {
247
+ info.baseClass = firstBase;
248
+ info.interfaces = bases.slice(1);
249
+ }
250
+ else {
251
+ info.interfaces = bases;
252
+ }
253
+ }
254
+ break;
255
+ case 'declaration_list':
256
+ this.parseClassMembers(child, info);
257
+ break;
258
+ }
259
+ }
260
+ return info;
261
+ }
262
+ parseClassMembers(node, classInfo) {
263
+ for (const child of node.children) {
264
+ switch (child.type) {
265
+ case 'method_declaration':
266
+ classInfo.methods.push(this.parseMethod(child));
267
+ break;
268
+ case 'property_declaration':
269
+ classInfo.properties.push(this.parseProperty(child));
270
+ break;
271
+ case 'field_declaration':
272
+ classInfo.fields.push(...this.parseField(child));
273
+ break;
274
+ case 'constructor_declaration':
275
+ classInfo.constructors.push(this.parseConstructor(child));
276
+ break;
277
+ case 'class_declaration':
278
+ case 'struct_declaration':
279
+ case 'interface_declaration':
280
+ case 'enum_declaration':
281
+ case 'record_declaration':
282
+ const nestedName = child.children.find(c => c.type === 'identifier')?.text;
283
+ if (nestedName) {
284
+ classInfo.nestedTypes.push(nestedName);
285
+ }
286
+ break;
287
+ }
288
+ }
289
+ }
290
+ extractRecords(root) {
291
+ const records = [];
292
+ this.findNodesOfType(root, 'record_declaration', (node) => {
293
+ records.push(this.parseRecord(node));
294
+ });
295
+ return records;
296
+ }
297
+ parseRecord(node) {
298
+ const info = {
299
+ name: '',
300
+ namespace: this.currentNamespace,
301
+ isStruct: false,
302
+ primaryConstructorParams: [],
303
+ baseRecord: null,
304
+ interfaces: [],
305
+ genericParameters: [],
306
+ attributes: [],
307
+ methods: [],
308
+ properties: [],
309
+ accessibility: 'internal',
310
+ isSealed: false,
311
+ isAbstract: false,
312
+ isPartial: false,
313
+ startPosition: { row: node.startPosition.row, column: node.startPosition.column },
314
+ endPosition: { row: node.endPosition.row, column: node.endPosition.column },
315
+ };
316
+ for (const child of node.children) {
317
+ switch (child.type) {
318
+ case 'identifier':
319
+ info.name = child.text;
320
+ break;
321
+ case 'struct':
322
+ info.isStruct = true;
323
+ break;
324
+ case 'attribute_list':
325
+ info.attributes.push(...this.parseAttributeList(child));
326
+ break;
327
+ case 'modifier':
328
+ this.applyRecordModifier(info, child.text);
329
+ break;
330
+ case 'type_parameter_list':
331
+ info.genericParameters = this.parseTypeParameters(child);
332
+ break;
333
+ case 'parameter_list':
334
+ info.primaryConstructorParams = this.parseParameters(child);
335
+ break;
336
+ case 'base_list':
337
+ const bases = this.parseBaseList(child);
338
+ if (bases.length > 0) {
339
+ info.baseRecord = bases[0] ?? null;
340
+ info.interfaces = bases.slice(1);
341
+ }
342
+ break;
343
+ case 'declaration_list':
344
+ this.parseRecordMembers(child, info);
345
+ break;
346
+ }
347
+ }
348
+ return info;
349
+ }
350
+ parseRecordMembers(node, recordInfo) {
351
+ for (const child of node.children) {
352
+ switch (child.type) {
353
+ case 'method_declaration':
354
+ recordInfo.methods.push(this.parseMethod(child));
355
+ break;
356
+ case 'property_declaration':
357
+ recordInfo.properties.push(this.parseProperty(child));
358
+ break;
359
+ }
360
+ }
361
+ }
362
+ extractStructs(root) {
363
+ const structs = [];
364
+ this.findNodesOfType(root, 'struct_declaration', (node) => {
365
+ structs.push(this.parseStruct(node));
366
+ });
367
+ return structs;
368
+ }
369
+ parseStruct(node) {
370
+ const info = {
371
+ name: '',
372
+ namespace: this.currentNamespace,
373
+ interfaces: [],
374
+ genericParameters: [],
375
+ attributes: [],
376
+ methods: [],
377
+ properties: [],
378
+ fields: [],
379
+ constructors: [],
380
+ accessibility: 'internal',
381
+ isReadonly: false,
382
+ isRef: false,
383
+ isPartial: false,
384
+ startPosition: { row: node.startPosition.row, column: node.startPosition.column },
385
+ endPosition: { row: node.endPosition.row, column: node.endPosition.column },
386
+ };
387
+ for (const child of node.children) {
388
+ switch (child.type) {
389
+ case 'identifier':
390
+ info.name = child.text;
391
+ break;
392
+ case 'attribute_list':
393
+ info.attributes.push(...this.parseAttributeList(child));
394
+ break;
395
+ case 'modifier':
396
+ this.applyStructModifier(info, child.text);
397
+ break;
398
+ case 'type_parameter_list':
399
+ info.genericParameters = this.parseTypeParameters(child);
400
+ break;
401
+ case 'base_list':
402
+ info.interfaces = this.parseBaseList(child);
403
+ break;
404
+ case 'declaration_list':
405
+ this.parseStructMembers(child, info);
406
+ break;
407
+ }
408
+ }
409
+ return info;
410
+ }
411
+ parseStructMembers(node, structInfo) {
412
+ for (const child of node.children) {
413
+ switch (child.type) {
414
+ case 'method_declaration':
415
+ structInfo.methods.push(this.parseMethod(child));
416
+ break;
417
+ case 'property_declaration':
418
+ structInfo.properties.push(this.parseProperty(child));
419
+ break;
420
+ case 'field_declaration':
421
+ structInfo.fields.push(...this.parseField(child));
422
+ break;
423
+ case 'constructor_declaration':
424
+ structInfo.constructors.push(this.parseConstructor(child));
425
+ break;
426
+ }
427
+ }
428
+ }
429
+ extractInterfaces(root) {
430
+ const interfaces = [];
431
+ this.findNodesOfType(root, 'interface_declaration', (node) => {
432
+ interfaces.push(this.parseInterface(node));
433
+ });
434
+ return interfaces;
435
+ }
436
+ parseInterface(node) {
437
+ const info = {
438
+ name: '',
439
+ namespace: this.currentNamespace,
440
+ extends: [],
441
+ genericParameters: [],
442
+ attributes: [],
443
+ methods: [],
444
+ properties: [],
445
+ accessibility: 'internal',
446
+ isPartial: false,
447
+ startPosition: { row: node.startPosition.row, column: node.startPosition.column },
448
+ endPosition: { row: node.endPosition.row, column: node.endPosition.column },
449
+ };
450
+ for (const child of node.children) {
451
+ switch (child.type) {
452
+ case 'identifier':
453
+ info.name = child.text;
454
+ break;
455
+ case 'attribute_list':
456
+ info.attributes.push(...this.parseAttributeList(child));
457
+ break;
458
+ case 'modifier':
459
+ this.applyInterfaceModifier(info, child.text);
460
+ break;
461
+ case 'type_parameter_list':
462
+ info.genericParameters = this.parseTypeParameters(child);
463
+ break;
464
+ case 'base_list':
465
+ info.extends = this.parseBaseList(child);
466
+ break;
467
+ case 'declaration_list':
468
+ this.parseInterfaceMembers(child, info);
469
+ break;
470
+ }
471
+ }
472
+ return info;
473
+ }
474
+ parseInterfaceMembers(node, interfaceInfo) {
475
+ for (const child of node.children) {
476
+ switch (child.type) {
477
+ case 'method_declaration':
478
+ interfaceInfo.methods.push(this.parseMethod(child));
479
+ break;
480
+ case 'property_declaration':
481
+ interfaceInfo.properties.push(this.parseProperty(child));
482
+ break;
483
+ }
484
+ }
485
+ }
486
+ extractEnums(root) {
487
+ const enums = [];
488
+ this.findNodesOfType(root, 'enum_declaration', (node) => {
489
+ enums.push(this.parseEnum(node));
490
+ });
491
+ return enums;
492
+ }
493
+ parseEnum(node) {
494
+ const info = {
495
+ name: '',
496
+ namespace: this.currentNamespace,
497
+ underlyingType: null,
498
+ members: [],
499
+ attributes: [],
500
+ accessibility: 'internal',
501
+ startPosition: { row: node.startPosition.row, column: node.startPosition.column },
502
+ endPosition: { row: node.endPosition.row, column: node.endPosition.column },
503
+ };
504
+ for (const child of node.children) {
505
+ switch (child.type) {
506
+ case 'identifier':
507
+ info.name = child.text;
508
+ break;
509
+ case 'attribute_list':
510
+ info.attributes.push(...this.parseAttributeList(child));
511
+ break;
512
+ case 'modifier':
513
+ if (child.text === 'public')
514
+ info.accessibility = 'public';
515
+ else if (child.text === 'internal')
516
+ info.accessibility = 'internal';
517
+ else if (child.text === 'private')
518
+ info.accessibility = 'private';
519
+ break;
520
+ case 'base_list':
521
+ const bases = this.parseBaseList(child);
522
+ if (bases.length > 0) {
523
+ info.underlyingType = bases[0] ?? null;
524
+ }
525
+ break;
526
+ case 'enum_member_declaration_list':
527
+ info.members = this.parseEnumMembers(child);
528
+ break;
529
+ }
530
+ }
531
+ return info;
532
+ }
533
+ parseEnumMembers(node) {
534
+ const members = [];
535
+ for (const child of node.children) {
536
+ if (child.type === 'enum_member_declaration') {
537
+ let name = '';
538
+ let value = null;
539
+ for (const memberChild of child.children) {
540
+ if (memberChild.type === 'identifier') {
541
+ name = memberChild.text;
542
+ }
543
+ else if (memberChild.type === 'equals_value_clause') {
544
+ value = memberChild.children.find(c => c.type !== '=')?.text ?? null;
545
+ }
546
+ }
547
+ if (name) {
548
+ members.push({ name, value });
549
+ }
550
+ }
551
+ }
552
+ return members;
553
+ }
554
+ hasTopLevelStatements(root) {
555
+ for (const child of root.children) {
556
+ if (child.type === 'global_statement') {
557
+ // Check if it's not just a using directive
558
+ const hasNonUsing = child.children.some(c => c.type !== 'using_directive');
559
+ if (hasNonUsing) {
560
+ return true;
561
+ }
562
+ }
563
+ }
564
+ return false;
565
+ }
566
+ // ============================================
567
+ // Helper Methods
568
+ // ============================================
569
+ parseAttributeList(node) {
570
+ const attributes = [];
571
+ for (const child of node.children) {
572
+ if (child.type === 'attribute') {
573
+ attributes.push(this.parseAttribute(child));
574
+ }
575
+ }
576
+ return attributes;
577
+ }
578
+ parseAttribute(node) {
579
+ const info = {
580
+ name: '',
581
+ fullName: '',
582
+ arguments: [],
583
+ namedArguments: {},
584
+ target: null,
585
+ startPosition: { row: node.startPosition.row, column: node.startPosition.column },
586
+ endPosition: { row: node.endPosition.row, column: node.endPosition.column },
587
+ };
588
+ for (const child of node.children) {
589
+ if (child.type === 'identifier' || child.type === 'qualified_name') {
590
+ info.fullName = child.text;
591
+ // Remove 'Attribute' suffix if present
592
+ info.name = info.fullName.replace(/Attribute$/, '');
593
+ }
594
+ else if (child.type === 'attribute_argument_list') {
595
+ this.parseAttributeArguments(child, info);
596
+ }
597
+ }
598
+ return info;
599
+ }
600
+ parseAttributeArguments(node, info) {
601
+ for (const child of node.children) {
602
+ if (child.type === 'attribute_argument') {
603
+ const nameEquals = child.children.find(c => c.type === 'name_equals');
604
+ if (nameEquals) {
605
+ const name = nameEquals.children.find(c => c.type === 'identifier')?.text;
606
+ const value = child.children.find(c => c.type !== 'name_equals')?.text;
607
+ if (name && value) {
608
+ info.namedArguments[name] = value;
609
+ }
610
+ }
611
+ else {
612
+ const value = child.text;
613
+ if (value) {
614
+ info.arguments.push(value);
615
+ }
616
+ }
617
+ }
618
+ }
619
+ }
620
+ parseMethod(node) {
621
+ const info = {
622
+ name: '',
623
+ returnType: 'void',
624
+ parameters: [],
625
+ genericParameters: [],
626
+ attributes: [],
627
+ accessibility: 'private',
628
+ isStatic: false,
629
+ isAsync: false,
630
+ isVirtual: false,
631
+ isOverride: false,
632
+ isAbstract: false,
633
+ isSealed: false,
634
+ isExtern: false,
635
+ isPartial: false,
636
+ startPosition: { row: node.startPosition.row, column: node.startPosition.column },
637
+ endPosition: { row: node.endPosition.row, column: node.endPosition.column },
638
+ };
639
+ for (const child of node.children) {
640
+ switch (child.type) {
641
+ case 'identifier':
642
+ info.name = child.text;
643
+ break;
644
+ case 'attribute_list':
645
+ info.attributes.push(...this.parseAttributeList(child));
646
+ break;
647
+ case 'modifier':
648
+ this.applyMethodModifier(info, child.text);
649
+ break;
650
+ case 'type_parameter_list':
651
+ info.genericParameters = this.parseTypeParameters(child);
652
+ break;
653
+ case 'parameter_list':
654
+ info.parameters = this.parseParameters(child);
655
+ break;
656
+ case 'predefined_type':
657
+ case 'identifier':
658
+ case 'qualified_name':
659
+ case 'generic_name':
660
+ case 'nullable_type':
661
+ case 'array_type':
662
+ case 'tuple_type':
663
+ // Return type - take the first type we find before the method name
664
+ if (!info.name) {
665
+ info.returnType = child.text;
666
+ }
667
+ break;
668
+ }
669
+ }
670
+ // Handle return type more carefully
671
+ const returnTypeNode = node.childForFieldName?.('type') ??
672
+ node.children.find(c => ['predefined_type', 'generic_name', 'qualified_name', 'nullable_type', 'array_type', 'tuple_type'].includes(c.type));
673
+ if (returnTypeNode) {
674
+ info.returnType = returnTypeNode.text;
675
+ }
676
+ return info;
677
+ }
678
+ parseProperty(node) {
679
+ const info = {
680
+ name: '',
681
+ type: '',
682
+ hasGetter: false,
683
+ hasSetter: false,
684
+ isInit: false,
685
+ isRequired: false,
686
+ attributes: [],
687
+ accessibility: 'private',
688
+ isStatic: false,
689
+ isVirtual: false,
690
+ isOverride: false,
691
+ isAbstract: false,
692
+ startPosition: { row: node.startPosition.row, column: node.startPosition.column },
693
+ endPosition: { row: node.endPosition.row, column: node.endPosition.column },
694
+ };
695
+ for (const child of node.children) {
696
+ switch (child.type) {
697
+ case 'identifier':
698
+ info.name = child.text;
699
+ break;
700
+ case 'attribute_list':
701
+ info.attributes.push(...this.parseAttributeList(child));
702
+ break;
703
+ case 'modifier':
704
+ this.applyPropertyModifier(info, child.text);
705
+ break;
706
+ case 'predefined_type':
707
+ case 'generic_name':
708
+ case 'qualified_name':
709
+ case 'nullable_type':
710
+ case 'array_type':
711
+ case 'tuple_type':
712
+ info.type = child.text;
713
+ break;
714
+ case 'accessor_list':
715
+ this.parseAccessors(child, info);
716
+ break;
717
+ }
718
+ }
719
+ return info;
720
+ }
721
+ parseAccessors(node, propertyInfo) {
722
+ for (const child of node.children) {
723
+ if (child.type === 'accessor_declaration') {
724
+ const accessorType = child.children.find(c => c.type === 'identifier' || c.text === 'get' || c.text === 'set' || c.text === 'init');
725
+ if (accessorType) {
726
+ if (accessorType.text === 'get') {
727
+ propertyInfo.hasGetter = true;
728
+ }
729
+ else if (accessorType.text === 'set') {
730
+ propertyInfo.hasSetter = true;
731
+ }
732
+ else if (accessorType.text === 'init') {
733
+ propertyInfo.hasSetter = true;
734
+ propertyInfo.isInit = true;
735
+ }
736
+ }
737
+ }
738
+ }
739
+ }
740
+ parseField(node) {
741
+ const fields = [];
742
+ const baseInfo = {
743
+ type: '',
744
+ defaultValue: null,
745
+ attributes: [],
746
+ accessibility: 'private',
747
+ isStatic: false,
748
+ isReadonly: false,
749
+ isConst: false,
750
+ isVolatile: false,
751
+ };
752
+ for (const child of node.children) {
753
+ switch (child.type) {
754
+ case 'attribute_list':
755
+ baseInfo.attributes = [...(baseInfo.attributes ?? []), ...this.parseAttributeList(child)];
756
+ break;
757
+ case 'modifier':
758
+ this.applyFieldModifier(baseInfo, child.text);
759
+ break;
760
+ case 'predefined_type':
761
+ case 'generic_name':
762
+ case 'qualified_name':
763
+ case 'nullable_type':
764
+ case 'array_type':
765
+ case 'tuple_type':
766
+ baseInfo.type = child.text;
767
+ break;
768
+ case 'variable_declaration':
769
+ for (const varChild of child.children) {
770
+ if (varChild.type === 'variable_declarator') {
771
+ const fieldInfo = {
772
+ name: '',
773
+ type: baseInfo.type ?? '',
774
+ defaultValue: null,
775
+ attributes: baseInfo.attributes ?? [],
776
+ accessibility: baseInfo.accessibility ?? 'private',
777
+ isStatic: baseInfo.isStatic ?? false,
778
+ isReadonly: baseInfo.isReadonly ?? false,
779
+ isConst: baseInfo.isConst ?? false,
780
+ isVolatile: baseInfo.isVolatile ?? false,
781
+ startPosition: { row: node.startPosition.row, column: node.startPosition.column },
782
+ endPosition: { row: node.endPosition.row, column: node.endPosition.column },
783
+ };
784
+ for (const declChild of varChild.children) {
785
+ if (declChild.type === 'identifier') {
786
+ fieldInfo.name = declChild.text;
787
+ }
788
+ else if (declChild.type === 'equals_value_clause') {
789
+ fieldInfo.defaultValue = declChild.children.find(c => c.type !== '=')?.text ?? null;
790
+ }
791
+ }
792
+ if (fieldInfo.name) {
793
+ fields.push(fieldInfo);
794
+ }
795
+ }
796
+ }
797
+ break;
798
+ }
799
+ }
800
+ return fields;
801
+ }
802
+ parseConstructor(node) {
803
+ const info = {
804
+ parameters: [],
805
+ attributes: [],
806
+ accessibility: 'private',
807
+ isStatic: false,
808
+ initializer: null,
809
+ startPosition: { row: node.startPosition.row, column: node.startPosition.column },
810
+ endPosition: { row: node.endPosition.row, column: node.endPosition.column },
811
+ };
812
+ for (const child of node.children) {
813
+ switch (child.type) {
814
+ case 'attribute_list':
815
+ info.attributes.push(...this.parseAttributeList(child));
816
+ break;
817
+ case 'modifier':
818
+ if (child.text === 'public')
819
+ info.accessibility = 'public';
820
+ else if (child.text === 'private')
821
+ info.accessibility = 'private';
822
+ else if (child.text === 'protected')
823
+ info.accessibility = 'protected';
824
+ else if (child.text === 'internal')
825
+ info.accessibility = 'internal';
826
+ else if (child.text === 'static')
827
+ info.isStatic = true;
828
+ break;
829
+ case 'parameter_list':
830
+ info.parameters = this.parseParameters(child);
831
+ break;
832
+ case 'constructor_initializer':
833
+ const initType = child.children.find(c => c.text === 'base' || c.text === 'this');
834
+ if (initType) {
835
+ info.initializer = {
836
+ type: initType.text,
837
+ arguments: [],
838
+ };
839
+ const argList = child.children.find(c => c.type === 'argument_list');
840
+ if (argList) {
841
+ info.initializer.arguments = argList.children
842
+ .filter(c => c.type === 'argument')
843
+ .map(c => c.text);
844
+ }
845
+ }
846
+ break;
847
+ }
848
+ }
849
+ return info;
850
+ }
851
+ parseParameters(node) {
852
+ const params = [];
853
+ for (const child of node.children) {
854
+ if (child.type === 'parameter') {
855
+ params.push(this.parseParameter(child));
856
+ }
857
+ }
858
+ return params;
859
+ }
860
+ parseParameter(node) {
861
+ const info = {
862
+ name: '',
863
+ type: '',
864
+ defaultValue: null,
865
+ isRef: false,
866
+ isOut: false,
867
+ isIn: false,
868
+ isParams: false,
869
+ isThis: false,
870
+ attributes: [],
871
+ };
872
+ for (const child of node.children) {
873
+ switch (child.type) {
874
+ case 'identifier':
875
+ info.name = child.text;
876
+ break;
877
+ case 'attribute_list':
878
+ info.attributes.push(...this.parseAttributeList(child));
879
+ break;
880
+ case 'parameter_modifier':
881
+ case 'modifier':
882
+ if (child.text === 'ref')
883
+ info.isRef = true;
884
+ else if (child.text === 'out')
885
+ info.isOut = true;
886
+ else if (child.text === 'in')
887
+ info.isIn = true;
888
+ else if (child.text === 'params')
889
+ info.isParams = true;
890
+ else if (child.text === 'this')
891
+ info.isThis = true;
892
+ break;
893
+ case 'predefined_type':
894
+ case 'generic_name':
895
+ case 'qualified_name':
896
+ case 'nullable_type':
897
+ case 'array_type':
898
+ case 'tuple_type':
899
+ info.type = child.text;
900
+ break;
901
+ case 'equals_value_clause':
902
+ info.defaultValue = child.children.find(c => c.type !== '=')?.text ?? null;
903
+ break;
904
+ }
905
+ }
906
+ return info;
907
+ }
908
+ parseTypeParameters(node) {
909
+ const params = [];
910
+ for (const child of node.children) {
911
+ if (child.type === 'type_parameter') {
912
+ const name = child.children.find(c => c.type === 'identifier')?.text;
913
+ if (name) {
914
+ params.push(name);
915
+ }
916
+ }
917
+ }
918
+ return params;
919
+ }
920
+ parseBaseList(node) {
921
+ const bases = [];
922
+ for (const child of node.children) {
923
+ if (child.type === 'simple_base_type' || child.type === 'primary_constructor_base_type') {
924
+ const typeName = child.children.find(c => c.type === 'identifier' || c.type === 'generic_name' || c.type === 'qualified_name')?.text;
925
+ if (typeName) {
926
+ bases.push(typeName);
927
+ }
928
+ }
929
+ }
930
+ return bases;
931
+ }
932
+ // ============================================
933
+ // Modifier Application
934
+ // ============================================
935
+ applyModifier(info, modifier) {
936
+ switch (modifier) {
937
+ case 'public':
938
+ info.accessibility = 'public';
939
+ break;
940
+ case 'private':
941
+ info.accessibility = 'private';
942
+ break;
943
+ case 'protected':
944
+ info.accessibility = 'protected';
945
+ break;
946
+ case 'internal':
947
+ info.accessibility = 'internal';
948
+ break;
949
+ case 'static':
950
+ info.isStatic = true;
951
+ break;
952
+ case 'abstract':
953
+ info.isAbstract = true;
954
+ break;
955
+ case 'sealed':
956
+ info.isSealed = true;
957
+ break;
958
+ case 'partial':
959
+ info.isPartial = true;
960
+ break;
961
+ }
962
+ }
963
+ applyRecordModifier(info, modifier) {
964
+ switch (modifier) {
965
+ case 'public':
966
+ info.accessibility = 'public';
967
+ break;
968
+ case 'private':
969
+ info.accessibility = 'private';
970
+ break;
971
+ case 'protected':
972
+ info.accessibility = 'protected';
973
+ break;
974
+ case 'internal':
975
+ info.accessibility = 'internal';
976
+ break;
977
+ case 'sealed':
978
+ info.isSealed = true;
979
+ break;
980
+ case 'abstract':
981
+ info.isAbstract = true;
982
+ break;
983
+ case 'partial':
984
+ info.isPartial = true;
985
+ break;
986
+ }
987
+ }
988
+ applyStructModifier(info, modifier) {
989
+ switch (modifier) {
990
+ case 'public':
991
+ info.accessibility = 'public';
992
+ break;
993
+ case 'private':
994
+ info.accessibility = 'private';
995
+ break;
996
+ case 'protected':
997
+ info.accessibility = 'protected';
998
+ break;
999
+ case 'internal':
1000
+ info.accessibility = 'internal';
1001
+ break;
1002
+ case 'readonly':
1003
+ info.isReadonly = true;
1004
+ break;
1005
+ case 'ref':
1006
+ info.isRef = true;
1007
+ break;
1008
+ case 'partial':
1009
+ info.isPartial = true;
1010
+ break;
1011
+ }
1012
+ }
1013
+ applyInterfaceModifier(info, modifier) {
1014
+ switch (modifier) {
1015
+ case 'public':
1016
+ info.accessibility = 'public';
1017
+ break;
1018
+ case 'private':
1019
+ info.accessibility = 'private';
1020
+ break;
1021
+ case 'protected':
1022
+ info.accessibility = 'protected';
1023
+ break;
1024
+ case 'internal':
1025
+ info.accessibility = 'internal';
1026
+ break;
1027
+ case 'partial':
1028
+ info.isPartial = true;
1029
+ break;
1030
+ }
1031
+ }
1032
+ applyMethodModifier(info, modifier) {
1033
+ switch (modifier) {
1034
+ case 'public':
1035
+ info.accessibility = 'public';
1036
+ break;
1037
+ case 'private':
1038
+ info.accessibility = 'private';
1039
+ break;
1040
+ case 'protected':
1041
+ info.accessibility = 'protected';
1042
+ break;
1043
+ case 'internal':
1044
+ info.accessibility = 'internal';
1045
+ break;
1046
+ case 'static':
1047
+ info.isStatic = true;
1048
+ break;
1049
+ case 'async':
1050
+ info.isAsync = true;
1051
+ break;
1052
+ case 'virtual':
1053
+ info.isVirtual = true;
1054
+ break;
1055
+ case 'override':
1056
+ info.isOverride = true;
1057
+ break;
1058
+ case 'abstract':
1059
+ info.isAbstract = true;
1060
+ break;
1061
+ case 'sealed':
1062
+ info.isSealed = true;
1063
+ break;
1064
+ case 'extern':
1065
+ info.isExtern = true;
1066
+ break;
1067
+ case 'partial':
1068
+ info.isPartial = true;
1069
+ break;
1070
+ }
1071
+ }
1072
+ applyPropertyModifier(info, modifier) {
1073
+ switch (modifier) {
1074
+ case 'public':
1075
+ info.accessibility = 'public';
1076
+ break;
1077
+ case 'private':
1078
+ info.accessibility = 'private';
1079
+ break;
1080
+ case 'protected':
1081
+ info.accessibility = 'protected';
1082
+ break;
1083
+ case 'internal':
1084
+ info.accessibility = 'internal';
1085
+ break;
1086
+ case 'static':
1087
+ info.isStatic = true;
1088
+ break;
1089
+ case 'virtual':
1090
+ info.isVirtual = true;
1091
+ break;
1092
+ case 'override':
1093
+ info.isOverride = true;
1094
+ break;
1095
+ case 'abstract':
1096
+ info.isAbstract = true;
1097
+ break;
1098
+ case 'required':
1099
+ info.isRequired = true;
1100
+ break;
1101
+ }
1102
+ }
1103
+ applyFieldModifier(info, modifier) {
1104
+ switch (modifier) {
1105
+ case 'public':
1106
+ info.accessibility = 'public';
1107
+ break;
1108
+ case 'private':
1109
+ info.accessibility = 'private';
1110
+ break;
1111
+ case 'protected':
1112
+ info.accessibility = 'protected';
1113
+ break;
1114
+ case 'internal':
1115
+ info.accessibility = 'internal';
1116
+ break;
1117
+ case 'static':
1118
+ info.isStatic = true;
1119
+ break;
1120
+ case 'readonly':
1121
+ info.isReadonly = true;
1122
+ break;
1123
+ case 'const':
1124
+ info.isConst = true;
1125
+ break;
1126
+ case 'volatile':
1127
+ info.isVolatile = true;
1128
+ break;
1129
+ }
1130
+ }
1131
+ // ============================================
1132
+ // Utility Methods
1133
+ // ============================================
1134
+ findNodesOfType(node, type, callback) {
1135
+ if (node.type === type) {
1136
+ callback(node);
1137
+ }
1138
+ for (const child of node.children) {
1139
+ this.findNodesOfType(child, type, callback);
1140
+ }
1141
+ }
1142
+ isUpperCase(char) {
1143
+ return char === char.toUpperCase() && char !== char.toLowerCase();
1144
+ }
1145
+ }
1146
+ //# sourceMappingURL=tree-sitter-csharp-parser.js.map