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,649 @@
1
+ "use strict";
2
+ /**
3
+ * Java Language Support for LinguClaw
4
+ * Advanced Java parser with class hierarchy and annotation analysis
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.JavaLanguageSupport = exports.JavaAnalyzer = exports.JavaParser = void 0;
8
+ class JavaParser {
9
+ source = '';
10
+ lines = [];
11
+ parse(source, filePath) {
12
+ this.source = source;
13
+ this.lines = source.split('\n');
14
+ try {
15
+ const ast = this.parseJava(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
+ parseJava(source, filePath) {
29
+ const root = {
30
+ type: 'CompilationUnit',
31
+ id: `${filePath}:0:0`,
32
+ location: this.createLocation(filePath, 0, 0, this.lines.length, 0),
33
+ children: [],
34
+ metadata: { language: 'java', package: '' },
35
+ };
36
+ // Extract package declaration
37
+ const packageMatch = source.match(/package\s+([\w.]+);/);
38
+ if (packageMatch) {
39
+ root.metadata.package = packageMatch[1];
40
+ root.children.push({
41
+ type: 'PackageDeclaration',
42
+ id: `${filePath}:1:0`,
43
+ location: this.createLocation(filePath, 1, 0, 1, packageMatch[0].length),
44
+ children: [],
45
+ metadata: { name: packageMatch[1] },
46
+ });
47
+ }
48
+ // Parse imports
49
+ const imports = this.parseImports(source, filePath);
50
+ root.children.push(...imports);
51
+ // Parse type declarations (classes, interfaces, enums, records)
52
+ const types = this.parseTypeDeclarations(source, filePath);
53
+ root.children.push(...types);
54
+ return root;
55
+ }
56
+ parseImports(source, filePath) {
57
+ const imports = [];
58
+ const importRegex = /import\s+(static\s+)?([\w.*]+);/g;
59
+ let match;
60
+ while ((match = importRegex.exec(source)) !== null) {
61
+ const isStatic = !!match[1];
62
+ const importPath = match[2];
63
+ const isWildcard = importPath.endsWith('.*');
64
+ imports.push({
65
+ type: 'ImportDeclaration',
66
+ id: `${filePath}:0:${match.index}`,
67
+ location: this.createLocation(filePath, 0, match.index, 0, match.index + match[0].length),
68
+ children: [],
69
+ metadata: {
70
+ path: importPath,
71
+ isStatic,
72
+ isWildcard,
73
+ isJavaStandard: importPath.startsWith('java.') || importPath.startsWith('javax.'),
74
+ isThirdParty: !importPath.startsWith('java.') &&
75
+ !importPath.startsWith('javax.') &&
76
+ !importPath.startsWith(this.getPackageName(source)),
77
+ },
78
+ });
79
+ }
80
+ return imports;
81
+ }
82
+ parseTypeDeclarations(source, filePath) {
83
+ const types = [];
84
+ // Match class, interface, enum, record, annotation declarations
85
+ const typeRegex = /(public\s+|private\s+|protected\s+)?(abstract\s+|final\s+|sealed\s+|non-sealed\s+)?(static\s+)?(class|interface|enum|record|@interface)\s+(\w+)(?:<([^>]+)>)?(?:\s+(?:extends|implements)\s+([^{]+))?/g;
86
+ let match;
87
+ while ((match = typeRegex.exec(source)) !== null) {
88
+ const visibility = match[1]?.trim() || 'package-private';
89
+ const modifiers = match[2]?.trim() || '';
90
+ const isStatic = !!match[3];
91
+ const typeKind = match[4];
92
+ const typeName = match[5];
93
+ const generics = match[6];
94
+ const extendsOrImplements = match[7]?.trim();
95
+ // Find the body
96
+ const bodyStart = source.indexOf('{', match.index);
97
+ if (bodyStart === -1)
98
+ continue;
99
+ const bodyEnd = this.findMatchingBrace(source, bodyStart);
100
+ const body = source.substring(bodyStart + 1, bodyEnd);
101
+ const typeNode = {
102
+ type: this.mapTypeKind(typeKind),
103
+ id: `${filePath}:0:${match.index}`,
104
+ location: this.createLocation(filePath, 0, match.index, 0, bodyEnd + 1),
105
+ children: this.parseClassBody(body, filePath),
106
+ metadata: {
107
+ name: typeName,
108
+ visibility,
109
+ isAbstract: modifiers.includes('abstract'),
110
+ isFinal: modifiers.includes('final'),
111
+ isSealed: modifiers.includes('sealed'),
112
+ isStatic,
113
+ isRecord: typeKind === 'record',
114
+ isAnnotation: typeKind === '@interface',
115
+ generics: generics ? generics.split(',').map(g => g.trim()) : [],
116
+ extends: this.parseExtends(extendsOrImplements),
117
+ implements: this.parseImplements(extendsOrImplements),
118
+ annotations: this.extractAnnotations(source, match.index),
119
+ javadoc: this.extractJavadoc(source, match.index),
120
+ },
121
+ };
122
+ types.push(typeNode);
123
+ }
124
+ return types;
125
+ }
126
+ parseClassBody(body, filePath) {
127
+ const members = [];
128
+ const lines = body.split('\n');
129
+ // Parse fields
130
+ const fieldRegex = /(private\s+|public\s+|protected\s+)?(static\s+)?(final\s+)?(transient\s+)?(volatile\s+)?([\w<>,\s\[\]]+?)\s+(\w+)\s*(?:=\s*([^;]+))?;/g;
131
+ let match;
132
+ while ((match = fieldRegex.exec(body)) !== null) {
133
+ members.push({
134
+ type: 'FieldDeclaration',
135
+ id: `${filePath}:0:${match.index}`,
136
+ location: this.createLocation(filePath, 0, match.index, 0, match.index + match[0].length),
137
+ children: [],
138
+ metadata: {
139
+ name: match[7],
140
+ type: match[6].trim(),
141
+ visibility: match[1]?.trim() || 'package-private',
142
+ isStatic: !!match[2],
143
+ isFinal: !!match[3],
144
+ isTransient: !!match[4],
145
+ isVolatile: !!match[5],
146
+ initializer: match[8]?.trim(),
147
+ annotations: this.extractAnnotations(body, match.index),
148
+ },
149
+ });
150
+ }
151
+ // Parse methods
152
+ const methodRegex = /(private\s+|public\s+|protected\s+)?(static\s+)?(abstract\s+)?(final\s+)?(synchronized\s+)?(native\s+)?(strictfp\s+)?(<[^>]+>\s+)?([\w<>,\s\[\]]+?)\s+(\w+)\s*\(([^)]*)\)\s*(?:throws\s+([^{]+))?/g;
153
+ while ((match = methodRegex.exec(body)) !== null) {
154
+ const visibility = match[1]?.trim() || 'package-private';
155
+ const isStatic = !!match[2];
156
+ const isAbstract = !!match[3];
157
+ const isFinal = !!match[4];
158
+ const isSynchronized = !!match[5];
159
+ const isNative = !!match[6];
160
+ const generics = match[8];
161
+ const returnType = match[9].trim();
162
+ const methodName = match[10];
163
+ const params = match[11];
164
+ const throwsClause = match[12]?.trim();
165
+ // Find method body
166
+ const afterSignature = body.indexOf('(', match.index) + params.length + 1;
167
+ let bodyStart = body.indexOf('{', afterSignature);
168
+ let hasBody = bodyStart !== -1;
169
+ let bodyEnd = hasBody ? this.findMatchingBrace(body, bodyStart) : afterSignature;
170
+ const methodNode = {
171
+ type: 'MethodDeclaration',
172
+ id: `${filePath}:0:${match.index}`,
173
+ location: this.createLocation(filePath, 0, match.index, 0, hasBody ? bodyEnd + 1 : afterSignature + 1),
174
+ children: hasBody ? this.parseMethodBody(body.substring(bodyStart + 1, bodyEnd), filePath) : [],
175
+ metadata: {
176
+ name: methodName,
177
+ returnType,
178
+ visibility,
179
+ isStatic,
180
+ isAbstract,
181
+ isFinal,
182
+ isSynchronized,
183
+ isNative,
184
+ hasBody,
185
+ isConstructor: methodName === this.getEnclosingClassName(body, match.index),
186
+ generics: generics ? generics.replace(/[<>]/g, '').split(',').map(g => g.trim()) : [],
187
+ parameters: this.parseJavaParameters(params),
188
+ throws: throwsClause ? throwsClause.split(',').map(t => t.trim()) : [],
189
+ annotations: this.extractAnnotations(body, match.index),
190
+ javadoc: this.extractJavadoc(body, match.index),
191
+ },
192
+ };
193
+ members.push(methodNode);
194
+ }
195
+ // Parse inner classes
196
+ const innerClassRegex = /class\s+(\w+)/g;
197
+ while ((match = innerClassRegex.exec(body)) !== null) {
198
+ // Skip if it's part of a method (heuristic)
199
+ const precedingText = body.substring(0, match.index);
200
+ const openBraces = (precedingText.match(/{/g) || []).length;
201
+ const closeBraces = (precedingText.match(/}/g) || []).length;
202
+ if (openBraces === closeBraces) {
203
+ // Top-level in class body
204
+ const innerBodyStart = body.indexOf('{', match.index);
205
+ const innerBodyEnd = this.findMatchingBrace(body, innerBodyStart);
206
+ members.push({
207
+ type: 'ClassDeclaration',
208
+ id: `${filePath}:0:${match.index}`,
209
+ location: this.createLocation(filePath, 0, match.index, 0, innerBodyEnd + 1),
210
+ children: [],
211
+ metadata: {
212
+ name: match[1],
213
+ isInnerClass: true,
214
+ isStatic: precedingText.substring(match.index - 20, match.index).includes('static'),
215
+ },
216
+ });
217
+ }
218
+ }
219
+ return members;
220
+ }
221
+ parseMethodBody(body, filePath) {
222
+ const statements = [];
223
+ // Variable declarations
224
+ const varRegex = /([\w<>,\s\[\]]+?)\s+(\w+)\s*=\s*([^;]+);/g;
225
+ let match;
226
+ while ((match = varRegex.exec(body)) !== null) {
227
+ statements.push({
228
+ type: 'VariableDeclaration',
229
+ id: `${filePath}:0:${match.index}`,
230
+ location: this.createLocation(filePath, 0, match.index, 0, match.index + match[0].length),
231
+ children: [],
232
+ metadata: {
233
+ type: match[1].trim(),
234
+ name: match[2],
235
+ initializer: match[3].trim(),
236
+ },
237
+ });
238
+ }
239
+ // Method invocations (for call graph)
240
+ const invocationRegex = /(\w+(?:\.\w+)*)\s*\(/g;
241
+ while ((match = invocationRegex.exec(body)) !== null) {
242
+ const preceding = body.substring(Math.max(0, match.index - 20), match.index);
243
+ // Skip if it's a control structure
244
+ if (!/(if|while|for|switch|catch|synchronized)\s*$/.test(preceding)) {
245
+ statements.push({
246
+ type: 'MethodInvocation',
247
+ id: `${filePath}:0:${match.index}`,
248
+ location: this.createLocation(filePath, 0, match.index, 0, match.index + match[0].length),
249
+ children: [],
250
+ metadata: {
251
+ method: match[1],
252
+ isQualified: match[1].includes('.'),
253
+ object: match[1].includes('.') ? match[1].split('.')[0] : 'this',
254
+ methodName: match[1].includes('.') ? match[1].split('.').pop() : match[1],
255
+ },
256
+ });
257
+ }
258
+ }
259
+ // Exception handling
260
+ const tryCatchRegex = /try\s*\{/g;
261
+ while ((match = tryCatchRegex.exec(body)) !== null) {
262
+ statements.push({
263
+ type: 'TryStatement',
264
+ id: `${filePath}:0:${match.index}`,
265
+ location: this.createLocation(filePath, 0, match.index, 0, match.index + 3),
266
+ children: [],
267
+ metadata: {},
268
+ });
269
+ }
270
+ return statements;
271
+ }
272
+ parseJavaParameters(params) {
273
+ if (!params.trim())
274
+ return [];
275
+ const result = [];
276
+ const paramList = this.splitParams(params);
277
+ for (const param of paramList) {
278
+ const trimmed = param.trim();
279
+ if (!trimmed)
280
+ continue;
281
+ const isFinal = trimmed.startsWith('final ');
282
+ const withoutFinal = isFinal ? trimmed.substring(6) : trimmed;
283
+ const isVarArgs = withoutFinal.includes('...');
284
+ // Split type and name
285
+ const parts = withoutFinal.replace('...', '').trim().split(/\s+/);
286
+ if (parts.length >= 2) {
287
+ const type = parts.slice(0, -1).join(' ');
288
+ const name = parts[parts.length - 1];
289
+ result.push({
290
+ name,
291
+ type: isVarArgs ? type + '...' : type,
292
+ isVarArgs,
293
+ isFinal,
294
+ });
295
+ }
296
+ }
297
+ return result;
298
+ }
299
+ parseExtends(extendsOrImplements) {
300
+ if (!extendsOrImplements)
301
+ return undefined;
302
+ const match = extendsOrImplements.match(/extends\s+(\w+)/);
303
+ return match ? match[1] : undefined;
304
+ }
305
+ parseImplements(extendsOrImplements) {
306
+ if (!extendsOrImplements)
307
+ return [];
308
+ const match = extendsOrImplements.match(/implements\s+(.+)$/);
309
+ if (match) {
310
+ return match[1].split(',').map(i => i.trim());
311
+ }
312
+ return [];
313
+ }
314
+ extractAnnotations(source, position) {
315
+ const annotations = [];
316
+ const preceding = source.substring(0, position);
317
+ const annotationRegex = /@(\w+)(?:\(([^)]*)\))?/g;
318
+ let match;
319
+ // Find annotations in the last few lines before position
320
+ const relevantText = preceding.substring(Math.max(0, preceding.length - 500));
321
+ while ((match = annotationRegex.exec(relevantText)) !== null) {
322
+ annotations.push(match[1]);
323
+ }
324
+ return annotations;
325
+ }
326
+ extractJavadoc(source, position) {
327
+ const preceding = source.substring(0, position);
328
+ const javadocMatch = preceding.match(/\/\*\*([\s\S]*?)\*\/\s*$/);
329
+ if (javadocMatch) {
330
+ return javadocMatch[1].replace(/^\s*\*\s?/gm, '').trim();
331
+ }
332
+ return undefined;
333
+ }
334
+ mapTypeKind(kind) {
335
+ const map = {
336
+ 'class': 'ClassDeclaration',
337
+ 'interface': 'InterfaceDeclaration',
338
+ 'enum': 'EnumDeclaration',
339
+ 'record': 'RecordDeclaration',
340
+ '@interface': 'AnnotationDeclaration',
341
+ };
342
+ return map[kind] || 'TypeDeclaration';
343
+ }
344
+ findMatchingBrace(source, startPos) {
345
+ let depth = 1;
346
+ for (let i = startPos + 1; i < source.length; i++) {
347
+ if (source[i] === '{')
348
+ depth++;
349
+ if (source[i] === '}')
350
+ depth--;
351
+ if (depth === 0)
352
+ return i;
353
+ }
354
+ return source.length - 1;
355
+ }
356
+ splitParams(params) {
357
+ const result = [];
358
+ let current = '';
359
+ let depth = 0;
360
+ for (const char of params) {
361
+ if (char === '<' || char === '(')
362
+ depth++;
363
+ if (char === '>' || char === ')')
364
+ depth--;
365
+ if (char === ',' && depth === 0) {
366
+ result.push(current.trim());
367
+ current = '';
368
+ }
369
+ else {
370
+ current += char;
371
+ }
372
+ }
373
+ if (current.trim()) {
374
+ result.push(current.trim());
375
+ }
376
+ return result;
377
+ }
378
+ getPackageName(source) {
379
+ const match = source.match(/package\s+([\w.]+);/);
380
+ return match ? match[1] : '';
381
+ }
382
+ getEnclosingClassName(source, position) {
383
+ const preceding = source.substring(0, position);
384
+ const classMatch = preceding.match(/class\s+(\w+)/g);
385
+ if (classMatch) {
386
+ const lastMatch = classMatch[classMatch.length - 1];
387
+ const nameMatch = lastMatch.match(/class\s+(\w+)/);
388
+ return nameMatch ? nameMatch[1] : null;
389
+ }
390
+ return null;
391
+ }
392
+ createLocation(file, startLine, startCol, endLine, endCol) {
393
+ return {
394
+ file,
395
+ startLine,
396
+ startColumn: startCol,
397
+ endLine,
398
+ endColumn: endCol,
399
+ byteOffset: 0,
400
+ };
401
+ }
402
+ findSyntaxErrors() {
403
+ const errors = [];
404
+ let braceCount = 0;
405
+ let parenCount = 0;
406
+ for (let i = 0; i < this.lines.length; i++) {
407
+ const line = this.lines[i];
408
+ for (const char of line) {
409
+ if (char === '{')
410
+ braceCount++;
411
+ if (char === '}')
412
+ braceCount--;
413
+ if (char === '(')
414
+ parenCount++;
415
+ if (char === ')')
416
+ parenCount--;
417
+ }
418
+ if (braceCount < 0) {
419
+ errors.push({ message: 'Unexpected }', line: i + 1, severity: 'error' });
420
+ braceCount = 0;
421
+ }
422
+ if (parenCount < 0) {
423
+ errors.push({ message: 'Unexpected )', line: i + 1, severity: 'error' });
424
+ parenCount = 0;
425
+ }
426
+ }
427
+ if (braceCount > 0) {
428
+ errors.push({ message: `Unclosed braces: ${braceCount}`, line: this.lines.length, severity: 'error' });
429
+ }
430
+ return errors;
431
+ }
432
+ extractComments() {
433
+ const comments = [];
434
+ for (let i = 0; i < this.lines.length; i++) {
435
+ const line = this.lines[i];
436
+ // Single line comments
437
+ const singleIdx = line.indexOf('//');
438
+ if (singleIdx !== -1) {
439
+ comments.push({
440
+ type: 'Line',
441
+ value: line.substring(singleIdx + 2).trim(),
442
+ line: i + 1,
443
+ });
444
+ }
445
+ }
446
+ // Block comments
447
+ const blockRegex = /\/\*[\s\S]*?\*\//g;
448
+ let match;
449
+ while ((match = blockRegex.exec(this.source)) !== null) {
450
+ const lineNum = this.source.substring(0, match.index).split('\n').length;
451
+ comments.push({
452
+ type: 'Block',
453
+ value: match[0].substring(2, match[0].length - 2).trim(),
454
+ line: lineNum,
455
+ });
456
+ }
457
+ return comments;
458
+ }
459
+ fallbackParse(filePath) {
460
+ return {
461
+ ast: this.parseJava(this.source, filePath),
462
+ errors: this.findSyntaxErrors(),
463
+ warnings: [{ message: 'Using fallback parser' }],
464
+ tokens: [],
465
+ comments: this.extractComments(),
466
+ };
467
+ }
468
+ }
469
+ exports.JavaParser = JavaParser;
470
+ class JavaAnalyzer {
471
+ analyze(ast, context) {
472
+ const symbolTable = this.buildSymbolTable(ast);
473
+ const classHierarchy = this.analyzeClassHierarchy(ast);
474
+ const springAnalysis = this.analyzeSpringAnnotations(ast);
475
+ const securityIssues = this.findSecurityIssues(ast);
476
+ return {
477
+ symbols: symbolTable,
478
+ callGraph: this.buildCallGraph(ast),
479
+ dataFlow: { definitions: new Map(), uses: new Map(), taintedSources: [], sinks: [] },
480
+ controlFlow: { nodes: [], edges: [], loops: [], branches: [] },
481
+ typeInference: new Map(),
482
+ metrics: this.calculateMetrics(ast),
483
+ suggestions: [
484
+ ...springAnalysis.suggestions,
485
+ ...securityIssues.map(i => ({
486
+ type: 'security',
487
+ severity: i.severity,
488
+ message: i.description,
489
+ remediation: i.remediation,
490
+ })),
491
+ ],
492
+ };
493
+ }
494
+ buildSymbolTable(ast) {
495
+ return {
496
+ variables: new Map(),
497
+ functions: new Map(),
498
+ classes: new Map(),
499
+ modules: new Map(),
500
+ imports: [],
501
+ exports: [],
502
+ };
503
+ }
504
+ analyzeClassHierarchy(ast) {
505
+ const classes = [];
506
+ const traverse = (node) => {
507
+ if (node.type === 'ClassDeclaration') {
508
+ classes.push({
509
+ name: node.metadata.name,
510
+ extends: node.metadata.extends,
511
+ implements: node.metadata.implements,
512
+ isAbstract: node.metadata.isAbstract,
513
+ isFinal: node.metadata.isFinal,
514
+ });
515
+ }
516
+ node.children.forEach(traverse);
517
+ };
518
+ traverse(ast);
519
+ return { classes, inheritanceDepth: this.calculateInheritanceDepth(classes) };
520
+ }
521
+ calculateInheritanceDepth(classes) {
522
+ let maxDepth = 0;
523
+ const getDepth = (className, visited = new Set()) => {
524
+ if (visited.has(className))
525
+ return 0; // Circular
526
+ visited.add(className);
527
+ const cls = classes.find(c => c.name === className);
528
+ if (!cls || !cls.extends)
529
+ return 0;
530
+ return 1 + getDepth(cls.extends, visited);
531
+ };
532
+ for (const cls of classes) {
533
+ maxDepth = Math.max(maxDepth, getDepth(cls.name));
534
+ }
535
+ return maxDepth;
536
+ }
537
+ analyzeSpringAnnotations(ast) {
538
+ const suggestions = [];
539
+ let controllerCount = 0;
540
+ let serviceCount = 0;
541
+ let repositoryCount = 0;
542
+ const traverse = (node) => {
543
+ const annotations = node.metadata.annotations || [];
544
+ if (annotations.includes('Controller') || annotations.includes('RestController')) {
545
+ controllerCount++;
546
+ }
547
+ if (annotations.includes('Service'))
548
+ serviceCount++;
549
+ if (annotations.includes('Repository'))
550
+ repositoryCount++;
551
+ // Check for proper transaction management
552
+ if (annotations.includes('Service') && !annotations.includes('Transactional')) {
553
+ suggestions.push({
554
+ type: 'best-practice',
555
+ severity: 'info',
556
+ message: `Service class ${node.metadata.name} missing @Transactional`,
557
+ remediation: 'Consider adding @Transactional for database operations',
558
+ });
559
+ }
560
+ node.children.forEach(traverse);
561
+ };
562
+ traverse(ast);
563
+ // Architecture validation
564
+ if (controllerCount > 0 && serviceCount === 0) {
565
+ suggestions.push({
566
+ type: 'architecture',
567
+ severity: 'warning',
568
+ message: 'Controllers without Service layer detected',
569
+ remediation: 'Add Service layer for business logic separation',
570
+ });
571
+ }
572
+ return { suggestions };
573
+ }
574
+ findSecurityIssues(ast) {
575
+ const issues = [];
576
+ const traverse = (node) => {
577
+ // Check for SQL injection in string concatenation
578
+ if (node.type === 'MethodInvocation') {
579
+ const method = node.metadata.method;
580
+ if (method?.includes('createQuery') || method?.includes('prepareStatement')) {
581
+ // Check for string concatenation in parameters
582
+ }
583
+ }
584
+ // Check for insecure deserialization
585
+ const annotations = node.metadata.annotations || [];
586
+ if (annotations.includes('RequestMapping') || annotations.includes('GetMapping')) {
587
+ const params = node.metadata.parameters || [];
588
+ for (const param of params) {
589
+ if (!param.annotations?.includes('Valid')) {
590
+ issues.push({
591
+ id: 'JAVA001',
592
+ severity: 'medium',
593
+ category: 'broken-authentication',
594
+ location: node.location,
595
+ description: `Parameter ${param.name} in API endpoint lacks validation`,
596
+ remediation: 'Add @Valid annotation and validation constraints',
597
+ falsePositiveLikelihood: 0.3,
598
+ });
599
+ }
600
+ }
601
+ }
602
+ // Check for hardcoded credentials
603
+ if (node.type === 'FieldDeclaration') {
604
+ const name = node.metadata.name?.toLowerCase();
605
+ if (name?.includes('password') || name?.includes('secret') || name?.includes('key')) {
606
+ if (node.metadata.initializer) {
607
+ issues.push({
608
+ id: 'JAVA002',
609
+ severity: 'critical',
610
+ category: 'sensitive-data-exposure',
611
+ location: node.location,
612
+ description: `Potential hardcoded credential: ${node.metadata.name}`,
613
+ remediation: 'Use externalized configuration (e.g., Spring @Value)',
614
+ falsePositiveLikelihood: 0.4,
615
+ });
616
+ }
617
+ }
618
+ }
619
+ node.children.forEach(traverse);
620
+ };
621
+ traverse(ast);
622
+ return issues;
623
+ }
624
+ buildCallGraph(ast) {
625
+ return { nodes: [], edges: [], entryPoints: [], deadCode: [] };
626
+ }
627
+ calculateMetrics(ast) {
628
+ return {
629
+ linesOfCode: 0,
630
+ logicalLines: 0,
631
+ commentLines: 0,
632
+ blankLines: 0,
633
+ cyclomaticComplexity: 0,
634
+ cognitiveComplexity: 0,
635
+ halsteadMetrics: { operators: 0, operands: 0, uniqueOperators: 0, uniqueOperands: 0, volume: 0, difficulty: 0, effort: 0, timeToProgram: 0, bugsDelivered: 0 },
636
+ maintainabilityIndex: 0,
637
+ duplicateRate: 0,
638
+ };
639
+ }
640
+ }
641
+ exports.JavaAnalyzer = JavaAnalyzer;
642
+ exports.JavaLanguageSupport = {
643
+ id: 'java',
644
+ name: 'Java',
645
+ extensions: ['.java'],
646
+ parser: new JavaParser(),
647
+ analyzer: new JavaAnalyzer(),
648
+ };
649
+ //# sourceMappingURL=java.js.map