projscan 1.1.1 → 1.2.1

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 (71) hide show
  1. package/README.md +18 -14
  2. package/dist/cli/commands/coverage.js +4 -0
  3. package/dist/cli/commands/coverage.js.map +1 -1
  4. package/dist/cli/commands/prDiff.js +4 -0
  5. package/dist/cli/commands/prDiff.js.map +1 -1
  6. package/dist/core/ast.d.ts +14 -0
  7. package/dist/core/ast.js +30 -8
  8. package/dist/core/ast.js.map +1 -1
  9. package/dist/core/codeGraph.js +68 -3
  10. package/dist/core/codeGraph.js.map +1 -1
  11. package/dist/core/languages/LanguageAdapter.d.ts +1 -1
  12. package/dist/core/languages/csharpAdapter.d.ts +2 -0
  13. package/dist/core/languages/csharpAdapter.js +148 -0
  14. package/dist/core/languages/csharpAdapter.js.map +1 -0
  15. package/dist/core/languages/csharpCallSites.d.ts +22 -0
  16. package/dist/core/languages/csharpCallSites.js +73 -0
  17. package/dist/core/languages/csharpCallSites.js.map +1 -0
  18. package/dist/core/languages/csharpCyclomatic.d.ts +23 -0
  19. package/dist/core/languages/csharpCyclomatic.js +61 -0
  20. package/dist/core/languages/csharpCyclomatic.js.map +1 -0
  21. package/dist/core/languages/csharpExports.d.ts +13 -0
  22. package/dist/core/languages/csharpExports.js +69 -0
  23. package/dist/core/languages/csharpExports.js.map +1 -0
  24. package/dist/core/languages/csharpFunctions.d.ts +24 -0
  25. package/dist/core/languages/csharpFunctions.js +170 -0
  26. package/dist/core/languages/csharpFunctions.js.map +1 -0
  27. package/dist/core/languages/csharpImports.d.ts +30 -0
  28. package/dist/core/languages/csharpImports.js +90 -0
  29. package/dist/core/languages/csharpImports.js.map +1 -0
  30. package/dist/core/languages/goFunctions.js +31 -7
  31. package/dist/core/languages/goFunctions.js.map +1 -1
  32. package/dist/core/languages/javaFunctions.js +12 -5
  33. package/dist/core/languages/javaFunctions.js.map +1 -1
  34. package/dist/core/languages/phpAdapter.d.ts +2 -0
  35. package/dist/core/languages/phpAdapter.js +149 -0
  36. package/dist/core/languages/phpAdapter.js.map +1 -0
  37. package/dist/core/languages/phpCallSites.d.ts +21 -0
  38. package/dist/core/languages/phpCallSites.js +56 -0
  39. package/dist/core/languages/phpCallSites.js.map +1 -0
  40. package/dist/core/languages/phpCyclomatic.d.ts +27 -0
  41. package/dist/core/languages/phpCyclomatic.js +69 -0
  42. package/dist/core/languages/phpCyclomatic.js.map +1 -0
  43. package/dist/core/languages/phpExports.d.ts +13 -0
  44. package/dist/core/languages/phpExports.js +58 -0
  45. package/dist/core/languages/phpExports.js.map +1 -0
  46. package/dist/core/languages/phpFunctions.d.ts +25 -0
  47. package/dist/core/languages/phpFunctions.js +144 -0
  48. package/dist/core/languages/phpFunctions.js.map +1 -0
  49. package/dist/core/languages/phpImports.d.ts +31 -0
  50. package/dist/core/languages/phpImports.js +142 -0
  51. package/dist/core/languages/phpImports.js.map +1 -0
  52. package/dist/core/languages/phpManifests.d.ts +31 -0
  53. package/dist/core/languages/phpManifests.js +89 -0
  54. package/dist/core/languages/phpManifests.js.map +1 -0
  55. package/dist/core/languages/pythonFunctions.js +34 -8
  56. package/dist/core/languages/pythonFunctions.js.map +1 -1
  57. package/dist/core/languages/registry.js +3 -1
  58. package/dist/core/languages/registry.js.map +1 -1
  59. package/dist/core/languages/rubyFunctions.js +37 -5
  60. package/dist/core/languages/rubyFunctions.js.map +1 -1
  61. package/dist/core/languages/rustFunctions.js +44 -8
  62. package/dist/core/languages/rustFunctions.js.map +1 -1
  63. package/dist/core/languages/treeSitterLoader.js +3 -1
  64. package/dist/core/languages/treeSitterLoader.js.map +1 -1
  65. package/dist/grammars/tree-sitter-c_sharp.wasm +0 -0
  66. package/dist/grammars/tree-sitter-php.wasm +0 -0
  67. package/dist/reporters/htmlReporter.d.ts +3 -1
  68. package/dist/reporters/htmlReporter.js +86 -0
  69. package/dist/reporters/htmlReporter.js.map +1 -1
  70. package/dist/tool-manifest.json +2 -2
  71. package/package.json +4 -2
@@ -0,0 +1,148 @@
1
+ import path from 'node:path';
2
+ import { createParserFor } from './treeSitterLoader.js';
3
+ import { extractCsharpImports } from './csharpImports.js';
4
+ import { extractCsharpExports } from './csharpExports.js';
5
+ import { extractCsharpCyclomatic } from './csharpCyclomatic.js';
6
+ import { extractCsharpFunctions } from './csharpFunctions.js';
7
+ import { extractCsharpCallSites } from './csharpCallSites.js';
8
+ const CSHARP_EXTENSIONS = new Set(['.cs']);
9
+ const MAX_CSHARP_FILE = 1024 * 1024;
10
+ let parserPromise = null;
11
+ async function getParser() {
12
+ if (!parserPromise)
13
+ parserPromise = createParserFor('tree-sitter-c_sharp.wasm');
14
+ return parserPromise;
15
+ }
16
+ export const csharpAdapter = {
17
+ id: 'csharp',
18
+ extensions: CSHARP_EXTENSIONS,
19
+ sourceExtensions: CSHARP_EXTENSIONS,
20
+ // C# has no barrel-file convention.
21
+ barrelBasenames: new Set(),
22
+ maxFileSize: MAX_CSHARP_FILE,
23
+ async parse(_filePath, content) {
24
+ try {
25
+ const parser = await getParser();
26
+ const tree = parser.parse(content);
27
+ if (!tree || !tree.rootNode) {
28
+ return {
29
+ ok: false,
30
+ reason: 'tree-sitter returned null tree',
31
+ imports: [],
32
+ exports: [],
33
+ callSites: [],
34
+ lineCount: content ? content.split('\n').length : 0,
35
+ cyclomaticComplexity: 0,
36
+ functions: [],
37
+ };
38
+ }
39
+ const root = tree.rootNode;
40
+ const imports = extractCsharpImports(root);
41
+ const exports = extractCsharpExports(root);
42
+ const cyclomaticComplexity = extractCsharpCyclomatic(root);
43
+ const callSites = extractCsharpCallSites(root);
44
+ const functions = extractCsharpFunctions(root);
45
+ return {
46
+ ok: true,
47
+ imports,
48
+ exports,
49
+ callSites,
50
+ lineCount: content ? content.split('\n').length : 0,
51
+ cyclomaticComplexity,
52
+ functions,
53
+ };
54
+ }
55
+ catch (err) {
56
+ const msg = err instanceof Error ? err.message : String(err);
57
+ return {
58
+ ok: false,
59
+ reason: `c# parse failure: ${msg.slice(0, 120)}`,
60
+ imports: [],
61
+ exports: [],
62
+ callSites: [],
63
+ lineCount: content ? content.split('\n').length : 0,
64
+ cyclomaticComplexity: 0,
65
+ functions: [],
66
+ };
67
+ }
68
+ },
69
+ resolveImport(importingFile, source, graphFiles, context) {
70
+ return resolveCsharpImport(importingFile, source, graphFiles, context);
71
+ },
72
+ toPackageName(source) {
73
+ if (!source)
74
+ return null;
75
+ // The first dotted segment. `System.X` lands on the BCL, anything else
76
+ // could be a NuGet package (e.g. `Newtonsoft.Json`) or a local namespace.
77
+ return source.split('.')[0];
78
+ },
79
+ async preparePackageRoots(rootPath, files) {
80
+ // Find every .csproj file; each defines a project root and a default
81
+ // root namespace (the csproj filename without `.csproj`). When an import
82
+ // starts with that root namespace we strip it before mapping to a path.
83
+ const projects = [];
84
+ for (const f of files) {
85
+ if (!f.relativePath.endsWith('.csproj'))
86
+ continue;
87
+ const dir = path.posix.dirname(f.relativePath);
88
+ const stem = path.posix.basename(f.relativePath, '.csproj');
89
+ projects.push({ dir: dir === '' ? '.' : dir, rootNamespace: stem });
90
+ }
91
+ const packageRoots = projects.length > 0 ? projects.map((p) => p.dir) : ['.'];
92
+ return { packageRoots, meta: { repoRoot: rootPath, csharpProjects: projects } };
93
+ },
94
+ };
95
+ /**
96
+ * Resolve a C# `using` to a repo-local file or null.
97
+ *
98
+ * Strategy: C# has no manifest equivalent of PSR-4 — namespaces map to
99
+ * filesystem paths by *convention*. For `using A.B.C;` we probe each
100
+ * project root with `<root>/A/B/C.cs`, `<root>/A/B/C/<importingBasename>.cs`,
101
+ * and a few other shapes. The grammar itself can't tell us whether `C` is
102
+ * a type or a namespace, so we try the type-shape first.
103
+ */
104
+ function resolveCsharpImport(importingFile, source, graphFiles, context) {
105
+ if (!source)
106
+ return null;
107
+ const baseSegments = source.split('.').filter(Boolean);
108
+ if (baseSegments.length === 0)
109
+ return null;
110
+ const projects = context.meta?.csharpProjects ?? [];
111
+ const projectList = projects.length > 0
112
+ ? projects.map((p) => ({ dir: p.dir, strip: p.rootNamespace.split('.').filter(Boolean) }))
113
+ : [{ dir: '.', strip: [] }];
114
+ for (const { dir, strip } of projectList) {
115
+ const rootSegs = dir === '.' || dir === '' ? [] : dir.split('/').filter(Boolean);
116
+ const candidates = [];
117
+ candidates.push(baseSegments);
118
+ if (strip.length > 0 && segmentsStartWith(baseSegments, strip)) {
119
+ candidates.push(baseSegments.slice(strip.length));
120
+ }
121
+ for (const segs of candidates) {
122
+ if (segs.length === 0)
123
+ continue;
124
+ const last = segs[segs.length - 1];
125
+ // <root>/A/B/C.cs (type-name file under the namespace dir).
126
+ const typeFile = [...rootSegs, ...segs].join('/') + '.cs';
127
+ if (graphFiles.has(typeFile))
128
+ return typeFile;
129
+ // <root>/A/B/<last>.cs — same as above but expressing it via the
130
+ // explicit type-name path.
131
+ const dirPath = [...rootSegs, ...segs].join('/');
132
+ const candidate = `${dirPath}/${last}.cs`;
133
+ if (graphFiles.has(candidate))
134
+ return candidate;
135
+ }
136
+ }
137
+ return null;
138
+ }
139
+ function segmentsStartWith(segs, prefix) {
140
+ if (prefix.length > segs.length)
141
+ return false;
142
+ for (let i = 0; i < prefix.length; i++) {
143
+ if (segs[i] !== prefix[i])
144
+ return false;
145
+ }
146
+ return true;
147
+ }
148
+ //# sourceMappingURL=csharpAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csharpAdapter.js","sourceRoot":"","sources":["../../../src/core/languages/csharpAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ interface TsNode {
2
+ type: string;
3
+ text: string;
4
+ namedChildren: TsNode[];
5
+ childForFieldName?: (name: string) => TsNode | null;
6
+ }
7
+ /**
8
+ * Extract called-function names from C#. We surface a deduplicated list of
9
+ * bare identifiers (mirrors JS / Python / Go / Java / Ruby / Rust / PHP).
10
+ *
11
+ * invocation_expression : function child is one of:
12
+ * identifier foo(args) → "foo"
13
+ * member_access_expression obj.Method(args) → "Method"
14
+ * generic_name Foo<T>(args) → "Foo"
15
+ * conditional_access_expression obj?.Method(args) → "Method"
16
+ *
17
+ * Object-creation calls (`new Foo()`) are NOT surfaced — they're tracked as
18
+ * type instantiations elsewhere if needed; consistent with the other adapters
19
+ * which don't emit constructors as call sites.
20
+ */
21
+ export declare function extractCsharpCallSites(root: TsNode): string[];
22
+ export {};
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Extract called-function names from C#. We surface a deduplicated list of
3
+ * bare identifiers (mirrors JS / Python / Go / Java / Ruby / Rust / PHP).
4
+ *
5
+ * invocation_expression : function child is one of:
6
+ * identifier foo(args) → "foo"
7
+ * member_access_expression obj.Method(args) → "Method"
8
+ * generic_name Foo<T>(args) → "Foo"
9
+ * conditional_access_expression obj?.Method(args) → "Method"
10
+ *
11
+ * Object-creation calls (`new Foo()`) are NOT surfaced — they're tracked as
12
+ * type instantiations elsewhere if needed; consistent with the other adapters
13
+ * which don't emit constructors as call sites.
14
+ */
15
+ export function extractCsharpCallSites(root) {
16
+ const seen = new Set();
17
+ walk(root, (n) => {
18
+ if (n.type !== 'invocation_expression')
19
+ return;
20
+ const fn = n.childForFieldName ? n.childForFieldName('function') : firstNamedChild(n);
21
+ if (!fn)
22
+ return;
23
+ const name = nameOf(fn);
24
+ if (name)
25
+ seen.add(name);
26
+ });
27
+ return [...seen];
28
+ }
29
+ function nameOf(node) {
30
+ switch (node.type) {
31
+ case 'identifier':
32
+ return node.text;
33
+ case 'member_access_expression':
34
+ case 'conditional_access_expression':
35
+ case 'member_binding_expression': {
36
+ const name = node.childForFieldName ? node.childForFieldName('name') : null;
37
+ if (name)
38
+ return nameOf(name);
39
+ // Fallback: last identifier-bearing child.
40
+ const named = node.namedChildren;
41
+ if (named.length === 0)
42
+ return null;
43
+ return nameOf(named[named.length - 1]);
44
+ }
45
+ case 'generic_name': {
46
+ for (const c of node.namedChildren) {
47
+ if (c.type === 'identifier')
48
+ return c.text;
49
+ }
50
+ return null;
51
+ }
52
+ case 'qualified_name': {
53
+ // Take the last segment.
54
+ let last = null;
55
+ for (const c of node.namedChildren) {
56
+ if (c.type === 'identifier')
57
+ last = c.text;
58
+ }
59
+ return last;
60
+ }
61
+ default:
62
+ return null;
63
+ }
64
+ }
65
+ function firstNamedChild(n) {
66
+ return n.namedChildren[0] ?? null;
67
+ }
68
+ function walk(node, visit) {
69
+ visit(node);
70
+ for (const child of node.namedChildren)
71
+ walk(child, visit);
72
+ }
73
+ //# sourceMappingURL=csharpCallSites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csharpCallSites.js","sourceRoot":"","sources":["../../../src/core/languages/csharpCallSites.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;QACf,IAAI,CAAC,CAAC,IAAI,KAAK,uBAAuB;YAAE,OAAO;QAC/C,MAAM,EAAE,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACtF,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QACxB,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,MAAM,CAAC,IAAY;IAC1B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,YAAY;YACf,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,KAAK,0BAA0B,CAAC;QAChC,KAAK,+BAA+B,CAAC;QACrC,KAAK,2BAA2B,CAAC,CAAC,CAAC;YACjC,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5E,IAAI,IAAI;gBAAE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9B,2CAA2C;YAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC;YACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YACpC,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnC,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY;oBAAE,OAAO,CAAC,CAAC,IAAI,CAAC;YAC7C,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,yBAAyB;YACzB,IAAI,IAAI,GAAkB,IAAI,CAAC;YAC/B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnC,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY;oBAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;YAC7C,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,CAAS;IAChC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACpC,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,23 @@
1
+ interface TsNode {
2
+ type: string;
3
+ text: string;
4
+ namedChildren: TsNode[];
5
+ }
6
+ /**
7
+ * File-level McCabe cyclomatic complexity for tree-sitter-c-sharp.
8
+ *
9
+ * Decision points:
10
+ * if_statement +1
11
+ * for_statement / foreach_statement +1 each
12
+ * while_statement / do_statement +1 each
13
+ * switch_section +1 per non-default arm
14
+ * switch_expression_arm +1 per non-discard arm
15
+ * catch_clause +1 each
16
+ * conditional_expression (ternary `?:`) +1
17
+ * binary_expression with `&&` / `||` / `??` +1 each
18
+ *
19
+ * `else if` is modeled by the grammar as `else_clause > if_statement`, so
20
+ * the inner if_statement counts naturally.
21
+ */
22
+ export declare function extractCsharpCyclomatic(root: TsNode): number;
23
+ export {};
@@ -0,0 +1,61 @@
1
+ /**
2
+ * File-level McCabe cyclomatic complexity for tree-sitter-c-sharp.
3
+ *
4
+ * Decision points:
5
+ * if_statement +1
6
+ * for_statement / foreach_statement +1 each
7
+ * while_statement / do_statement +1 each
8
+ * switch_section +1 per non-default arm
9
+ * switch_expression_arm +1 per non-discard arm
10
+ * catch_clause +1 each
11
+ * conditional_expression (ternary `?:`) +1
12
+ * binary_expression with `&&` / `||` / `??` +1 each
13
+ *
14
+ * `else if` is modeled by the grammar as `else_clause > if_statement`, so
15
+ * the inner if_statement counts naturally.
16
+ */
17
+ export function extractCsharpCyclomatic(root) {
18
+ let decisions = 0;
19
+ walk(root, (n) => {
20
+ if (isDecisionPoint(n))
21
+ decisions++;
22
+ });
23
+ return decisions + 1;
24
+ }
25
+ function isDecisionPoint(n) {
26
+ switch (n.type) {
27
+ case 'if_statement':
28
+ case 'for_statement':
29
+ case 'foreach_statement':
30
+ case 'while_statement':
31
+ case 'do_statement':
32
+ case 'catch_clause':
33
+ case 'conditional_expression':
34
+ return true;
35
+ case 'switch_section': {
36
+ // A switch_section starts with `case X:` or `default:`. The default
37
+ // arm is the fallthrough; everything else is a branch. Note: each
38
+ // case label gets its own switch_section even with `case 1: case 2:`.
39
+ return !/^\s*default\b/.test(n.text);
40
+ }
41
+ case 'switch_expression_arm': {
42
+ // `_ =>` (discard) is the fallthrough; everything else is a branch.
43
+ const t = n.text.trimStart();
44
+ return !/^_\s*=>/.test(t);
45
+ }
46
+ case 'binary_expression': {
47
+ const t = n.text;
48
+ if (/(\s|^)(\|\||&&|\?\?)(\s|$)/.test(t))
49
+ return true;
50
+ return false;
51
+ }
52
+ default:
53
+ return false;
54
+ }
55
+ }
56
+ function walk(node, visit) {
57
+ visit(node);
58
+ for (const child of node.namedChildren)
59
+ walk(child, visit);
60
+ }
61
+ //# sourceMappingURL=csharpCyclomatic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csharpCyclomatic.js","sourceRoot":"","sources":["../../../src/core/languages/csharpCyclomatic.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,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,mBAAmB,CAAC;QACzB,KAAK,iBAAiB,CAAC;QACvB,KAAK,cAAc,CAAC;QACpB,KAAK,cAAc,CAAC;QACpB,KAAK,wBAAwB;YAC3B,OAAO,IAAI,CAAC;QACd,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,oEAAoE;YACpE,kEAAkE;YAClE,sEAAsE;YACtE,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QACD,KAAK,uBAAuB,CAAC,CAAC,CAAC;YAC7B,oEAAoE;YACpE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAC7B,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;QACD,KAAK,mBAAmB,CAAC,CAAC,CAAC;YACzB,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACjB,IAAI,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACtD,OAAO,KAAK,CAAC;QACf,CAAC;QACD;YACE,OAAO,KAAK,CAAC;IACjB,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,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 extractCsharpExports(root: TsNode): AstExport[];
13
+ export {};
@@ -0,0 +1,69 @@
1
+ /**
2
+ * C# top-level type declarations are visible to anything that imports their
3
+ * namespace iff they are `public`. Everything else (`internal`, `private`,
4
+ * `file`, no modifier — defaults to `internal` at namespace scope) stays
5
+ * inside the assembly and is *not* an export from this file.
6
+ *
7
+ * Type kinds we surface:
8
+ * class_declaration / record_declaration / struct_declaration → 'class'
9
+ * interface_declaration → 'interface'
10
+ * enum_declaration → 'enum'
11
+ * delegate_declaration → 'function'
12
+ * method_declaration (top-level statements / static class) → 'function'
13
+ *
14
+ * We descend into namespace_declaration / file_scoped_namespace_declaration
15
+ * so namespace-wrapped types still count as top-level for export purposes.
16
+ */
17
+ const TOP_LEVEL_KINDS = {
18
+ class_declaration: 'class',
19
+ record_declaration: 'class',
20
+ struct_declaration: 'class',
21
+ interface_declaration: 'interface',
22
+ enum_declaration: 'enum',
23
+ delegate_declaration: 'function',
24
+ method_declaration: 'function',
25
+ };
26
+ export function extractCsharpExports(root) {
27
+ const exports = [];
28
+ for (const child of root.namedChildren)
29
+ visit(child, exports);
30
+ return exports;
31
+ }
32
+ function visit(node, out) {
33
+ if (node.type === 'namespace_declaration' || node.type === 'file_scoped_namespace_declaration') {
34
+ const body = node.namedChildren.find((c) => c.type === 'declaration_list');
35
+ const target = body ?? node;
36
+ for (const c of target.namedChildren)
37
+ visit(c, out);
38
+ return;
39
+ }
40
+ const kind = TOP_LEVEL_KINDS[node.type];
41
+ if (!kind)
42
+ return;
43
+ if (!isPublic(node))
44
+ return;
45
+ const name = nameOf(node);
46
+ if (!name)
47
+ return;
48
+ out.push({ name, kind, typeOnly: false, line: node.startPosition.row + 1 });
49
+ }
50
+ function isPublic(node) {
51
+ for (const c of node.namedChildren) {
52
+ if (c.type === 'modifier' && c.text === 'public')
53
+ return true;
54
+ }
55
+ return false;
56
+ }
57
+ function nameOf(node) {
58
+ if (node.childForFieldName) {
59
+ const id = node.childForFieldName('name');
60
+ if (id)
61
+ return id.text;
62
+ }
63
+ for (const c of node.namedChildren) {
64
+ if (c.type === 'identifier')
65
+ return c.text;
66
+ }
67
+ return null;
68
+ }
69
+ //# sourceMappingURL=csharpExports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csharpExports.js","sourceRoot":"","sources":["../../../src/core/languages/csharpExports.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,eAAe,GAA+B;IAClD,iBAAiB,EAAE,OAAO;IAC1B,kBAAkB,EAAE,OAAO;IAC3B,kBAAkB,EAAE,OAAO;IAC3B,qBAAqB,EAAE,WAAW;IAClC,gBAAgB,EAAE,MAAM;IACxB,oBAAoB,EAAE,UAAU;IAChC,kBAAkB,EAAE,UAAU;CAC/B,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;QAAE,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,KAAK,CAAC,IAAY,EAAE,GAAgB;IAC3C,IAAI,IAAI,CAAC,IAAI,KAAK,uBAAuB,IAAI,IAAI,CAAC,IAAI,KAAK,mCAAmC,EAAE,CAAC;QAC/F,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,IAAI,IAAI,IAAI,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,aAAa;YAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO;IAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;IAChE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,MAAM,CAAC,IAAY;IAC1B,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,MAAM,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,EAAE;YAAE,OAAO,EAAE,CAAC,IAAI,CAAC;IACzB,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC;IAC7C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,24 @@
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 `method_declaration`,
18
+ * `constructor_declaration`, `local_function_statement`, and
19
+ * `destructor_declaration` nodes. Methods inside a type are named
20
+ * `Type.method`. Lambdas (parenthesized_lambda_expression / lambda_expression)
21
+ * fold into their enclosing function.
22
+ */
23
+ export declare function extractCsharpFunctions(root: TsNode): FunctionInfo[];
24
+ export {};
@@ -0,0 +1,170 @@
1
+ const CSHARP_DECISION_NODES = new Set([
2
+ 'if_statement',
3
+ 'for_statement',
4
+ 'foreach_statement',
5
+ 'while_statement',
6
+ 'do_statement',
7
+ 'catch_clause',
8
+ 'conditional_expression',
9
+ ]);
10
+ /**
11
+ * Per-function McCabe CC for C#. Walks `method_declaration`,
12
+ * `constructor_declaration`, `local_function_statement`, and
13
+ * `destructor_declaration` nodes. Methods inside a type are named
14
+ * `Type.method`. Lambdas (parenthesized_lambda_expression / lambda_expression)
15
+ * fold into their enclosing function.
16
+ */
17
+ export function extractCsharpFunctions(root) {
18
+ const out = [];
19
+ walk(root, null, out);
20
+ return out;
21
+ }
22
+ function walk(node, ownerName, out) {
23
+ if (node.type === 'class_declaration' ||
24
+ node.type === 'struct_declaration' ||
25
+ node.type === 'interface_declaration' ||
26
+ node.type === 'record_declaration' ||
27
+ node.type === 'enum_declaration') {
28
+ const cls = nameOfType(node) ?? ownerName;
29
+ const body = node.namedChildren.find((c) => c.type === 'declaration_list');
30
+ if (body) {
31
+ for (const child of body.namedChildren)
32
+ walk(child, cls, out);
33
+ }
34
+ return;
35
+ }
36
+ if (node.type === 'namespace_declaration' ||
37
+ node.type === 'file_scoped_namespace_declaration' ||
38
+ node.type === 'compilation_unit' ||
39
+ node.type === 'declaration_list') {
40
+ for (const child of node.namedChildren)
41
+ walk(child, ownerName, out);
42
+ return;
43
+ }
44
+ if (node.type === 'method_declaration' ||
45
+ node.type === 'constructor_declaration' ||
46
+ node.type === 'destructor_declaration' ||
47
+ node.type === 'local_function_statement') {
48
+ const baseName = nameOfFn(node) ?? '<anonymous>';
49
+ const fnName = ownerName ? `${ownerName}.${baseName}` : baseName;
50
+ const line = node.startPosition.row + 1;
51
+ const endLine = node.endPosition.row + 1;
52
+ const { cc, callSites } = analyzeBody(node);
53
+ out.push({ name: fnName, line, endLine, cyclomaticComplexity: cc, callSites });
54
+ return;
55
+ }
56
+ for (const child of node.namedChildren)
57
+ walk(child, ownerName, out);
58
+ }
59
+ function analyzeBody(fnNode) {
60
+ let count = 0;
61
+ const calls = new Set();
62
+ const body = fnNode.namedChildren.find((c) => c.type === 'block') ??
63
+ fnNode.namedChildren.find((c) => c.type === 'arrow_expression_clause');
64
+ if (!body)
65
+ return { cc: 1, callSites: [] };
66
+ walkSkipNested(body, (n) => {
67
+ if (CSHARP_DECISION_NODES.has(n.type)) {
68
+ count++;
69
+ return;
70
+ }
71
+ if (n.type === 'switch_section') {
72
+ if (!/^\s*default\b/.test(n.text))
73
+ count++;
74
+ return;
75
+ }
76
+ if (n.type === 'switch_expression_arm') {
77
+ const t = n.text.trimStart();
78
+ if (!/^_\s*=>/.test(t))
79
+ count++;
80
+ return;
81
+ }
82
+ if (n.type === 'binary_expression') {
83
+ if (/(\s|^)(\|\||&&|\?\?)(\s|$)/.test(n.text))
84
+ count++;
85
+ return;
86
+ }
87
+ if (n.type === 'invocation_expression') {
88
+ const name = csharpCalleeName(n);
89
+ if (name)
90
+ calls.add(name);
91
+ }
92
+ });
93
+ return { cc: count + 1, callSites: [...calls] };
94
+ }
95
+ function csharpCalleeName(call) {
96
+ const fn = call.childForFieldName ? call.childForFieldName('function') : (call.namedChildren[0] ?? null);
97
+ if (!fn)
98
+ return null;
99
+ return calleeBareName(fn);
100
+ }
101
+ function calleeBareName(node) {
102
+ switch (node.type) {
103
+ case 'identifier':
104
+ return node.text;
105
+ case 'member_access_expression':
106
+ case 'conditional_access_expression':
107
+ case 'member_binding_expression': {
108
+ const name = node.childForFieldName ? node.childForFieldName('name') : null;
109
+ if (name)
110
+ return calleeBareName(name);
111
+ const named = node.namedChildren;
112
+ return named.length > 0 ? calleeBareName(named[named.length - 1]) : null;
113
+ }
114
+ case 'generic_name': {
115
+ for (const c of node.namedChildren) {
116
+ if (c.type === 'identifier')
117
+ return c.text;
118
+ }
119
+ return null;
120
+ }
121
+ case 'qualified_name': {
122
+ let last = null;
123
+ for (const c of node.namedChildren) {
124
+ if (c.type === 'identifier')
125
+ last = c.text;
126
+ }
127
+ return last;
128
+ }
129
+ default:
130
+ return null;
131
+ }
132
+ }
133
+ function walkSkipNested(node, visit) {
134
+ visit(node);
135
+ for (const child of node.namedChildren) {
136
+ if (child.type === 'method_declaration' ||
137
+ child.type === 'constructor_declaration' ||
138
+ child.type === 'local_function_statement' ||
139
+ child.type === 'lambda_expression' ||
140
+ child.type === 'parenthesized_lambda_expression' ||
141
+ child.type === 'anonymous_method_expression') {
142
+ // Nested fn / lambda: skip so its decisions don't double-count.
143
+ continue;
144
+ }
145
+ walkSkipNested(child, visit);
146
+ }
147
+ }
148
+ function nameOfType(node) {
149
+ for (const c of node.namedChildren) {
150
+ if (c.type === 'identifier')
151
+ return c.text;
152
+ }
153
+ return null;
154
+ }
155
+ function nameOfFn(node) {
156
+ if (node.childForFieldName) {
157
+ const id = node.childForFieldName('name');
158
+ if (id)
159
+ return id.text;
160
+ }
161
+ // For methods, the name is the identifier that comes AFTER the return type.
162
+ // For constructors / destructors, it's the only identifier child.
163
+ let lastIdentifier = null;
164
+ for (const c of node.namedChildren) {
165
+ if (c.type === 'identifier')
166
+ lastIdentifier = c.text;
167
+ }
168
+ return lastIdentifier;
169
+ }
170
+ //# sourceMappingURL=csharpFunctions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csharpFunctions.js","sourceRoot":"","sources":["../../../src/core/languages/csharpFunctions.ts"],"names":[],"mappings":"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"}