@shapeshift-labs/frontier-lang-compiler 0.2.30 → 0.2.31
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/README.md +10 -2
- package/bench/smoke.mjs +2 -1
- package/dist/index.d.ts +35 -0
- package/dist/index.js +713 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -333,6 +333,7 @@ Use injected parser adapters when a real language parser is available but should
|
|
|
333
333
|
import {
|
|
334
334
|
createBabelNativeImporterAdapter,
|
|
335
335
|
createClangAstNativeImporterAdapter,
|
|
336
|
+
createCSharpRoslynNativeImporterAdapter,
|
|
336
337
|
createGoAstNativeImporterAdapter,
|
|
337
338
|
createJavaAstNativeImporterAdapter,
|
|
338
339
|
createPythonAstNativeImporterAdapter,
|
|
@@ -365,6 +366,11 @@ const javaAstAdapter = createJavaAstNativeImporterAdapter({
|
|
|
365
366
|
javaVersion: '21',
|
|
366
367
|
sourceLevel: '21'
|
|
367
368
|
});
|
|
369
|
+
const csharpRoslynAdapter = createCSharpRoslynNativeImporterAdapter({
|
|
370
|
+
parserModule: hostRoslynParser,
|
|
371
|
+
languageVersion: '12',
|
|
372
|
+
nullableContext: 'enabled'
|
|
373
|
+
});
|
|
368
374
|
|
|
369
375
|
const imported = await runNativeImporterAdapter(babelAdapter, {
|
|
370
376
|
sourcePath: 'src/todo.ts',
|
|
@@ -373,14 +379,15 @@ const imported = await runNativeImporterAdapter(babelAdapter, {
|
|
|
373
379
|
|
|
374
380
|
const project = await importNativeProject({
|
|
375
381
|
projectRoot: 'src',
|
|
376
|
-
adapters: [babelAdapter, pythonAstAdapter, rustSynAdapter, clangAstAdapter, goAstAdapter, javaAstAdapter],
|
|
382
|
+
adapters: [babelAdapter, pythonAstAdapter, rustSynAdapter, clangAstAdapter, goAstAdapter, javaAstAdapter, csharpRoslynAdapter],
|
|
377
383
|
sources: [
|
|
378
384
|
{ language: 'typescript', adapter: babelAdapter.id, sourcePath: 'src/todo.ts', sourceText },
|
|
379
385
|
{ language: 'python', adapter: pythonAstAdapter.id, sourcePath: 'tools/todo.py', sourceText: pythonSource },
|
|
380
386
|
{ language: 'rust', adapter: rustSynAdapter.id, sourcePath: 'src/todo.rs', sourceText: rustSource },
|
|
381
387
|
{ language: 'c', adapter: clangAstAdapter.id, sourcePath: 'native/todo.c', sourceText: cSource },
|
|
382
388
|
{ language: 'go', adapter: goAstAdapter.id, sourcePath: 'cmd/todo/main.go', sourceText: goSource },
|
|
383
|
-
{ language: 'java', adapter: javaAstAdapter.id, sourcePath: 'src/main/java/Todo.java', sourceText: javaSource }
|
|
389
|
+
{ language: 'java', adapter: javaAstAdapter.id, sourcePath: 'src/main/java/Todo.java', sourceText: javaSource },
|
|
390
|
+
{ language: 'csharp', adapter: csharpRoslynAdapter.id, sourcePath: 'src/Todo.cs', sourceText: csharpSource }
|
|
384
391
|
]
|
|
385
392
|
});
|
|
386
393
|
|
|
@@ -404,6 +411,7 @@ The built-in adapter factories are dependency-light wrappers for caller-owned pa
|
|
|
404
411
|
- `createClangAstNativeImporterAdapter`
|
|
405
412
|
- `createGoAstNativeImporterAdapter`
|
|
406
413
|
- `createJavaAstNativeImporterAdapter`
|
|
414
|
+
- `createCSharpRoslynNativeImporterAdapter`
|
|
407
415
|
- `createTreeSitterNativeImporterAdapter`
|
|
408
416
|
|
|
409
417
|
Adapter summaries include a structured `coverage` record so merge queues can distinguish exact parser AST imports from declaration scans. The record declares exactness, parser token/trivia support, diagnostics support, source-range and generated-range support, and semantic coverage. Built-in wrappers normalize native AST/CST nodes and declaration-level semantic indexes; they do not claim resolved references, types, control flow, generated ranges, or token/trivia fidelity unless the host adapter supplies that evidence.
|
package/bench/smoke.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
compileNativeSource,
|
|
4
4
|
compileFrontierSource,
|
|
5
5
|
createClangAstNativeImporterAdapter,
|
|
6
|
+
createCSharpRoslynNativeImporterAdapter,
|
|
6
7
|
createEstreeNativeImporterAdapter,
|
|
7
8
|
createGoAstNativeImporterAdapter,
|
|
8
9
|
createJavaAstNativeImporterAdapter,
|
|
@@ -82,7 +83,7 @@ const matrixDurationMs = performance.now() - matrixStart;
|
|
|
82
83
|
const parserFormatMatrixStart = performance.now();
|
|
83
84
|
const parserFormatMatrix = createNativeParserAstFormatMatrix({
|
|
84
85
|
imports: nativeImportResults,
|
|
85
|
-
adapters: [estreeAdapter, createPythonAstNativeImporterAdapter(), createRustSynNativeImporterAdapter(), createClangAstNativeImporterAdapter(), createGoAstNativeImporterAdapter(), createJavaAstNativeImporterAdapter()]
|
|
86
|
+
adapters: [estreeAdapter, createPythonAstNativeImporterAdapter(), createRustSynNativeImporterAdapter(), createClangAstNativeImporterAdapter(), createGoAstNativeImporterAdapter(), createJavaAstNativeImporterAdapter(), createCSharpRoslynNativeImporterAdapter()]
|
|
86
87
|
});
|
|
87
88
|
const parserFormatMatrixDurationMs = performance.now() - parserFormatMatrixStart;
|
|
88
89
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1497,6 +1497,40 @@ export interface JavaAstNativeImporterAdapterOptions {
|
|
|
1497
1497
|
readonly maxNodes?: number;
|
|
1498
1498
|
}
|
|
1499
1499
|
|
|
1500
|
+
export interface CSharpRoslynNativeImporterAdapterOptions {
|
|
1501
|
+
readonly id?: string;
|
|
1502
|
+
readonly language?: FrontierSourceLanguage;
|
|
1503
|
+
readonly parser?: string;
|
|
1504
|
+
readonly version?: string;
|
|
1505
|
+
readonly capabilities?: readonly string[];
|
|
1506
|
+
readonly coverage?: NativeImporterAdapterCoverageInput;
|
|
1507
|
+
readonly supportedExtensions?: readonly string[];
|
|
1508
|
+
readonly diagnostics?: readonly NativeImporterAdapterDiagnostic[];
|
|
1509
|
+
readonly ast?: unknown;
|
|
1510
|
+
readonly nativeAst?: unknown;
|
|
1511
|
+
readonly syntaxTree?: unknown;
|
|
1512
|
+
readonly tree?: unknown;
|
|
1513
|
+
readonly root?: unknown;
|
|
1514
|
+
readonly compilationUnit?: unknown;
|
|
1515
|
+
readonly parse?: (sourceText: string, options: Record<string, unknown>) => unknown;
|
|
1516
|
+
readonly parserModule?: { readonly parse: (sourceText: string, options: Record<string, unknown>) => unknown };
|
|
1517
|
+
readonly roslyn?: { readonly parse: (sourceText: string, options: Record<string, unknown>) => unknown };
|
|
1518
|
+
readonly csharpRoslyn?: { readonly parse: (sourceText: string, options: Record<string, unknown>) => unknown };
|
|
1519
|
+
readonly parserOptions?: Record<string, unknown>;
|
|
1520
|
+
readonly csharpVersion?: string;
|
|
1521
|
+
readonly languageVersion?: string;
|
|
1522
|
+
readonly nullableContext?: string | boolean;
|
|
1523
|
+
readonly sourceCodeKind?: string;
|
|
1524
|
+
readonly generated?: boolean;
|
|
1525
|
+
readonly projectReferences?: unknown;
|
|
1526
|
+
readonly analyzerDiagnostics?: unknown;
|
|
1527
|
+
readonly semanticModelEvidence?: unknown;
|
|
1528
|
+
readonly sourceGeneratorEvidence?: unknown;
|
|
1529
|
+
readonly positionResolver?: (position: unknown) => unknown;
|
|
1530
|
+
readonly lineMap?: unknown;
|
|
1531
|
+
readonly maxNodes?: number;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1500
1534
|
export interface TreeSitterNativeImporterAdapterOptions {
|
|
1501
1535
|
readonly id?: string;
|
|
1502
1536
|
readonly language?: FrontierSourceLanguage;
|
|
@@ -1871,6 +1905,7 @@ export declare function createRustSynNativeImporterAdapter(options?: RustSynNati
|
|
|
1871
1905
|
export declare function createClangAstNativeImporterAdapter(options?: ClangAstNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1872
1906
|
export declare function createGoAstNativeImporterAdapter(options?: GoAstNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1873
1907
|
export declare function createJavaAstNativeImporterAdapter(options?: JavaAstNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1908
|
+
export declare function createCSharpRoslynNativeImporterAdapter(options?: CSharpRoslynNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1874
1909
|
export declare function createTreeSitterNativeImporterAdapter(options?: TreeSitterNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1875
1910
|
export declare function runNativeImporterAdapter(adapter: NativeImporterAdapter, input: RunNativeImporterAdapterOptions): Promise<NativeImporterAdapterImportResult>;
|
|
1876
1911
|
export declare function runNativeTargetProjectionAdapter(adapter: NativeTargetProjectionAdapter, input: NativeTargetProjectionAdapterInput): NativeTargetProjectionResult;
|
package/dist/index.js
CHANGED
|
@@ -439,6 +439,19 @@ export const NativeParserAstFormatProfiles = Object.freeze([
|
|
|
439
439
|
supportsErrorRecovery: true,
|
|
440
440
|
notes: ['Java compiler/parser ASTs expose package/import/type/member declarations and source ranges; classpath/module-path, bindings, annotation processors, generated sources, Lombok expansion, comments/trivia, and control-flow evidence remain host-owned.']
|
|
441
441
|
}),
|
|
442
|
+
nativeParserAstFormatProfile('roslyn-csharp', {
|
|
443
|
+
aliases: ['roslyn', 'csharp-roslyn', 'c#-roslyn', 'microsoft-codeanalysis-csharp', 'csharp-syntax'],
|
|
444
|
+
kind: 'compiler-ast',
|
|
445
|
+
languages: ['csharp'],
|
|
446
|
+
parserAdapters: ['roslyn', 'microsoft.codeanalysis.csharp', 'csharp-roslyn'],
|
|
447
|
+
exactness: 'exact-parser-ast',
|
|
448
|
+
sourceRangeModel: 'text-span-line-position-span',
|
|
449
|
+
preservesTokens: true,
|
|
450
|
+
preservesTrivia: true,
|
|
451
|
+
supportsIncremental: true,
|
|
452
|
+
supportsErrorRecovery: true,
|
|
453
|
+
notes: ['Roslyn C# syntax trees expose immutable nodes, tokens, trivia, spans, diagnostics, directives, and skipped text; SemanticModel symbols, nullable analysis, generated sources, partial type stitching, analyzer results, and project references remain host-owned evidence.']
|
|
454
|
+
}),
|
|
442
455
|
nativeParserAstFormatProfile('tree-sitter', {
|
|
443
456
|
kind: 'concrete-syntax-tree',
|
|
444
457
|
languages: ['mixed'],
|
|
@@ -2932,6 +2945,73 @@ export function createJavaAstNativeImporterAdapter(options = {}) {
|
|
|
2932
2945
|
};
|
|
2933
2946
|
}
|
|
2934
2947
|
|
|
2948
|
+
export function createCSharpRoslynNativeImporterAdapter(options = {}) {
|
|
2949
|
+
return {
|
|
2950
|
+
id: options.id ?? 'frontier.csharp-roslyn-native-importer',
|
|
2951
|
+
language: options.language ?? 'csharp',
|
|
2952
|
+
parser: options.parser ?? 'roslyn',
|
|
2953
|
+
version: options.version,
|
|
2954
|
+
capabilities: uniqueStrings(['nativeAst', 'semanticIndex', 'sourceMaps', 'diagnostics', ...(options.capabilities ?? [])]),
|
|
2955
|
+
coverage: nativeImporterAdapterCoverage({
|
|
2956
|
+
exactness: 'exact-parser-ast',
|
|
2957
|
+
exactAst: true,
|
|
2958
|
+
tokens: true,
|
|
2959
|
+
trivia: true,
|
|
2960
|
+
diagnostics: true,
|
|
2961
|
+
sourceRanges: true,
|
|
2962
|
+
generatedRanges: false,
|
|
2963
|
+
semanticCoverage: declarationSemanticCoverage(),
|
|
2964
|
+
notes: [
|
|
2965
|
+
'Normalizes caller-owned Roslyn C# SyntaxTree/SyntaxNode-shaped objects into native AST nodes and declaration-level semantic index records.',
|
|
2966
|
+
'Roslyn syntax imports do not resolve SemanticModel symbols, overloads, nullable flow, source generators, partial types, project references, or analyzer results by themselves; attach host evidence for those claims.'
|
|
2967
|
+
]
|
|
2968
|
+
}, options.coverage),
|
|
2969
|
+
supportedExtensions: options.supportedExtensions ?? ['.cs'],
|
|
2970
|
+
diagnostics: options.diagnostics,
|
|
2971
|
+
parse(input) {
|
|
2972
|
+
const parsed = input.options?.ast
|
|
2973
|
+
?? input.options?.nativeAst
|
|
2974
|
+
?? input.options?.syntaxTree
|
|
2975
|
+
?? input.options?.tree
|
|
2976
|
+
?? input.options?.root
|
|
2977
|
+
?? input.options?.compilationUnit
|
|
2978
|
+
?? options.ast
|
|
2979
|
+
?? options.syntaxTree
|
|
2980
|
+
?? options.tree
|
|
2981
|
+
?? options.root
|
|
2982
|
+
?? options.compilationUnit
|
|
2983
|
+
?? parseCSharpRoslynSource(input, options);
|
|
2984
|
+
const root = csharpRoslynRoot(parsed);
|
|
2985
|
+
if (!root) {
|
|
2986
|
+
return missingInjectedParserResult(input, {
|
|
2987
|
+
parser: options.parser ?? 'roslyn',
|
|
2988
|
+
adapterId: options.id ?? 'frontier.csharp-roslyn-native-importer',
|
|
2989
|
+
message: 'createCSharpRoslynNativeImporterAdapter requires an injected Roslyn SyntaxTree/SyntaxNode object, parserModule.parse function, parse function, or adapterOptions.ast.'
|
|
2990
|
+
});
|
|
2991
|
+
}
|
|
2992
|
+
const parseDiagnostics = normalizeParserErrors(parsed?.errors ?? parsed?.diagnostics ?? parsed?.parseDiagnostics, input, {
|
|
2993
|
+
parser: options.parser ?? 'roslyn'
|
|
2994
|
+
});
|
|
2995
|
+
return createNativeImportFromCSharpRoslyn(root, input, {
|
|
2996
|
+
parser: options.parser ?? 'roslyn',
|
|
2997
|
+
astFormat: 'roslyn-csharp',
|
|
2998
|
+
maxNodes: options.maxNodes,
|
|
2999
|
+
diagnostics: parseDiagnostics,
|
|
3000
|
+
csharpVersion: options.csharpVersion ?? input.options?.csharpVersion ?? parsed?.csharpVersion,
|
|
3001
|
+
languageVersion: options.languageVersion ?? input.options?.languageVersion ?? parsed?.languageVersion,
|
|
3002
|
+
nullableContext: input.options?.nullableContext ?? options.nullableContext ?? parsed?.nullableContext,
|
|
3003
|
+
generated: input.options?.generated ?? options.generated ?? parsed?.generated ?? csharpGeneratedSourcePath(input.sourcePath),
|
|
3004
|
+
projectReferences: input.options?.projectReferences ?? options.projectReferences ?? parsed?.projectReferences,
|
|
3005
|
+
analyzerDiagnostics: input.options?.analyzerDiagnostics ?? options.analyzerDiagnostics ?? parsed?.analyzerDiagnostics,
|
|
3006
|
+
semanticModelEvidence: input.options?.semanticModelEvidence ?? options.semanticModelEvidence ?? parsed?.semanticModelEvidence,
|
|
3007
|
+
sourceGeneratorEvidence: input.options?.sourceGeneratorEvidence ?? options.sourceGeneratorEvidence ?? parsed?.sourceGeneratorEvidence,
|
|
3008
|
+
positionResolver: input.options?.positionResolver ?? options.positionResolver,
|
|
3009
|
+
lineMap: input.options?.lineMap ?? options.lineMap ?? parsed?.lineMap
|
|
3010
|
+
});
|
|
3011
|
+
}
|
|
3012
|
+
};
|
|
3013
|
+
}
|
|
3014
|
+
|
|
2935
3015
|
export function createTreeSitterNativeImporterAdapter(options = {}) {
|
|
2936
3016
|
return {
|
|
2937
3017
|
id: options.id ?? `frontier.tree-sitter-${idFragment(options.language ?? 'source')}-native-importer`,
|
|
@@ -7375,6 +7455,7 @@ function parserAstFormatIdForParser(parser) {
|
|
|
7375
7455
|
if (text.includes('clang') || text.includes('libclang')) return 'clang-ast-json';
|
|
7376
7456
|
if (text === 'go' || text.includes('go-parser') || text.includes('go-ast') || text.includes('go/parser') || text.includes('go/ast')) return 'go-ast';
|
|
7377
7457
|
if (text === 'java' || text.includes('javac') || text.includes('jdt') || text.includes('javaparser') || text.includes('java-parser') || text.includes('java-ast')) return 'java-ast';
|
|
7458
|
+
if (text === 'csharp' || text === 'c#' || text === 'cs' || text.includes('roslyn') || text.includes('microsoft-codeanalysis-csharp') || text.includes('csharp-syntax')) return 'roslyn-csharp';
|
|
7378
7459
|
if (text.includes('tree-sitter') || text.includes('treesitter')) return 'tree-sitter';
|
|
7379
7460
|
if (text.includes('babel')) return 'babel';
|
|
7380
7461
|
if (text.includes('estree')) return 'estree';
|
|
@@ -8473,6 +8554,22 @@ function parseJavaAstSource(input, options) {
|
|
|
8473
8554
|
return parse(input.sourceText, parserOptions);
|
|
8474
8555
|
}
|
|
8475
8556
|
|
|
8557
|
+
function parseCSharpRoslynSource(input, options) {
|
|
8558
|
+
const parse = options.parse ?? options.parserModule?.parse ?? options.roslyn?.parse ?? options.csharpRoslyn?.parse;
|
|
8559
|
+
if (typeof parse !== 'function') return undefined;
|
|
8560
|
+
const parserOptions = {
|
|
8561
|
+
sourcePath: input.sourcePath,
|
|
8562
|
+
filename: input.sourcePath,
|
|
8563
|
+
languageVersion: options.languageVersion ?? input.options?.languageVersion,
|
|
8564
|
+
csharpVersion: options.csharpVersion ?? input.options?.csharpVersion,
|
|
8565
|
+
nullableContext: options.nullableContext ?? input.options?.nullableContext,
|
|
8566
|
+
kind: options.sourceCodeKind ?? input.options?.sourceCodeKind,
|
|
8567
|
+
...(options.parserOptions ?? {}),
|
|
8568
|
+
...(input.options?.parserOptions ?? {})
|
|
8569
|
+
};
|
|
8570
|
+
return parse(input.sourceText, parserOptions);
|
|
8571
|
+
}
|
|
8572
|
+
|
|
8476
8573
|
function createNativeImportFromSyntaxAst(ast, input, options) {
|
|
8477
8574
|
const root = normalizeSyntaxAstRoot(ast, options.astFormat);
|
|
8478
8575
|
if (!root) {
|
|
@@ -8703,6 +8800,45 @@ function createNativeImportFromJavaAst(root, input, options) {
|
|
|
8703
8800
|
};
|
|
8704
8801
|
}
|
|
8705
8802
|
|
|
8803
|
+
function createNativeImportFromCSharpRoslyn(root, input, options) {
|
|
8804
|
+
const context = createAstNormalizationContext(input, options);
|
|
8805
|
+
visitCSharpRoslynNode(root, context, 'root');
|
|
8806
|
+
if (context.truncated) {
|
|
8807
|
+
context.losses.push(truncatedAstLoss(input, context, options));
|
|
8808
|
+
}
|
|
8809
|
+
if (options.generated && !context.losses.some((loss) => loss.kind === 'generatedCode')) {
|
|
8810
|
+
context.losses.push(csharpGeneratedCodeLoss(input, context.rootId, undefined, options));
|
|
8811
|
+
}
|
|
8812
|
+
const semantic = semanticIndexFromNativeDeclarations(context.declarations, input, options);
|
|
8813
|
+
return {
|
|
8814
|
+
rootId: context.rootId,
|
|
8815
|
+
nodes: context.nodes,
|
|
8816
|
+
semanticIndex: semantic.semanticIndex,
|
|
8817
|
+
mappings: semantic.mappings,
|
|
8818
|
+
losses: mergeNativeLosses(context.losses, options.diagnostics?.map((diagnostic, index) => adapterDiagnosticToLoss(diagnostic, index, {
|
|
8819
|
+
id: input.adapterId,
|
|
8820
|
+
version: input.adapterVersion
|
|
8821
|
+
}, input)) ?? []),
|
|
8822
|
+
evidence: semantic.evidence,
|
|
8823
|
+
diagnostics: options.diagnostics,
|
|
8824
|
+
metadata: {
|
|
8825
|
+
astFormat: options.astFormat,
|
|
8826
|
+
parser: options.parser,
|
|
8827
|
+
csharpVersion: options.csharpVersion,
|
|
8828
|
+
languageVersion: options.languageVersion,
|
|
8829
|
+
nullableContext: options.nullableContext,
|
|
8830
|
+
generated: options.generated,
|
|
8831
|
+
projectReferences: csharpEvidenceSummary(options.projectReferences),
|
|
8832
|
+
analyzerDiagnostics: csharpEvidenceSummary(options.analyzerDiagnostics),
|
|
8833
|
+
semanticModelEvidence: csharpEvidenceSummary(options.semanticModelEvidence),
|
|
8834
|
+
sourceGeneratorEvidence: csharpEvidenceSummary(options.sourceGeneratorEvidence),
|
|
8835
|
+
normalizedNodeCount: Object.keys(context.nodes).length,
|
|
8836
|
+
declarationCount: context.declarations.length,
|
|
8837
|
+
truncated: context.truncated
|
|
8838
|
+
}
|
|
8839
|
+
};
|
|
8840
|
+
}
|
|
8841
|
+
|
|
8706
8842
|
function createNativeImportFromTreeSitter(root, input, options) {
|
|
8707
8843
|
const context = createAstNormalizationContext(input, options);
|
|
8708
8844
|
visitTreeSitterNode(root, context, 'root');
|
|
@@ -9178,6 +9314,92 @@ function visitJavaAstNode(node, context, propertyPath) {
|
|
|
9178
9314
|
return id;
|
|
9179
9315
|
}
|
|
9180
9316
|
|
|
9317
|
+
function visitCSharpRoslynNode(node, context, propertyPath) {
|
|
9318
|
+
if (!isCSharpRoslynNode(node) || context.truncated) return undefined;
|
|
9319
|
+
if (context.objectIds.has(node)) return context.objectIds.get(node);
|
|
9320
|
+
if (context.counter >= context.maxNodes) {
|
|
9321
|
+
context.truncated = true;
|
|
9322
|
+
return undefined;
|
|
9323
|
+
}
|
|
9324
|
+
const kind = csharpRoslynKind(node);
|
|
9325
|
+
const span = spanFromCSharpRoslynNode(node, context.input, context.options);
|
|
9326
|
+
const id = nativeNodeId(context, kind, { start: { line: span?.startLine, column: span?.startColumn } }, propertyPath);
|
|
9327
|
+
context.objectIds.set(node, id);
|
|
9328
|
+
if (!context.rootId) context.rootId = id;
|
|
9329
|
+
const children = [];
|
|
9330
|
+
for (const [field, value] of csharpRoslynChildEntries(node, kind)) {
|
|
9331
|
+
if (Array.isArray(value)) {
|
|
9332
|
+
value.forEach((entry, index) => {
|
|
9333
|
+
const childId = visitCSharpRoslynNode(entry, context, `${propertyPath}.${field}[${index}]`);
|
|
9334
|
+
if (childId) children.push(childId);
|
|
9335
|
+
});
|
|
9336
|
+
} else {
|
|
9337
|
+
const childId = visitCSharpRoslynNode(value, context, `${propertyPath}.${field}`);
|
|
9338
|
+
if (childId) children.push(childId);
|
|
9339
|
+
}
|
|
9340
|
+
}
|
|
9341
|
+
const declarations = csharpRoslynDeclarations(node, kind, id, context.input);
|
|
9342
|
+
const declaration = declarations[0];
|
|
9343
|
+
const nativeNode = {
|
|
9344
|
+
id,
|
|
9345
|
+
kind,
|
|
9346
|
+
languageKind: `${context.input.language}.${kind}`,
|
|
9347
|
+
span,
|
|
9348
|
+
value: declaration?.name ?? csharpRoslynNodeValue(node),
|
|
9349
|
+
fields: primitiveCSharpRoslynFields(node, kind),
|
|
9350
|
+
children,
|
|
9351
|
+
metadata: {
|
|
9352
|
+
astFormat: context.options.astFormat,
|
|
9353
|
+
propertyPath,
|
|
9354
|
+
rawKind: numberOrUndefined(node.rawKind ?? node.RawKind),
|
|
9355
|
+
positionKind: csharpRoslynPositionKind(node),
|
|
9356
|
+
parser: context.options.parser
|
|
9357
|
+
}
|
|
9358
|
+
};
|
|
9359
|
+
context.nodes[id] = nativeNode;
|
|
9360
|
+
for (const entry of declarations) {
|
|
9361
|
+
context.declarations.push({ ...entry, nativeNode });
|
|
9362
|
+
}
|
|
9363
|
+
if (csharpRoslynRecoveredKind(kind) || csharpRoslynProblemNode(node, kind)) {
|
|
9364
|
+
context.losses.push({
|
|
9365
|
+
id: `loss_${idFragment(id)}_csharp_roslyn_recovered_node`,
|
|
9366
|
+
severity: 'error',
|
|
9367
|
+
phase: 'parse',
|
|
9368
|
+
sourceFormat: context.input.language,
|
|
9369
|
+
kind: 'unsupportedSyntax',
|
|
9370
|
+
message: 'Roslyn reported skipped text, missing syntax, or syntax diagnostics; semantic import is partial until syntax errors are resolved.',
|
|
9371
|
+
span,
|
|
9372
|
+
nodeId: id,
|
|
9373
|
+
metadata: {
|
|
9374
|
+
parser: context.options.parser,
|
|
9375
|
+
astFormat: context.options.astFormat,
|
|
9376
|
+
nodeKind: kind
|
|
9377
|
+
}
|
|
9378
|
+
});
|
|
9379
|
+
}
|
|
9380
|
+
if (csharpRoslynDirectiveKind(kind)) {
|
|
9381
|
+
context.losses.push({
|
|
9382
|
+
id: `loss_${idFragment(id)}_csharp_preprocessor`,
|
|
9383
|
+
severity: 'warning',
|
|
9384
|
+
phase: 'parse',
|
|
9385
|
+
sourceFormat: context.input.language,
|
|
9386
|
+
kind: 'preprocessor',
|
|
9387
|
+
message: 'C# preprocessor directive was imported as syntax; conditional compilation state and inactive branches require host evidence.',
|
|
9388
|
+
span,
|
|
9389
|
+
nodeId: id,
|
|
9390
|
+
metadata: {
|
|
9391
|
+
parser: context.options.parser,
|
|
9392
|
+
astFormat: context.options.astFormat,
|
|
9393
|
+
nodeKind: kind
|
|
9394
|
+
}
|
|
9395
|
+
});
|
|
9396
|
+
}
|
|
9397
|
+
if (csharpGeneratedCodeMarker(node, kind)) {
|
|
9398
|
+
context.losses.push(csharpGeneratedCodeLoss(context.input, id, span, context.options, { nodeKind: kind }));
|
|
9399
|
+
}
|
|
9400
|
+
return id;
|
|
9401
|
+
}
|
|
9402
|
+
|
|
9181
9403
|
function visitTreeSitterNode(node, context, propertyPath) {
|
|
9182
9404
|
if (!node || typeof node !== 'object' || context.truncated) return undefined;
|
|
9183
9405
|
if (context.objectIds.has(node)) return context.objectIds.get(node);
|
|
@@ -11896,6 +12118,497 @@ function javaBindingEvidenceSummary(value) {
|
|
|
11896
12118
|
return Object.keys(summary).length ? summary : { present: true };
|
|
11897
12119
|
}
|
|
11898
12120
|
|
|
12121
|
+
function csharpRoslynRoot(value) {
|
|
12122
|
+
if (!value || typeof value !== 'object') return undefined;
|
|
12123
|
+
if (isCSharpRoslynNode(value)) return value;
|
|
12124
|
+
if (isCSharpRoslynNode(value.ast)) return value.ast;
|
|
12125
|
+
if (isCSharpRoslynNode(value.root)) return value.root;
|
|
12126
|
+
if (isCSharpRoslynNode(value.rootNode)) return value.rootNode;
|
|
12127
|
+
if (isCSharpRoslynNode(value.compilationUnit)) return value.compilationUnit;
|
|
12128
|
+
if (isCSharpRoslynNode(value.syntaxTree)) return csharpRoslynRoot(value.syntaxTree);
|
|
12129
|
+
if (isCSharpRoslynNode(value.tree)) return csharpRoslynRoot(value.tree);
|
|
12130
|
+
if (Array.isArray(value.members) || Array.isArray(value.usings) || Array.isArray(value.externs)) {
|
|
12131
|
+
return { kind: 'CompilationUnit', ...value };
|
|
12132
|
+
}
|
|
12133
|
+
return undefined;
|
|
12134
|
+
}
|
|
12135
|
+
|
|
12136
|
+
function isCSharpRoslynNode(value) {
|
|
12137
|
+
return Boolean(value && typeof value === 'object' && typeof csharpRoslynKind(value) === 'string');
|
|
12138
|
+
}
|
|
12139
|
+
|
|
12140
|
+
function csharpRoslynKind(node) {
|
|
12141
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
12142
|
+
const declared = node.kind ?? node.Kind ?? node._type ?? node.type ?? node.nodeType ?? node.syntaxKind ?? node.SyntaxKind;
|
|
12143
|
+
if (typeof declared === 'string') return normalizeCSharpRoslynKind(declared);
|
|
12144
|
+
if (Array.isArray(node.members) || Array.isArray(node.usings) || Array.isArray(node.externs)) return 'CompilationUnit';
|
|
12145
|
+
if (node.identifier && (node.members || node.baseList || node.parameterList || node.modifiers)) return 'ClassDeclaration';
|
|
12146
|
+
if (node.declaration && (node.eventKeyword || node.eventField)) return 'EventFieldDeclaration';
|
|
12147
|
+
if (node.declaration && Array.isArray(node.declaration.variables)) return 'FieldDeclaration';
|
|
12148
|
+
return undefined;
|
|
12149
|
+
}
|
|
12150
|
+
|
|
12151
|
+
function normalizeCSharpRoslynKind(kind) {
|
|
12152
|
+
const text = String(kind)
|
|
12153
|
+
.replace(/^(?:Microsoft\.CodeAnalysis\.CSharp\.Syntax\.|Microsoft\.CodeAnalysis\.CSharp\.)/, '')
|
|
12154
|
+
.replace(/Syntax$/, '');
|
|
12155
|
+
const compact = text.replace(/[_\s.-]+/g, '').toLowerCase();
|
|
12156
|
+
if (compact === 'compilationunit') return 'CompilationUnit';
|
|
12157
|
+
if (compact === 'usingdirective') return 'UsingDirective';
|
|
12158
|
+
if (compact === 'namespacedeclaration') return 'NamespaceDeclaration';
|
|
12159
|
+
if (compact === 'filescopednamespacedeclaration') return 'FileScopedNamespaceDeclaration';
|
|
12160
|
+
if (compact === 'classdeclaration') return 'ClassDeclaration';
|
|
12161
|
+
if (compact === 'interfacedeclaration') return 'InterfaceDeclaration';
|
|
12162
|
+
if (compact === 'structdeclaration') return 'StructDeclaration';
|
|
12163
|
+
if (compact === 'recorddeclaration') return 'RecordDeclaration';
|
|
12164
|
+
if (compact === 'recordstructdeclaration') return 'RecordStructDeclaration';
|
|
12165
|
+
if (compact === 'enumdeclaration') return 'EnumDeclaration';
|
|
12166
|
+
if (compact === 'methoddeclaration') return 'MethodDeclaration';
|
|
12167
|
+
if (compact === 'constructordeclaration') return 'ConstructorDeclaration';
|
|
12168
|
+
if (compact === 'destructordeclaration') return 'DestructorDeclaration';
|
|
12169
|
+
if (compact === 'operatordeclaration') return 'OperatorDeclaration';
|
|
12170
|
+
if (compact === 'conversionoperatordeclaration') return 'ConversionOperatorDeclaration';
|
|
12171
|
+
if (compact === 'propertydeclaration') return 'PropertyDeclaration';
|
|
12172
|
+
if (compact === 'indexerdeclaration') return 'IndexerDeclaration';
|
|
12173
|
+
if (compact === 'fielddeclaration') return 'FieldDeclaration';
|
|
12174
|
+
if (compact === 'variabledeclarator') return 'VariableDeclarator';
|
|
12175
|
+
if (compact === 'eventdeclaration') return 'EventDeclaration';
|
|
12176
|
+
if (compact === 'eventfielddeclaration') return 'EventFieldDeclaration';
|
|
12177
|
+
if (compact === 'delegatedeclaration') return 'DelegateDeclaration';
|
|
12178
|
+
if (compact === 'enummemberdeclaration') return 'EnumMemberDeclaration';
|
|
12179
|
+
if (compact === 'attributelist') return 'AttributeList';
|
|
12180
|
+
if (compact === 'attribute') return 'Attribute';
|
|
12181
|
+
if (compact === 'parameter') return 'Parameter';
|
|
12182
|
+
if (compact === 'incompletemember') return 'IncompleteMember';
|
|
12183
|
+
if (compact === 'skippedtokenstrivia' || compact === 'skippedtokens') return 'SkippedTokensTrivia';
|
|
12184
|
+
if (compact.endsWith('directivetrivia')) return `${upperFirst(compact.slice(0, -'directivetrivia'.length))}DirectiveTrivia`;
|
|
12185
|
+
if (/^[A-Z0-9_]+$/.test(text)) return text.toLowerCase().split('_').map(upperFirst).join('');
|
|
12186
|
+
return text;
|
|
12187
|
+
}
|
|
12188
|
+
|
|
12189
|
+
function ignoredCSharpRoslynField(key) {
|
|
12190
|
+
return key === '_type'
|
|
12191
|
+
|| key === 'type'
|
|
12192
|
+
|| key === 'kind'
|
|
12193
|
+
|| key === 'Kind'
|
|
12194
|
+
|| key === 'nodeType'
|
|
12195
|
+
|| key === 'syntaxKind'
|
|
12196
|
+
|| key === 'SyntaxKind'
|
|
12197
|
+
|| key === 'rawKind'
|
|
12198
|
+
|| key === 'RawKind'
|
|
12199
|
+
|| key === 'parent'
|
|
12200
|
+
|| key === 'parentKind'
|
|
12201
|
+
|| key === 'parentField'
|
|
12202
|
+
|| key === 'span'
|
|
12203
|
+
|| key === 'Span'
|
|
12204
|
+
|| key === 'fullSpan'
|
|
12205
|
+
|| key === 'FullSpan'
|
|
12206
|
+
|| key === 'lineSpan'
|
|
12207
|
+
|| key === 'location'
|
|
12208
|
+
|| key === 'locations'
|
|
12209
|
+
|| key === 'identifier'
|
|
12210
|
+
|| key === 'name'
|
|
12211
|
+
|| key === 'simpleName'
|
|
12212
|
+
|| key === 'qualifiedName'
|
|
12213
|
+
|| key === 'semanticModel'
|
|
12214
|
+
|| key === 'symbol'
|
|
12215
|
+
|| key === 'declaredSymbol'
|
|
12216
|
+
|| key === 'typeInfo'
|
|
12217
|
+
|| key === 'conversion'
|
|
12218
|
+
|| key === 'constantValue';
|
|
12219
|
+
}
|
|
12220
|
+
|
|
12221
|
+
function primitiveCSharpRoslynFields(node, kind) {
|
|
12222
|
+
const fields = { kind };
|
|
12223
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12224
|
+
if (name) fields.name = name;
|
|
12225
|
+
const importPath = csharpRoslynUsingPath(node);
|
|
12226
|
+
if (importPath) fields.importPath = importPath;
|
|
12227
|
+
const type = csharpRoslynTypeName(node.type ?? node.Type ?? node.returnType ?? node.ReturnType);
|
|
12228
|
+
if (type) fields.type = type;
|
|
12229
|
+
const modifiers = csharpRoslynModifierNames(node);
|
|
12230
|
+
if (modifiers.length) fields.modifiers = modifiers.join(',');
|
|
12231
|
+
const alias = csharpRoslynName(node.alias ?? node.Alias);
|
|
12232
|
+
if (alias) fields.alias = alias;
|
|
12233
|
+
if (node.static === true || node.isStatic === true) fields.static = true;
|
|
12234
|
+
if (node.global === true || node.isGlobal === true) fields.global = true;
|
|
12235
|
+
if (node.generated === true || node.Generated === true) fields.generated = true;
|
|
12236
|
+
if (node.containsDiagnostics === true || node.ContainsDiagnostics === true) fields.containsDiagnostics = true;
|
|
12237
|
+
if (node.containsSkippedText === true || node.ContainsSkippedText === true) fields.containsSkippedText = true;
|
|
12238
|
+
if (node.isMissing === true || node.IsMissing === true) fields.isMissing = true;
|
|
12239
|
+
if (Array.isArray(node.parameterList?.parameters ?? node.parameters)) fields.parameterCount = (node.parameterList?.parameters ?? node.parameters).length;
|
|
12240
|
+
if (Array.isArray(node.attributeLists)) fields.attributeListCount = node.attributeLists.length;
|
|
12241
|
+
return fields;
|
|
12242
|
+
}
|
|
12243
|
+
|
|
12244
|
+
function spanFromCSharpRoslynNode(node, input, options = {}) {
|
|
12245
|
+
const lineSpan = node.lineSpan ?? node.location?.lineSpan ?? node.location?.LineSpan ?? node.FileLinePositionSpan;
|
|
12246
|
+
const fromLineSpan = spanFromCSharpLineSpan(lineSpan, input);
|
|
12247
|
+
if (fromLineSpan) return fromLineSpan;
|
|
12248
|
+
const direct = spanFromCSharpLineFields(node, input);
|
|
12249
|
+
if (direct) return direct;
|
|
12250
|
+
const start = csharpRoslynPosition(node.start ?? node.Start ?? node.span?.start ?? node.Span?.Start ?? node.position, options);
|
|
12251
|
+
const end = csharpRoslynPosition(node.end ?? node.End ?? node.span?.end ?? node.Span?.End, options);
|
|
12252
|
+
if (!start) return undefined;
|
|
12253
|
+
return {
|
|
12254
|
+
sourceId: input.sourceHash,
|
|
12255
|
+
path: start.path ?? end?.path ?? input.sourcePath,
|
|
12256
|
+
startLine: start.line,
|
|
12257
|
+
startColumn: start.column,
|
|
12258
|
+
endLine: end?.line,
|
|
12259
|
+
endColumn: end?.column
|
|
12260
|
+
};
|
|
12261
|
+
}
|
|
12262
|
+
|
|
12263
|
+
function spanFromCSharpLineSpan(lineSpan, input) {
|
|
12264
|
+
if (!lineSpan || typeof lineSpan !== 'object') return undefined;
|
|
12265
|
+
const start = lineSpan.startLinePosition ?? lineSpan.StartLinePosition ?? lineSpan.start ?? lineSpan.Start;
|
|
12266
|
+
const end = lineSpan.endLinePosition ?? lineSpan.EndLinePosition ?? lineSpan.end ?? lineSpan.End;
|
|
12267
|
+
const line = start?.line ?? start?.Line;
|
|
12268
|
+
if (typeof line !== 'number') return undefined;
|
|
12269
|
+
const character = start.character ?? start.Character ?? start.column ?? start.Column;
|
|
12270
|
+
const endLine = end?.line ?? end?.Line;
|
|
12271
|
+
const endCharacter = end?.character ?? end?.Character ?? end?.column ?? end?.Column;
|
|
12272
|
+
return {
|
|
12273
|
+
sourceId: input.sourceHash,
|
|
12274
|
+
path: lineSpan.path ?? lineSpan.filePath ?? lineSpan.FilePath ?? input.sourcePath,
|
|
12275
|
+
startLine: line + 1,
|
|
12276
|
+
startColumn: typeof character === 'number' ? character + 1 : undefined,
|
|
12277
|
+
endLine: typeof endLine === 'number' ? endLine + 1 : undefined,
|
|
12278
|
+
endColumn: typeof endCharacter === 'number' ? endCharacter + 1 : undefined
|
|
12279
|
+
};
|
|
12280
|
+
}
|
|
12281
|
+
|
|
12282
|
+
function spanFromCSharpLineFields(node, input) {
|
|
12283
|
+
const startLine = node.startLine ?? node.line ?? node.beginLine;
|
|
12284
|
+
if (typeof startLine !== 'number') return undefined;
|
|
12285
|
+
return {
|
|
12286
|
+
sourceId: input.sourceHash,
|
|
12287
|
+
path: node.path ?? node.filePath ?? node.file ?? input.sourcePath,
|
|
12288
|
+
startLine,
|
|
12289
|
+
startColumn: node.startColumn ?? node.column ?? node.beginColumn,
|
|
12290
|
+
endLine: node.endLine,
|
|
12291
|
+
endColumn: node.endColumn
|
|
12292
|
+
};
|
|
12293
|
+
}
|
|
12294
|
+
|
|
12295
|
+
function csharpRoslynPosition(value, options = {}) {
|
|
12296
|
+
if (value === undefined || value === null) return undefined;
|
|
12297
|
+
if (typeof value === 'object') {
|
|
12298
|
+
const position = value.position ?? value.Position ?? value;
|
|
12299
|
+
const line = position.line ?? position.Line;
|
|
12300
|
+
const column = position.column ?? position.Column ?? position.character ?? position.Character;
|
|
12301
|
+
if (typeof line === 'number') {
|
|
12302
|
+
return {
|
|
12303
|
+
path: position.path ?? position.filePath ?? position.FilePath ?? position.file,
|
|
12304
|
+
line,
|
|
12305
|
+
column: typeof column === 'number' ? column : undefined
|
|
12306
|
+
};
|
|
12307
|
+
}
|
|
12308
|
+
}
|
|
12309
|
+
const resolver = typeof options.positionResolver === 'function'
|
|
12310
|
+
? options.positionResolver
|
|
12311
|
+
: typeof options.lineMap?.position === 'function'
|
|
12312
|
+
? options.lineMap.position.bind(options.lineMap)
|
|
12313
|
+
: typeof options.lineMap?.getLinePosition === 'function'
|
|
12314
|
+
? options.lineMap.getLinePosition.bind(options.lineMap)
|
|
12315
|
+
: undefined;
|
|
12316
|
+
if (resolver) {
|
|
12317
|
+
const resolved = resolver(value);
|
|
12318
|
+
if (resolved !== value) return csharpRoslynPosition(resolved, options);
|
|
12319
|
+
}
|
|
12320
|
+
return undefined;
|
|
12321
|
+
}
|
|
12322
|
+
|
|
12323
|
+
function csharpRoslynPositionKind(node) {
|
|
12324
|
+
if (node.lineSpan || node.location?.lineSpan) return 'line-position-span';
|
|
12325
|
+
if (node.span || node.Span) return 'text-span';
|
|
12326
|
+
if (typeof node.startLine === 'number' || typeof node.line === 'number') return 'line-column-fields';
|
|
12327
|
+
return undefined;
|
|
12328
|
+
}
|
|
12329
|
+
|
|
12330
|
+
function csharpRoslynDeclarations(node, kind, nativeNodeId, input) {
|
|
12331
|
+
if (kind === 'UsingDirective') {
|
|
12332
|
+
const name = csharpRoslynUsingPath(node);
|
|
12333
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'module', 'import')] : [];
|
|
12334
|
+
}
|
|
12335
|
+
if (kind === 'NamespaceDeclaration' || kind === 'FileScopedNamespaceDeclaration') {
|
|
12336
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12337
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'namespace', 'definition')] : [];
|
|
12338
|
+
}
|
|
12339
|
+
if (csharpRoslynTypeDeclarationKind(kind)) {
|
|
12340
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12341
|
+
return name ? [declarationRecord(input, nativeNodeId, name, csharpRoslynTypeDeclarationSymbolKind(kind), 'definition')] : [];
|
|
12342
|
+
}
|
|
12343
|
+
if (kind === 'DelegateDeclaration') {
|
|
12344
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12345
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'type', 'definition')] : [];
|
|
12346
|
+
}
|
|
12347
|
+
if (csharpRoslynMethodLikeKind(kind)) {
|
|
12348
|
+
const name = csharpRoslynDeclarationName(node) ?? csharpRoslynOperatorName(node, kind);
|
|
12349
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'method', csharpRoslynHasBody(node) ? 'definition' : 'declaration')] : [];
|
|
12350
|
+
}
|
|
12351
|
+
if (kind === 'PropertyDeclaration' || kind === 'IndexerDeclaration') {
|
|
12352
|
+
const name = csharpRoslynDeclarationName(node) ?? (kind === 'IndexerDeclaration' ? 'this[]' : undefined);
|
|
12353
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'property', 'definition')] : [];
|
|
12354
|
+
}
|
|
12355
|
+
if (kind === 'FieldDeclaration') {
|
|
12356
|
+
return csharpRoslynVariableNames(node).map((name) => declarationRecord(input, nativeNodeId, name, 'property', 'definition'));
|
|
12357
|
+
}
|
|
12358
|
+
if (kind === 'EventDeclaration') {
|
|
12359
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12360
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'event', 'definition')] : [];
|
|
12361
|
+
}
|
|
12362
|
+
if (kind === 'EventFieldDeclaration') {
|
|
12363
|
+
return csharpRoslynVariableNames(node).map((name) => declarationRecord(input, nativeNodeId, name, 'event', 'definition'));
|
|
12364
|
+
}
|
|
12365
|
+
if (kind === 'VariableDeclarator') {
|
|
12366
|
+
if (node.parentKind === 'FieldDeclaration') {
|
|
12367
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12368
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'property', 'definition')] : [];
|
|
12369
|
+
}
|
|
12370
|
+
if (node.parentKind === 'EventFieldDeclaration') {
|
|
12371
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12372
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'event', 'definition')] : [];
|
|
12373
|
+
}
|
|
12374
|
+
return [];
|
|
12375
|
+
}
|
|
12376
|
+
if (kind === 'EnumMemberDeclaration') {
|
|
12377
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12378
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'enumMember', 'definition')] : [];
|
|
12379
|
+
}
|
|
12380
|
+
return [];
|
|
12381
|
+
}
|
|
12382
|
+
|
|
12383
|
+
function csharpRoslynChildEntries(node, kind = csharpRoslynKind(node)) {
|
|
12384
|
+
const fieldNames = Object.keys(node).filter((key) => !ignoredCSharpRoslynField(key));
|
|
12385
|
+
const entries = [];
|
|
12386
|
+
for (const field of fieldNames) {
|
|
12387
|
+
const value = node[field];
|
|
12388
|
+
if (Array.isArray(value)) {
|
|
12389
|
+
entries.push([field, value.map((entry) => csharpRoslynChildWithParent(entry, kind, field))]);
|
|
12390
|
+
continue;
|
|
12391
|
+
}
|
|
12392
|
+
if (value && typeof value === 'object') {
|
|
12393
|
+
entries.push([field, csharpRoslynChildWithParent(value, kind, field)]);
|
|
12394
|
+
}
|
|
12395
|
+
}
|
|
12396
|
+
return entries.filter(([, value]) => Array.isArray(value)
|
|
12397
|
+
? value.some(isCSharpRoslynNode)
|
|
12398
|
+
: isCSharpRoslynNode(value));
|
|
12399
|
+
}
|
|
12400
|
+
|
|
12401
|
+
function csharpRoslynChildWithParent(entry, parentKind, parentField) {
|
|
12402
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return entry;
|
|
12403
|
+
if (!isCSharpRoslynNode(entry)) return entry;
|
|
12404
|
+
return { parentKind, parentField, ...entry };
|
|
12405
|
+
}
|
|
12406
|
+
|
|
12407
|
+
function csharpRoslynNodeValue(node) {
|
|
12408
|
+
return csharpRoslynDeclarationName(node)
|
|
12409
|
+
?? csharpRoslynUsingPath(node)
|
|
12410
|
+
?? csharpRoslynTypeName(node.type ?? node.returnType)
|
|
12411
|
+
?? csharpRoslynLiteralValue(node);
|
|
12412
|
+
}
|
|
12413
|
+
|
|
12414
|
+
function csharpRoslynDeclarationName(node) {
|
|
12415
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
12416
|
+
for (const key of ['identifier', 'name', 'simpleName', 'qualifiedName', 'id']) {
|
|
12417
|
+
const value = node[key];
|
|
12418
|
+
const name = csharpRoslynName(value);
|
|
12419
|
+
if (name) return name;
|
|
12420
|
+
}
|
|
12421
|
+
if (node.declaration && typeof node.declaration === 'object') return csharpRoslynDeclarationName(node.declaration);
|
|
12422
|
+
return undefined;
|
|
12423
|
+
}
|
|
12424
|
+
|
|
12425
|
+
function csharpRoslynName(value) {
|
|
12426
|
+
if (!value) return undefined;
|
|
12427
|
+
if (typeof value === 'string') return value;
|
|
12428
|
+
if (typeof value.text === 'string') return value.text;
|
|
12429
|
+
if (typeof value.valueText === 'string') return value.valueText;
|
|
12430
|
+
if (typeof value.identifier === 'string') return value.identifier;
|
|
12431
|
+
if (typeof value.name === 'string') return value.name;
|
|
12432
|
+
if (typeof value.qualifiedName === 'string') return value.qualifiedName;
|
|
12433
|
+
if (typeof value.value === 'string') return value.value;
|
|
12434
|
+
if (value.identifier && value.identifier !== value) return csharpRoslynName(value.identifier);
|
|
12435
|
+
if (value.name && value.name !== value) return csharpRoslynName(value.name);
|
|
12436
|
+
return undefined;
|
|
12437
|
+
}
|
|
12438
|
+
|
|
12439
|
+
function csharpRoslynUsingPath(node) {
|
|
12440
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
12441
|
+
return csharpRoslynName(node.name ?? node.Name ?? node.qualifiedName ?? node.path);
|
|
12442
|
+
}
|
|
12443
|
+
|
|
12444
|
+
function csharpRoslynVariableNames(node) {
|
|
12445
|
+
const variables = node.variables
|
|
12446
|
+
?? node.declaration?.variables
|
|
12447
|
+
?? node.Declaration?.Variables
|
|
12448
|
+
?? node.variableDeclarators;
|
|
12449
|
+
if (Array.isArray(variables)) return variables.map(csharpRoslynDeclarationName).filter(Boolean);
|
|
12450
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12451
|
+
return name ? [name] : [];
|
|
12452
|
+
}
|
|
12453
|
+
|
|
12454
|
+
function csharpRoslynTypeName(value) {
|
|
12455
|
+
if (!value) return undefined;
|
|
12456
|
+
if (typeof value === 'string') return value;
|
|
12457
|
+
if (typeof value.name === 'string') return value.name;
|
|
12458
|
+
if (typeof value.text === 'string') return value.text;
|
|
12459
|
+
if (typeof value.valueText === 'string') return value.valueText;
|
|
12460
|
+
if (typeof value.qualifiedName === 'string') return value.qualifiedName;
|
|
12461
|
+
if (value.elementType) {
|
|
12462
|
+
const inner = csharpRoslynTypeName(value.elementType);
|
|
12463
|
+
return inner ? `${inner}[]` : '[]';
|
|
12464
|
+
}
|
|
12465
|
+
if (Array.isArray(value.typeArgumentList?.arguments ?? value.typeArguments)) {
|
|
12466
|
+
const base = csharpRoslynName(value.name) ?? csharpRoslynName(value);
|
|
12467
|
+
const args = (value.typeArgumentList?.arguments ?? value.typeArguments).map(csharpRoslynTypeName).filter(Boolean);
|
|
12468
|
+
return base ? `${base}<${args.join(', ')}>` : undefined;
|
|
12469
|
+
}
|
|
12470
|
+
return csharpRoslynName(value);
|
|
12471
|
+
}
|
|
12472
|
+
|
|
12473
|
+
function csharpRoslynModifierNames(node) {
|
|
12474
|
+
const modifiers = node.modifiers ?? node.Modifiers;
|
|
12475
|
+
if (!modifiers) return [];
|
|
12476
|
+
if (Array.isArray(modifiers)) {
|
|
12477
|
+
return uniqueStrings(modifiers.map((entry) => typeof entry === 'string' ? entry : csharpRoslynName(entry) ?? entry.kind).filter(Boolean));
|
|
12478
|
+
}
|
|
12479
|
+
if (typeof modifiers === 'string') return uniqueStrings(modifiers.split(/\s+/).filter(Boolean));
|
|
12480
|
+
if (typeof modifiers === 'object') {
|
|
12481
|
+
return uniqueStrings(Object.entries(modifiers)
|
|
12482
|
+
.filter(([, enabled]) => enabled === true)
|
|
12483
|
+
.map(([key]) => key));
|
|
12484
|
+
}
|
|
12485
|
+
return [];
|
|
12486
|
+
}
|
|
12487
|
+
|
|
12488
|
+
function csharpRoslynTypeDeclarationKind(kind) {
|
|
12489
|
+
return kind === 'ClassDeclaration'
|
|
12490
|
+
|| kind === 'InterfaceDeclaration'
|
|
12491
|
+
|| kind === 'StructDeclaration'
|
|
12492
|
+
|| kind === 'RecordDeclaration'
|
|
12493
|
+
|| kind === 'RecordStructDeclaration'
|
|
12494
|
+
|| kind === 'EnumDeclaration';
|
|
12495
|
+
}
|
|
12496
|
+
|
|
12497
|
+
function csharpRoslynTypeDeclarationSymbolKind(kind) {
|
|
12498
|
+
if (kind === 'ClassDeclaration' || kind === 'RecordDeclaration') return 'class';
|
|
12499
|
+
if (kind === 'InterfaceDeclaration') return 'interface';
|
|
12500
|
+
return 'type';
|
|
12501
|
+
}
|
|
12502
|
+
|
|
12503
|
+
function csharpRoslynMethodLikeKind(kind) {
|
|
12504
|
+
return kind === 'MethodDeclaration'
|
|
12505
|
+
|| kind === 'ConstructorDeclaration'
|
|
12506
|
+
|| kind === 'DestructorDeclaration'
|
|
12507
|
+
|| kind === 'OperatorDeclaration'
|
|
12508
|
+
|| kind === 'ConversionOperatorDeclaration';
|
|
12509
|
+
}
|
|
12510
|
+
|
|
12511
|
+
function csharpRoslynHasBody(node) {
|
|
12512
|
+
return Boolean(node.body || node.expressionBody || node.accessorList || Array.isArray(node.statements));
|
|
12513
|
+
}
|
|
12514
|
+
|
|
12515
|
+
function csharpRoslynOperatorName(node, kind) {
|
|
12516
|
+
if (kind === 'ConstructorDeclaration') return csharpRoslynDeclarationName(node);
|
|
12517
|
+
if (kind === 'DestructorDeclaration') return `~${csharpRoslynDeclarationName(node) ?? 'destructor'}`;
|
|
12518
|
+
if (kind === 'OperatorDeclaration') return `operator ${csharpRoslynName(node.operatorToken) ?? csharpRoslynName(node.operatorKeyword) ?? 'operator'}`;
|
|
12519
|
+
if (kind === 'ConversionOperatorDeclaration') return `operator ${csharpRoslynTypeName(node.type) ?? 'conversion'}`;
|
|
12520
|
+
return undefined;
|
|
12521
|
+
}
|
|
12522
|
+
|
|
12523
|
+
function csharpRoslynLiteralValue(node) {
|
|
12524
|
+
const value = node.value ?? node.literal;
|
|
12525
|
+
if (value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') return value;
|
|
12526
|
+
return undefined;
|
|
12527
|
+
}
|
|
12528
|
+
|
|
12529
|
+
function csharpRoslynRecoveredKind(kind) {
|
|
12530
|
+
return kind === 'IncompleteMember'
|
|
12531
|
+
|| kind === 'SkippedTokensTrivia'
|
|
12532
|
+
|| /Skipped|Missing|Bad|Incomplete/.test(String(kind));
|
|
12533
|
+
}
|
|
12534
|
+
|
|
12535
|
+
function csharpRoslynProblemNode(node, kind) {
|
|
12536
|
+
return Boolean(
|
|
12537
|
+
node.containsDiagnostics
|
|
12538
|
+
|| node.ContainsDiagnostics
|
|
12539
|
+
|| node.containsSkippedText
|
|
12540
|
+
|| node.ContainsSkippedText
|
|
12541
|
+
|| node.isMissing
|
|
12542
|
+
|| node.IsMissing
|
|
12543
|
+
|| node.hasDiagnostics
|
|
12544
|
+
|| node.HasDiagnostics
|
|
12545
|
+
|| kind === 'IncompleteMember'
|
|
12546
|
+
|| kind === 'SkippedTokensTrivia'
|
|
12547
|
+
);
|
|
12548
|
+
}
|
|
12549
|
+
|
|
12550
|
+
function csharpRoslynDirectiveKind(kind) {
|
|
12551
|
+
return /DirectiveTrivia$/.test(String(kind)) || /^(IfDirective|ElifDirective|ElseDirective|EndIfDirective|DefineDirective|UndefDirective|NullableDirective|RegionDirective|EndRegionDirective|PragmaWarningDirective|LineDirective|ErrorDirective|WarningDirective|LoadDirective|ReferenceDirective)/.test(String(kind));
|
|
12552
|
+
}
|
|
12553
|
+
|
|
12554
|
+
function csharpGeneratedCodeMarker(node, kind) {
|
|
12555
|
+
if (node.generated || node.Generated || node.isGenerated) return true;
|
|
12556
|
+
const path = String(node.filePath ?? node.path ?? node.sourcePath ?? '');
|
|
12557
|
+
if (csharpGeneratedSourcePath(path)) return true;
|
|
12558
|
+
if (kind === 'Attribute') {
|
|
12559
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12560
|
+
if (name && /(^|\.)(GeneratedCode|CompilerGenerated|DebuggerNonUserCode)Attribute?$/.test(name)) return true;
|
|
12561
|
+
}
|
|
12562
|
+
const attributes = node.attributeLists ?? node.attributes;
|
|
12563
|
+
if (Array.isArray(attributes)) {
|
|
12564
|
+
return JSON.stringify(attributes).includes('GeneratedCode')
|
|
12565
|
+
|| JSON.stringify(attributes).includes('CompilerGenerated');
|
|
12566
|
+
}
|
|
12567
|
+
return false;
|
|
12568
|
+
}
|
|
12569
|
+
|
|
12570
|
+
function csharpGeneratedSourcePath(path) {
|
|
12571
|
+
return typeof path === 'string' && /\.(g|generated|designer)\.cs$/i.test(path);
|
|
12572
|
+
}
|
|
12573
|
+
|
|
12574
|
+
function csharpGeneratedCodeLoss(input, nodeId, span, options = {}, metadata = {}) {
|
|
12575
|
+
return {
|
|
12576
|
+
id: `loss_${idFragment(nodeId ?? input.sourcePath ?? 'csharp')}_csharp_generated_code`,
|
|
12577
|
+
severity: 'warning',
|
|
12578
|
+
phase: 'parse',
|
|
12579
|
+
sourceFormat: input.language,
|
|
12580
|
+
kind: 'generatedCode',
|
|
12581
|
+
message: 'C# generated-source or source-generator marker was imported; generated member provenance and source ownership require host evidence.',
|
|
12582
|
+
span,
|
|
12583
|
+
nodeId,
|
|
12584
|
+
metadata: {
|
|
12585
|
+
parser: options.parser,
|
|
12586
|
+
astFormat: options.astFormat,
|
|
12587
|
+
sourceGeneratorEvidence: csharpEvidenceSummary(options.sourceGeneratorEvidence),
|
|
12588
|
+
...metadata
|
|
12589
|
+
}
|
|
12590
|
+
};
|
|
12591
|
+
}
|
|
12592
|
+
|
|
12593
|
+
function csharpEvidenceSummary(value) {
|
|
12594
|
+
if (!value) return undefined;
|
|
12595
|
+
if (Array.isArray(value)) return { entryCount: value.length };
|
|
12596
|
+
if (typeof value === 'string') return { value };
|
|
12597
|
+
if (typeof value === 'object') {
|
|
12598
|
+
const summary = {};
|
|
12599
|
+
if (typeof value.hash === 'string') summary.hash = value.hash;
|
|
12600
|
+
if (typeof value.solver === 'string') summary.solver = value.solver;
|
|
12601
|
+
if (Array.isArray(value.entries)) summary.entryCount = value.entries.length;
|
|
12602
|
+
if (Array.isArray(value.references)) summary.referenceCount = value.references.length;
|
|
12603
|
+
if (Array.isArray(value.symbols)) summary.symbolCount = value.symbols.length;
|
|
12604
|
+
if (Array.isArray(value.diagnostics)) summary.diagnosticCount = value.diagnostics.length;
|
|
12605
|
+
if (Array.isArray(value.generators)) summary.generatorCount = value.generators.length;
|
|
12606
|
+
if (Array.isArray(value.projects)) summary.projectCount = value.projects.length;
|
|
12607
|
+
return Object.keys(summary).length ? summary : { present: true };
|
|
12608
|
+
}
|
|
12609
|
+
return { present: true };
|
|
12610
|
+
}
|
|
12611
|
+
|
|
11899
12612
|
function declarationRecord(input, nativeNodeId, name, symbolKind, role = 'definition') {
|
|
11900
12613
|
return {
|
|
11901
12614
|
name: String(name),
|
package/package.json
CHANGED