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,930 @@
1
+ "use strict";
2
+ /**
3
+ * C++ Language Support for LinguClaw
4
+ * Advanced C++ parser with template and memory management analysis
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.CppLanguageSupport = exports.CppAnalyzer = exports.CppParser = void 0;
8
+ class CppParser {
9
+ source = '';
10
+ lines = [];
11
+ parse(source, filePath) {
12
+ this.source = source;
13
+ this.lines = source.split('\n');
14
+ try {
15
+ const ast = this.parseCpp(source, filePath);
16
+ return {
17
+ ast,
18
+ errors: this.findSyntaxErrors(),
19
+ warnings: this.findPreprocessorIssues(),
20
+ tokens: [],
21
+ comments: this.extractComments(),
22
+ };
23
+ }
24
+ catch (error) {
25
+ return this.fallbackParse(filePath);
26
+ }
27
+ }
28
+ parseCpp(source, filePath) {
29
+ const root = {
30
+ type: 'TranslationUnit',
31
+ id: `${filePath}:0:0`,
32
+ location: this.createLocation(filePath, 0, 0, this.lines.length, 0),
33
+ children: [],
34
+ metadata: { language: 'cpp' },
35
+ };
36
+ // Parse preprocessor directives
37
+ const preprocessor = this.parsePreprocessor(source, filePath);
38
+ root.children.push(...preprocessor);
39
+ // Parse declarations
40
+ const declarations = this.parseDeclarations(source, filePath);
41
+ root.children.push(...declarations);
42
+ return root;
43
+ }
44
+ parsePreprocessor(source, filePath) {
45
+ const directives = [];
46
+ const directiveRegex = /^#(\w+)(?:\s+(.+))?$/gm;
47
+ let match;
48
+ while ((match = directiveRegex.exec(source)) !== null) {
49
+ const directive = match[1];
50
+ const value = match[2]?.trim();
51
+ const lineNum = source.substring(0, match.index).split('\n').length;
52
+ const node = {
53
+ type: 'PreprocessorDirective',
54
+ id: `${filePath}:${lineNum}:0`,
55
+ location: this.createLocation(filePath, lineNum, 0, lineNum, match[0].length),
56
+ children: [],
57
+ metadata: {
58
+ directive,
59
+ value,
60
+ isInclude: directive === 'include',
61
+ isDefine: directive === 'define',
62
+ isIfdef: directive === 'ifdef' || directive === 'ifndef',
63
+ isPragma: directive === 'pragma',
64
+ includePath: directive === 'include' ? this.extractIncludePath(value || '') : undefined,
65
+ },
66
+ };
67
+ directives.push(node);
68
+ }
69
+ return directives;
70
+ }
71
+ extractIncludePath(value) {
72
+ const match = value.match(/[<"](.+)[>"]/);
73
+ return match ? match[1] : value;
74
+ }
75
+ parseDeclarations(source, filePath) {
76
+ const declarations = [];
77
+ const lines = source.split('\n');
78
+ let i = 0;
79
+ while (i < lines.length) {
80
+ const line = lines[i].trim();
81
+ // Skip empty lines and comments
82
+ if (!line || line.startsWith('//') || line.startsWith('#')) {
83
+ i++;
84
+ continue;
85
+ }
86
+ // Namespace
87
+ if (line.startsWith('namespace ')) {
88
+ const nsDecl = this.parseNamespace(lines, i, filePath);
89
+ if (nsDecl) {
90
+ declarations.push(nsDecl.node);
91
+ i = nsDecl.endIndex + 1;
92
+ continue;
93
+ }
94
+ }
95
+ // Class/Struct/Union
96
+ if (this.isClassDeclaration(line)) {
97
+ const classDecl = this.parseClass(lines, i, filePath);
98
+ if (classDecl) {
99
+ declarations.push(classDecl.node);
100
+ i = classDecl.endIndex + 1;
101
+ continue;
102
+ }
103
+ }
104
+ // Function
105
+ if (this.isFunctionDeclaration(line)) {
106
+ const funcDecl = this.parseFunction(lines, i, filePath);
107
+ if (funcDecl) {
108
+ declarations.push(funcDecl.node);
109
+ i = funcDecl.endIndex + 1;
110
+ continue;
111
+ }
112
+ }
113
+ // Variable declaration
114
+ if (this.isVariableDeclaration(line)) {
115
+ const varDecl = this.parseVariableDeclaration(lines, i, filePath);
116
+ if (varDecl) {
117
+ declarations.push(varDecl.node);
118
+ i = varDecl.endIndex + 1;
119
+ continue;
120
+ }
121
+ }
122
+ // Template
123
+ if (line.startsWith('template<')) {
124
+ const templateDecl = this.parseTemplate(lines, i, filePath);
125
+ if (templateDecl) {
126
+ declarations.push(templateDecl.node);
127
+ i = templateDecl.endIndex + 1;
128
+ continue;
129
+ }
130
+ }
131
+ // Enum
132
+ if (line.startsWith('enum ')) {
133
+ const enumDecl = this.parseEnum(lines, i, filePath);
134
+ if (enumDecl) {
135
+ declarations.push(enumDecl.node);
136
+ i = enumDecl.endIndex + 1;
137
+ continue;
138
+ }
139
+ }
140
+ // Using/Type alias
141
+ if (line.startsWith('using ') || line.startsWith('typedef ')) {
142
+ const aliasDecl = this.parseTypeAlias(lines, i, filePath);
143
+ if (aliasDecl) {
144
+ declarations.push(aliasDecl.node);
145
+ i = aliasDecl.endIndex + 1;
146
+ continue;
147
+ }
148
+ }
149
+ // Extern
150
+ if (line.startsWith('extern ')) {
151
+ const externDecl = this.parseExtern(lines, i, filePath);
152
+ if (externDecl) {
153
+ declarations.push(externDecl.node);
154
+ i = externDecl.endIndex + 1;
155
+ continue;
156
+ }
157
+ }
158
+ i++;
159
+ }
160
+ return declarations;
161
+ }
162
+ isClassDeclaration(line) {
163
+ return /^(?:class|struct|union)(?:\s+\w+|$)/.test(line) ||
164
+ /^(?:template\s*<[^>]+>\s+)?(?:class|struct)/.test(line);
165
+ }
166
+ isFunctionDeclaration(line) {
167
+ // Matches function signatures but not variable declarations with initializers
168
+ return /(?:^|::)(\w+)\s*\([^)]*\)\s*(?:const|volatile|&|&&|\{|->|noexcept)?\s*$/.test(line) ||
169
+ /^(?:inline|virtual|static|explicit|constexpr|consteval)\s+/.test(line);
170
+ }
171
+ isVariableDeclaration(line) {
172
+ return /^(?:const|constexpr|static|extern|volatile|mutable|thread_local)?\s*[\w:<>,\s*&*]+\s+\w+\s*(?:=|;)/.test(line) ||
173
+ /^[\w:<>,\s*&*]+\s+\w+\s*\{[^}]*\}/.test(line);
174
+ }
175
+ parseNamespace(lines, startIdx, filePath) {
176
+ const line = lines[startIdx].trim();
177
+ const match = line.match(/namespace\s+(\w+)?/);
178
+ if (!match)
179
+ return null;
180
+ const name = match[1] || 'anonymous';
181
+ let endIdx = startIdx;
182
+ let braceCount = 0;
183
+ for (let i = startIdx; i < lines.length; i++) {
184
+ for (const char of lines[i]) {
185
+ if (char === '{')
186
+ braceCount++;
187
+ if (char === '}')
188
+ braceCount--;
189
+ }
190
+ if (braceCount === 0 && i > startIdx) {
191
+ endIdx = i;
192
+ break;
193
+ }
194
+ }
195
+ const body = lines.slice(startIdx + 1, endIdx);
196
+ const nested = this.parseDeclarations(body.join('\n'), filePath);
197
+ const node = {
198
+ type: 'NamespaceDeclaration',
199
+ id: `${filePath}:${startIdx + 1}:0`,
200
+ location: this.createLocation(filePath, startIdx + 1, 0, endIdx + 1, lines[endIdx]?.length || 0),
201
+ children: nested,
202
+ metadata: {
203
+ name,
204
+ isAnonymous: !match[1],
205
+ isInline: line.includes('inline'),
206
+ isNested: false,
207
+ },
208
+ };
209
+ return { node, endIndex: endIdx };
210
+ }
211
+ parseClass(lines, startIdx, filePath) {
212
+ const line = lines[startIdx].trim();
213
+ // Handle template prefix
214
+ let templatePrefix = '';
215
+ let actualLine = line;
216
+ if (line.startsWith('template')) {
217
+ // Find the actual class line
218
+ for (let i = startIdx + 1; i < lines.length; i++) {
219
+ if (lines[i].includes('class') || lines[i].includes('struct')) {
220
+ actualLine = lines[i].trim();
221
+ break;
222
+ }
223
+ }
224
+ }
225
+ const match = actualLine.match(/(class|struct|union)\s+(?:\w+\s+)?(\w+)(?:<([^>]+)>)?(?:\s*:\s*([^{]+))?/);
226
+ if (!match)
227
+ return null;
228
+ const kind = match[1];
229
+ const name = match[2];
230
+ const templateParams = match[3];
231
+ const inheritance = match[4];
232
+ let endIdx = startIdx;
233
+ let braceCount = 0;
234
+ for (let i = startIdx; i < lines.length; i++) {
235
+ for (const char of lines[i]) {
236
+ if (char === '{')
237
+ braceCount++;
238
+ if (char === '}')
239
+ braceCount--;
240
+ }
241
+ if (braceCount === 0 && i > startIdx) {
242
+ endIdx = i;
243
+ break;
244
+ }
245
+ }
246
+ const body = lines.slice(startIdx, endIdx + 1).join('\n');
247
+ const members = this.parseClassMembers(body, filePath);
248
+ const node = {
249
+ type: kind === 'class' ? 'ClassDeclaration' : kind === 'struct' ? 'StructDeclaration' : 'UnionDeclaration',
250
+ id: `${filePath}:${startIdx + 1}:0`,
251
+ location: this.createLocation(filePath, startIdx + 1, 0, endIdx + 1, lines[endIdx]?.length || 0),
252
+ children: members,
253
+ metadata: {
254
+ name,
255
+ templateParameters: templateParams ? templateParams.split(',').map(p => p.trim()) : [],
256
+ isTemplate: !!templateParams,
257
+ isStruct: kind === 'struct',
258
+ isUnion: kind === 'union',
259
+ inheritance: this.parseInheritance(inheritance),
260
+ accessSpecifiers: this.extractAccessSpecifiers(body),
261
+ hasVirtualDestructor: body.includes('~' + name) && body.includes('virtual'),
262
+ isAbstract: body.includes('= 0') || body.includes('=0'),
263
+ },
264
+ };
265
+ return { node, endIndex: endIdx };
266
+ }
267
+ parseClassMembers(body, filePath) {
268
+ const members = [];
269
+ const lines = body.split('\n');
270
+ // Simple member extraction - this could be more sophisticated
271
+ for (let i = 0; i < lines.length; i++) {
272
+ const line = lines[i].trim();
273
+ // Access specifiers
274
+ if (line.match(/^(public|private|protected):/)) {
275
+ members.push({
276
+ type: 'AccessSpecifier',
277
+ id: `${filePath}:${i + 1}:0`,
278
+ location: this.createLocation(filePath, i + 1, 0, i + 1, line.length),
279
+ children: [],
280
+ metadata: { access: line.replace(':', '') },
281
+ });
282
+ continue;
283
+ }
284
+ // Member variables
285
+ const varMatch = line.match(/([\w:<>,\s&*]+)\s+(\w+)\s*(?:=\s*([^;]+))?;/);
286
+ if (varMatch && !line.includes('(')) {
287
+ members.push({
288
+ type: 'FieldDeclaration',
289
+ id: `${filePath}:${i + 1}:0`,
290
+ location: this.createLocation(filePath, i + 1, 0, i + 1, line.length),
291
+ children: [],
292
+ metadata: {
293
+ name: varMatch[2],
294
+ type: varMatch[1].trim(),
295
+ initializer: varMatch[3]?.trim(),
296
+ },
297
+ });
298
+ }
299
+ // Member functions
300
+ const funcMatch = line.match(/(?:virtual\s+)?(?:static\s+)?(?:const\s+)?([\w:<>,\s&*]+)\s+(\w+)\s*\(([^)]*)\)\s*(?:const|override|final|noexcept)?\s*(?:=\s*0)?/);
301
+ if (funcMatch && line.includes('(')) {
302
+ members.push({
303
+ type: 'MethodDeclaration',
304
+ id: `${filePath}:${i + 1}:0`,
305
+ location: this.createLocation(filePath, i + 1, 0, i + 1, line.length),
306
+ children: [],
307
+ metadata: {
308
+ name: funcMatch[2],
309
+ returnType: funcMatch[1].trim(),
310
+ parameters: funcMatch[3],
311
+ isVirtual: line.includes('virtual'),
312
+ isPureVirtual: line.includes('= 0') || line.includes('=0'),
313
+ isOverride: line.includes('override'),
314
+ isFinal: line.includes('final'),
315
+ isConst: line.includes('const'),
316
+ },
317
+ });
318
+ }
319
+ // Constructors
320
+ const ctorMatch = line.match(/(\w+)\s*\(([^)]*)\)(?:\s*:\s*([^{]+))?/);
321
+ if (ctorMatch && !line.match(/^[\w:]+\s+\w+\s*\(/)) {
322
+ // Heuristic: if name matches class and not a return type pattern
323
+ members.push({
324
+ type: 'ConstructorDeclaration',
325
+ id: `${filePath}:${i + 1}:0`,
326
+ location: this.createLocation(filePath, i + 1, 0, i + 1, line.length),
327
+ children: [],
328
+ metadata: {
329
+ parameters: ctorMatch[2],
330
+ initializerList: ctorMatch[3],
331
+ isExplicit: line.includes('explicit'),
332
+ isDefault: line.includes('= default'),
333
+ isDeleted: line.includes('= delete'),
334
+ },
335
+ });
336
+ }
337
+ }
338
+ return members;
339
+ }
340
+ parseFunction(lines, startIdx, filePath) {
341
+ const line = lines[startIdx].trim();
342
+ // Handle template functions
343
+ let templateParams;
344
+ let actualStart = startIdx;
345
+ if (line.startsWith('template<')) {
346
+ templateParams = line.match(/template<(.+)>/)?.[1];
347
+ actualStart = startIdx + 1;
348
+ }
349
+ const actualLine = lines[actualStart]?.trim() || line;
350
+ // Match function signature
351
+ const match = actualLine.match(/(?:template<[^>]+>\s*)?(?:(\w+)::)?(?:~)?(\w+)\s*\(([^)]*)\)(?:\s*->\s*([^{]+))?/);
352
+ if (!match && !actualLine.includes('('))
353
+ return null;
354
+ // Find function body
355
+ let endIdx = actualStart;
356
+ let braceCount = 0;
357
+ let hasBody = false;
358
+ for (let i = actualStart; i < lines.length; i++) {
359
+ const currentLine = lines[i];
360
+ // Check for function try block
361
+ if (currentLine.includes('try') && i === actualStart) {
362
+ continue;
363
+ }
364
+ for (const char of currentLine) {
365
+ if (char === '{') {
366
+ braceCount++;
367
+ hasBody = true;
368
+ }
369
+ if (char === '}')
370
+ braceCount--;
371
+ }
372
+ if (hasBody && braceCount === 0) {
373
+ endIdx = i;
374
+ break;
375
+ }
376
+ // Function declaration without body
377
+ if (currentLine.includes(';') && !hasBody && i > actualStart) {
378
+ endIdx = i;
379
+ break;
380
+ }
381
+ }
382
+ const isDestructor = actualLine.includes('~');
383
+ const isOperator = actualLine.match(/operator\s*\W+/);
384
+ const node = {
385
+ type: 'FunctionDeclaration',
386
+ id: `${filePath}:${actualStart + 1}:0`,
387
+ location: this.createLocation(filePath, actualStart + 1, 0, endIdx + 1, lines[endIdx]?.length || 0),
388
+ children: [],
389
+ metadata: {
390
+ name: isDestructor ? 'destructor' : isOperator ? 'operator' : match?.[2] || 'unknown',
391
+ isTemplate: !!templateParams,
392
+ templateParameters: templateParams ? templateParams.split(',').map(p => p.trim()) : [],
393
+ isDestructor,
394
+ isOperator: !!isOperator,
395
+ isConstexpr: actualLine.includes('constexpr'),
396
+ isConsteval: actualLine.includes('consteval'),
397
+ isNoexcept: actualLine.includes('noexcept'),
398
+ isInline: actualLine.includes('inline'),
399
+ isStatic: actualLine.includes('static'),
400
+ isExtern: actualLine.includes('extern'),
401
+ hasBody,
402
+ trailingReturn: match?.[4]?.trim(),
403
+ },
404
+ };
405
+ return { node, endIndex: endIdx };
406
+ }
407
+ parseVariableDeclaration(lines, startIdx, filePath) {
408
+ const line = lines[startIdx].trim();
409
+ // Match variable declarations including modern C++ features
410
+ const match = line.match(/^(?:(const|constexpr|static|extern|volatile|mutable|thread_local|inline)\s+)*([\w:<>,\s&*]+?)\s+(\w+)(?:\[(\d+)\])?\s*(?:=\s*([^;{]+|\{[^}]*\}))?(?:;|$)/);
411
+ if (!match)
412
+ return null;
413
+ const node = {
414
+ type: 'VariableDeclaration',
415
+ id: `${filePath}:${startIdx + 1}:0`,
416
+ location: this.createLocation(filePath, startIdx + 1, 0, startIdx + 1, line.length),
417
+ children: [],
418
+ metadata: {
419
+ name: match[3],
420
+ type: match[2].trim(),
421
+ isConst: line.includes('const') && !line.includes('const&') && !line.includes('const*'),
422
+ isConstexpr: line.includes('constexpr'),
423
+ isStatic: line.includes('static'),
424
+ isExtern: line.includes('extern'),
425
+ isMutable: line.includes('mutable'),
426
+ isThreadLocal: line.includes('thread_local'),
427
+ isArray: !!match[4],
428
+ arraySize: match[4] ? parseInt(match[4]) : undefined,
429
+ initializer: match[5]?.trim(),
430
+ isBraceInit: match[5]?.startsWith('{'),
431
+ isAuto: match[2].trim() === 'auto',
432
+ },
433
+ };
434
+ return { node, endIndex: startIdx };
435
+ }
436
+ parseTemplate(lines, startIdx, filePath) {
437
+ const line = lines[startIdx].trim();
438
+ const match = line.match(/template<(.+)>/);
439
+ if (!match)
440
+ return null;
441
+ // The actual declaration follows the template
442
+ let endIdx = startIdx;
443
+ for (let i = startIdx + 1; i < lines.length; i++) {
444
+ if (lines[i].includes('{') || lines[i].includes(';')) {
445
+ endIdx = i;
446
+ break;
447
+ }
448
+ }
449
+ const node = {
450
+ type: 'TemplateDeclaration',
451
+ id: `${filePath}:${startIdx + 1}:0`,
452
+ location: this.createLocation(filePath, startIdx + 1, 0, endIdx + 1, lines[endIdx]?.length || 0),
453
+ children: [],
454
+ metadata: {
455
+ parameters: match[1].split(',').map(p => {
456
+ const param = p.trim();
457
+ const typenameMatch = param.match(/(?:typename|class)\s+(\w+)/);
458
+ const typeMatch = param.match(/(\w+)\s+(\w+)/);
459
+ return {
460
+ kind: param.startsWith('typename') ? 'typename' :
461
+ param.startsWith('class') ? 'class' : 'type',
462
+ name: typenameMatch?.[1] || typeMatch?.[2] || param,
463
+ defaultValue: param.includes('=') ? param.split('=')[1].trim() : undefined,
464
+ };
465
+ }),
466
+ isVariadic: match[1].includes('...'),
467
+ requiresClause: lines.slice(startIdx, endIdx).join(' ').match(/requires\s+(.+)/)?.[1],
468
+ },
469
+ };
470
+ return { node, endIndex: endIdx };
471
+ }
472
+ parseEnum(lines, startIdx, filePath) {
473
+ const line = lines[startIdx].trim();
474
+ const match = line.match(/enum\s+(?:class\s+)?(\w+)(?:\s*:\s*(\w+))?/);
475
+ if (!match)
476
+ return null;
477
+ let endIdx = startIdx;
478
+ let braceCount = 0;
479
+ for (let i = startIdx; i < lines.length; i++) {
480
+ for (const char of lines[i]) {
481
+ if (char === '{')
482
+ braceCount++;
483
+ if (char === '}')
484
+ braceCount--;
485
+ }
486
+ if (braceCount === 0 && i > startIdx) {
487
+ endIdx = i;
488
+ break;
489
+ }
490
+ }
491
+ const body = lines.slice(startIdx, endIdx + 1).join('\n');
492
+ const values = this.extractEnumValues(body);
493
+ const node = {
494
+ type: 'EnumDeclaration',
495
+ id: `${filePath}:${startIdx + 1}:0`,
496
+ location: this.createLocation(filePath, startIdx + 1, 0, endIdx + 1, lines[endIdx]?.length || 0),
497
+ children: [],
498
+ metadata: {
499
+ name: match[1],
500
+ isScoped: line.includes('enum class') || line.includes('enum struct'),
501
+ underlyingType: match[2],
502
+ values,
503
+ hasAssignedValues: body.includes('='),
504
+ },
505
+ };
506
+ return { node, endIndex: endIdx };
507
+ }
508
+ extractEnumValues(body) {
509
+ const values = [];
510
+ const valueRegex = /(\w+)\s*(?:=\s*([^,]+))?/g;
511
+ let match;
512
+ while ((match = valueRegex.exec(body)) !== null) {
513
+ if (!['enum', 'class', 'struct'].includes(match[1])) {
514
+ values.push({
515
+ name: match[1],
516
+ value: match[2]?.trim(),
517
+ });
518
+ }
519
+ }
520
+ return values;
521
+ }
522
+ parseTypeAlias(lines, startIdx, filePath) {
523
+ const line = lines[startIdx].trim();
524
+ // Using alias
525
+ const usingMatch = line.match(/using\s+(\w+)\s*=\s*(.+);/);
526
+ if (usingMatch) {
527
+ const node = {
528
+ type: 'TypeAliasDeclaration',
529
+ id: `${filePath}:${startIdx + 1}:0`,
530
+ location: this.createLocation(filePath, startIdx + 1, 0, startIdx + 1, line.length),
531
+ children: [],
532
+ metadata: {
533
+ name: usingMatch[1],
534
+ target: usingMatch[2],
535
+ isUsing: true,
536
+ isTemplateAlias: line.includes('template'),
537
+ },
538
+ };
539
+ return { node, endIndex: startIdx };
540
+ }
541
+ // Typedef
542
+ const typedefMatch = line.match(/typedef\s+([\w<>,\s&*]+)\s+(\w+);/);
543
+ if (typedefMatch) {
544
+ const node = {
545
+ type: 'TypeAliasDeclaration',
546
+ id: `${filePath}:${startIdx + 1}:0`,
547
+ location: this.createLocation(filePath, startIdx + 1, 0, startIdx + 1, line.length),
548
+ children: [],
549
+ metadata: {
550
+ name: typedefMatch[2],
551
+ target: typedefMatch[1].trim(),
552
+ isUsing: false,
553
+ },
554
+ };
555
+ return { node, endIndex: startIdx };
556
+ }
557
+ return null;
558
+ }
559
+ parseExtern(lines, startIdx, filePath) {
560
+ const line = lines[startIdx].trim();
561
+ const match = line.match(/extern\s+"(\w+)"\s*\{/);
562
+ if (!match) {
563
+ // Single extern declaration
564
+ const singleMatch = line.match(/extern\s+([\w<>,\s&*]+)\s+(\w+)\s*;/);
565
+ if (singleMatch) {
566
+ const node = {
567
+ type: 'ExternDeclaration',
568
+ id: `${filePath}:${startIdx + 1}:0`,
569
+ location: this.createLocation(filePath, startIdx + 1, 0, startIdx + 1, line.length),
570
+ children: [],
571
+ metadata: {
572
+ language: 'C',
573
+ isBlock: false,
574
+ },
575
+ };
576
+ return { node, endIndex: startIdx };
577
+ }
578
+ return null;
579
+ }
580
+ let endIdx = startIdx;
581
+ let braceCount = 0;
582
+ for (let i = startIdx; i < lines.length; i++) {
583
+ for (const char of lines[i]) {
584
+ if (char === '{')
585
+ braceCount++;
586
+ if (char === '}')
587
+ braceCount--;
588
+ }
589
+ if (braceCount === 0 && i > startIdx) {
590
+ endIdx = i;
591
+ break;
592
+ }
593
+ }
594
+ const node = {
595
+ type: 'ExternDeclaration',
596
+ id: `${filePath}:${startIdx + 1}:0`,
597
+ location: this.createLocation(filePath, startIdx + 1, 0, endIdx + 1, lines[endIdx]?.length || 0),
598
+ children: [],
599
+ metadata: {
600
+ language: match[1],
601
+ isBlock: true,
602
+ },
603
+ };
604
+ return { node, endIndex: endIdx };
605
+ }
606
+ parseInheritance(inheritance) {
607
+ if (!inheritance)
608
+ return [];
609
+ const result = [];
610
+ const parts = inheritance.split(',');
611
+ for (const part of parts) {
612
+ const trimmed = part.trim();
613
+ const virtual = trimmed.includes('virtual');
614
+ const visibility = trimmed.match(/(public|private|protected)/)?.[1] || 'private';
615
+ const className = trimmed.replace(/virtual|public|private|protected/g, '').trim();
616
+ if (className) {
617
+ result.push({ class: className, visibility, isVirtual: virtual });
618
+ }
619
+ }
620
+ return result;
621
+ }
622
+ extractAccessSpecifiers(body) {
623
+ const specifiers = [];
624
+ const regex = /(public|private|protected):/g;
625
+ let match;
626
+ while ((match = regex.exec(body)) !== null) {
627
+ specifiers.push(match[1]);
628
+ }
629
+ return specifiers;
630
+ }
631
+ findSyntaxErrors() {
632
+ const errors = [];
633
+ let braceCount = 0;
634
+ let parenCount = 0;
635
+ for (let i = 0; i < this.lines.length; i++) {
636
+ const line = this.lines[i];
637
+ // Skip preprocessor lines and comments
638
+ if (line.trim().startsWith('#') || line.trim().startsWith('//'))
639
+ continue;
640
+ for (const char of line) {
641
+ if (char === '{')
642
+ braceCount++;
643
+ if (char === '}')
644
+ braceCount--;
645
+ if (char === '(')
646
+ parenCount++;
647
+ if (char === ')')
648
+ parenCount--;
649
+ }
650
+ if (braceCount < 0) {
651
+ errors.push({ message: 'Unexpected }', line: i + 1, severity: 'error' });
652
+ braceCount = 0;
653
+ }
654
+ if (parenCount < 0) {
655
+ errors.push({ message: 'Unexpected )', line: i + 1, severity: 'error' });
656
+ parenCount = 0;
657
+ }
658
+ }
659
+ if (braceCount > 0) {
660
+ errors.push({ message: `Unclosed braces: ${braceCount}`, line: this.lines.length, severity: 'error' });
661
+ }
662
+ return errors;
663
+ }
664
+ findPreprocessorIssues() {
665
+ const warnings = [];
666
+ // Check for common issues
667
+ for (let i = 0; i < this.lines.length; i++) {
668
+ const line = this.lines[i];
669
+ // Missing header guard
670
+ if (i === 0 && !line.includes('#ifndef') && !line.includes('#pragma once')) {
671
+ // Only for .h/.hpp files
672
+ if (line.includes('.h') || line.includes('.hpp')) {
673
+ warnings.push({
674
+ message: 'Missing header guard (consider using #pragma once or #ifndef)',
675
+ line: 1,
676
+ severity: 'warning',
677
+ });
678
+ }
679
+ }
680
+ // Deprecated macros
681
+ if (line.includes('malloc') || line.includes('free') || line.includes('sprintf')) {
682
+ warnings.push({
683
+ message: 'Using C-style memory/string functions, consider C++ alternatives',
684
+ line: i + 1,
685
+ severity: 'info',
686
+ });
687
+ }
688
+ }
689
+ return warnings;
690
+ }
691
+ extractComments() {
692
+ const comments = [];
693
+ for (let i = 0; i < this.lines.length; i++) {
694
+ const line = this.lines[i];
695
+ // Single line comments
696
+ const singleIdx = line.indexOf('//');
697
+ if (singleIdx !== -1) {
698
+ comments.push({
699
+ type: 'Line',
700
+ value: line.substring(singleIdx + 2).trim(),
701
+ line: i + 1,
702
+ });
703
+ }
704
+ }
705
+ // Block comments
706
+ const blockRegex = /\/\*[\s\S]*?\*\//g;
707
+ let match;
708
+ while ((match = blockRegex.exec(this.source)) !== null) {
709
+ const lineNum = this.source.substring(0, match.index).split('\n').length;
710
+ comments.push({
711
+ type: 'Block',
712
+ value: match[0].substring(2, match[0].length - 2).trim(),
713
+ line: lineNum,
714
+ });
715
+ }
716
+ return comments;
717
+ }
718
+ createLocation(file, startLine, startCol, endLine, endCol) {
719
+ return {
720
+ file,
721
+ startLine,
722
+ startColumn: startCol,
723
+ endLine,
724
+ endColumn: endCol,
725
+ byteOffset: 0,
726
+ };
727
+ }
728
+ fallbackParse(filePath) {
729
+ return {
730
+ ast: this.parseCpp(this.source, filePath),
731
+ errors: this.findSyntaxErrors(),
732
+ warnings: this.findPreprocessorIssues(),
733
+ tokens: [],
734
+ comments: this.extractComments(),
735
+ };
736
+ }
737
+ }
738
+ exports.CppParser = CppParser;
739
+ class CppAnalyzer {
740
+ analyze(ast, context) {
741
+ const symbolTable = this.buildSymbolTable(ast);
742
+ const memoryAnalysis = this.analyzeMemoryManagement(ast);
743
+ const templateAnalysis = this.analyzeTemplates(ast);
744
+ const securityIssues = this.findSecurityIssues(ast);
745
+ return {
746
+ symbols: symbolTable,
747
+ callGraph: this.buildCallGraph(ast),
748
+ dataFlow: { definitions: new Map(), uses: new Map(), taintedSources: [], sinks: [] },
749
+ controlFlow: { nodes: [], edges: [], loops: [], branches: [] },
750
+ typeInference: new Map(),
751
+ metrics: this.calculateMetrics(ast),
752
+ suggestions: [
753
+ ...memoryAnalysis.suggestions,
754
+ ...templateAnalysis.suggestions,
755
+ ...securityIssues.map(i => ({
756
+ type: 'security',
757
+ severity: i.severity,
758
+ message: i.description,
759
+ remediation: i.remediation,
760
+ })),
761
+ ],
762
+ };
763
+ }
764
+ buildSymbolTable(ast) {
765
+ return {
766
+ variables: new Map(),
767
+ functions: new Map(),
768
+ classes: new Map(),
769
+ modules: new Map(),
770
+ imports: [],
771
+ exports: [],
772
+ };
773
+ }
774
+ analyzeMemoryManagement(ast) {
775
+ const suggestions = [];
776
+ let rawPointerCount = 0;
777
+ let newCount = 0;
778
+ let deleteCount = 0;
779
+ let uniquePtrCount = 0;
780
+ let sharedPtrCount = 0;
781
+ const traverse = (node) => {
782
+ // Check for raw pointers
783
+ if (node.type === 'VariableDeclaration') {
784
+ const type = node.metadata.type || '';
785
+ if (type.includes('*') && !type.includes('const*') && !type.includes('const *')) {
786
+ rawPointerCount++;
787
+ }
788
+ }
789
+ // Check for new/delete
790
+ if (node.type === 'MethodInvocation' || node.type === 'FunctionCall') {
791
+ const method = node.metadata.method || node.metadata.name || '';
792
+ if (method === 'new' || method.includes('::operator new'))
793
+ newCount++;
794
+ if (method === 'delete' || method === 'delete[]')
795
+ deleteCount++;
796
+ }
797
+ // Check for smart pointers
798
+ const type = node.metadata.type || '';
799
+ if (type.includes('unique_ptr'))
800
+ uniquePtrCount++;
801
+ if (type.includes('shared_ptr'))
802
+ sharedPtrCount++;
803
+ node.children.forEach(traverse);
804
+ };
805
+ traverse(ast);
806
+ // Memory management suggestions
807
+ if (newCount > 0 && deleteCount === 0) {
808
+ suggestions.push({
809
+ type: 'memory',
810
+ severity: 'warning',
811
+ message: `Using 'new' ${newCount} times without corresponding 'delete' - potential memory leak`,
812
+ remediation: 'Use smart pointers (std::unique_ptr, std::shared_ptr) or RAII containers',
813
+ });
814
+ }
815
+ if (rawPointerCount > 0 && uniquePtrCount + sharedPtrCount === 0) {
816
+ suggestions.push({
817
+ type: 'modernization',
818
+ severity: 'info',
819
+ message: `Using ${rawPointerCount} raw pointers - consider smart pointers`,
820
+ remediation: 'Replace raw pointers with std::unique_ptr for ownership, std::shared_ptr for shared ownership',
821
+ });
822
+ }
823
+ return { suggestions };
824
+ }
825
+ analyzeTemplates(ast) {
826
+ const suggestions = [];
827
+ let templateCount = 0;
828
+ let deepNesting = 0;
829
+ const traverse = (node, depth = 0) => {
830
+ if (node.type === 'TemplateDeclaration') {
831
+ templateCount++;
832
+ if (depth > 2) {
833
+ deepNesting++;
834
+ }
835
+ }
836
+ node.children.forEach(child => traverse(child, depth + 1));
837
+ };
838
+ traverse(ast);
839
+ if (deepNesting > 0) {
840
+ suggestions.push({
841
+ type: 'complexity',
842
+ severity: 'warning',
843
+ message: `Deep template nesting detected (${deepNesting} instances)`,
844
+ remediation: 'Consider using type aliases or concepts to simplify template instantiation',
845
+ });
846
+ }
847
+ return { suggestions };
848
+ }
849
+ findSecurityIssues(ast) {
850
+ const issues = [];
851
+ const traverse = (node) => {
852
+ // Check for unsafe functions
853
+ if (node.type === 'MethodInvocation' || node.type === 'FunctionCall') {
854
+ const method = node.metadata.method || node.metadata.name || '';
855
+ // Buffer overflow risks
856
+ const unsafeFunctions = ['strcpy', 'strcat', 'sprintf', 'gets', 'scanf'];
857
+ if (unsafeFunctions.some(f => method.includes(f))) {
858
+ issues.push({
859
+ id: 'CPP001',
860
+ severity: 'critical',
861
+ category: 'memory-safety',
862
+ location: node.location,
863
+ description: `Using unsafe C function: ${method} - buffer overflow risk`,
864
+ remediation: 'Use safe alternatives: strncpy, strncat, snprintf, fgets',
865
+ falsePositiveLikelihood: 0.1,
866
+ });
867
+ }
868
+ // Memory management issues
869
+ if (method === 'malloc' || method === 'calloc' || method === 'realloc') {
870
+ const parent = node.parent;
871
+ if (!parent || parent.type !== 'VariableDeclaration') {
872
+ issues.push({
873
+ id: 'CPP002',
874
+ severity: 'medium',
875
+ category: 'memory-safety',
876
+ location: node.location,
877
+ description: 'C-style memory allocation without immediate assignment',
878
+ remediation: 'Use new/delete or smart pointers',
879
+ falsePositiveLikelihood: 0.3,
880
+ });
881
+ }
882
+ }
883
+ }
884
+ // Check for missing virtual destructor
885
+ if (node.type === 'ClassDeclaration') {
886
+ const hasVirtualMethod = node.children.some(c => c.type === 'MethodDeclaration' && c.metadata.isVirtual);
887
+ const hasVirtualDestructor = node.metadata.hasVirtualDestructor;
888
+ if (hasVirtualMethod && !hasVirtualDestructor) {
889
+ issues.push({
890
+ id: 'CPP003',
891
+ severity: 'high',
892
+ category: 'memory-safety',
893
+ location: node.location,
894
+ description: `Class ${node.metadata.name} has virtual methods but non-virtual destructor`,
895
+ remediation: 'Add virtual ~ClassName() = default; or mark class as final',
896
+ falsePositiveLikelihood: 0.2,
897
+ });
898
+ }
899
+ }
900
+ node.children.forEach(traverse);
901
+ };
902
+ traverse(ast);
903
+ return issues;
904
+ }
905
+ buildCallGraph(ast) {
906
+ return { nodes: [], edges: [], entryPoints: [], deadCode: [] };
907
+ }
908
+ calculateMetrics(ast) {
909
+ return {
910
+ linesOfCode: 0,
911
+ logicalLines: 0,
912
+ commentLines: 0,
913
+ blankLines: 0,
914
+ cyclomaticComplexity: 0,
915
+ cognitiveComplexity: 0,
916
+ halsteadMetrics: { operators: 0, operands: 0, uniqueOperators: 0, uniqueOperands: 0, volume: 0, difficulty: 0, effort: 0, timeToProgram: 0, bugsDelivered: 0 },
917
+ maintainabilityIndex: 0,
918
+ duplicateRate: 0,
919
+ };
920
+ }
921
+ }
922
+ exports.CppAnalyzer = CppAnalyzer;
923
+ exports.CppLanguageSupport = {
924
+ id: 'cpp',
925
+ name: 'C++',
926
+ extensions: ['.cpp', '.cc', '.cxx', '.hpp', '.h', '.hh', '.hxx'],
927
+ parser: new CppParser(),
928
+ analyzer: new CppAnalyzer(),
929
+ };
930
+ //# sourceMappingURL=cpp.js.map