gitnexus 1.6.3-rc.9 → 1.6.3
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 +21 -5
- package/dist/_shared/graph/types.d.ts +16 -0
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/index.d.ts +4 -2
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js +2 -0
- package/dist/_shared/index.js.map +1 -1
- package/dist/_shared/scope-resolution/def-index.js +2 -2
- package/dist/_shared/scope-resolution/def-index.js.map +1 -1
- package/dist/_shared/scope-resolution/method-dispatch-index.d.ts +8 -0
- package/dist/_shared/scope-resolution/method-dispatch-index.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/method-dispatch-index.js +2 -2
- package/dist/_shared/scope-resolution/method-dispatch-index.js.map +1 -1
- package/dist/_shared/scope-resolution/module-scope-index.d.ts +8 -0
- package/dist/_shared/scope-resolution/module-scope-index.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/module-scope-index.js +10 -2
- package/dist/_shared/scope-resolution/module-scope-index.js.map +1 -1
- package/dist/_shared/scope-resolution/parsed-file.d.ts +76 -0
- package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/parsed-file.js +54 -0
- package/dist/_shared/scope-resolution/parsed-file.js.map +1 -0
- package/dist/_shared/scope-resolution/position-index.d.ts +12 -0
- package/dist/_shared/scope-resolution/position-index.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/position-index.js +2 -2
- package/dist/_shared/scope-resolution/position-index.js.map +1 -1
- package/dist/_shared/scope-resolution/qualified-name-index.js +2 -2
- package/dist/_shared/scope-resolution/qualified-name-index.js.map +1 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts +75 -0
- package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/reference-site.js +24 -0
- package/dist/_shared/scope-resolution/reference-site.js.map +1 -0
- package/dist/_shared/scope-resolution/registries/evidence.js +5 -0
- package/dist/_shared/scope-resolution/registries/evidence.js.map +1 -1
- package/dist/_shared/scope-resolution/registries/lookup-core.js +21 -5
- package/dist/_shared/scope-resolution/registries/lookup-core.js.map +1 -1
- package/dist/_shared/scope-resolution/resolve-type-ref.d.ts +1 -10
- package/dist/_shared/scope-resolution/resolve-type-ref.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/resolve-type-ref.js +6 -0
- package/dist/_shared/scope-resolution/resolve-type-ref.js.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.d.ts +4 -4
- package/dist/_shared/scope-resolution/scope-tree.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.js +3 -2
- package/dist/_shared/scope-resolution/scope-tree.js.map +1 -1
- package/dist/_shared/scope-resolution/shadow/aggregate.d.ts +6 -2
- package/dist/_shared/scope-resolution/shadow/aggregate.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/shadow/aggregate.js +5 -0
- package/dist/_shared/scope-resolution/shadow/aggregate.js.map +1 -1
- package/dist/_shared/scope-resolution/types.d.ts +11 -0
- package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
- package/dist/cli/ai-context.js +35 -4
- package/dist/cli/analyze.d.ts +27 -0
- package/dist/cli/analyze.js +31 -1
- package/dist/cli/clean.js +19 -1
- package/dist/cli/group.js +73 -0
- package/dist/cli/index-repo.js +8 -1
- package/dist/cli/index.js +26 -1
- package/dist/cli/list.js +11 -1
- package/dist/cli/remove.d.ts +30 -0
- package/dist/cli/remove.js +99 -0
- package/dist/cli/setup.js +185 -57
- package/dist/cli/tool.d.ts +5 -0
- package/dist/cli/tool.js +42 -0
- package/dist/config/ignore-service.d.ts +9 -0
- package/dist/config/ignore-service.js +80 -13
- package/dist/core/embedding-mode.d.ts +30 -0
- package/dist/core/embedding-mode.js +30 -0
- package/dist/core/embeddings/ast-utils.js +22 -22
- package/dist/core/embeddings/chunker.js +30 -25
- package/dist/core/embeddings/embedding-pipeline.d.ts +6 -0
- package/dist/core/embeddings/embedding-pipeline.js +15 -6
- package/dist/core/embeddings/text-generator.d.ts +1 -1
- package/dist/core/embeddings/text-generator.js +33 -24
- package/dist/core/embeddings/types.d.ts +43 -1
- package/dist/core/embeddings/types.js +101 -29
- package/dist/core/git-staleness.d.ts +18 -0
- package/dist/core/git-staleness.js +108 -0
- package/dist/core/graph/graph.js +115 -20
- package/dist/core/graph/types.d.ts +12 -1
- package/dist/core/group/config-parser.d.ts +4 -0
- package/dist/core/group/config-parser.js +18 -1
- package/dist/core/group/cross-impact.d.ts +41 -0
- package/dist/core/group/cross-impact.js +441 -0
- package/dist/core/group/extractors/http-patterns/php.js +126 -18
- package/dist/core/group/group-path-utils.d.ts +17 -0
- package/dist/core/group/group-path-utils.js +40 -0
- package/dist/core/group/resolve-at-member.d.ts +10 -0
- package/dist/core/group/resolve-at-member.js +31 -0
- package/dist/core/group/service.d.ts +9 -0
- package/dist/core/group/service.js +259 -25
- package/dist/core/group/types.d.ts +30 -0
- package/dist/core/ingestion/ast-cache.d.ts +16 -1
- package/dist/core/ingestion/ast-cache.js +14 -2
- package/dist/core/ingestion/call-processor.js +9 -0
- package/dist/core/ingestion/emit-references.d.ts +88 -0
- package/dist/core/ingestion/emit-references.js +229 -0
- package/dist/core/ingestion/filesystem-walker.js +6 -4
- package/dist/core/ingestion/finalize-orchestrator.d.ts +63 -0
- package/dist/core/ingestion/finalize-orchestrator.js +139 -0
- package/dist/core/ingestion/framework-detection.js +6 -2
- package/dist/core/ingestion/import-processor.js +4 -0
- package/dist/core/ingestion/import-resolvers/python.js +9 -6
- package/dist/core/ingestion/import-target-adapter.d.ts +73 -0
- package/dist/core/ingestion/import-target-adapter.js +95 -0
- package/dist/core/ingestion/language-provider.d.ts +36 -33
- package/dist/core/ingestion/languages/csharp/accessor-unwrap.d.ts +21 -0
- package/dist/core/ingestion/languages/csharp/accessor-unwrap.js +56 -0
- package/dist/core/ingestion/languages/csharp/arity-metadata.d.ts +26 -0
- package/dist/core/ingestion/languages/csharp/arity-metadata.js +46 -0
- package/dist/core/ingestion/languages/csharp/arity.d.ts +23 -0
- package/dist/core/ingestion/languages/csharp/arity.js +37 -0
- package/dist/core/ingestion/languages/csharp/cache-stats.d.ts +15 -0
- package/dist/core/ingestion/languages/csharp/cache-stats.js +26 -0
- package/dist/core/ingestion/languages/csharp/captures.d.ts +19 -0
- package/dist/core/ingestion/languages/csharp/captures.js +249 -0
- package/dist/core/ingestion/languages/csharp/import-decomposer.d.ts +19 -0
- package/dist/core/ingestion/languages/csharp/import-decomposer.js +93 -0
- package/dist/core/ingestion/languages/csharp/import-target.d.ts +25 -0
- package/dist/core/ingestion/languages/csharp/import-target.js +123 -0
- package/dist/core/ingestion/languages/csharp/index.d.ts +82 -0
- package/dist/core/ingestion/languages/csharp/index.js +82 -0
- package/dist/core/ingestion/languages/csharp/interpret.d.ts +15 -0
- package/dist/core/ingestion/languages/csharp/interpret.js +132 -0
- package/dist/core/ingestion/languages/csharp/merge-bindings.d.ts +27 -0
- package/dist/core/ingestion/languages/csharp/merge-bindings.js +55 -0
- package/dist/core/ingestion/languages/csharp/namespace-siblings.d.ts +50 -0
- package/dist/core/ingestion/languages/csharp/namespace-siblings.js +374 -0
- package/dist/core/ingestion/languages/csharp/query.d.ts +35 -0
- package/dist/core/ingestion/languages/csharp/query.js +515 -0
- package/dist/core/ingestion/languages/csharp/receiver-binding.d.ts +31 -0
- package/dist/core/ingestion/languages/csharp/receiver-binding.js +135 -0
- package/dist/core/ingestion/languages/csharp/scope-resolver.d.ts +10 -0
- package/dist/core/ingestion/languages/csharp/scope-resolver.js +63 -0
- package/dist/core/ingestion/languages/csharp/simple-hooks.d.ts +53 -0
- package/dist/core/ingestion/languages/csharp/simple-hooks.js +76 -0
- package/dist/core/ingestion/languages/csharp.js +14 -0
- package/dist/core/ingestion/languages/python/arity-metadata.d.ts +24 -0
- package/dist/core/ingestion/languages/python/arity-metadata.js +45 -0
- package/dist/core/ingestion/languages/python/arity.d.ts +22 -0
- package/dist/core/ingestion/languages/python/arity.js +38 -0
- package/dist/core/ingestion/languages/python/cache-stats.d.ts +17 -0
- package/dist/core/ingestion/languages/python/cache-stats.js +28 -0
- package/dist/core/ingestion/languages/python/captures.d.ts +19 -0
- package/dist/core/ingestion/languages/python/captures.js +106 -0
- package/dist/core/ingestion/languages/python/import-decomposer.d.ts +15 -0
- package/dist/core/ingestion/languages/python/import-decomposer.js +112 -0
- package/dist/core/ingestion/languages/python/import-target.d.ts +21 -0
- package/dist/core/ingestion/languages/python/import-target.js +99 -0
- package/dist/core/ingestion/languages/python/index.d.ts +80 -0
- package/dist/core/ingestion/languages/python/index.js +80 -0
- package/dist/core/ingestion/languages/python/interpret.d.ts +15 -0
- package/dist/core/ingestion/languages/python/interpret.js +191 -0
- package/dist/core/ingestion/languages/python/merge-bindings.d.ts +16 -0
- package/dist/core/ingestion/languages/python/merge-bindings.js +44 -0
- package/dist/core/ingestion/languages/python/query.d.ts +9 -0
- package/dist/core/ingestion/languages/python/query.js +267 -0
- package/dist/core/ingestion/languages/python/receiver-binding.d.ts +21 -0
- package/dist/core/ingestion/languages/python/receiver-binding.js +116 -0
- package/dist/core/ingestion/languages/python/scope-resolver.d.ts +16 -0
- package/dist/core/ingestion/languages/python/scope-resolver.js +53 -0
- package/dist/core/ingestion/languages/python/simple-hooks.d.ts +23 -0
- package/dist/core/ingestion/languages/python/simple-hooks.js +35 -0
- package/dist/core/ingestion/languages/python.js +14 -0
- package/dist/core/ingestion/model/method-registry.d.ts +9 -0
- package/dist/core/ingestion/model/method-registry.js +4 -0
- package/dist/core/ingestion/model/scope-resolution-indexes.d.ts +59 -0
- package/dist/core/ingestion/model/scope-resolution-indexes.js +42 -0
- package/dist/core/ingestion/model/semantic-model.d.ts +64 -0
- package/dist/core/ingestion/model/semantic-model.js +55 -0
- package/dist/core/ingestion/mro-processor.js +38 -22
- package/dist/core/ingestion/parsing-processor.d.ts +18 -1
- package/dist/core/ingestion/parsing-processor.js +45 -11
- package/dist/core/ingestion/pipeline-phases/index.d.ts +1 -0
- package/dist/core/ingestion/pipeline-phases/index.js +1 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +10 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +17 -2
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +18 -0
- package/dist/core/ingestion/pipeline.js +2 -1
- package/dist/core/ingestion/registry-primary-flag.d.ts +86 -0
- package/dist/core/ingestion/registry-primary-flag.js +111 -0
- package/dist/core/ingestion/resolve-references.d.ts +63 -0
- package/dist/core/ingestion/resolve-references.js +175 -0
- package/dist/core/ingestion/scope-extractor-bridge.d.ts +32 -0
- package/dist/core/ingestion/scope-extractor-bridge.js +44 -0
- package/dist/core/ingestion/scope-extractor.d.ts +86 -0
- package/dist/core/ingestion/scope-extractor.js +758 -0
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +372 -0
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.js +212 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +43 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +79 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.d.ts +57 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +112 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/imports-to-edges.d.ts +17 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/imports-to-edges.js +46 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/method-dispatch.d.ts +19 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/method-dispatch.js +30 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.d.ts +37 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +113 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.d.ts +38 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +73 -0
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.d.ts +42 -0
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.js +198 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +27 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +131 -0
- package/dist/core/ingestion/scope-resolution/passes/imported-return-types.d.ts +48 -0
- package/dist/core/ingestion/scope-resolution/passes/imported-return-types.js +130 -0
- package/dist/core/ingestion/scope-resolution/passes/mro.d.ts +42 -0
- package/dist/core/ingestion/scope-resolution/passes/mro.js +99 -0
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +26 -0
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +61 -0
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +46 -0
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +327 -0
- package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +47 -0
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +130 -0
- package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.d.ts +68 -0
- package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +125 -0
- package/dist/core/ingestion/scope-resolution/pipeline/registry.d.ts +17 -0
- package/dist/core/ingestion/scope-resolution/pipeline/registry.js +21 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +66 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +157 -0
- package/dist/core/ingestion/scope-resolution/scope/namespace-targets.d.ts +36 -0
- package/dist/core/ingestion/scope-resolution/scope/namespace-targets.js +52 -0
- package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +127 -0
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +349 -0
- package/dist/core/ingestion/scope-resolution/workspace-index.d.ts +52 -0
- package/dist/core/ingestion/scope-resolution/workspace-index.js +61 -0
- package/dist/core/ingestion/shadow-harness.d.ts +113 -0
- package/dist/core/ingestion/shadow-harness.js +148 -0
- package/dist/core/ingestion/utils/ast-helpers.d.ts +19 -1
- package/dist/core/ingestion/utils/ast-helpers.js +70 -0
- package/dist/core/ingestion/utils/max-file-size.d.ts +20 -0
- package/dist/core/ingestion/utils/max-file-size.js +52 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +9 -0
- package/dist/core/ingestion/workers/parse-worker.js +57 -21
- package/dist/core/lbug/lbug-adapter.d.ts +22 -2
- package/dist/core/lbug/lbug-adapter.js +58 -14
- package/dist/core/lbug/pool-adapter.d.ts +17 -0
- package/dist/core/lbug/pool-adapter.js +24 -14
- package/dist/core/run-analyze.d.ts +32 -0
- package/dist/core/run-analyze.js +74 -19
- package/dist/core/search/bm25-index.d.ts +18 -0
- package/dist/core/search/bm25-index.js +125 -12
- package/dist/core/tree-sitter/parser-loader.js +6 -1
- package/dist/mcp/local/local-backend.d.ts +67 -3
- package/dist/mcp/local/local-backend.js +296 -34
- package/dist/mcp/resources.d.ts +31 -0
- package/dist/mcp/resources.js +100 -17
- package/dist/mcp/tools.d.ts +4 -1
- package/dist/mcp/tools.js +75 -54
- package/dist/server/api.js +6 -2
- package/dist/storage/git.d.ts +49 -0
- package/dist/storage/git.js +111 -0
- package/dist/storage/repo-manager.d.ts +246 -1
- package/dist/storage/repo-manager.js +391 -9
- package/package.json +7 -6
- package/scripts/bench-scope-resolution.ts +134 -0
- package/scripts/ci-list-migrated-languages.ts +24 -0
- package/skills/gitnexus-cli.md +1 -0
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree-sitter query for C# scope captures (RFC §5.1).
|
|
3
|
+
*
|
|
4
|
+
* Captures the structural skeleton the generic scope-resolution
|
|
5
|
+
* pipeline consumes: scopes (module/namespace/class/function),
|
|
6
|
+
* declarations (class-likes, method-likes, properties, variables,
|
|
7
|
+
* local functions), imports (using directives), type bindings
|
|
8
|
+
* (parameter annotations, variable annotations, constructor
|
|
9
|
+
* inference), and references (call sites, member writes).
|
|
10
|
+
*
|
|
11
|
+
* C# specifics that shape this query:
|
|
12
|
+
*
|
|
13
|
+
* - Both block-scoped (`namespace X { }`) and file-scoped
|
|
14
|
+
* (`namespace X;`) namespaces. tree-sitter-c-sharp emits them
|
|
15
|
+
* under distinct node types (`namespace_declaration` vs
|
|
16
|
+
* `file_scoped_namespace_declaration`); both map to
|
|
17
|
+
* `@scope.namespace` since the scope semantics are identical.
|
|
18
|
+
* - `partial class X` splits a Class def across files. Each file
|
|
19
|
+
* emits its own `@declaration.class`; cross-file resolution is
|
|
20
|
+
* handled at the graph-bridge layer via the qualified-name key.
|
|
21
|
+
* - `using X = Y;` aliases and `using static X;` are interpreted in
|
|
22
|
+
* `interpret.ts` via the `@import.*` captures. All three using
|
|
23
|
+
* flavors share the same anchor (`@import.statement`).
|
|
24
|
+
* - Explicit interface implementations (`void IFoo.Bar() { }`)
|
|
25
|
+
* expose the qualified name via the existing `@declaration.name`
|
|
26
|
+
* — the extractor's `csharpMethodConfig.extractQualifiedName`
|
|
27
|
+
* picks up the explicit qualifier from the method declaration
|
|
28
|
+
* node.
|
|
29
|
+
*
|
|
30
|
+
* Exposes lazy `Parser` and `Query` singletons so callers don't pay
|
|
31
|
+
* tree-sitter init cost per file.
|
|
32
|
+
*/
|
|
33
|
+
import Parser from 'tree-sitter';
|
|
34
|
+
import CSharp from 'tree-sitter-c-sharp';
|
|
35
|
+
const CSHARP_SCOPE_QUERY = `
|
|
36
|
+
;; Scopes
|
|
37
|
+
(compilation_unit) @scope.module
|
|
38
|
+
|
|
39
|
+
(namespace_declaration) @scope.namespace
|
|
40
|
+
(file_scoped_namespace_declaration) @scope.namespace
|
|
41
|
+
|
|
42
|
+
(class_declaration) @scope.class
|
|
43
|
+
(interface_declaration) @scope.class
|
|
44
|
+
(struct_declaration) @scope.class
|
|
45
|
+
(record_declaration) @scope.class
|
|
46
|
+
(enum_declaration) @scope.class
|
|
47
|
+
|
|
48
|
+
(method_declaration) @scope.function
|
|
49
|
+
(constructor_declaration) @scope.function
|
|
50
|
+
(destructor_declaration) @scope.function
|
|
51
|
+
(local_function_statement) @scope.function
|
|
52
|
+
(operator_declaration) @scope.function
|
|
53
|
+
(conversion_operator_declaration) @scope.function
|
|
54
|
+
;; Property accessors are blocks within a property; not scoped here.
|
|
55
|
+
;; Anonymous methods / lambdas are not scoped — out of scope per plan.
|
|
56
|
+
|
|
57
|
+
;; Declarations — types
|
|
58
|
+
(class_declaration
|
|
59
|
+
name: (identifier) @declaration.name) @declaration.class
|
|
60
|
+
|
|
61
|
+
(interface_declaration
|
|
62
|
+
name: (identifier) @declaration.name) @declaration.interface
|
|
63
|
+
|
|
64
|
+
(struct_declaration
|
|
65
|
+
name: (identifier) @declaration.name) @declaration.struct
|
|
66
|
+
|
|
67
|
+
(record_declaration
|
|
68
|
+
name: (identifier) @declaration.name) @declaration.record
|
|
69
|
+
|
|
70
|
+
(enum_declaration
|
|
71
|
+
name: (identifier) @declaration.name) @declaration.enum
|
|
72
|
+
|
|
73
|
+
;; Declarations — methods / constructors / properties
|
|
74
|
+
(method_declaration
|
|
75
|
+
name: (identifier) @declaration.name) @declaration.method
|
|
76
|
+
|
|
77
|
+
(constructor_declaration
|
|
78
|
+
name: (identifier) @declaration.name) @declaration.constructor
|
|
79
|
+
|
|
80
|
+
(destructor_declaration
|
|
81
|
+
name: (identifier) @declaration.name) @declaration.method
|
|
82
|
+
|
|
83
|
+
(local_function_statement
|
|
84
|
+
name: (identifier) @declaration.name) @declaration.function
|
|
85
|
+
|
|
86
|
+
;; Operator declarations — \`public static T operator +(T a, T b)\`.
|
|
87
|
+
;; tree-sitter-c-sharp exposes the operator token under the \`operator:\`
|
|
88
|
+
;; field (an anonymous node like \`+\`, \`-\`, \`==\`). Capture the whole
|
|
89
|
+
;; node under @declaration.name so the extractor reads the operator
|
|
90
|
+
;; symbol as the declared name; downstream csharpMethodConfig can
|
|
91
|
+
;; normalize it (e.g. to \`op_Addition\`) when it runs.
|
|
92
|
+
(operator_declaration
|
|
93
|
+
operator: _ @declaration.name) @declaration.method
|
|
94
|
+
|
|
95
|
+
;; Conversion operators — \`public static explicit operator int(T x)\`.
|
|
96
|
+
;; No operator token; the target type (\`int\`) identifies the conversion
|
|
97
|
+
;; and serves as the name anchor.
|
|
98
|
+
(conversion_operator_declaration
|
|
99
|
+
type: _ @declaration.name) @declaration.method
|
|
100
|
+
|
|
101
|
+
(property_declaration
|
|
102
|
+
name: (identifier) @declaration.name) @declaration.property
|
|
103
|
+
|
|
104
|
+
(indexer_declaration) @declaration.property
|
|
105
|
+
|
|
106
|
+
;; Fields — \`int x;\` at class scope. variable_declarator inside
|
|
107
|
+
;; field_declaration carries the name.
|
|
108
|
+
(field_declaration
|
|
109
|
+
(variable_declaration
|
|
110
|
+
(variable_declarator
|
|
111
|
+
name: (identifier) @declaration.name))) @declaration.variable
|
|
112
|
+
|
|
113
|
+
;; Local variables — \`int x = 1;\` inside a method body
|
|
114
|
+
(local_declaration_statement
|
|
115
|
+
(variable_declaration
|
|
116
|
+
(variable_declarator
|
|
117
|
+
name: (identifier) @declaration.name))) @declaration.variable
|
|
118
|
+
|
|
119
|
+
;; Imports — single anchor per directive; interpretCsharpImport classifies
|
|
120
|
+
(using_directive) @import.statement
|
|
121
|
+
|
|
122
|
+
;; Type bindings — parameter annotations: \`void F(User u)\`
|
|
123
|
+
(parameter
|
|
124
|
+
type: (identifier) @type-binding.type
|
|
125
|
+
name: (identifier) @type-binding.name) @type-binding.parameter
|
|
126
|
+
|
|
127
|
+
(parameter
|
|
128
|
+
type: (generic_name) @type-binding.type
|
|
129
|
+
name: (identifier) @type-binding.name) @type-binding.parameter
|
|
130
|
+
|
|
131
|
+
(parameter
|
|
132
|
+
type: (qualified_name) @type-binding.type
|
|
133
|
+
name: (identifier) @type-binding.name) @type-binding.parameter
|
|
134
|
+
|
|
135
|
+
(parameter
|
|
136
|
+
type: (nullable_type) @type-binding.type
|
|
137
|
+
name: (identifier) @type-binding.name) @type-binding.parameter
|
|
138
|
+
|
|
139
|
+
;; Type bindings — local variable annotations: \`User u = new User();\`
|
|
140
|
+
;; Typed local with identifier type + \`new X()\` initializer — shape
|
|
141
|
+
;; matters so \`u\` binds to \`X\` (the constructor call's type), not the
|
|
142
|
+
;; declared type alias (which is usually the same, but \`new DerivedUser()\`
|
|
143
|
+
;; would be distinct).
|
|
144
|
+
(local_declaration_statement
|
|
145
|
+
(variable_declaration
|
|
146
|
+
type: (identifier) @type-binding.type
|
|
147
|
+
(variable_declarator
|
|
148
|
+
name: (identifier) @type-binding.name))) @type-binding.annotation
|
|
149
|
+
|
|
150
|
+
(local_declaration_statement
|
|
151
|
+
(variable_declaration
|
|
152
|
+
type: (generic_name) @type-binding.type
|
|
153
|
+
(variable_declarator
|
|
154
|
+
name: (identifier) @type-binding.name))) @type-binding.annotation
|
|
155
|
+
|
|
156
|
+
(local_declaration_statement
|
|
157
|
+
(variable_declaration
|
|
158
|
+
type: (qualified_name) @type-binding.type
|
|
159
|
+
(variable_declarator
|
|
160
|
+
name: (identifier) @type-binding.name))) @type-binding.annotation
|
|
161
|
+
|
|
162
|
+
;; Type bindings — \`var u = new User();\` — constructor-inferred.
|
|
163
|
+
;; Captures object_creation_expression's type as the binding type.
|
|
164
|
+
;; variable_declarator wraps the \`= <expr>\` directly; tree-sitter-c-sharp
|
|
165
|
+
;; does not surface an equals_value_clause wrapper here.
|
|
166
|
+
(local_declaration_statement
|
|
167
|
+
(variable_declaration
|
|
168
|
+
(variable_declarator
|
|
169
|
+
name: (identifier) @type-binding.name
|
|
170
|
+
(object_creation_expression
|
|
171
|
+
type: (identifier) @type-binding.type)))) @type-binding.constructor
|
|
172
|
+
|
|
173
|
+
(local_declaration_statement
|
|
174
|
+
(variable_declaration
|
|
175
|
+
(variable_declarator
|
|
176
|
+
name: (identifier) @type-binding.name
|
|
177
|
+
(object_creation_expression
|
|
178
|
+
type: (generic_name) @type-binding.type)))) @type-binding.constructor
|
|
179
|
+
|
|
180
|
+
(local_declaration_statement
|
|
181
|
+
(variable_declaration
|
|
182
|
+
(variable_declarator
|
|
183
|
+
name: (identifier) @type-binding.name
|
|
184
|
+
(object_creation_expression
|
|
185
|
+
type: (qualified_name) @type-binding.type)))) @type-binding.constructor
|
|
186
|
+
|
|
187
|
+
;; Type bindings — \`var u = factory();\` alias (chain-follow picks up
|
|
188
|
+
;; factory's return type via propagateImportedReturnTypes)
|
|
189
|
+
(local_declaration_statement
|
|
190
|
+
(variable_declaration
|
|
191
|
+
(variable_declarator
|
|
192
|
+
name: (identifier) @type-binding.name
|
|
193
|
+
(invocation_expression
|
|
194
|
+
function: (identifier) @type-binding.type)))) @type-binding.alias
|
|
195
|
+
|
|
196
|
+
;; Type bindings — identifier-to-identifier alias: \`var alias = u;\`.
|
|
197
|
+
;; The resolver's chain-follow walks from \`alias\` → \`u\` → u's
|
|
198
|
+
;; declared type, so we only need to tag the rename here.
|
|
199
|
+
(local_declaration_statement
|
|
200
|
+
(variable_declaration
|
|
201
|
+
type: (implicit_type)
|
|
202
|
+
(variable_declarator
|
|
203
|
+
name: (identifier) @type-binding.name
|
|
204
|
+
(identifier) @type-binding.type))) @type-binding.alias
|
|
205
|
+
|
|
206
|
+
;; Type bindings — chained method-call alias: \`var u = svc.GetUser();\`.
|
|
207
|
+
;; The chain-follow then walks GetUser's return-type binding.
|
|
208
|
+
(local_declaration_statement
|
|
209
|
+
(variable_declaration
|
|
210
|
+
type: (implicit_type)
|
|
211
|
+
(variable_declarator
|
|
212
|
+
name: (identifier) @type-binding.name
|
|
213
|
+
(invocation_expression
|
|
214
|
+
function: (member_access_expression
|
|
215
|
+
name: (identifier) @type-binding.type))))) @type-binding.alias
|
|
216
|
+
|
|
217
|
+
;; Type bindings — \`await\` propagation: \`var u = await Factory();\`.
|
|
218
|
+
;; Strip the await wrapper to get the underlying invocation; interpret
|
|
219
|
+
;; layer's stripGeneric handles Task<T> / ValueTask<T>.
|
|
220
|
+
(local_declaration_statement
|
|
221
|
+
(variable_declaration
|
|
222
|
+
type: (implicit_type)
|
|
223
|
+
(variable_declarator
|
|
224
|
+
name: (identifier) @type-binding.name
|
|
225
|
+
(await_expression
|
|
226
|
+
(invocation_expression
|
|
227
|
+
function: (identifier) @type-binding.type))))) @type-binding.alias
|
|
228
|
+
|
|
229
|
+
(local_declaration_statement
|
|
230
|
+
(variable_declaration
|
|
231
|
+
type: (implicit_type)
|
|
232
|
+
(variable_declarator
|
|
233
|
+
name: (identifier) @type-binding.name
|
|
234
|
+
(await_expression
|
|
235
|
+
(invocation_expression
|
|
236
|
+
function: (member_access_expression
|
|
237
|
+
name: (identifier) @type-binding.type)))))) @type-binding.alias
|
|
238
|
+
|
|
239
|
+
;; Type bindings — identifier-to-identifier assignment rebind:
|
|
240
|
+
;; \`alias = u;\` — aliases the rhs identifier's current type.
|
|
241
|
+
(assignment_expression
|
|
242
|
+
left: (identifier) @type-binding.name
|
|
243
|
+
right: (identifier) @type-binding.type) @type-binding.alias
|
|
244
|
+
|
|
245
|
+
;; Type bindings — method return type: \`public User GetUser() { ... }\`.
|
|
246
|
+
;; Anchor on the method_declaration so bindingScopeFor can hoist the
|
|
247
|
+
;; binding from function scope to the enclosing class/module scope
|
|
248
|
+
;; (callers, not the function body, look up the return type by the
|
|
249
|
+
;; function's name). Required for cross-file return-type propagation
|
|
250
|
+
;; via propagateImportedReturnTypes.
|
|
251
|
+
(method_declaration
|
|
252
|
+
returns: (identifier) @type-binding.type
|
|
253
|
+
name: (identifier) @type-binding.name) @type-binding.return
|
|
254
|
+
|
|
255
|
+
(method_declaration
|
|
256
|
+
returns: (generic_name) @type-binding.type
|
|
257
|
+
name: (identifier) @type-binding.name) @type-binding.return
|
|
258
|
+
|
|
259
|
+
(method_declaration
|
|
260
|
+
returns: (qualified_name) @type-binding.type
|
|
261
|
+
name: (identifier) @type-binding.name) @type-binding.return
|
|
262
|
+
|
|
263
|
+
(method_declaration
|
|
264
|
+
returns: (nullable_type) @type-binding.type
|
|
265
|
+
name: (identifier) @type-binding.name) @type-binding.return
|
|
266
|
+
|
|
267
|
+
;; Type bindings — field declaration: \`private City _city;\`. Attaches
|
|
268
|
+
;; to the enclosing class scope via positionIndex, so \`this._city.X\`
|
|
269
|
+
;; can look up _city's type on the class.
|
|
270
|
+
(field_declaration
|
|
271
|
+
(variable_declaration
|
|
272
|
+
type: (identifier) @type-binding.type
|
|
273
|
+
(variable_declarator
|
|
274
|
+
name: (identifier) @type-binding.name))) @type-binding.annotation
|
|
275
|
+
|
|
276
|
+
(field_declaration
|
|
277
|
+
(variable_declaration
|
|
278
|
+
type: (generic_name) @type-binding.type
|
|
279
|
+
(variable_declarator
|
|
280
|
+
name: (identifier) @type-binding.name))) @type-binding.annotation
|
|
281
|
+
|
|
282
|
+
(field_declaration
|
|
283
|
+
(variable_declaration
|
|
284
|
+
type: (qualified_name) @type-binding.type
|
|
285
|
+
(variable_declarator
|
|
286
|
+
name: (identifier) @type-binding.name))) @type-binding.annotation
|
|
287
|
+
|
|
288
|
+
;; Type bindings — property declaration: \`public User Owner { get; set; }\`.
|
|
289
|
+
(property_declaration
|
|
290
|
+
type: (identifier) @type-binding.type
|
|
291
|
+
name: (identifier) @type-binding.name) @type-binding.annotation
|
|
292
|
+
|
|
293
|
+
(property_declaration
|
|
294
|
+
type: (generic_name) @type-binding.type
|
|
295
|
+
name: (identifier) @type-binding.name) @type-binding.annotation
|
|
296
|
+
|
|
297
|
+
(property_declaration
|
|
298
|
+
type: (qualified_name) @type-binding.type
|
|
299
|
+
name: (identifier) @type-binding.name) @type-binding.annotation
|
|
300
|
+
|
|
301
|
+
(property_declaration
|
|
302
|
+
type: (nullable_type) @type-binding.type
|
|
303
|
+
name: (identifier) @type-binding.name) @type-binding.annotation
|
|
304
|
+
|
|
305
|
+
;; Type bindings — assignment rebind: \`alias = Factory();\` where
|
|
306
|
+
;; \`alias\` was previously declared. Same alias shape as \`var x = F();\`.
|
|
307
|
+
(assignment_expression
|
|
308
|
+
left: (identifier) @type-binding.name
|
|
309
|
+
right: (invocation_expression
|
|
310
|
+
function: (identifier) @type-binding.type)) @type-binding.alias
|
|
311
|
+
|
|
312
|
+
;; Type bindings — assignment with constructor: \`alias = new User();\`.
|
|
313
|
+
(assignment_expression
|
|
314
|
+
left: (identifier) @type-binding.name
|
|
315
|
+
right: (object_creation_expression
|
|
316
|
+
type: (identifier) @type-binding.type)) @type-binding.constructor
|
|
317
|
+
|
|
318
|
+
(assignment_expression
|
|
319
|
+
left: (identifier) @type-binding.name
|
|
320
|
+
right: (object_creation_expression
|
|
321
|
+
type: (generic_name) @type-binding.type)) @type-binding.constructor
|
|
322
|
+
|
|
323
|
+
;; Type bindings — \`is\` pattern: \`if (obj is User u) { u.Save(); }\`.
|
|
324
|
+
;; The declaration_pattern carries both the matched type and the
|
|
325
|
+
;; binding name; scope narrowing to the guarded branch is simplified
|
|
326
|
+
;; to function-scope (matches Python's match-case treatment) since we
|
|
327
|
+
;; don't emit @scope.block.
|
|
328
|
+
(is_pattern_expression
|
|
329
|
+
pattern: (declaration_pattern
|
|
330
|
+
type: (identifier) @type-binding.type
|
|
331
|
+
name: (identifier) @type-binding.name)) @type-binding.annotation
|
|
332
|
+
|
|
333
|
+
(is_pattern_expression
|
|
334
|
+
pattern: (declaration_pattern
|
|
335
|
+
type: (generic_name) @type-binding.type
|
|
336
|
+
name: (identifier) @type-binding.name)) @type-binding.annotation
|
|
337
|
+
|
|
338
|
+
(is_pattern_expression
|
|
339
|
+
pattern: (declaration_pattern
|
|
340
|
+
type: (qualified_name) @type-binding.type
|
|
341
|
+
name: (identifier) @type-binding.name)) @type-binding.annotation
|
|
342
|
+
|
|
343
|
+
;; Type bindings — \`case User u:\` inside a switch section.
|
|
344
|
+
;; tree-sitter-c-sharp's switch_section directly contains the
|
|
345
|
+
;; declaration_pattern / recursive_pattern (no case_pattern_switch_label
|
|
346
|
+
;; wrapper as in other C# grammars).
|
|
347
|
+
(switch_section
|
|
348
|
+
(declaration_pattern
|
|
349
|
+
type: (identifier) @type-binding.type
|
|
350
|
+
name: (identifier) @type-binding.name)) @type-binding.annotation
|
|
351
|
+
|
|
352
|
+
(switch_section
|
|
353
|
+
(declaration_pattern
|
|
354
|
+
type: (generic_name) @type-binding.type
|
|
355
|
+
name: (identifier) @type-binding.name)) @type-binding.annotation
|
|
356
|
+
|
|
357
|
+
;; Type bindings — recursive_pattern with named binding:
|
|
358
|
+
;; \`x is User { Age: 1 } u\` / \`case User { Age: 1 } u:\`. type + name
|
|
359
|
+
;; are named fields on recursive_pattern; inner property/positional
|
|
360
|
+
;; clauses don't affect the binding.
|
|
361
|
+
(is_pattern_expression
|
|
362
|
+
pattern: (recursive_pattern
|
|
363
|
+
type: (identifier) @type-binding.type
|
|
364
|
+
name: (identifier) @type-binding.name)) @type-binding.annotation
|
|
365
|
+
|
|
366
|
+
(switch_section
|
|
367
|
+
(recursive_pattern
|
|
368
|
+
type: (identifier) @type-binding.type
|
|
369
|
+
name: (identifier) @type-binding.name)) @type-binding.annotation
|
|
370
|
+
|
|
371
|
+
;; Type bindings — switch-expression arms: \`obj switch { User u => …, Repo { Name: "x" } r => … }\`.
|
|
372
|
+
;; Distinct from the \`switch_statement\` shape above — expression-switch
|
|
373
|
+
;; uses \`switch_expression_arm\` nodes.
|
|
374
|
+
(switch_expression_arm
|
|
375
|
+
(declaration_pattern
|
|
376
|
+
type: (identifier) @type-binding.type
|
|
377
|
+
name: (identifier) @type-binding.name)) @type-binding.annotation
|
|
378
|
+
|
|
379
|
+
(switch_expression_arm
|
|
380
|
+
(declaration_pattern
|
|
381
|
+
type: (generic_name) @type-binding.type
|
|
382
|
+
name: (identifier) @type-binding.name)) @type-binding.annotation
|
|
383
|
+
|
|
384
|
+
(switch_expression_arm
|
|
385
|
+
(recursive_pattern
|
|
386
|
+
type: (identifier) @type-binding.type
|
|
387
|
+
name: (identifier) @type-binding.name)) @type-binding.annotation
|
|
388
|
+
|
|
389
|
+
;; Type bindings — typed foreach: \`foreach (User u in xs)\`.
|
|
390
|
+
;; Shape parity with \`User u = …;\` — left binds to the declared type.
|
|
391
|
+
(foreach_statement
|
|
392
|
+
type: (identifier) @type-binding.type
|
|
393
|
+
left: (identifier) @type-binding.name) @type-binding.annotation
|
|
394
|
+
|
|
395
|
+
(foreach_statement
|
|
396
|
+
type: (generic_name) @type-binding.type
|
|
397
|
+
left: (identifier) @type-binding.name) @type-binding.annotation
|
|
398
|
+
|
|
399
|
+
(foreach_statement
|
|
400
|
+
type: (qualified_name) @type-binding.type
|
|
401
|
+
left: (identifier) @type-binding.name) @type-binding.annotation
|
|
402
|
+
|
|
403
|
+
(foreach_statement
|
|
404
|
+
type: (nullable_type) @type-binding.type
|
|
405
|
+
left: (identifier) @type-binding.name) @type-binding.annotation
|
|
406
|
+
|
|
407
|
+
;; Type bindings — \`var\` foreach: \`foreach (var u in xs)\`. Alias to
|
|
408
|
+
;; the iterable's identifier / chain so chain-follow unwraps
|
|
409
|
+
;; \`List<User>\` / \`Dictionary<K,V>.Values\` to the element type via
|
|
410
|
+
;; the generic-stripper in interpret.ts. Mirrors Python's for-loop
|
|
411
|
+
;; alias patterns.
|
|
412
|
+
(foreach_statement
|
|
413
|
+
type: (implicit_type)
|
|
414
|
+
left: (identifier) @type-binding.name
|
|
415
|
+
right: (identifier) @type-binding.type) @type-binding.alias
|
|
416
|
+
|
|
417
|
+
(foreach_statement
|
|
418
|
+
type: (implicit_type)
|
|
419
|
+
left: (identifier) @type-binding.name
|
|
420
|
+
right: (member_access_expression) @type-binding.type) @type-binding.alias
|
|
421
|
+
|
|
422
|
+
(foreach_statement
|
|
423
|
+
type: (implicit_type)
|
|
424
|
+
left: (identifier) @type-binding.name
|
|
425
|
+
right: (invocation_expression
|
|
426
|
+
function: (identifier) @type-binding.type)) @type-binding.alias
|
|
427
|
+
|
|
428
|
+
;; Return-type captures on method_declaration / property_declaration /
|
|
429
|
+
;; field_declaration are deferred — tree-sitter-c-sharp does not expose
|
|
430
|
+
;; the return/field type under a simple named field that pattern-matches
|
|
431
|
+
;; cleanly. When Unit 7's parity gate surfaces a gap requiring these
|
|
432
|
+
;; bindings, revisit with a positional pattern or a post-hoc lookup via
|
|
433
|
+
;; csharpMethodConfig.extractReturnType / csharpFieldConfig.extractType.
|
|
434
|
+
|
|
435
|
+
;; References — free calls: \`Foo()\`
|
|
436
|
+
(invocation_expression
|
|
437
|
+
function: (identifier) @reference.name) @reference.call.free
|
|
438
|
+
|
|
439
|
+
;; References — member calls: \`obj.Method()\`
|
|
440
|
+
;; \`(_)\` matches only named nodes in tree-sitter queries. \`this\` and
|
|
441
|
+
;; \`base\` are anonymous tokens in tree-sitter-c-sharp (unlike Python's
|
|
442
|
+
;; \`self\` which is a regular identifier), so they need explicit
|
|
443
|
+
;; patterns to emit a receiver capture.
|
|
444
|
+
(invocation_expression
|
|
445
|
+
function: (member_access_expression
|
|
446
|
+
expression: (_) @reference.receiver
|
|
447
|
+
name: (identifier) @reference.name)) @reference.call.member
|
|
448
|
+
|
|
449
|
+
(invocation_expression
|
|
450
|
+
function: (member_access_expression
|
|
451
|
+
expression: "this" @reference.receiver
|
|
452
|
+
name: (identifier) @reference.name)) @reference.call.member
|
|
453
|
+
|
|
454
|
+
(invocation_expression
|
|
455
|
+
function: (member_access_expression
|
|
456
|
+
expression: "base" @reference.receiver
|
|
457
|
+
name: (identifier) @reference.name)) @reference.call.member
|
|
458
|
+
|
|
459
|
+
;; References — null-conditional member calls: \`obj?.Method()\`
|
|
460
|
+
;; conditional_access_expression wraps a receiver followed by a
|
|
461
|
+
;; member_binding_expression. Capture the receiver explicitly so
|
|
462
|
+
;; receiver-bound resolution doesn't silently downgrade the call to
|
|
463
|
+
;; a free-call (which would misresolve to an imported \`Save\`).
|
|
464
|
+
;; tree-sitter-c-sharp doesn't expose named fields here, so use
|
|
465
|
+
;; positional wildcards.
|
|
466
|
+
(invocation_expression
|
|
467
|
+
function: (conditional_access_expression
|
|
468
|
+
(_) @reference.receiver
|
|
469
|
+
(member_binding_expression
|
|
470
|
+
(identifier) @reference.name))) @reference.call.member
|
|
471
|
+
|
|
472
|
+
;; References — constructor calls: \`new User(...)\`
|
|
473
|
+
(object_creation_expression
|
|
474
|
+
type: (identifier) @reference.name) @reference.call.constructor
|
|
475
|
+
|
|
476
|
+
(object_creation_expression
|
|
477
|
+
type: (generic_name
|
|
478
|
+
(identifier) @reference.name)) @reference.call.constructor
|
|
479
|
+
|
|
480
|
+
(object_creation_expression
|
|
481
|
+
type: (qualified_name) @reference.call.constructor.qualified) @reference.call.constructor
|
|
482
|
+
|
|
483
|
+
;; References — field/property writes: \`obj.Name = "x"\` emits a write
|
|
484
|
+
;; ACCESSES edge from the enclosing method to the field/property on
|
|
485
|
+
;; obj's class.
|
|
486
|
+
(assignment_expression
|
|
487
|
+
left: (member_access_expression
|
|
488
|
+
expression: (_) @reference.receiver
|
|
489
|
+
name: (identifier) @reference.name)) @reference.write.member
|
|
490
|
+
|
|
491
|
+
(assignment_expression
|
|
492
|
+
left: (member_access_expression
|
|
493
|
+
expression: "this" @reference.receiver
|
|
494
|
+
name: (identifier) @reference.name)) @reference.write.member
|
|
495
|
+
|
|
496
|
+
(assignment_expression
|
|
497
|
+
left: (member_access_expression
|
|
498
|
+
expression: "base" @reference.receiver
|
|
499
|
+
name: (identifier) @reference.name)) @reference.write.member
|
|
500
|
+
`;
|
|
501
|
+
let _parser = null;
|
|
502
|
+
let _query = null;
|
|
503
|
+
export function getCsharpParser() {
|
|
504
|
+
if (_parser === null) {
|
|
505
|
+
_parser = new Parser();
|
|
506
|
+
_parser.setLanguage(CSharp);
|
|
507
|
+
}
|
|
508
|
+
return _parser;
|
|
509
|
+
}
|
|
510
|
+
export function getCsharpScopeQuery() {
|
|
511
|
+
if (_query === null) {
|
|
512
|
+
_query = new Parser.Query(CSharp, CSHARP_SCOPE_QUERY);
|
|
513
|
+
}
|
|
514
|
+
return _query;
|
|
515
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synthesize `@type-binding.self` captures for C# instance methods —
|
|
3
|
+
* one for `this` (always on non-static methods inside a type
|
|
4
|
+
* declaration) and optionally one for `base` (only on class methods
|
|
5
|
+
* when the enclosing class has an explicit base in its `base_list`).
|
|
6
|
+
*
|
|
7
|
+
* Mirrors `languages/python/receiver-binding.ts` in structure. The
|
|
8
|
+
* tree-sitter-c-sharp grammar doesn't give us a clean `.scm` pattern
|
|
9
|
+
* for "this-receiver on every instance method inside an enclosing
|
|
10
|
+
* type" because the binding isn't a parameter — it's an implicit
|
|
11
|
+
* receiver. Synthesis in code is the same approach Python uses for
|
|
12
|
+
* `self` / `cls`.
|
|
13
|
+
*/
|
|
14
|
+
import type { CaptureMatch } from '../../../../_shared/index.js';
|
|
15
|
+
import { type SyntaxNode } from '../../utils/ast-helpers.js';
|
|
16
|
+
/**
|
|
17
|
+
* Build zero, one, or two `@type-binding.self` matches for `fnNode`:
|
|
18
|
+
*
|
|
19
|
+
* - Returns `null` if the function is free (no enclosing type),
|
|
20
|
+
* static, or the enclosing type has no resolvable name.
|
|
21
|
+
* - Returns one match (`this`) for non-static methods inside a
|
|
22
|
+
* class/struct/record/interface.
|
|
23
|
+
* - Returns two matches (`this` + `base`) only when the function
|
|
24
|
+
* lives in a `class_declaration` (or `record_declaration`) that has
|
|
25
|
+
* at least one base entry. Structs cannot inherit classes;
|
|
26
|
+
* interfaces cannot call `base.X`.
|
|
27
|
+
*
|
|
28
|
+
* The caller is responsible for guaranteeing
|
|
29
|
+
* `FUNCTION_NODE_TYPES.has(fnNode.type)`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function synthesizeCsharpReceiverBinding(fnNode: SyntaxNode): CaptureMatch[];
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synthesize `@type-binding.self` captures for C# instance methods —
|
|
3
|
+
* one for `this` (always on non-static methods inside a type
|
|
4
|
+
* declaration) and optionally one for `base` (only on class methods
|
|
5
|
+
* when the enclosing class has an explicit base in its `base_list`).
|
|
6
|
+
*
|
|
7
|
+
* Mirrors `languages/python/receiver-binding.ts` in structure. The
|
|
8
|
+
* tree-sitter-c-sharp grammar doesn't give us a clean `.scm` pattern
|
|
9
|
+
* for "this-receiver on every instance method inside an enclosing
|
|
10
|
+
* type" because the binding isn't a parameter — it's an implicit
|
|
11
|
+
* receiver. Synthesis in code is the same approach Python uses for
|
|
12
|
+
* `self` / `cls`.
|
|
13
|
+
*/
|
|
14
|
+
import { nodeToCapture, syntheticCapture } from '../../utils/ast-helpers.js';
|
|
15
|
+
const TYPE_DECL_NODE_TYPES = new Set([
|
|
16
|
+
'class_declaration',
|
|
17
|
+
'struct_declaration',
|
|
18
|
+
'record_declaration',
|
|
19
|
+
'interface_declaration',
|
|
20
|
+
]);
|
|
21
|
+
const FUNCTION_NODE_TYPES = new Set([
|
|
22
|
+
'method_declaration',
|
|
23
|
+
'constructor_declaration',
|
|
24
|
+
'destructor_declaration',
|
|
25
|
+
'operator_declaration',
|
|
26
|
+
'conversion_operator_declaration',
|
|
27
|
+
'local_function_statement',
|
|
28
|
+
]);
|
|
29
|
+
/** Walk up to the enclosing type declaration, stopping at any other
|
|
30
|
+
* function-like node (nested local functions shouldn't leak `this`
|
|
31
|
+
* from an outer class to an inner closure). */
|
|
32
|
+
function findEnclosingTypeDeclaration(node) {
|
|
33
|
+
let cur = node.parent;
|
|
34
|
+
while (cur !== null) {
|
|
35
|
+
if (TYPE_DECL_NODE_TYPES.has(cur.type))
|
|
36
|
+
return cur;
|
|
37
|
+
// A local function nested inside another method still sees `this`
|
|
38
|
+
// from the enclosing class — don't break on function-like nodes.
|
|
39
|
+
cur = cur.parent;
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
function typeName(typeNode) {
|
|
44
|
+
return typeNode.childForFieldName('name')?.text ?? null;
|
|
45
|
+
}
|
|
46
|
+
/** First entry in the type's `base_list`, read as raw text. C# allows
|
|
47
|
+
* generic and qualified bases (`Foo<T>`, `N.M.Base`); we keep the raw
|
|
48
|
+
* form so downstream interpret layer can strip generics/qualifiers
|
|
49
|
+
* the same way as other type-binding captures. Returns null when the
|
|
50
|
+
* type has no base (or an empty base_list). */
|
|
51
|
+
function firstBaseText(typeNode) {
|
|
52
|
+
for (let i = 0; i < typeNode.namedChildCount; i++) {
|
|
53
|
+
const child = typeNode.namedChild(i);
|
|
54
|
+
if (child === null || child.type !== 'base_list')
|
|
55
|
+
continue;
|
|
56
|
+
const firstBase = child.namedChild(0);
|
|
57
|
+
if (firstBase === null)
|
|
58
|
+
return null;
|
|
59
|
+
return firstBase.text;
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
function isStaticMethod(fnNode) {
|
|
64
|
+
// A `static` modifier appears as a named `modifier` child whose text
|
|
65
|
+
// is exactly "static". collectModifierTexts in field-extractors
|
|
66
|
+
// handles this, but duplicating the tiny scan here keeps the
|
|
67
|
+
// receiver-binding module dependency-free.
|
|
68
|
+
for (let i = 0; i < fnNode.namedChildCount; i++) {
|
|
69
|
+
const child = fnNode.namedChild(i);
|
|
70
|
+
if (child !== null && child.type === 'modifier' && child.text.trim() === 'static')
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build zero, one, or two `@type-binding.self` matches for `fnNode`:
|
|
77
|
+
*
|
|
78
|
+
* - Returns `null` if the function is free (no enclosing type),
|
|
79
|
+
* static, or the enclosing type has no resolvable name.
|
|
80
|
+
* - Returns one match (`this`) for non-static methods inside a
|
|
81
|
+
* class/struct/record/interface.
|
|
82
|
+
* - Returns two matches (`this` + `base`) only when the function
|
|
83
|
+
* lives in a `class_declaration` (or `record_declaration`) that has
|
|
84
|
+
* at least one base entry. Structs cannot inherit classes;
|
|
85
|
+
* interfaces cannot call `base.X`.
|
|
86
|
+
*
|
|
87
|
+
* The caller is responsible for guaranteeing
|
|
88
|
+
* `FUNCTION_NODE_TYPES.has(fnNode.type)`.
|
|
89
|
+
*/
|
|
90
|
+
export function synthesizeCsharpReceiverBinding(fnNode) {
|
|
91
|
+
if (!FUNCTION_NODE_TYPES.has(fnNode.type))
|
|
92
|
+
return [];
|
|
93
|
+
if (isStaticMethod(fnNode))
|
|
94
|
+
return [];
|
|
95
|
+
const enclosingType = findEnclosingTypeDeclaration(fnNode);
|
|
96
|
+
if (enclosingType === null)
|
|
97
|
+
return [];
|
|
98
|
+
const enclosingName = typeName(enclosingType);
|
|
99
|
+
if (enclosingName === null)
|
|
100
|
+
return [];
|
|
101
|
+
// Anchor the synthesized captures to a node clearly *inside* the
|
|
102
|
+
// function's scope (not at the method's start position, which maps
|
|
103
|
+
// to the enclosing class scope via positionIndex). The method's
|
|
104
|
+
// `body` field is the block statement — its range is guaranteed to
|
|
105
|
+
// be inside the function scope. If the method has no body (interface
|
|
106
|
+
// declaration, `abstract`), skip — there's no function scope to
|
|
107
|
+
// attach the binding to.
|
|
108
|
+
const anchorNode = fnNode.childForFieldName('body');
|
|
109
|
+
if (anchorNode === null)
|
|
110
|
+
return [];
|
|
111
|
+
const out = [];
|
|
112
|
+
out.push(buildReceiverMatch(anchorNode, 'this', enclosingName));
|
|
113
|
+
// `base` applies only to class / record methods with an explicit
|
|
114
|
+
// base class. `struct` can't inherit a class; `interface` can't
|
|
115
|
+
// call `base.X`. The first entry of `base_list` is the base class
|
|
116
|
+
// (interfaces follow); we can't statically distinguish the two here,
|
|
117
|
+
// but `base.X` only compiles when the first entry IS a class, so we
|
|
118
|
+
// trust the source — if the user wrote `base.X` in a class with
|
|
119
|
+
// interface-only bases, their code wouldn't compile anyway.
|
|
120
|
+
if (enclosingType.type === 'class_declaration' || enclosingType.type === 'record_declaration') {
|
|
121
|
+
const baseText = firstBaseText(enclosingType);
|
|
122
|
+
if (baseText !== null) {
|
|
123
|
+
out.push(buildReceiverMatch(anchorNode, 'base', baseText));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
function buildReceiverMatch(anchorNode, name, typeText) {
|
|
129
|
+
const m = {
|
|
130
|
+
'@type-binding.self': nodeToCapture('@type-binding.self', anchorNode),
|
|
131
|
+
'@type-binding.name': syntheticCapture('@type-binding.name', anchorNode, name),
|
|
132
|
+
'@type-binding.type': syntheticCapture('@type-binding.type', anchorNode, typeText),
|
|
133
|
+
};
|
|
134
|
+
return m;
|
|
135
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C# `ScopeResolver` registered in `SCOPE_RESOLVERS` and consumed by
|
|
3
|
+
* the generic `runScopeResolution` orchestrator (RFC #909 Ring 3).
|
|
4
|
+
*
|
|
5
|
+
* Second migration after Python — see `pythonScopeResolver` for the
|
|
6
|
+
* canonical shape.
|
|
7
|
+
*/
|
|
8
|
+
import type { ScopeResolver } from '../../scope-resolution/contract/scope-resolver.js';
|
|
9
|
+
declare const csharpScopeResolver: ScopeResolver;
|
|
10
|
+
export { csharpScopeResolver };
|