linguclaw 0.4.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 (168) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +161 -0
  3. package/dist/agent-system.d.ts +196 -0
  4. package/dist/agent-system.d.ts.map +1 -0
  5. package/dist/agent-system.js +738 -0
  6. package/dist/agent-system.js.map +1 -0
  7. package/dist/alphabeta.d.ts +54 -0
  8. package/dist/alphabeta.d.ts.map +1 -0
  9. package/dist/alphabeta.js +193 -0
  10. package/dist/alphabeta.js.map +1 -0
  11. package/dist/browser.d.ts +62 -0
  12. package/dist/browser.d.ts.map +1 -0
  13. package/dist/browser.js +224 -0
  14. package/dist/browser.js.map +1 -0
  15. package/dist/cli.d.ts +7 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +565 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/code-parser.d.ts +39 -0
  20. package/dist/code-parser.d.ts.map +1 -0
  21. package/dist/code-parser.js +385 -0
  22. package/dist/code-parser.js.map +1 -0
  23. package/dist/config.d.ts +66 -0
  24. package/dist/config.d.ts.map +1 -0
  25. package/dist/config.js +232 -0
  26. package/dist/config.js.map +1 -0
  27. package/dist/core/engine.d.ts +359 -0
  28. package/dist/core/engine.d.ts.map +1 -0
  29. package/dist/core/engine.js +127 -0
  30. package/dist/core/engine.js.map +1 -0
  31. package/dist/daemon.d.ts +29 -0
  32. package/dist/daemon.d.ts.map +1 -0
  33. package/dist/daemon.js +212 -0
  34. package/dist/daemon.js.map +1 -0
  35. package/dist/email-receiver.d.ts +63 -0
  36. package/dist/email-receiver.d.ts.map +1 -0
  37. package/dist/email-receiver.js +553 -0
  38. package/dist/email-receiver.js.map +1 -0
  39. package/dist/git-integration.d.ts +180 -0
  40. package/dist/git-integration.d.ts.map +1 -0
  41. package/dist/git-integration.js +850 -0
  42. package/dist/git-integration.js.map +1 -0
  43. package/dist/inbox.d.ts +84 -0
  44. package/dist/inbox.d.ts.map +1 -0
  45. package/dist/inbox.js +198 -0
  46. package/dist/inbox.js.map +1 -0
  47. package/dist/index.d.ts +6 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +41 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/languages/cpp.d.ts +51 -0
  52. package/dist/languages/cpp.d.ts.map +1 -0
  53. package/dist/languages/cpp.js +930 -0
  54. package/dist/languages/cpp.js.map +1 -0
  55. package/dist/languages/csharp.d.ts +79 -0
  56. package/dist/languages/csharp.d.ts.map +1 -0
  57. package/dist/languages/csharp.js +1776 -0
  58. package/dist/languages/csharp.js.map +1 -0
  59. package/dist/languages/go.d.ts +50 -0
  60. package/dist/languages/go.d.ts.map +1 -0
  61. package/dist/languages/go.js +882 -0
  62. package/dist/languages/go.js.map +1 -0
  63. package/dist/languages/java.d.ts +47 -0
  64. package/dist/languages/java.d.ts.map +1 -0
  65. package/dist/languages/java.js +649 -0
  66. package/dist/languages/java.js.map +1 -0
  67. package/dist/languages/python.d.ts +47 -0
  68. package/dist/languages/python.d.ts.map +1 -0
  69. package/dist/languages/python.js +655 -0
  70. package/dist/languages/python.js.map +1 -0
  71. package/dist/languages/rust.d.ts +61 -0
  72. package/dist/languages/rust.d.ts.map +1 -0
  73. package/dist/languages/rust.js +1064 -0
  74. package/dist/languages/rust.js.map +1 -0
  75. package/dist/logger.d.ts +20 -0
  76. package/dist/logger.d.ts.map +1 -0
  77. package/dist/logger.js +133 -0
  78. package/dist/logger.js.map +1 -0
  79. package/dist/longterm-memory.d.ts +47 -0
  80. package/dist/longterm-memory.d.ts.map +1 -0
  81. package/dist/longterm-memory.js +300 -0
  82. package/dist/longterm-memory.js.map +1 -0
  83. package/dist/memory.d.ts +42 -0
  84. package/dist/memory.d.ts.map +1 -0
  85. package/dist/memory.js +274 -0
  86. package/dist/memory.js.map +1 -0
  87. package/dist/messaging.d.ts +103 -0
  88. package/dist/messaging.d.ts.map +1 -0
  89. package/dist/messaging.js +645 -0
  90. package/dist/messaging.js.map +1 -0
  91. package/dist/multi-provider.d.ts +69 -0
  92. package/dist/multi-provider.d.ts.map +1 -0
  93. package/dist/multi-provider.js +484 -0
  94. package/dist/multi-provider.js.map +1 -0
  95. package/dist/orchestrator.d.ts +65 -0
  96. package/dist/orchestrator.d.ts.map +1 -0
  97. package/dist/orchestrator.js +441 -0
  98. package/dist/orchestrator.js.map +1 -0
  99. package/dist/plugins.d.ts +52 -0
  100. package/dist/plugins.d.ts.map +1 -0
  101. package/dist/plugins.js +215 -0
  102. package/dist/plugins.js.map +1 -0
  103. package/dist/prism-orchestrator.d.ts +26 -0
  104. package/dist/prism-orchestrator.d.ts.map +1 -0
  105. package/dist/prism-orchestrator.js +191 -0
  106. package/dist/prism-orchestrator.js.map +1 -0
  107. package/dist/prism.d.ts +46 -0
  108. package/dist/prism.d.ts.map +1 -0
  109. package/dist/prism.js +188 -0
  110. package/dist/prism.js.map +1 -0
  111. package/dist/privacy.d.ts +23 -0
  112. package/dist/privacy.d.ts.map +1 -0
  113. package/dist/privacy.js +220 -0
  114. package/dist/privacy.js.map +1 -0
  115. package/dist/proactive.d.ts +30 -0
  116. package/dist/proactive.d.ts.map +1 -0
  117. package/dist/proactive.js +260 -0
  118. package/dist/proactive.js.map +1 -0
  119. package/dist/refactoring-engine.d.ts +100 -0
  120. package/dist/refactoring-engine.d.ts.map +1 -0
  121. package/dist/refactoring-engine.js +717 -0
  122. package/dist/refactoring-engine.js.map +1 -0
  123. package/dist/resilience.d.ts +43 -0
  124. package/dist/resilience.d.ts.map +1 -0
  125. package/dist/resilience.js +200 -0
  126. package/dist/resilience.js.map +1 -0
  127. package/dist/safety.d.ts +40 -0
  128. package/dist/safety.d.ts.map +1 -0
  129. package/dist/safety.js +133 -0
  130. package/dist/safety.js.map +1 -0
  131. package/dist/sandbox.d.ts +33 -0
  132. package/dist/sandbox.d.ts.map +1 -0
  133. package/dist/sandbox.js +173 -0
  134. package/dist/sandbox.js.map +1 -0
  135. package/dist/scheduler.d.ts +72 -0
  136. package/dist/scheduler.d.ts.map +1 -0
  137. package/dist/scheduler.js +374 -0
  138. package/dist/scheduler.js.map +1 -0
  139. package/dist/semantic-memory.d.ts +70 -0
  140. package/dist/semantic-memory.d.ts.map +1 -0
  141. package/dist/semantic-memory.js +430 -0
  142. package/dist/semantic-memory.js.map +1 -0
  143. package/dist/skills.d.ts +97 -0
  144. package/dist/skills.d.ts.map +1 -0
  145. package/dist/skills.js +575 -0
  146. package/dist/skills.js.map +1 -0
  147. package/dist/static/dashboard.html +853 -0
  148. package/dist/static/hub.html +772 -0
  149. package/dist/static/index.html +818 -0
  150. package/dist/static/logo.svg +24 -0
  151. package/dist/static/workflow-editor.html +913 -0
  152. package/dist/tools.d.ts +67 -0
  153. package/dist/tools.d.ts.map +1 -0
  154. package/dist/tools.js +303 -0
  155. package/dist/tools.js.map +1 -0
  156. package/dist/types.d.ts +295 -0
  157. package/dist/types.d.ts.map +1 -0
  158. package/dist/types.js +90 -0
  159. package/dist/types.js.map +1 -0
  160. package/dist/web.d.ts +76 -0
  161. package/dist/web.d.ts.map +1 -0
  162. package/dist/web.js +2139 -0
  163. package/dist/web.js.map +1 -0
  164. package/dist/workflow-engine.d.ts +114 -0
  165. package/dist/workflow-engine.d.ts.map +1 -0
  166. package/dist/workflow-engine.js +855 -0
  167. package/dist/workflow-engine.js.map +1 -0
  168. package/package.json +77 -0
@@ -0,0 +1,882 @@
1
+ "use strict";
2
+ /**
3
+ * Go Language Support for LinguClaw
4
+ * Advanced Go parser with goroutine and channel analysis
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.GoLanguageSupport = exports.GoAnalyzer = exports.GoParser = void 0;
8
+ class GoParser {
9
+ source = '';
10
+ lines = [];
11
+ parse(source, filePath) {
12
+ this.source = source;
13
+ this.lines = source.split('\n');
14
+ try {
15
+ const ast = this.parseGo(source, filePath);
16
+ return {
17
+ ast,
18
+ errors: this.findSyntaxErrors(),
19
+ warnings: [],
20
+ tokens: [],
21
+ comments: this.extractComments(),
22
+ };
23
+ }
24
+ catch (error) {
25
+ return this.fallbackParse(filePath);
26
+ }
27
+ }
28
+ async *parseStream(source) {
29
+ const reader = source.getReader();
30
+ let buffer = '';
31
+ while (true) {
32
+ const { done, value } = await reader.read();
33
+ if (done)
34
+ break;
35
+ buffer += value;
36
+ // Go statements end with newlines or semicolons
37
+ const lines = buffer.split('\n');
38
+ const complete = [];
39
+ let remaining = '';
40
+ let braceCount = 0;
41
+ let parenCount = 0;
42
+ let inRawString = false;
43
+ for (const line of lines) {
44
+ for (let i = 0; i < line.length; i++) {
45
+ const char = line[i];
46
+ const nextChar = line[i + 1] || '';
47
+ // Handle raw string literals
48
+ if (char === '`') {
49
+ inRawString = !inRawString;
50
+ }
51
+ if (!inRawString) {
52
+ if (char === '{')
53
+ braceCount++;
54
+ if (char === '}')
55
+ braceCount--;
56
+ if (char === '(')
57
+ parenCount++;
58
+ if (char === ')')
59
+ parenCount--;
60
+ }
61
+ }
62
+ if (braceCount === 0 && parenCount === 0 && !inRawString) {
63
+ complete.push(line);
64
+ }
65
+ else {
66
+ remaining += line + '\n';
67
+ }
68
+ }
69
+ if (complete.length > 0) {
70
+ yield this.parse(complete.join('\n'), '<stream>');
71
+ }
72
+ buffer = remaining;
73
+ }
74
+ if (buffer.trim()) {
75
+ yield this.parse(buffer, '<stream>');
76
+ }
77
+ }
78
+ parseGo(source, filePath) {
79
+ const root = {
80
+ type: 'Program',
81
+ id: `${filePath}:0:0`,
82
+ location: this.createLocation(filePath, 0, 0, this.lines.length, 0),
83
+ children: [],
84
+ metadata: { language: 'go', package: '' },
85
+ };
86
+ // Parse package declaration
87
+ const packageMatch = source.match(/package\s+(\w+)/);
88
+ if (packageMatch) {
89
+ root.metadata.package = packageMatch[1];
90
+ root.children.push({
91
+ type: 'PackageDeclaration',
92
+ id: `${filePath}:1:0`,
93
+ location: this.createLocation(filePath, 1, 0, 1, packageMatch[0].length),
94
+ children: [],
95
+ metadata: { name: packageMatch[1] },
96
+ });
97
+ }
98
+ // Parse imports
99
+ const imports = this.parseImports(source, filePath);
100
+ root.children.push(...imports);
101
+ // Parse declarations
102
+ const declarations = this.parseDeclarations(source, filePath);
103
+ root.children.push(...declarations);
104
+ return root;
105
+ }
106
+ parseImports(source, filePath) {
107
+ const imports = [];
108
+ const importRegex = /import\s*(?:\(|([^)]+))/g;
109
+ let match;
110
+ while ((match = importRegex.exec(source)) !== null) {
111
+ if (match[1]) {
112
+ // Single import
113
+ const importPath = match[1].trim().replace(/["']/g, '');
114
+ const alias = match[1].match(/^(\w+)\s+/)?.[1];
115
+ imports.push({
116
+ type: 'ImportDeclaration',
117
+ id: `${filePath}:0:${match.index}`,
118
+ location: this.createLocation(filePath, 0, match.index, 0, match.index + match[0].length),
119
+ children: [],
120
+ metadata: {
121
+ path: importPath,
122
+ alias,
123
+ isStandard: !importPath.includes('.'),
124
+ isCgo: importPath === 'C',
125
+ },
126
+ });
127
+ }
128
+ else {
129
+ // Block import - find closing paren
130
+ const startIdx = match.index;
131
+ const blockEnd = this.findMatchingParen(source, startIdx + 6);
132
+ const blockContent = source.substring(startIdx + 7, blockEnd);
133
+ const blockLines = blockContent.split('\n');
134
+ for (const line of blockLines) {
135
+ const trimmed = line.trim();
136
+ if (trimmed && !trimmed.startsWith('//')) {
137
+ const pathMatch = trimmed.match(/["']([^"']+)["']/);
138
+ if (pathMatch) {
139
+ const aliasMatch = trimmed.match(/^(\w+)\s+/);
140
+ imports.push({
141
+ type: 'ImportDeclaration',
142
+ id: `${filePath}:0:0`,
143
+ location: this.createLocation(filePath, 0, 0, 0, 0),
144
+ children: [],
145
+ metadata: {
146
+ path: pathMatch[1],
147
+ alias: aliasMatch?.[1],
148
+ isStandard: !pathMatch[1].includes('.'),
149
+ isCgo: pathMatch[1] === 'C',
150
+ },
151
+ });
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
157
+ return imports;
158
+ }
159
+ parseDeclarations(source, filePath) {
160
+ const declarations = [];
161
+ const lines = source.split('\n');
162
+ let i = 0;
163
+ while (i < lines.length) {
164
+ const line = lines[i].trim();
165
+ // Skip comments and empty lines
166
+ if (!line || line.startsWith('//')) {
167
+ i++;
168
+ continue;
169
+ }
170
+ // Type declarations
171
+ if (line.startsWith('type ')) {
172
+ const typeDecl = this.parseTypeDeclaration(lines, i, filePath);
173
+ if (typeDecl) {
174
+ declarations.push(typeDecl.node);
175
+ i = typeDecl.endIndex + 1;
176
+ continue;
177
+ }
178
+ }
179
+ // Const declarations
180
+ if (line.startsWith('const ')) {
181
+ const constDecl = this.parseConstDeclaration(lines, i, filePath);
182
+ if (constDecl) {
183
+ declarations.push(constDecl.node);
184
+ i = constDecl.endIndex + 1;
185
+ continue;
186
+ }
187
+ }
188
+ // Var declarations
189
+ if (line.startsWith('var ')) {
190
+ const varDecl = this.parseVarDeclaration(lines, i, filePath);
191
+ if (varDecl) {
192
+ declarations.push(varDecl.node);
193
+ i = varDecl.endIndex + 1;
194
+ continue;
195
+ }
196
+ }
197
+ // Function declarations
198
+ if (line.match(/^func\s/)) {
199
+ const funcDecl = this.parseFunction(lines, i, filePath);
200
+ if (funcDecl) {
201
+ declarations.push(funcDecl.node);
202
+ i = funcDecl.endIndex + 1;
203
+ continue;
204
+ }
205
+ }
206
+ i++;
207
+ }
208
+ return declarations;
209
+ }
210
+ parseTypeDeclaration(lines, startIdx, filePath) {
211
+ const line = lines[startIdx].trim();
212
+ const match = line.match(/type\s+(\w+)\s*(?:\[([^\]]*)\])?\s*(.+)/);
213
+ if (!match && !line.includes('type '))
214
+ return null;
215
+ const typeName = match?.[1] || line.match(/type\s+(\w+)/)?.[1];
216
+ if (!typeName)
217
+ return null;
218
+ let endIdx = startIdx;
219
+ let braceCount = 0;
220
+ // Check if it's a block type (struct, interface)
221
+ if (line.includes('{') || (!match?.[3] && lines[startIdx + 1]?.trim().startsWith('{'))) {
222
+ for (let i = startIdx; i < lines.length; i++) {
223
+ for (const char of lines[i]) {
224
+ if (char === '{')
225
+ braceCount++;
226
+ if (char === '}')
227
+ braceCount--;
228
+ }
229
+ if (braceCount === 0 && i > startIdx) {
230
+ endIdx = i;
231
+ break;
232
+ }
233
+ }
234
+ }
235
+ const body = lines.slice(startIdx, endIdx + 1).join('\n');
236
+ const isStruct = body.includes('struct {');
237
+ const isInterface = body.includes('interface {');
238
+ const isAlias = !isStruct && !isInterface && match?.[3];
239
+ const node = {
240
+ type: 'TypeDeclaration',
241
+ id: `${filePath}:${startIdx + 1}:0`,
242
+ location: this.createLocation(filePath, startIdx + 1, 0, endIdx + 1, lines[endIdx]?.length || 0),
243
+ children: [],
244
+ metadata: {
245
+ name: typeName,
246
+ isStruct,
247
+ isInterface,
248
+ isAlias,
249
+ underlyingType: isAlias ? match[3] : undefined,
250
+ fields: isStruct ? this.extractStructFields(body) : [],
251
+ methods: isInterface ? this.extractInterfaceMethods(body) : [],
252
+ },
253
+ };
254
+ return { node, endIndex: endIdx };
255
+ }
256
+ parseFunction(lines, startIdx, filePath) {
257
+ const line = lines[startIdx].trim();
258
+ // Match function signature
259
+ const sigMatch = line.match(/^func\s+(?:\(([^)]+)\)\s+)?(\w+)\s*\(([^)]*)\)\s*(\([^)]*\)|[^{]+)?/);
260
+ if (!sigMatch)
261
+ return null;
262
+ const receiver = sigMatch[1];
263
+ const funcName = sigMatch[2];
264
+ const params = sigMatch[3];
265
+ const returnType = sigMatch[4]?.trim();
266
+ // Find function body
267
+ let endIdx = startIdx;
268
+ let braceCount = 0;
269
+ let foundOpening = false;
270
+ for (let i = startIdx; i < lines.length; i++) {
271
+ for (const char of lines[i]) {
272
+ if (char === '{') {
273
+ braceCount++;
274
+ foundOpening = true;
275
+ }
276
+ if (char === '}')
277
+ braceCount--;
278
+ }
279
+ if (foundOpening && braceCount === 0) {
280
+ endIdx = i;
281
+ break;
282
+ }
283
+ }
284
+ const body = lines.slice(startIdx, endIdx + 1).join('\n');
285
+ const statements = this.parseGoStatements(lines.slice(startIdx + 1, endIdx), filePath, startIdx + 1);
286
+ // Analyze concurrency patterns
287
+ const concurrency = this.analyzeConcurrency(body);
288
+ const node = {
289
+ type: 'FunctionDeclaration',
290
+ id: `${filePath}:${startIdx + 1}:0`,
291
+ location: this.createLocation(filePath, startIdx + 1, 0, endIdx + 1, lines[endIdx]?.length || 0),
292
+ children: statements,
293
+ metadata: {
294
+ name: funcName,
295
+ receiver: receiver ? this.parseReceiver(receiver) : undefined,
296
+ parameters: this.parseParameters(params),
297
+ returnType,
298
+ isMethod: !!receiver,
299
+ isExported: /^[A-Z]/.test(funcName),
300
+ hasDefer: body.includes('defer '),
301
+ hasPanic: body.includes('panic('),
302
+ hasRecover: body.includes('recover()'),
303
+ goroutines: concurrency.goroutines,
304
+ channels: concurrency.channels,
305
+ isConcurrent: concurrency.goroutines.length > 0,
306
+ },
307
+ };
308
+ return { node, endIndex: endIdx };
309
+ }
310
+ parseReceiver(receiver) {
311
+ const parts = receiver.trim().split(/\s+/);
312
+ if (parts.length === 2) {
313
+ return {
314
+ name: parts[0],
315
+ type: parts[1].replace('*', ''),
316
+ pointer: parts[1].startsWith('*'),
317
+ };
318
+ }
319
+ return { name: 'this', type: receiver.replace('*', ''), pointer: receiver.startsWith('*') };
320
+ }
321
+ parseParameters(params) {
322
+ const parameters = [];
323
+ if (!params.trim())
324
+ return parameters;
325
+ // Go allows grouped types: "a, b int"
326
+ const segments = this.splitParams(params);
327
+ for (const segment of segments) {
328
+ const trimmed = segment.trim();
329
+ if (!trimmed)
330
+ continue;
331
+ const parts = trimmed.split(/\s+/);
332
+ if (parts.length >= 2) {
333
+ const type = parts[parts.length - 1];
334
+ const isVariadic = type.startsWith('...');
335
+ // All names before the type share the same type
336
+ for (let i = 0; i < parts.length - 1; i++) {
337
+ parameters.push({
338
+ name: parts[i].replace(',', ''),
339
+ type: type.replace(',', ''),
340
+ variadic: isVariadic,
341
+ });
342
+ }
343
+ }
344
+ }
345
+ return parameters;
346
+ }
347
+ parseConstDeclaration(lines, startIdx, filePath) {
348
+ const line = lines[startIdx].trim();
349
+ if (line.includes('(')) {
350
+ // Block const declaration
351
+ let endIdx = startIdx;
352
+ let parenCount = 0;
353
+ for (let i = startIdx; i < lines.length; i++) {
354
+ for (const char of lines[i]) {
355
+ if (char === '(')
356
+ parenCount++;
357
+ if (char === ')')
358
+ parenCount--;
359
+ }
360
+ if (parenCount === 0 && i > startIdx) {
361
+ endIdx = i;
362
+ break;
363
+ }
364
+ }
365
+ const blockContent = lines.slice(startIdx + 1, endIdx).join('\n');
366
+ const consts = this.extractConstsFromBlock(blockContent);
367
+ const node = {
368
+ type: 'ConstDeclaration',
369
+ id: `${filePath}:${startIdx + 1}:0`,
370
+ location: this.createLocation(filePath, startIdx + 1, 0, endIdx + 1, lines[endIdx]?.length || 0),
371
+ children: consts.map((c, idx) => ({
372
+ type: 'ConstSpec',
373
+ id: `${filePath}:${startIdx + 1 + idx}:0`,
374
+ location: this.createLocation(filePath, startIdx + 1 + idx, 0, startIdx + 1 + idx, 0),
375
+ children: [],
376
+ metadata: c,
377
+ })),
378
+ metadata: { isBlock: true },
379
+ };
380
+ return { node, endIndex: endIdx };
381
+ }
382
+ else {
383
+ // Single const
384
+ const match = line.match(/const\s+(\w+)\s+(\w+)?\s*=\s*(.+)/);
385
+ if (match) {
386
+ const node = {
387
+ type: 'ConstDeclaration',
388
+ id: `${filePath}:${startIdx + 1}:0`,
389
+ location: this.createLocation(filePath, startIdx + 1, 0, startIdx + 1, line.length),
390
+ children: [],
391
+ metadata: {
392
+ name: match[1],
393
+ type: match[2],
394
+ value: match[3],
395
+ isBlock: false,
396
+ },
397
+ };
398
+ return { node, endIndex: startIdx };
399
+ }
400
+ }
401
+ return null;
402
+ }
403
+ parseVarDeclaration(lines, startIdx, filePath) {
404
+ const line = lines[startIdx].trim();
405
+ if (line.includes('(')) {
406
+ // Block var declaration
407
+ let endIdx = startIdx;
408
+ let parenCount = 0;
409
+ for (let i = startIdx; i < lines.length; i++) {
410
+ for (const char of lines[i]) {
411
+ if (char === '(')
412
+ parenCount++;
413
+ if (char === ')')
414
+ parenCount--;
415
+ }
416
+ if (parenCount === 0 && i > startIdx) {
417
+ endIdx = i;
418
+ break;
419
+ }
420
+ }
421
+ const blockContent = lines.slice(startIdx + 1, endIdx).join('\n');
422
+ const vars = this.extractVarsFromBlock(blockContent);
423
+ const node = {
424
+ type: 'VariableDeclaration',
425
+ id: `${filePath}:${startIdx + 1}:0`,
426
+ location: this.createLocation(filePath, startIdx + 1, 0, endIdx + 1, lines[endIdx]?.length || 0),
427
+ children: vars.map((v, idx) => ({
428
+ type: 'VarSpec',
429
+ id: `${filePath}:${startIdx + 1 + idx}:0`,
430
+ location: this.createLocation(filePath, startIdx + 1 + idx, 0, startIdx + 1 + idx, 0),
431
+ children: [],
432
+ metadata: v,
433
+ })),
434
+ metadata: { isBlock: true },
435
+ };
436
+ return { node, endIndex: endIdx };
437
+ }
438
+ else {
439
+ // Single var or short declaration
440
+ const shortMatch = line.match(/^(\w+)\s*:=\s*(.+)/);
441
+ if (shortMatch) {
442
+ const node = {
443
+ type: 'ShortVariableDeclaration',
444
+ id: `${filePath}:${startIdx + 1}:0`,
445
+ location: this.createLocation(filePath, startIdx + 1, 0, startIdx + 1, line.length),
446
+ children: [],
447
+ metadata: {
448
+ name: shortMatch[1],
449
+ initializer: shortMatch[2],
450
+ inferred: true,
451
+ },
452
+ };
453
+ return { node, endIndex: startIdx };
454
+ }
455
+ const varMatch = line.match(/var\s+(\w+)\s+(\w+)?\s*(?:=\s*(.+))?/);
456
+ if (varMatch) {
457
+ const node = {
458
+ type: 'VariableDeclaration',
459
+ id: `${filePath}:${startIdx + 1}:0`,
460
+ location: this.createLocation(filePath, startIdx + 1, 0, startIdx + 1, line.length),
461
+ children: [],
462
+ metadata: {
463
+ name: varMatch[1],
464
+ type: varMatch[2],
465
+ initializer: varMatch[3],
466
+ isBlock: false,
467
+ },
468
+ };
469
+ return { node, endIndex: startIdx };
470
+ }
471
+ }
472
+ return null;
473
+ }
474
+ parseGoStatements(lines, filePath, lineOffset) {
475
+ const statements = [];
476
+ for (let i = 0; i < lines.length; i++) {
477
+ const line = lines[i].trim();
478
+ // Goroutine spawn
479
+ if (line.startsWith('go ')) {
480
+ statements.push({
481
+ type: 'GoStatement',
482
+ id: `${filePath}:${lineOffset + i + 1}:0`,
483
+ location: this.createLocation(filePath, lineOffset + i + 1, 0, lineOffset + i + 1, line.length),
484
+ children: [],
485
+ metadata: {
486
+ call: line.substring(3).trim(),
487
+ },
488
+ });
489
+ }
490
+ // Channel operations
491
+ if (line.includes('<-') || line.includes('chan ')) {
492
+ const isSend = line.match(/([^<]+)\s*<-\s*(.+)/);
493
+ const isRecv = line.match(/<-\s*(.+)/);
494
+ if (isSend || isRecv) {
495
+ statements.push({
496
+ type: 'ChannelOperation',
497
+ id: `${filePath}:${lineOffset + i + 1}:0`,
498
+ location: this.createLocation(filePath, lineOffset + i + 1, 0, lineOffset + i + 1, line.length),
499
+ children: [],
500
+ metadata: {
501
+ isSend: !!isSend,
502
+ isRecv: !!isRecv,
503
+ channel: isSend?.[1]?.trim() || 'unknown',
504
+ value: isSend?.[2]?.trim() || isRecv?.[1]?.trim(),
505
+ },
506
+ });
507
+ }
508
+ }
509
+ // Select statement
510
+ if (line.startsWith('select {')) {
511
+ statements.push({
512
+ type: 'SelectStatement',
513
+ id: `${filePath}:${lineOffset + i + 1}:0`,
514
+ location: this.createLocation(filePath, lineOffset + i + 1, 0, lineOffset + i + 1, line.length),
515
+ children: [],
516
+ metadata: {},
517
+ });
518
+ }
519
+ // Defer
520
+ if (line.startsWith('defer ')) {
521
+ statements.push({
522
+ type: 'DeferStatement',
523
+ id: `${filePath}:${lineOffset + i + 1}:0`,
524
+ location: this.createLocation(filePath, lineOffset + i + 1, 0, lineOffset + i + 1, line.length),
525
+ children: [],
526
+ metadata: {
527
+ call: line.substring(6).trim(),
528
+ },
529
+ });
530
+ }
531
+ // Panic/Recover
532
+ if (line.includes('panic(')) {
533
+ statements.push({
534
+ type: 'PanicStatement',
535
+ id: `${filePath}:${lineOffset + i + 1}:0`,
536
+ location: this.createLocation(filePath, lineOffset + i + 1, 0, lineOffset + i + 1, line.length),
537
+ children: [],
538
+ metadata: {},
539
+ });
540
+ }
541
+ // Range statement
542
+ if (line.startsWith('for ') && line.includes(' range ')) {
543
+ statements.push({
544
+ type: 'RangeStatement',
545
+ id: `${filePath}:${lineOffset + i + 1}:0`,
546
+ location: this.createLocation(filePath, lineOffset + i + 1, 0, lineOffset + i + 1, line.length),
547
+ children: [],
548
+ metadata: {},
549
+ });
550
+ }
551
+ }
552
+ return statements;
553
+ }
554
+ analyzeConcurrency(body) {
555
+ const goroutines = [];
556
+ const channels = [];
557
+ // Find goroutine spawns
558
+ const goRegex = /go\s+(\w+)\s*\(/g;
559
+ let match;
560
+ while ((match = goRegex.exec(body)) !== null) {
561
+ goroutines.push(match[1]);
562
+ }
563
+ // Find channel operations
564
+ const chanRegex = /make\(chan\s+(\w+)/g;
565
+ while ((match = chanRegex.exec(body)) !== null) {
566
+ channels.push(match[1]);
567
+ }
568
+ return { goroutines, channels };
569
+ }
570
+ extractStructFields(body) {
571
+ const fields = [];
572
+ const fieldRegex = /(\w+)\s+(\S+)(?:\s+`([^`]+)`)?/g;
573
+ let match;
574
+ while ((match = fieldRegex.exec(body)) !== null) {
575
+ fields.push({
576
+ name: match[1],
577
+ type: match[2],
578
+ tag: match[3],
579
+ });
580
+ }
581
+ return fields;
582
+ }
583
+ extractInterfaceMethods(body) {
584
+ const methods = [];
585
+ const methodRegex = /(\w+)\s*\(([^)]*)\)\s*(\([^)]*\)|\w+)?/g;
586
+ let match;
587
+ while ((match = methodRegex.exec(body)) !== null) {
588
+ methods.push({
589
+ name: match[1],
590
+ signature: match[0],
591
+ });
592
+ }
593
+ return methods;
594
+ }
595
+ extractConstsFromBlock(content) {
596
+ const consts = [];
597
+ const lines = content.split('\n');
598
+ for (const line of lines) {
599
+ const trimmed = line.trim();
600
+ if (!trimmed || trimmed.startsWith('//'))
601
+ continue;
602
+ const match = trimmed.match(/(\w+)\s+(\w+)?\s*=\s*(.+)/);
603
+ if (match) {
604
+ consts.push({
605
+ name: match[1],
606
+ type: match[2],
607
+ value: match[3].replace(/,$/, ''),
608
+ });
609
+ }
610
+ }
611
+ return consts;
612
+ }
613
+ extractVarsFromBlock(content) {
614
+ const vars = [];
615
+ const lines = content.split('\n');
616
+ for (const line of lines) {
617
+ const trimmed = line.trim();
618
+ if (!trimmed || trimmed.startsWith('//'))
619
+ continue;
620
+ const match = trimmed.match(/(\w+)\s+(\w+)?\s*(?:=\s*(.+))?/);
621
+ if (match) {
622
+ vars.push({
623
+ name: match[1],
624
+ type: match[2],
625
+ value: match[3]?.replace(/,$/, ''),
626
+ });
627
+ }
628
+ }
629
+ return vars;
630
+ }
631
+ splitParams(params) {
632
+ const result = [];
633
+ let current = '';
634
+ let depth = 0;
635
+ for (const char of params) {
636
+ if (char === '(' || char === '[' || char === '<')
637
+ depth++;
638
+ if (char === ')' || char === ']' || char === '>')
639
+ depth--;
640
+ if (char === ',' && depth === 0) {
641
+ result.push(current.trim());
642
+ current = '';
643
+ }
644
+ else {
645
+ current += char;
646
+ }
647
+ }
648
+ if (current.trim()) {
649
+ result.push(current.trim());
650
+ }
651
+ return result;
652
+ }
653
+ findMatchingParen(source, startIdx) {
654
+ let depth = 1;
655
+ for (let i = startIdx + 1; i < source.length; i++) {
656
+ if (source[i] === '(')
657
+ depth++;
658
+ if (source[i] === ')')
659
+ depth--;
660
+ if (depth === 0)
661
+ return i;
662
+ }
663
+ return source.length - 1;
664
+ }
665
+ findSyntaxErrors() {
666
+ const errors = [];
667
+ let braceCount = 0;
668
+ let parenCount = 0;
669
+ for (let i = 0; i < this.lines.length; i++) {
670
+ const line = this.lines[i];
671
+ // Skip comments and strings
672
+ let inString = false;
673
+ let stringChar = '';
674
+ let escaped = false;
675
+ for (const char of line) {
676
+ if (escaped) {
677
+ escaped = false;
678
+ continue;
679
+ }
680
+ if (char === '\\') {
681
+ escaped = true;
682
+ continue;
683
+ }
684
+ if (!inString && (char === '"' || char === "'" || char === '`')) {
685
+ inString = true;
686
+ stringChar = char;
687
+ continue;
688
+ }
689
+ if (inString && char === stringChar) {
690
+ inString = false;
691
+ continue;
692
+ }
693
+ if (!inString) {
694
+ if (char === '{')
695
+ braceCount++;
696
+ if (char === '}')
697
+ braceCount--;
698
+ if (char === '(')
699
+ parenCount++;
700
+ if (char === ')')
701
+ parenCount--;
702
+ }
703
+ }
704
+ if (braceCount < 0) {
705
+ errors.push({ message: 'Unexpected }', line: i + 1, severity: 'error' });
706
+ braceCount = 0;
707
+ }
708
+ if (parenCount < 0) {
709
+ errors.push({ message: 'Unexpected )', line: i + 1, severity: 'error' });
710
+ parenCount = 0;
711
+ }
712
+ }
713
+ if (braceCount > 0) {
714
+ errors.push({ message: `Missing ${braceCount} closing brace(s)`, line: this.lines.length, severity: 'error' });
715
+ }
716
+ if (parenCount > 0) {
717
+ errors.push({ message: `Missing ${parenCount} closing paren(s)`, line: this.lines.length, severity: 'error' });
718
+ }
719
+ return errors;
720
+ }
721
+ extractComments() {
722
+ const comments = [];
723
+ for (let i = 0; i < this.lines.length; i++) {
724
+ const line = this.lines[i];
725
+ const commentIdx = line.indexOf('//');
726
+ if (commentIdx !== -1) {
727
+ comments.push({
728
+ type: 'Line',
729
+ value: line.substring(commentIdx + 2).trim(),
730
+ line: i + 1,
731
+ });
732
+ }
733
+ }
734
+ // Block comments /* */
735
+ const blockRegex = /\/\*[\s\S]*?\*\//g;
736
+ let match;
737
+ while ((match = blockRegex.exec(this.source)) !== null) {
738
+ const lineNum = this.source.substring(0, match.index).split('\n').length;
739
+ comments.push({
740
+ type: 'Block',
741
+ value: match[0].substring(2, match[0].length - 2).trim(),
742
+ line: lineNum,
743
+ });
744
+ }
745
+ return comments;
746
+ }
747
+ createLocation(file, startLine, startCol, endLine, endCol) {
748
+ return {
749
+ file,
750
+ startLine,
751
+ startColumn: startCol,
752
+ endLine,
753
+ endColumn: endCol,
754
+ byteOffset: 0,
755
+ };
756
+ }
757
+ fallbackParse(filePath) {
758
+ return {
759
+ ast: this.parseGo(this.source, filePath),
760
+ errors: this.findSyntaxErrors(),
761
+ warnings: [{ message: 'Using fallback parser' }],
762
+ tokens: [],
763
+ comments: this.extractComments(),
764
+ };
765
+ }
766
+ }
767
+ exports.GoParser = GoParser;
768
+ class GoAnalyzer {
769
+ analyze(ast, context) {
770
+ const symbolTable = this.buildSymbolTable(ast);
771
+ const concurrencyAnalysis = this.analyzeConcurrency(ast);
772
+ const errorAnalysis = this.analyzeErrorHandling(ast);
773
+ return {
774
+ symbols: symbolTable,
775
+ callGraph: this.buildCallGraph(ast),
776
+ dataFlow: this.buildDataFlow(ast),
777
+ controlFlow: this.buildControlFlow(ast),
778
+ typeInference: new Map(),
779
+ metrics: this.calculateMetrics(ast),
780
+ suggestions: [
781
+ ...concurrencyAnalysis.suggestions,
782
+ ...errorAnalysis.suggestions,
783
+ ],
784
+ };
785
+ }
786
+ buildSymbolTable(ast) {
787
+ return {
788
+ variables: new Map(),
789
+ functions: new Map(),
790
+ classes: new Map(),
791
+ modules: new Map(),
792
+ imports: [],
793
+ exports: [],
794
+ };
795
+ }
796
+ analyzeConcurrency(ast) {
797
+ const suggestions = [];
798
+ let goroutineCount = 0;
799
+ let channelCount = 0;
800
+ let selectCount = 0;
801
+ const traverse = (node) => {
802
+ if (node.type === 'GoStatement')
803
+ goroutineCount++;
804
+ if (node.type === 'ChannelOperation')
805
+ channelCount++;
806
+ if (node.type === 'SelectStatement')
807
+ selectCount++;
808
+ node.children.forEach(traverse);
809
+ };
810
+ traverse(ast);
811
+ if (goroutineCount > 0 && channelCount === 0) {
812
+ suggestions.push({
813
+ type: 'concurrency',
814
+ severity: 'warning',
815
+ message: `Spawning ${goroutineCount} goroutines without explicit synchronization`,
816
+ remediation: 'Use channels or sync.WaitGroup for coordination',
817
+ });
818
+ }
819
+ if (goroutineCount > 10) {
820
+ suggestions.push({
821
+ type: 'performance',
822
+ severity: 'info',
823
+ message: 'High number of goroutines - consider using worker pools',
824
+ remediation: 'Use a bounded worker pool pattern',
825
+ });
826
+ }
827
+ return { suggestions };
828
+ }
829
+ analyzeErrorHandling(ast) {
830
+ const suggestions = [];
831
+ let panicCount = 0;
832
+ let recoverCount = 0;
833
+ const traverse = (node) => {
834
+ if (node.type === 'PanicStatement')
835
+ panicCount++;
836
+ if (node.metadata?.hasRecover)
837
+ recoverCount++;
838
+ node.children.forEach(traverse);
839
+ };
840
+ traverse(ast);
841
+ if (panicCount > 0 && recoverCount === 0) {
842
+ suggestions.push({
843
+ type: 'error-handling',
844
+ severity: 'warning',
845
+ message: `Using ${panicCount} panic(s) without recover`,
846
+ remediation: 'Add defer/recover or return errors instead',
847
+ });
848
+ }
849
+ return { suggestions };
850
+ }
851
+ buildCallGraph(ast) {
852
+ return { nodes: [], edges: [], entryPoints: [], deadCode: [] };
853
+ }
854
+ buildDataFlow(ast) {
855
+ return { definitions: new Map(), uses: new Map(), taintedSources: [], sinks: [] };
856
+ }
857
+ buildControlFlow(ast) {
858
+ return { nodes: [], edges: [], loops: [], branches: [] };
859
+ }
860
+ calculateMetrics(ast) {
861
+ return {
862
+ linesOfCode: 0,
863
+ logicalLines: 0,
864
+ commentLines: 0,
865
+ blankLines: 0,
866
+ cyclomaticComplexity: 0,
867
+ cognitiveComplexity: 0,
868
+ halsteadMetrics: { operators: 0, operands: 0, uniqueOperators: 0, uniqueOperands: 0, volume: 0, difficulty: 0, effort: 0, timeToProgram: 0, bugsDelivered: 0 },
869
+ maintainabilityIndex: 0,
870
+ duplicateRate: 0,
871
+ };
872
+ }
873
+ }
874
+ exports.GoAnalyzer = GoAnalyzer;
875
+ exports.GoLanguageSupport = {
876
+ id: 'go',
877
+ name: 'Go',
878
+ extensions: ['.go'],
879
+ parser: new GoParser(),
880
+ analyzer: new GoAnalyzer(),
881
+ };
882
+ //# sourceMappingURL=go.js.map