projscan 1.6.2 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/languages/LanguageAdapter.d.ts +1 -1
- package/dist/core/languages/cppAdapter.d.ts +2 -0
- package/dist/core/languages/cppAdapter.js +145 -0
- package/dist/core/languages/cppAdapter.js.map +1 -0
- package/dist/core/languages/cppCallSites.d.ts +13 -0
- package/dist/core/languages/cppCallSites.js +62 -0
- package/dist/core/languages/cppCallSites.js.map +1 -0
- package/dist/core/languages/cppCyclomatic.d.ts +25 -0
- package/dist/core/languages/cppCyclomatic.js +82 -0
- package/dist/core/languages/cppCyclomatic.js.map +1 -0
- package/dist/core/languages/cppExports.d.ts +13 -0
- package/dist/core/languages/cppExports.js +120 -0
- package/dist/core/languages/cppExports.js.map +1 -0
- package/dist/core/languages/cppFunctions.d.ts +30 -0
- package/dist/core/languages/cppFunctions.js +242 -0
- package/dist/core/languages/cppFunctions.js.map +1 -0
- package/dist/core/languages/cppImports.d.ts +25 -0
- package/dist/core/languages/cppImports.js +77 -0
- package/dist/core/languages/cppImports.js.map +1 -0
- package/dist/core/languages/cppManifests.d.ts +18 -0
- package/dist/core/languages/cppManifests.js +41 -0
- package/dist/core/languages/cppManifests.js.map +1 -0
- package/dist/core/languages/kotlinAdapter.d.ts +2 -0
- package/dist/core/languages/kotlinAdapter.js +141 -0
- package/dist/core/languages/kotlinAdapter.js.map +1 -0
- package/dist/core/languages/kotlinCallSites.d.ts +15 -0
- package/dist/core/languages/kotlinCallSites.js +62 -0
- package/dist/core/languages/kotlinCallSites.js.map +1 -0
- package/dist/core/languages/kotlinCyclomatic.d.ts +24 -0
- package/dist/core/languages/kotlinCyclomatic.js +54 -0
- package/dist/core/languages/kotlinCyclomatic.js.map +1 -0
- package/dist/core/languages/kotlinExports.d.ts +13 -0
- package/dist/core/languages/kotlinExports.js +103 -0
- package/dist/core/languages/kotlinExports.js.map +1 -0
- package/dist/core/languages/kotlinFunctions.d.ts +27 -0
- package/dist/core/languages/kotlinFunctions.js +147 -0
- package/dist/core/languages/kotlinFunctions.js.map +1 -0
- package/dist/core/languages/kotlinImports.d.ts +25 -0
- package/dist/core/languages/kotlinImports.js +74 -0
- package/dist/core/languages/kotlinImports.js.map +1 -0
- package/dist/core/languages/kotlinManifests.d.ts +20 -0
- package/dist/core/languages/kotlinManifests.js +46 -0
- package/dist/core/languages/kotlinManifests.js.map +1 -0
- package/dist/core/languages/registry.js +14 -1
- package/dist/core/languages/registry.js.map +1 -1
- package/dist/core/languages/treeSitterLoader.js +19 -1
- package/dist/core/languages/treeSitterLoader.js.map +1 -1
- package/dist/core/memory.d.ts +30 -0
- package/dist/core/memory.js +42 -0
- package/dist/core/memory.js.map +1 -1
- package/dist/core/session.d.ts +5 -0
- package/dist/core/session.js +8 -3
- package/dist/core/session.js.map +1 -1
- package/dist/grammars/tree-sitter-cpp.wasm +0 -0
- package/dist/grammars/tree-sitter-kotlin.wasm +0 -0
- package/dist/mcp/server.js +47 -10
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/sessionTouchScanner.js +8 -2
- package/dist/mcp/sessionTouchScanner.js.map +1 -1
- package/dist/mcp/tools/costSummary.d.ts +26 -0
- package/dist/mcp/tools/costSummary.js +143 -0
- package/dist/mcp/tools/costSummary.js.map +1 -0
- package/dist/mcp/tools/fixSuggest.js +23 -2
- package/dist/mcp/tools/fixSuggest.js.map +1 -1
- package/dist/mcp/tools/memory.js +37 -4
- package/dist/mcp/tools/memory.js.map +1 -1
- package/dist/mcp/tools.js +2 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/tool-manifest.json +18 -4
- package/package.json +5 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FileEntry } from '../../types.js';
|
|
2
2
|
import type { AstResult } from '../ast.js';
|
|
3
|
-
export type LanguageId = 'javascript' | 'python' | 'go' | 'java' | 'ruby' | 'rust' | 'php' | 'csharp';
|
|
3
|
+
export type LanguageId = 'javascript' | 'python' | 'go' | 'java' | 'ruby' | 'rust' | 'php' | 'csharp' | 'kotlin' | 'cpp';
|
|
4
4
|
export interface LanguageResolveContext {
|
|
5
5
|
/** Language-specific root dirs used during import resolution. */
|
|
6
6
|
packageRoots?: string[];
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { createParserFor } from './treeSitterLoader.js';
|
|
3
|
+
import { extractCppImports } from './cppImports.js';
|
|
4
|
+
import { extractCppExports } from './cppExports.js';
|
|
5
|
+
import { extractCppCyclomatic } from './cppCyclomatic.js';
|
|
6
|
+
import { extractCppFunctions } from './cppFunctions.js';
|
|
7
|
+
import { extractCppCallSites } from './cppCallSites.js';
|
|
8
|
+
import { detectCppProject } from './cppManifests.js';
|
|
9
|
+
const CPP_EXTENSIONS = new Set(['.cpp', '.cc', '.cxx', '.c', '.h', '.hpp', '.hxx']);
|
|
10
|
+
const SOURCE_EXTENSIONS = new Set(['.cpp', '.cc', '.cxx', '.c']);
|
|
11
|
+
const MAX_CPP_FILE = 1024 * 1024;
|
|
12
|
+
let parserPromise = null;
|
|
13
|
+
async function getParser() {
|
|
14
|
+
if (!parserPromise)
|
|
15
|
+
parserPromise = createParserFor('tree-sitter-cpp.wasm');
|
|
16
|
+
return parserPromise;
|
|
17
|
+
}
|
|
18
|
+
export const cppAdapter = {
|
|
19
|
+
id: 'cpp',
|
|
20
|
+
extensions: CPP_EXTENSIONS,
|
|
21
|
+
// Only .cpp/.cc/.cxx/.c are "source" for dead-code purposes; headers
|
|
22
|
+
// hold the declarations they consume.
|
|
23
|
+
sourceExtensions: SOURCE_EXTENSIONS,
|
|
24
|
+
barrelBasenames: new Set(),
|
|
25
|
+
maxFileSize: MAX_CPP_FILE,
|
|
26
|
+
async parse(_filePath, content) {
|
|
27
|
+
try {
|
|
28
|
+
const parser = await getParser();
|
|
29
|
+
const tree = parser.parse(content);
|
|
30
|
+
if (!tree || !tree.rootNode) {
|
|
31
|
+
return {
|
|
32
|
+
ok: false,
|
|
33
|
+
reason: 'tree-sitter returned null tree',
|
|
34
|
+
imports: [],
|
|
35
|
+
exports: [],
|
|
36
|
+
callSites: [],
|
|
37
|
+
lineCount: content ? content.split('\n').length : 0,
|
|
38
|
+
cyclomaticComplexity: 0,
|
|
39
|
+
functions: [],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const root = tree.rootNode;
|
|
43
|
+
const imports = extractCppImports(root);
|
|
44
|
+
const exports = extractCppExports(root);
|
|
45
|
+
const cyclomaticComplexity = extractCppCyclomatic(root);
|
|
46
|
+
const callSites = extractCppCallSites(root);
|
|
47
|
+
const functions = extractCppFunctions(root);
|
|
48
|
+
return {
|
|
49
|
+
ok: true,
|
|
50
|
+
imports,
|
|
51
|
+
exports,
|
|
52
|
+
callSites,
|
|
53
|
+
lineCount: content ? content.split('\n').length : 0,
|
|
54
|
+
cyclomaticComplexity,
|
|
55
|
+
functions,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
60
|
+
return {
|
|
61
|
+
ok: false,
|
|
62
|
+
reason: `cpp parse failure: ${msg.slice(0, 120)}`,
|
|
63
|
+
imports: [],
|
|
64
|
+
exports: [],
|
|
65
|
+
callSites: [],
|
|
66
|
+
lineCount: content ? content.split('\n').length : 0,
|
|
67
|
+
cyclomaticComplexity: 0,
|
|
68
|
+
functions: [],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
resolveImport(importingFile, source, graphFiles, context) {
|
|
73
|
+
return resolveCppImport(importingFile, source, graphFiles, context);
|
|
74
|
+
},
|
|
75
|
+
toPackageName(source) {
|
|
76
|
+
if (!source)
|
|
77
|
+
return null;
|
|
78
|
+
// For #include, the "package" is the system header name (`vector`,
|
|
79
|
+
// `iostream`) when angle-bracketed. Quoted includes are project-local
|
|
80
|
+
// and should resolve via resolveImport — but we don't know quoting
|
|
81
|
+
// at this layer, so we conservatively return null for paths that
|
|
82
|
+
// look relative (`./`, `../`, contain `/`) and the bare leaf for
|
|
83
|
+
// angle-bracket-style names.
|
|
84
|
+
if (source.startsWith('./') || source.startsWith('../'))
|
|
85
|
+
return null;
|
|
86
|
+
if (source.includes('/'))
|
|
87
|
+
return source.split('/')[0];
|
|
88
|
+
return source;
|
|
89
|
+
},
|
|
90
|
+
async preparePackageRoots(rootPath, files) {
|
|
91
|
+
const info = await detectCppProject(rootPath, files);
|
|
92
|
+
return {
|
|
93
|
+
packageRoots: info ? info.includeRoots.map((r) => path.relative(rootPath, path.join(rootPath, r)) || '.') : [],
|
|
94
|
+
meta: info ? { cppProject: info } : undefined,
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Resolve a C++ `#include` source to a repo-local file. We try, in order:
|
|
100
|
+
*
|
|
101
|
+
* 1. Relative to the importing file's directory (quoted-include semantics).
|
|
102
|
+
* 2. Each detected include root (e.g., `include/`, `src/`, `lib/`).
|
|
103
|
+
*
|
|
104
|
+
* We return the first hit. Standard-library / third-party headers (e.g.,
|
|
105
|
+
* `<vector>`, `<boost/optional.hpp>`) won't match anything in the graph
|
|
106
|
+
* and resolve to null, which is correct — they're external.
|
|
107
|
+
*/
|
|
108
|
+
function resolveCppImport(importingFile, source, graphFiles, context) {
|
|
109
|
+
if (!source)
|
|
110
|
+
return null;
|
|
111
|
+
const project = context.meta?.cppProject;
|
|
112
|
+
const includeRoots = context.packageRoots ?? project?.includeRoots ?? [];
|
|
113
|
+
// 1) Relative to the importing file. tree-sitter doesn't tell us whether
|
|
114
|
+
// the source was quoted or angle-bracketed, but the resolver works the
|
|
115
|
+
// same way for either: we try the importing file's directory first.
|
|
116
|
+
const importingDir = path.posix.dirname(importingFile);
|
|
117
|
+
const relative = normalizeRelative(importingDir, source);
|
|
118
|
+
if (relative && graphFiles.has(relative))
|
|
119
|
+
return relative;
|
|
120
|
+
// 2) Each include root.
|
|
121
|
+
for (const root of includeRoots) {
|
|
122
|
+
const rootSegs = root === '.' || root === '' ? [] : root.split('/').filter(Boolean);
|
|
123
|
+
const candidate = [...rootSegs, ...source.split('/').filter(Boolean)].join('/');
|
|
124
|
+
if (graphFiles.has(candidate))
|
|
125
|
+
return candidate;
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
function normalizeRelative(baseDir, source) {
|
|
130
|
+
// Strip any leading `./`. For `../foo`, walk up the baseDir.
|
|
131
|
+
let dir = baseDir === '.' ? '' : baseDir;
|
|
132
|
+
let rest = source;
|
|
133
|
+
while (rest.startsWith('./'))
|
|
134
|
+
rest = rest.slice(2);
|
|
135
|
+
while (rest.startsWith('../')) {
|
|
136
|
+
if (!dir)
|
|
137
|
+
return null;
|
|
138
|
+
dir = path.posix.dirname(dir);
|
|
139
|
+
if (dir === '.')
|
|
140
|
+
dir = '';
|
|
141
|
+
rest = rest.slice(3);
|
|
142
|
+
}
|
|
143
|
+
return dir ? `${dir}/${rest}` : rest;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=cppAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cppAdapter.js","sourceRoot":"","sources":["../../../src/core/languages/cppAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAuB,MAAM,mBAAmB,CAAC;AAO1E,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AACpF,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;AACjE,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,CAAC;AAEjC,IAAI,aAAa,GAAqD,IAAI,CAAC;AAC3E,KAAK,UAAU,SAAS;IACtB,IAAI,CAAC,aAAa;QAAE,aAAa,GAAG,eAAe,CAAC,sBAAsB,CAAC,CAAC;IAC5E,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAoB;IACzC,EAAE,EAAE,KAAK;IACT,UAAU,EAAE,cAAc;IAC1B,qEAAqE;IACrE,sCAAsC;IACtC,gBAAgB,EAAE,iBAAiB;IACnC,eAAe,EAAE,IAAI,GAAG,EAAE;IAC1B,WAAW,EAAE,YAAY;IAEzB,KAAK,CAAC,KAAK,CAAC,SAAiB,EAAE,OAAe;QAC5C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACnC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC5B,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,MAAM,EAAE,gCAAgC;oBACxC,OAAO,EAAE,EAAE;oBACX,OAAO,EAAE,EAAE;oBACX,SAAS,EAAE,EAAE;oBACb,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;oBACnD,oBAAoB,EAAE,CAAC;oBACvB,SAAS,EAAE,EAAE;iBACd,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAA8D,CAAC;YACjF,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACxC,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAA+C,CAAC,CAAC;YACnF,MAAM,oBAAoB,GAAG,oBAAoB,CAC/C,IAAkD,CACnD,CAAC;YACF,MAAM,SAAS,GAAG,mBAAmB,CACnC,IAAiD,CAClD,CAAC;YACF,MAAM,SAAS,GAAG,mBAAmB,CACnC,IAAiD,CAClD,CAAC;YACF,OAAO;gBACL,EAAE,EAAE,IAAI;gBACR,OAAO;gBACP,OAAO;gBACP,SAAS;gBACT,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBACnD,oBAAoB;gBACpB,SAAS;aACV,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,sBAAsB,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;gBACjD,OAAO,EAAE,EAAE;gBACX,OAAO,EAAE,EAAE;gBACX,SAAS,EAAE,EAAE;gBACb,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBACnD,oBAAoB,EAAE,CAAC;gBACvB,SAAS,EAAE,EAAE;aACd,CAAC;QACJ,CAAC;IACH,CAAC;IAED,aAAa,CACX,aAAqB,EACrB,MAAc,EACd,UAAsC,EACtC,OAA+B;QAE/B,OAAO,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC;IAED,aAAa,CAAC,MAAc;QAC1B,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,mEAAmE;QACnE,sEAAsE;QACtE,mEAAmE;QACnE,iEAAiE;QACjE,iEAAiE;QACjE,6BAA6B;QAC7B,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACrE,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACtD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,mBAAmB,CACvB,QAAgB,EAChB,KAAkB;QAElB,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACrD,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE;YAC9G,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC;IACJ,CAAC;CACF,CAAC;AAEF;;;;;;;;;GASG;AACH,SAAS,gBAAgB,CACvB,aAAqB,EACrB,MAAc,EACd,UAAsC,EACtC,OAA+B;IAE/B,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,OAAO,GAAI,OAAO,CAAC,IAAoD,EAAE,UAAU,CAAC;IAC1F,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,EAAE,YAAY,IAAI,EAAE,CAAC;IAEzE,yEAAyE;IACzE,uEAAuE;IACvE,oEAAoE;IACpE,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACzD,IAAI,QAAQ,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAE1D,wBAAwB;IACxB,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpF,MAAM,SAAS,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChF,IAAI,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IAClD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAe,EAAE,MAAc;IACxD,6DAA6D;IAC7D,IAAI,GAAG,GAAG,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IACzC,IAAI,IAAI,GAAG,MAAM,CAAC;IAClB,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnD,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,GAAG,KAAK,GAAG;YAAE,GAAG,GAAG,EAAE,CAAC;QAC1B,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface TsNode {
|
|
2
|
+
type: string;
|
|
3
|
+
text: string;
|
|
4
|
+
namedChildren: TsNode[];
|
|
5
|
+
childForFieldName?: (name: string) => TsNode | null;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Extract called-name from each `call_expression` in a tree-sitter-cpp AST.
|
|
9
|
+
* Mirrors the existing adapter behaviour: dedupe names, strip qualification,
|
|
10
|
+
* so `obj.foo()`, `Foo::bar()`, and `bar()` all surface as just the leaf.
|
|
11
|
+
*/
|
|
12
|
+
export declare function extractCppCallSites(root: TsNode): string[];
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract called-name from each `call_expression` in a tree-sitter-cpp AST.
|
|
3
|
+
* Mirrors the existing adapter behaviour: dedupe names, strip qualification,
|
|
4
|
+
* so `obj.foo()`, `Foo::bar()`, and `bar()` all surface as just the leaf.
|
|
5
|
+
*/
|
|
6
|
+
export function extractCppCallSites(root) {
|
|
7
|
+
const seen = new Set();
|
|
8
|
+
walk(root, (n) => {
|
|
9
|
+
if (n.type !== 'call_expression')
|
|
10
|
+
return;
|
|
11
|
+
const fn = pickCallee(n);
|
|
12
|
+
if (!fn)
|
|
13
|
+
return;
|
|
14
|
+
const name = bareName(fn);
|
|
15
|
+
if (name)
|
|
16
|
+
seen.add(name);
|
|
17
|
+
});
|
|
18
|
+
return [...seen];
|
|
19
|
+
}
|
|
20
|
+
function pickCallee(node) {
|
|
21
|
+
if (node.childForFieldName) {
|
|
22
|
+
const f = node.childForFieldName('function');
|
|
23
|
+
if (f)
|
|
24
|
+
return f;
|
|
25
|
+
}
|
|
26
|
+
return node.namedChildren[0] ?? null;
|
|
27
|
+
}
|
|
28
|
+
function bareName(node) {
|
|
29
|
+
switch (node.type) {
|
|
30
|
+
case 'identifier':
|
|
31
|
+
case 'field_identifier':
|
|
32
|
+
case 'type_identifier':
|
|
33
|
+
return node.text;
|
|
34
|
+
case 'qualified_identifier': {
|
|
35
|
+
const last = node.namedChildren[node.namedChildren.length - 1];
|
|
36
|
+
return last ? bareName(last) : null;
|
|
37
|
+
}
|
|
38
|
+
case 'field_expression': {
|
|
39
|
+
const f = node.childForFieldName ? node.childForFieldName('field') : null;
|
|
40
|
+
if (f)
|
|
41
|
+
return bareName(f);
|
|
42
|
+
const last = node.namedChildren[node.namedChildren.length - 1];
|
|
43
|
+
return last ? bareName(last) : null;
|
|
44
|
+
}
|
|
45
|
+
case 'template_function': {
|
|
46
|
+
const f = node.childForFieldName ? node.childForFieldName('name') : null;
|
|
47
|
+
return f ? bareName(f) : null;
|
|
48
|
+
}
|
|
49
|
+
case 'call_expression': {
|
|
50
|
+
const inner = pickCallee(node);
|
|
51
|
+
return inner ? bareName(inner) : null;
|
|
52
|
+
}
|
|
53
|
+
default:
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function walk(node, visit) {
|
|
58
|
+
visit(node);
|
|
59
|
+
for (const child of node.namedChildren)
|
|
60
|
+
walk(child, visit);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=cppCallSites.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cppCallSites.js","sourceRoot":"","sources":["../../../src/core/languages/cppCallSites.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;QACf,IAAI,CAAC,CAAC,IAAI,KAAK,iBAAiB;YAAE,OAAO;QACzC,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,IAAI;YAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACvC,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,YAAY,CAAC;QAClB,KAAK,kBAAkB,CAAC;QACxB,KAAK,iBAAiB;YACpB,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,KAAK,sBAAsB,CAAC,CAAC,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACtC,CAAC;QACD,KAAK,kBAAkB,CAAC,CAAC,CAAC;YACxB,MAAM,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC1E,IAAI,CAAC;gBAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACtC,CAAC;QACD,KAAK,mBAAmB,CAAC,CAAC,CAAC;YACzB,MAAM,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACzE,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAChC,CAAC;QACD,KAAK,iBAAiB,CAAC,CAAC,CAAC;YACvB,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACxC,CAAC;QACD;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,IAAI,CAAC,IAAY,EAAE,KAA0B;IACpD,KAAK,CAAC,IAAI,CAAC,CAAC;IACZ,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;QAAE,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
interface TsNode {
|
|
2
|
+
type: string;
|
|
3
|
+
text: string;
|
|
4
|
+
namedChildren: TsNode[];
|
|
5
|
+
childForFieldName?: (name: string) => TsNode | null;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* File-level McCabe cyclomatic complexity for a tree-sitter-cpp AST.
|
|
9
|
+
*
|
|
10
|
+
* Decision points in C++:
|
|
11
|
+
* if_statement +1
|
|
12
|
+
* for_statement +1
|
|
13
|
+
* for_range_loop +1
|
|
14
|
+
* while_statement +1
|
|
15
|
+
* do_statement +1
|
|
16
|
+
* try_statement +1
|
|
17
|
+
* catch_clause +1 each
|
|
18
|
+
* case_statement (non-default) +1
|
|
19
|
+
* conditional_expression (`?:`) +1
|
|
20
|
+
* binary_expression `&&` / `||` +1 each
|
|
21
|
+
*
|
|
22
|
+
* `case 1:` and `case 2:` count individually; `default:` does not.
|
|
23
|
+
*/
|
|
24
|
+
export declare function extractCppCyclomatic(root: TsNode): number;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-level McCabe cyclomatic complexity for a tree-sitter-cpp AST.
|
|
3
|
+
*
|
|
4
|
+
* Decision points in C++:
|
|
5
|
+
* if_statement +1
|
|
6
|
+
* for_statement +1
|
|
7
|
+
* for_range_loop +1
|
|
8
|
+
* while_statement +1
|
|
9
|
+
* do_statement +1
|
|
10
|
+
* try_statement +1
|
|
11
|
+
* catch_clause +1 each
|
|
12
|
+
* case_statement (non-default) +1
|
|
13
|
+
* conditional_expression (`?:`) +1
|
|
14
|
+
* binary_expression `&&` / `||` +1 each
|
|
15
|
+
*
|
|
16
|
+
* `case 1:` and `case 2:` count individually; `default:` does not.
|
|
17
|
+
*/
|
|
18
|
+
export function extractCppCyclomatic(root) {
|
|
19
|
+
let decisions = 0;
|
|
20
|
+
walk(root, (n) => {
|
|
21
|
+
if (isDecisionPoint(n))
|
|
22
|
+
decisions++;
|
|
23
|
+
});
|
|
24
|
+
return decisions + 1;
|
|
25
|
+
}
|
|
26
|
+
function isDecisionPoint(n) {
|
|
27
|
+
switch (n.type) {
|
|
28
|
+
case 'if_statement':
|
|
29
|
+
case 'for_statement':
|
|
30
|
+
case 'for_range_loop':
|
|
31
|
+
case 'while_statement':
|
|
32
|
+
case 'do_statement':
|
|
33
|
+
case 'try_statement':
|
|
34
|
+
case 'catch_clause':
|
|
35
|
+
case 'conditional_expression':
|
|
36
|
+
return true;
|
|
37
|
+
case 'case_statement': {
|
|
38
|
+
// tree-sitter-cpp exposes a `value` field for `case X:` and leaves it
|
|
39
|
+
// null for `default:`. Field-based detection is more reliable than
|
|
40
|
+
// text inspection, which can misbehave when comments / whitespace
|
|
41
|
+
// sit between the keyword and the colon.
|
|
42
|
+
if (n.childForFieldName) {
|
|
43
|
+
const value = n.childForFieldName('value');
|
|
44
|
+
if (value)
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
// Fallback for grammar versions without the `value` field: a regular
|
|
48
|
+
// `case` has its label value as the first named child (literal /
|
|
49
|
+
// identifier / expression). The `default` form's first named child
|
|
50
|
+
// is whatever statement follows the colon.
|
|
51
|
+
const first = n.namedChildren[0];
|
|
52
|
+
if (!first)
|
|
53
|
+
return false;
|
|
54
|
+
return !STATEMENT_NODES.has(first.type);
|
|
55
|
+
}
|
|
56
|
+
case 'binary_expression':
|
|
57
|
+
return /(\s|^)(\|\||&&)(\s|$)/.test(n.text);
|
|
58
|
+
default:
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const STATEMENT_NODES = new Set([
|
|
63
|
+
'return_statement',
|
|
64
|
+
'break_statement',
|
|
65
|
+
'continue_statement',
|
|
66
|
+
'expression_statement',
|
|
67
|
+
'compound_statement',
|
|
68
|
+
'if_statement',
|
|
69
|
+
'for_statement',
|
|
70
|
+
'while_statement',
|
|
71
|
+
'do_statement',
|
|
72
|
+
'switch_statement',
|
|
73
|
+
'goto_statement',
|
|
74
|
+
'declaration',
|
|
75
|
+
'labeled_statement',
|
|
76
|
+
]);
|
|
77
|
+
function walk(node, visit) {
|
|
78
|
+
visit(node);
|
|
79
|
+
for (const child of node.namedChildren)
|
|
80
|
+
walk(child, visit);
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=cppCyclomatic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cppCyclomatic.js","sourceRoot":"","sources":["../../../src/core/languages/cppCyclomatic.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;QACf,IAAI,eAAe,CAAC,CAAC,CAAC;YAAE,SAAS,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,OAAO,SAAS,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,eAAe,CAAC,CAAS;IAChC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,cAAc,CAAC;QACpB,KAAK,eAAe,CAAC;QACrB,KAAK,gBAAgB,CAAC;QACtB,KAAK,iBAAiB,CAAC;QACvB,KAAK,cAAc,CAAC;QACpB,KAAK,eAAe,CAAC;QACrB,KAAK,cAAc,CAAC;QACpB,KAAK,wBAAwB;YAC3B,OAAO,IAAI,CAAC;QACd,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,sEAAsE;YACtE,mEAAmE;YACnE,kEAAkE;YAClE,yCAAyC;YACzC,IAAI,CAAC,CAAC,iBAAiB,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;gBAC3C,IAAI,KAAK;oBAAE,OAAO,IAAI,CAAC;YACzB,CAAC;YACD,qEAAqE;YACrE,iEAAiE;YACjE,mEAAmE;YACnE,2CAA2C;YAC3C,MAAM,KAAK,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YACjC,IAAI,CAAC,KAAK;gBAAE,OAAO,KAAK,CAAC;YACzB,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,mBAAmB;YACtB,OAAO,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC9C;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,kBAAkB;IAClB,iBAAiB;IACjB,oBAAoB;IACpB,sBAAsB;IACtB,oBAAoB;IACpB,cAAc;IACd,eAAe;IACf,iBAAiB;IACjB,cAAc;IACd,kBAAkB;IAClB,gBAAgB;IAChB,aAAa;IACb,mBAAmB;CACpB,CAAC,CAAC;AAEH,SAAS,IAAI,CAAC,IAAY,EAAE,KAA0B;IACpD,KAAK,CAAC,IAAI,CAAC,CAAC;IACZ,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;QAAE,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AstExport } from '../ast.js';
|
|
2
|
+
interface TsNode {
|
|
3
|
+
type: string;
|
|
4
|
+
text: string;
|
|
5
|
+
startPosition: {
|
|
6
|
+
row: number;
|
|
7
|
+
column: number;
|
|
8
|
+
};
|
|
9
|
+
namedChildren: TsNode[];
|
|
10
|
+
childForFieldName?: (name: string) => TsNode | null;
|
|
11
|
+
}
|
|
12
|
+
export declare function extractCppExports(root: TsNode): AstExport[];
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract top-level C++ declarations as exports.
|
|
3
|
+
*
|
|
4
|
+
* C++ has no first-class export model the way Rust / Kotlin do; "exports"
|
|
5
|
+
* for graph purposes are top-level declarations that are visible to other
|
|
6
|
+
* translation units. We surface:
|
|
7
|
+
*
|
|
8
|
+
* function_definition → function (free functions and methods)
|
|
9
|
+
* class_specifier → class
|
|
10
|
+
* struct_specifier → class (structs are classes with default-public)
|
|
11
|
+
* union_specifier → class
|
|
12
|
+
* enum_specifier → enum
|
|
13
|
+
* alias_declaration → type (`using Foo = Bar;`)
|
|
14
|
+
* type_definition → type (`typedef ... Foo;`)
|
|
15
|
+
* declaration (var/const) → variable (top-level globals)
|
|
16
|
+
*
|
|
17
|
+
* `static` at file scope marks a translation-unit-internal symbol; we
|
|
18
|
+
* still surface it (the graph treats it as a local definition).
|
|
19
|
+
*
|
|
20
|
+
* Member declarations inside class bodies are NOT extracted (they're
|
|
21
|
+
* reachable via the class export). Anonymous namespaces are descended.
|
|
22
|
+
*/
|
|
23
|
+
const EXPORT_NODE_TO_KIND = {
|
|
24
|
+
function_definition: 'function',
|
|
25
|
+
class_specifier: 'class',
|
|
26
|
+
struct_specifier: 'class',
|
|
27
|
+
union_specifier: 'class',
|
|
28
|
+
enum_specifier: 'enum',
|
|
29
|
+
alias_declaration: 'type',
|
|
30
|
+
type_definition: 'type',
|
|
31
|
+
};
|
|
32
|
+
export function extractCppExports(root) {
|
|
33
|
+
const exports = [];
|
|
34
|
+
visitTopLevel(root, exports);
|
|
35
|
+
return exports;
|
|
36
|
+
}
|
|
37
|
+
function visitTopLevel(node, out) {
|
|
38
|
+
// Descend through namespace and linkage_specification (`extern "C" { ... }`)
|
|
39
|
+
// wrappers — top-level declarations inside them are still file-scope.
|
|
40
|
+
if (node.type === 'translation_unit' ||
|
|
41
|
+
node.type === 'namespace_definition' ||
|
|
42
|
+
node.type === 'linkage_specification' ||
|
|
43
|
+
node.type === 'declaration_list') {
|
|
44
|
+
for (const c of node.namedChildren)
|
|
45
|
+
visitTopLevel(c, out);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const kind = EXPORT_NODE_TO_KIND[node.type];
|
|
49
|
+
if (kind) {
|
|
50
|
+
const name = nameOf(node);
|
|
51
|
+
if (name)
|
|
52
|
+
out.push({ name, kind, typeOnly: false, line: node.startPosition.row + 1 });
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Top-level variable / constant declarations: tree-sitter-cpp uses
|
|
56
|
+
// `declaration` for these. A declaration at translation-unit scope with
|
|
57
|
+
// a single declarator is a variable export.
|
|
58
|
+
if (node.type === 'declaration') {
|
|
59
|
+
const declarators = collectDeclarators(node);
|
|
60
|
+
for (const d of declarators) {
|
|
61
|
+
out.push({ name: d.name, kind: 'variable', typeOnly: false, line: node.startPosition.row + 1 });
|
|
62
|
+
}
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Don't recurse into anything else — class bodies and function bodies
|
|
66
|
+
// hold non-top-level declarations.
|
|
67
|
+
}
|
|
68
|
+
function collectDeclarators(declaration) {
|
|
69
|
+
const out = [];
|
|
70
|
+
for (const c of declaration.namedChildren) {
|
|
71
|
+
// function_declarator / init_declarator / array_declarator are wrappers
|
|
72
|
+
// around an identifier. Drill through them.
|
|
73
|
+
const id = innerIdentifier(c);
|
|
74
|
+
if (id)
|
|
75
|
+
out.push({ name: id });
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
79
|
+
function innerIdentifier(node) {
|
|
80
|
+
if (node.type === 'identifier' ||
|
|
81
|
+
node.type === 'field_identifier' ||
|
|
82
|
+
node.type === 'type_identifier') {
|
|
83
|
+
return node.text;
|
|
84
|
+
}
|
|
85
|
+
if (node.type === 'init_declarator' ||
|
|
86
|
+
node.type === 'array_declarator' ||
|
|
87
|
+
node.type === 'pointer_declarator' ||
|
|
88
|
+
node.type === 'reference_declarator' ||
|
|
89
|
+
node.type === 'parenthesized_declarator' ||
|
|
90
|
+
node.type === 'function_declarator') {
|
|
91
|
+
if (node.childForFieldName) {
|
|
92
|
+
const dec = node.childForFieldName('declarator');
|
|
93
|
+
if (dec)
|
|
94
|
+
return innerIdentifier(dec);
|
|
95
|
+
}
|
|
96
|
+
for (const c of node.namedChildren) {
|
|
97
|
+
const r = innerIdentifier(c);
|
|
98
|
+
if (r)
|
|
99
|
+
return r;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
function nameOf(node) {
|
|
105
|
+
if (node.childForFieldName) {
|
|
106
|
+
const id = node.childForFieldName('name');
|
|
107
|
+
if (id && id.text)
|
|
108
|
+
return id.text;
|
|
109
|
+
const dec = node.childForFieldName('declarator');
|
|
110
|
+
if (dec)
|
|
111
|
+
return innerIdentifier(dec);
|
|
112
|
+
}
|
|
113
|
+
for (const c of node.namedChildren) {
|
|
114
|
+
if (c.type === 'identifier' || c.type === 'field_identifier' || c.type === 'type_identifier') {
|
|
115
|
+
return c.text;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return innerIdentifier(node);
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=cppExports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cppExports.js","sourceRoot":"","sources":["../../../src/core/languages/cppExports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { FunctionInfo } from '../ast.js';
|
|
2
|
+
interface TsNode {
|
|
3
|
+
type: string;
|
|
4
|
+
text: string;
|
|
5
|
+
startPosition: {
|
|
6
|
+
row: number;
|
|
7
|
+
column: number;
|
|
8
|
+
};
|
|
9
|
+
endPosition: {
|
|
10
|
+
row: number;
|
|
11
|
+
column: number;
|
|
12
|
+
};
|
|
13
|
+
namedChildren: TsNode[];
|
|
14
|
+
childForFieldName?: (name: string) => TsNode | null;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Per-function McCabe CC for C++. Walks `function_definition` nodes
|
|
18
|
+
* (free functions, methods defined out-of-line, lambdas are NOT
|
|
19
|
+
* extracted as separate entries; their decisions fold into the
|
|
20
|
+
* enclosing function — matches the convention used elsewhere).
|
|
21
|
+
*
|
|
22
|
+
* Member functions defined inside a class body are named `Class.method`.
|
|
23
|
+
* Out-of-line definitions (`void Foo::bar() { ... }`) are also named
|
|
24
|
+
* `Foo.bar` based on the qualified declarator.
|
|
25
|
+
*
|
|
26
|
+
* `case` labels each contribute +1; `default:` does not. Ternaries (`?:`)
|
|
27
|
+
* count as +1. Logical `&&` and `||` each count.
|
|
28
|
+
*/
|
|
29
|
+
export declare function extractCppFunctions(root: TsNode): FunctionInfo[];
|
|
30
|
+
export {};
|