@lzehrung/codegraph 2.3.29 → 2.3.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.js +5982 -4145
- package/dist/bin/query-index-worker.js +1302 -753
- package/dist/document-links/asciidoc.d.ts.map +1 -1
- package/dist/document-links/asciidoc.js +3 -4
- package/dist/document-links/asciidoc.js.map +1 -1
- package/dist/document-links/html-forms.d.ts +39 -0
- package/dist/document-links/html-forms.d.ts.map +1 -0
- package/dist/document-links/html-forms.js +94 -0
- package/dist/document-links/html-forms.js.map +1 -0
- package/dist/document-links/html.d.ts +8 -0
- package/dist/document-links/html.d.ts.map +1 -1
- package/dist/document-links/html.js +30 -15
- package/dist/document-links/html.js.map +1 -1
- package/dist/document-links/markdown.d.ts.map +1 -1
- package/dist/document-links/markdown.js +6 -7
- package/dist/document-links/markdown.js.map +1 -1
- package/dist/document-links/rst.d.ts.map +1 -1
- package/dist/document-links/rst.js +6 -0
- package/dist/document-links/rst.js.map +1 -1
- package/dist/document-links/sfc.d.ts.map +1 -1
- package/dist/document-links/sfc.js +4 -4
- package/dist/document-links/sfc.js.map +1 -1
- package/dist/graphs/angularjs.d.ts.map +1 -1
- package/dist/graphs/angularjs.js +9 -1
- package/dist/graphs/angularjs.js.map +1 -1
- package/dist/graphs/edge-resolution.d.ts.map +1 -1
- package/dist/graphs/edge-resolution.js +8 -3
- package/dist/graphs/edge-resolution.js.map +1 -1
- package/dist/graphs/specifiers.d.ts.map +1 -1
- package/dist/graphs/specifiers.js +62 -104
- package/dist/graphs/specifiers.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed/edge-passes.js +118 -86
- package/dist/graphs/symbol-graph-detailed/edge-passes.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts +34 -0
- package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed/receiver-calls.js +525 -25
- package/dist/graphs/symbol-graph-detailed/receiver-calls.js.map +1 -1
- package/dist/impact/call-compatibility/providers/index.d.ts +3 -1
- package/dist/impact/call-compatibility/providers/index.d.ts.map +1 -1
- package/dist/impact/call-compatibility/providers/index.js +11 -4
- package/dist/impact/call-compatibility/providers/index.js.map +1 -1
- package/dist/impact/call-compatibility.d.ts.map +1 -1
- package/dist/impact/call-compatibility.js +2 -7
- package/dist/impact/call-compatibility.js.map +1 -1
- package/dist/impact/member-resolution-coverage.js +2 -2
- package/dist/impact/member-resolution-coverage.js.map +1 -1
- package/dist/indexer/build-cache/manifest.d.ts +7 -0
- package/dist/indexer/build-cache/manifest.d.ts.map +1 -1
- package/dist/indexer/build-cache/manifest.js +32 -1
- package/dist/indexer/build-cache/manifest.js.map +1 -1
- package/dist/indexer/build-cache/options.d.ts +16 -2
- package/dist/indexer/build-cache/options.d.ts.map +1 -1
- package/dist/indexer/build-cache/options.js +17 -3
- package/dist/indexer/build-cache/options.js.map +1 -1
- package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
- package/dist/indexer/build-cache/project-snapshot.js +1 -0
- package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
- package/dist/indexer/build-index.d.ts.map +1 -1
- package/dist/indexer/build-index.js +80 -2
- package/dist/indexer/build-index.js.map +1 -1
- package/dist/indexer/build-manifest.d.ts +1 -0
- package/dist/indexer/build-manifest.d.ts.map +1 -1
- package/dist/indexer/build-manifest.js +18 -0
- package/dist/indexer/build-manifest.js.map +1 -1
- package/dist/indexer/build-workers.js +1 -1
- package/dist/indexer/build-workers.js.map +1 -1
- package/dist/indexer/declaration-visibility.d.ts +43 -0
- package/dist/indexer/declaration-visibility.d.ts.map +1 -0
- package/dist/indexer/declaration-visibility.js +202 -0
- package/dist/indexer/declaration-visibility.js.map +1 -0
- package/dist/indexer/imports/binding-ranges.d.ts +1 -1
- package/dist/indexer/imports/binding-ranges.d.ts.map +1 -1
- package/dist/indexer/imports/binding-ranges.js +2 -123
- package/dist/indexer/imports/binding-ranges.js.map +1 -1
- package/dist/indexer/imports/js-text-imports.d.ts.map +1 -1
- package/dist/indexer/imports/js-text-imports.js +5 -2
- package/dist/indexer/imports/js-text-imports.js.map +1 -1
- package/dist/indexer/imports/language-specific.d.ts.map +1 -1
- package/dist/indexer/imports/language-specific.js +30 -216
- package/dist/indexer/imports/language-specific.js.map +1 -1
- package/dist/indexer/imports/native-captures.d.ts.map +1 -1
- package/dist/indexer/imports/native-captures.js +23 -32
- package/dist/indexer/imports/native-captures.js.map +1 -1
- package/dist/indexer/imports/text-import-extractors.d.ts +37 -0
- package/dist/indexer/imports/text-import-extractors.d.ts.map +1 -0
- package/dist/indexer/imports/text-import-extractors.js +358 -0
- package/dist/indexer/imports/text-import-extractors.js.map +1 -0
- package/dist/indexer/locals-and-exports.d.ts.map +1 -1
- package/dist/indexer/locals-and-exports.js +23 -27
- package/dist/indexer/locals-and-exports.js.map +1 -1
- package/dist/indexer/navigation-goto.d.ts +1 -7
- package/dist/indexer/navigation-goto.d.ts.map +1 -1
- package/dist/indexer/navigation-goto.js +180 -381
- package/dist/indexer/navigation-goto.js.map +1 -1
- package/dist/indexer/navigation-resolve.d.ts.map +1 -1
- package/dist/indexer/navigation-resolve.js +20 -1
- package/dist/indexer/navigation-resolve.js.map +1 -1
- package/dist/indexer/navigation.d.ts.map +1 -1
- package/dist/indexer/navigation.js +39 -7
- package/dist/indexer/navigation.js.map +1 -1
- package/dist/indexer/parse-context.js +2 -2
- package/dist/indexer/parse-context.js.map +1 -1
- package/dist/indexer/scope-nodes.d.ts +108 -0
- package/dist/indexer/scope-nodes.d.ts.map +1 -0
- package/dist/indexer/scope-nodes.js +238 -0
- package/dist/indexer/scope-nodes.js.map +1 -0
- package/dist/indexer/scope.d.ts.map +1 -1
- package/dist/indexer/scope.js +70 -130
- package/dist/indexer/scope.js.map +1 -1
- package/dist/indexer/types.d.ts +7 -0
- package/dist/indexer/types.d.ts.map +1 -1
- package/dist/languages/definitions/c-family.d.ts +18 -4
- package/dist/languages/definitions/c-family.d.ts.map +1 -1
- package/dist/languages/definitions/c-family.js +51 -13
- package/dist/languages/definitions/c-family.js.map +1 -1
- package/dist/languages/definitions/c.d.ts.map +1 -1
- package/dist/languages/definitions/c.js +7 -43
- package/dist/languages/definitions/c.js.map +1 -1
- package/dist/languages/definitions/cpp.d.ts.map +1 -1
- package/dist/languages/definitions/cpp.js +15 -61
- package/dist/languages/definitions/cpp.js.map +1 -1
- package/dist/languages/definitions/csharp.d.ts.map +1 -1
- package/dist/languages/definitions/csharp.js +46 -52
- package/dist/languages/definitions/csharp.js.map +1 -1
- package/dist/languages/definitions/css-like.d.ts.map +1 -1
- package/dist/languages/definitions/css-like.js +13 -10
- package/dist/languages/definitions/css-like.js.map +1 -1
- package/dist/languages/definitions/go.d.ts.map +1 -1
- package/dist/languages/definitions/go.js +29 -42
- package/dist/languages/definitions/go.js.map +1 -1
- package/dist/languages/definitions/html.d.ts.map +1 -1
- package/dist/languages/definitions/html.js +15 -14
- package/dist/languages/definitions/html.js.map +1 -1
- package/dist/languages/definitions/java.d.ts.map +1 -1
- package/dist/languages/definitions/java.js +42 -48
- package/dist/languages/definitions/java.js.map +1 -1
- package/dist/languages/definitions/javascript.d.ts.map +1 -1
- package/dist/languages/definitions/javascript.js +26 -54
- package/dist/languages/definitions/javascript.js.map +1 -1
- package/dist/languages/definitions/js-family.d.ts +15 -1
- package/dist/languages/definitions/js-family.d.ts.map +1 -1
- package/dist/languages/definitions/js-family.js +51 -0
- package/dist/languages/definitions/js-family.js.map +1 -1
- package/dist/languages/definitions/kotlin.d.ts.map +1 -1
- package/dist/languages/definitions/kotlin.js +26 -43
- package/dist/languages/definitions/kotlin.js.map +1 -1
- package/dist/languages/definitions/php.d.ts.map +1 -1
- package/dist/languages/definitions/php.js +50 -60
- package/dist/languages/definitions/php.js.map +1 -1
- package/dist/languages/definitions/python.d.ts.map +1 -1
- package/dist/languages/definitions/python.js +23 -14
- package/dist/languages/definitions/python.js.map +1 -1
- package/dist/languages/definitions/ruby.d.ts.map +1 -1
- package/dist/languages/definitions/ruby.js +14 -17
- package/dist/languages/definitions/ruby.js.map +1 -1
- package/dist/languages/definitions/rust.d.ts.map +1 -1
- package/dist/languages/definitions/rust.js +30 -52
- package/dist/languages/definitions/rust.js.map +1 -1
- package/dist/languages/definitions/scss.d.ts.map +1 -1
- package/dist/languages/definitions/scss.js +33 -49
- package/dist/languages/definitions/scss.js.map +1 -1
- package/dist/languages/definitions/sfc-graph.d.ts +4 -0
- package/dist/languages/definitions/sfc-graph.d.ts.map +1 -0
- package/dist/languages/definitions/sfc-graph.js +16 -0
- package/dist/languages/definitions/sfc-graph.js.map +1 -0
- package/dist/languages/definitions/shared.d.ts +33 -0
- package/dist/languages/definitions/shared.d.ts.map +1 -0
- package/dist/languages/definitions/shared.js +63 -0
- package/dist/languages/definitions/shared.js.map +1 -0
- package/dist/languages/definitions/sql.d.ts.map +1 -1
- package/dist/languages/definitions/sql.js +1 -0
- package/dist/languages/definitions/sql.js.map +1 -1
- package/dist/languages/definitions/svelte.d.ts.map +1 -1
- package/dist/languages/definitions/svelte.js +2 -10
- package/dist/languages/definitions/svelte.js.map +1 -1
- package/dist/languages/definitions/swift.d.ts.map +1 -1
- package/dist/languages/definitions/swift.js +37 -31
- package/dist/languages/definitions/swift.js.map +1 -1
- package/dist/languages/definitions/typescript.d.ts.map +1 -1
- package/dist/languages/definitions/typescript.js +56 -90
- package/dist/languages/definitions/typescript.js.map +1 -1
- package/dist/languages/definitions/vue.d.ts.map +1 -1
- package/dist/languages/definitions/vue.js +2 -10
- package/dist/languages/definitions/vue.js.map +1 -1
- package/dist/languages/definitions/zig.d.ts.map +1 -1
- package/dist/languages/definitions/zig.js +9 -15
- package/dist/languages/definitions/zig.js.map +1 -1
- package/dist/languages/graph-captures.d.ts +40 -0
- package/dist/languages/graph-captures.d.ts.map +1 -0
- package/dist/languages/graph-captures.js +46 -0
- package/dist/languages/graph-captures.js.map +1 -0
- package/dist/languages/import-statement-parsers.d.ts +17 -0
- package/dist/languages/import-statement-parsers.d.ts.map +1 -1
- package/dist/languages/import-statement-parsers.js +108 -0
- package/dist/languages/import-statement-parsers.js.map +1 -1
- package/dist/languages/js-family.d.ts +2 -0
- package/dist/languages/js-family.d.ts.map +1 -1
- package/dist/languages/js-family.js +15 -6
- package/dist/languages/js-family.js.map +1 -1
- package/dist/languages/types.d.ts +4 -0
- package/dist/languages/types.d.ts.map +1 -1
- package/dist/languages/types.js +1 -1
- package/dist/languages/types.js.map +1 -1
- package/dist/languages.js +1 -1
- package/dist/languages.js.map +1 -1
- package/dist/native/contracts.d.ts +1 -1
- package/dist/native/contracts.d.ts.map +1 -1
- package/dist/native/js-bridge.d.ts +10 -0
- package/dist/native/js-bridge.d.ts.map +1 -1
- package/dist/native/js-bridge.js +10 -0
- package/dist/native/js-bridge.js.map +1 -1
- package/dist/native/native-backend-report.d.ts.map +1 -1
- package/dist/native/native-backend-report.js +2 -0
- package/dist/native/native-backend-report.js.map +1 -1
- package/dist/util/comments.d.ts +7 -7
- package/dist/util/comments.d.ts.map +1 -1
- package/dist/util/comments.js +15 -214
- package/dist/util/comments.js.map +1 -1
- package/dist/util/lines.d.ts.map +1 -1
- package/dist/util/lines.js +4 -1
- package/dist/util/lines.js.map +1 -1
- package/dist/util/member-access.d.ts +2 -0
- package/dist/util/member-access.d.ts.map +1 -1
- package/dist/util/member-access.js +18 -5
- package/dist/util/member-access.js.map +1 -1
- package/dist/util/paths.d.ts +4 -0
- package/dist/util/paths.d.ts.map +1 -1
- package/dist/util/paths.js +26 -0
- package/dist/util/paths.js.map +1 -1
- package/dist/util/project-files.js +1 -1
- package/dist/util/project-files.js.map +1 -1
- package/dist/util/resolution/cargo-targets.d.ts.map +1 -1
- package/dist/util/resolution/cargo-targets.js +17 -14
- package/dist/util/resolution/cargo-targets.js.map +1 -1
- package/dist/util/resolution/cpp.d.ts +6 -0
- package/dist/util/resolution/cpp.d.ts.map +1 -0
- package/dist/util/resolution/cpp.js +69 -0
- package/dist/util/resolution/cpp.js.map +1 -0
- package/dist/util/resolution/csharp.d.ts +4 -3
- package/dist/util/resolution/csharp.d.ts.map +1 -1
- package/dist/util/resolution/csharp.js +27 -113
- package/dist/util/resolution/csharp.js.map +1 -1
- package/dist/util/resolution/files.d.ts +6 -0
- package/dist/util/resolution/files.d.ts.map +1 -1
- package/dist/util/resolution/files.js +108 -4
- package/dist/util/resolution/files.js.map +1 -1
- package/dist/util/resolution/go.d.ts +1 -0
- package/dist/util/resolution/go.d.ts.map +1 -1
- package/dist/util/resolution/go.js +4 -3
- package/dist/util/resolution/go.js.map +1 -1
- package/dist/util/resolution/jvm.d.ts +3 -3
- package/dist/util/resolution/jvm.d.ts.map +1 -1
- package/dist/util/resolution/jvm.js +90 -54
- package/dist/util/resolution/jvm.js.map +1 -1
- package/dist/util/resolution/node.js +2 -2
- package/dist/util/resolution/node.js.map +1 -1
- package/dist/util/resolution/php-composer.d.ts.map +1 -1
- package/dist/util/resolution/php-composer.js +8 -7
- package/dist/util/resolution/php-composer.js.map +1 -1
- package/dist/util/resolution/php.d.ts.map +1 -1
- package/dist/util/resolution/php.js +30 -43
- package/dist/util/resolution/php.js.map +1 -1
- package/dist/util/resolution/project-symbols.d.ts +5 -7
- package/dist/util/resolution/project-symbols.d.ts.map +1 -1
- package/dist/util/resolution/project-symbols.js +23 -9
- package/dist/util/resolution/project-symbols.js.map +1 -1
- package/dist/util/resolution/python.d.ts.map +1 -1
- package/dist/util/resolution/python.js +107 -62
- package/dist/util/resolution/python.js.map +1 -1
- package/dist/util/resolution/rust.d.ts.map +1 -1
- package/dist/util/resolution/rust.js +45 -34
- package/dist/util/resolution/rust.js.map +1 -1
- package/dist/util/resolution/tsconfig.d.ts.map +1 -1
- package/dist/util/resolution/tsconfig.js +3 -9
- package/dist/util/resolution/tsconfig.js.map +1 -1
- package/dist/util/resolution-candidates.d.ts +5 -1
- package/dist/util/resolution-candidates.d.ts.map +1 -1
- package/dist/util/resolution-candidates.js +18 -0
- package/dist/util/resolution-candidates.js.map +1 -1
- package/dist/util/resolution.d.ts.map +1 -1
- package/dist/util/resolution.js +93 -49
- package/dist/util/resolution.js.map +1 -1
- package/dist/util/specifiers.d.ts +4 -10
- package/dist/util/specifiers.d.ts.map +1 -1
- package/dist/util/specifiers.js +213 -164
- package/dist/util/specifiers.js.map +1 -1
- package/dist/util/trivia-tables.d.ts +69 -0
- package/dist/util/trivia-tables.d.ts.map +1 -0
- package/dist/util/trivia-tables.js +186 -0
- package/dist/util/trivia-tables.js.map +1 -0
- package/dist/util/trivia.d.ts +24 -0
- package/dist/util/trivia.d.ts.map +1 -0
- package/dist/util/trivia.js +621 -0
- package/dist/util/trivia.js.map +1 -0
- package/dist/util.d.ts +1 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +1 -1
- package/dist/util.js.map +1 -1
- package/dist/worker/native-extract-worker.d.ts.map +1 -1
- package/dist/worker/native-extract-worker.js +4 -4
- package/dist/worker/native-extract-worker.js.map +1 -1
- package/package.json +3 -3
|
@@ -2,29 +2,32 @@ import { isJsTsLanguage } from "../languages/js-family.js";
|
|
|
2
2
|
import { isPythonReceiverAttributeAssignmentName } from "../languages/definitions/python.js";
|
|
3
3
|
import { sliceText } from "../util/ast.js";
|
|
4
4
|
import { fileIdentityKey } from "../util/paths.js";
|
|
5
|
-
import { getMemberAccessParts, getNavigationExpressionProperty, isMemberAccessNode, memberAccessTraversalTypes, } from "../util/member-access.js";
|
|
6
|
-
import {
|
|
5
|
+
import { getMemberAccessParts, getNavigationExpressionProperty, isMemberAccessNode, isReceiverNameNode, memberAccessTraversalTypes, } from "../util/member-access.js";
|
|
6
|
+
import { declaresMembers, hasStaticMemberDistinction, isKeywordReceiver, nearestMemberContainer, receiverConstructorExpression, supportsReceiverMemberNavigation, unwrapNamedType, } from "../graphs/symbol-graph-detailed/receiver-calls.js";
|
|
7
7
|
import { ensureParsedContext } from "./parse-context.js";
|
|
8
8
|
import { okGoToResult } from "./navigation-provenance.js";
|
|
9
9
|
import { resolveExport, resolveImported } from "./navigation-resolve.js";
|
|
10
10
|
import { SymbolKind, } from "./types.js";
|
|
11
|
-
const RUBY_CONSTANT_SOURCE = String.raw `(?=\p{Lu})${XID_IDENTIFIER_SOURCE}`;
|
|
12
|
-
const CSHARP_CONSTANT_SOURCE = String.raw `(?=@?\p{Lu})${CSHARP_IDENTIFIER_SOURCE}`;
|
|
13
|
-
const JAVA_CONSTANT_SOURCE = String.raw `(?=\p{Lu})${JAVA_IDENTIFIER_SOURCE}`;
|
|
14
|
-
const RUST_CONSTANT_SOURCE = String.raw `(?=\p{Lu})${XID_IDENTIFIER_SOURCE}`;
|
|
15
|
-
const IDENTIFIER_BOUNDARY_SOURCE = String.raw `[$_\p{ID_Continue}\u200c\u200d]`;
|
|
16
11
|
export async function resolveMemberAccessDefinition(params) {
|
|
17
12
|
const { index, mod, node, source, sup, resolveLexicalBinding } = params;
|
|
18
13
|
const parent = node.parent;
|
|
19
|
-
if (!parent || !sup.supportsCrossModuleSymbols
|
|
14
|
+
if (!parent || !sup.supportsCrossModuleSymbols) {
|
|
20
15
|
return null;
|
|
21
16
|
}
|
|
22
|
-
|
|
17
|
+
let memberNode = null;
|
|
18
|
+
if (isMemberAccessNode(sup, parent)) {
|
|
19
|
+
memberNode = parent;
|
|
20
|
+
}
|
|
21
|
+
else if (parent.parent && isMemberAccessNode(sup, parent.parent)) {
|
|
22
|
+
memberNode = parent.parent;
|
|
23
|
+
}
|
|
24
|
+
if (!memberNode)
|
|
25
|
+
return null;
|
|
23
26
|
const { object: obj, property: prop } = getMemberAccessParts(sup, memberNode);
|
|
24
27
|
const optionalMemberTypes = memberAccessTraversalTypes(sup);
|
|
25
28
|
const resolveExpression = async (expr) => {
|
|
26
|
-
const exprIsId = sup
|
|
27
|
-
if (exprIsId
|
|
29
|
+
const exprIsId = isReceiverNameNode(sup, expr.type) && !isMemberAccessNode(sup, expr);
|
|
30
|
+
if (exprIsId) {
|
|
28
31
|
const lexicalBinding = resolveLexicalBinding?.(expr);
|
|
29
32
|
if (lexicalBinding)
|
|
30
33
|
return { kind: "resolved", def: lexicalBinding };
|
|
@@ -130,10 +133,8 @@ export async function resolveMemberAccessDefinition(params) {
|
|
|
130
133
|
}
|
|
131
134
|
}
|
|
132
135
|
const receiverName = obj ? sliceText(obj, source) : "";
|
|
133
|
-
const implicitClassReceiver = (
|
|
134
|
-
|
|
135
|
-
(sup.id === "rust" && /^(?:self|Self)$/.test(receiverName));
|
|
136
|
-
if (obj && prop && node.id === prop.id && (supportsReceiverMemberResolution(sup.id) || implicitClassReceiver)) {
|
|
136
|
+
const implicitClassReceiver = isKeywordReceiver(sup.id, receiverName);
|
|
137
|
+
if (obj && prop && node.id === prop.id && (supportsReceiverMemberNavigation(sup.id) || implicitClassReceiver)) {
|
|
137
138
|
const member = sliceText(prop, source);
|
|
138
139
|
if (sup.id === "python") {
|
|
139
140
|
const memberDef = await resolvePythonReceiverMember(index, mod, node, obj, member, source, sup, resolveExpression);
|
|
@@ -158,7 +159,7 @@ export async function resolveMemberAccessDefinition(params) {
|
|
|
158
159
|
});
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
|
-
const receiver = await resolveReceiverDefinition(obj, source, sup, resolveExpression);
|
|
162
|
+
const receiver = await resolveReceiverDefinition(obj, source, sup, resolveExpression, mod);
|
|
162
163
|
if (receiver) {
|
|
163
164
|
const objDef = receiver.def;
|
|
164
165
|
const targetContext = await ensureParsedContext(objDef.file, undefined, index.languageExtensions);
|
|
@@ -180,12 +181,12 @@ export async function resolveMemberAccessDefinition(params) {
|
|
|
180
181
|
const targetModule = index.byFile.get(fileIdentityKey(objDef.file));
|
|
181
182
|
if (targetModule) {
|
|
182
183
|
const normalizeIdentifier = targetContext.sup.normalizeIdentifier;
|
|
184
|
+
const memberPredicate = receiver.memberScope === "any"
|
|
185
|
+
? undefined
|
|
186
|
+
: (local) => matchesReceiverMemberScope(local, receiver.memberScope, targetContext, container);
|
|
183
187
|
let memberDef;
|
|
184
|
-
if (receiver.runtimeTypeOnly) {
|
|
185
|
-
memberDef = findDirectLocalWithinNode(targetModule.locals, member, container, targetContext, normalizeIdentifier);
|
|
186
|
-
}
|
|
187
|
-
else if (targetContext.sup.id === "java") {
|
|
188
|
-
memberDef = findDirectLocalWithinNode(targetModule.locals, member, container, targetContext, normalizeIdentifier);
|
|
188
|
+
if (receiver.runtimeTypeOnly || targetContext.sup.id === "java") {
|
|
189
|
+
memberDef = findDirectLocalWithinNode(targetModule.locals, member, container, targetContext, normalizeIdentifier, memberPredicate);
|
|
189
190
|
}
|
|
190
191
|
else {
|
|
191
192
|
memberDef = findReceiverMemberDefinition(targetModule.locals, member, objDef, container, targetContext, normalizeIdentifier, receiver.memberScope);
|
|
@@ -204,49 +205,47 @@ export async function resolveMemberAccessDefinition(params) {
|
|
|
204
205
|
return null;
|
|
205
206
|
}
|
|
206
207
|
function findEnclosingClassContainer(node) {
|
|
207
|
-
|
|
208
|
-
while (current) {
|
|
209
|
-
if (current.type === "class_declaration" ||
|
|
210
|
-
current.type === "abstract_class_declaration" ||
|
|
211
|
-
current.type === "class_definition" ||
|
|
212
|
-
current.type === "impl_item") {
|
|
213
|
-
return current;
|
|
214
|
-
}
|
|
215
|
-
current = current.parent;
|
|
216
|
-
}
|
|
217
|
-
return null;
|
|
208
|
+
return nearestMemberContainer(node);
|
|
218
209
|
}
|
|
219
|
-
export
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
languageId === "java" ||
|
|
224
|
-
languageId === "javascript" ||
|
|
225
|
-
languageId === "jsx" ||
|
|
226
|
-
languageId === "rust" ||
|
|
227
|
-
languageId === "ts" ||
|
|
228
|
-
languageId === "typescript" ||
|
|
229
|
-
languageId === "tsx");
|
|
210
|
+
export { supportsReceiverCallEdges, supportsReceiverMemberNavigation, } from "../graphs/symbol-graph-detailed/receiver-calls.js";
|
|
211
|
+
function memberDeclaringLocals(mod, typeName, normalize) {
|
|
212
|
+
const normalized = normalize(typeName);
|
|
213
|
+
return mod.locals.filter((local) => normalize(local.localName) === normalized && declaresMembers(local));
|
|
230
214
|
}
|
|
231
|
-
async function resolveReceiverDefinition(obj, source, sup, resolveExpression) {
|
|
215
|
+
async function resolveReceiverDefinition(obj, source, sup, resolveExpression, mod) {
|
|
232
216
|
const constructor = receiverConstructorExpression(obj, source, sup);
|
|
233
217
|
if (constructor) {
|
|
218
|
+
const typeName = sliceText(constructor, source);
|
|
219
|
+
const typedLocals = memberDeclaringLocals(mod, typeName, sup.normalizeIdentifier);
|
|
220
|
+
if (typedLocals.length === 1) {
|
|
221
|
+
return {
|
|
222
|
+
def: typedLocals[0],
|
|
223
|
+
memberScope: hasStaticMemberDistinction(sup.id) ? "instance" : "any",
|
|
224
|
+
};
|
|
225
|
+
}
|
|
234
226
|
const result = await resolveExpression(constructor);
|
|
235
|
-
if (result?.kind === "resolved") {
|
|
227
|
+
if (result?.kind === "resolved" && declaresMembers(result.def)) {
|
|
236
228
|
return {
|
|
237
229
|
def: result.def,
|
|
238
|
-
memberScope:
|
|
230
|
+
memberScope: hasStaticMemberDistinction(sup.id) ? "instance" : "any",
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
if (typedLocals[0]) {
|
|
234
|
+
return {
|
|
235
|
+
def: typedLocals[0],
|
|
236
|
+
memberScope: hasStaticMemberDistinction(sup.id) ? "instance" : "any",
|
|
239
237
|
};
|
|
240
238
|
}
|
|
241
239
|
}
|
|
242
240
|
const direct = await resolveExpression(obj);
|
|
243
|
-
if (
|
|
244
|
-
if (
|
|
245
|
-
return { def: direct.def, memberScope: "static" };
|
|
246
|
-
}
|
|
247
|
-
if (direct?.kind === "resolved" && direct.def.kind === SymbolKind.TypeAlias) {
|
|
241
|
+
if (direct?.kind === "resolved" && declaresMembers(direct.def)) {
|
|
242
|
+
if (isJsTsLanguage(sup.id) && direct.def.kind === SymbolKind.TypeAlias) {
|
|
248
243
|
return { def: direct.def, memberScope: "any", runtimeTypeOnly: true };
|
|
249
244
|
}
|
|
245
|
+
const memberScope = hasStaticMemberDistinction(sup.id) ? "static" : "any";
|
|
246
|
+
return { def: direct.def, memberScope };
|
|
247
|
+
}
|
|
248
|
+
if (isJsTsLanguage(sup.id) && isReceiverNameNode(sup, obj.type)) {
|
|
250
249
|
return null;
|
|
251
250
|
}
|
|
252
251
|
if (direct?.kind === "resolved") {
|
|
@@ -254,320 +253,6 @@ async function resolveReceiverDefinition(obj, source, sup, resolveExpression) {
|
|
|
254
253
|
}
|
|
255
254
|
return null;
|
|
256
255
|
}
|
|
257
|
-
/**
|
|
258
|
-
* Resolves the node naming the type a receiver expression was constructed from, or
|
|
259
|
-
* null when no constructor is proven for it. Shared with detailed symbol-graph call
|
|
260
|
-
* extraction so `goto` and resolved `calls` edges accept the same receiver forms.
|
|
261
|
-
*/
|
|
262
|
-
export function receiverConstructorExpression(obj, source, sup) {
|
|
263
|
-
if (obj.type === "new_expression" || obj.type === "object_creation_expression") {
|
|
264
|
-
return constructorNameNode(obj, sup);
|
|
265
|
-
}
|
|
266
|
-
if (sup.id === "ruby" && obj.type === "call") {
|
|
267
|
-
const rubyConstructor = rubyNewReceiverNameNode(obj, source, sup);
|
|
268
|
-
if (rubyConstructor)
|
|
269
|
-
return rubyConstructor;
|
|
270
|
-
}
|
|
271
|
-
if (!sup.nodeTypes.identifier.includes(obj.type)) {
|
|
272
|
-
return null;
|
|
273
|
-
}
|
|
274
|
-
const receiverName = sliceText(obj, source);
|
|
275
|
-
return findVisiblePriorNewConstructor(obj, receiverName, source, sup);
|
|
276
|
-
}
|
|
277
|
-
function constructorNameNode(node, sup) {
|
|
278
|
-
const constructor = node.childForFieldName("constructor") ?? node.child(0);
|
|
279
|
-
if (constructor && sup.nodeTypes.identifier.includes(constructor.type)) {
|
|
280
|
-
return constructor;
|
|
281
|
-
}
|
|
282
|
-
for (const child of node.namedChildren) {
|
|
283
|
-
if (sup.nodeTypes.identifier.includes(child.type) ||
|
|
284
|
-
child.type === "type_identifier" ||
|
|
285
|
-
child.type === "constant") {
|
|
286
|
-
return child;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
return null;
|
|
290
|
-
}
|
|
291
|
-
function rubyNewReceiverNameNode(node, source, sup) {
|
|
292
|
-
if (!new RegExp(String.raw `^(?:${RUBY_CONSTANT_SOURCE})\.new$`, "u").test(sliceText(node, source)))
|
|
293
|
-
return null;
|
|
294
|
-
return (node.namedChildren.find((child) => sup.nodeTypes.identifier.includes(child.type) || child.type === "constant") ??
|
|
295
|
-
null);
|
|
296
|
-
}
|
|
297
|
-
function rootOf(node) {
|
|
298
|
-
let current = node;
|
|
299
|
-
while (current.parent) {
|
|
300
|
-
current = current.parent;
|
|
301
|
-
}
|
|
302
|
-
return current;
|
|
303
|
-
}
|
|
304
|
-
const BINDING_CONTAINER_TYPES = new Set([
|
|
305
|
-
"program",
|
|
306
|
-
"compilation_unit",
|
|
307
|
-
"source_file",
|
|
308
|
-
"statement_block",
|
|
309
|
-
"block",
|
|
310
|
-
"function_declaration",
|
|
311
|
-
"function_item",
|
|
312
|
-
"function_definition",
|
|
313
|
-
"function",
|
|
314
|
-
"function_expression",
|
|
315
|
-
"arrow_function",
|
|
316
|
-
"method_definition",
|
|
317
|
-
"method_declaration",
|
|
318
|
-
"method",
|
|
319
|
-
]);
|
|
320
|
-
const BINDING_DECLARATION_TYPES = new Set([
|
|
321
|
-
"variable_declarator",
|
|
322
|
-
"let_declaration",
|
|
323
|
-
"assignment",
|
|
324
|
-
"formal_parameter",
|
|
325
|
-
"required_parameter",
|
|
326
|
-
"optional_parameter",
|
|
327
|
-
"parameter_declaration",
|
|
328
|
-
"short_var_declaration",
|
|
329
|
-
"var_spec",
|
|
330
|
-
]);
|
|
331
|
-
function findVisiblePriorNewConstructor(receiver, receiverName, source, sup) {
|
|
332
|
-
let current = receiver;
|
|
333
|
-
while (current) {
|
|
334
|
-
if (BINDING_CONTAINER_TYPES.has(current.type)) {
|
|
335
|
-
const constructor = findPriorNewConstructorInContainer(current, receiver, receiverName, source, sup);
|
|
336
|
-
if (constructor || bindingContainerDeclaresNameBefore(current, receiver, receiverName, source, sup)) {
|
|
337
|
-
return constructor;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
current = current.parent;
|
|
341
|
-
}
|
|
342
|
-
return findPriorNewConstructorInContainer(rootOf(receiver), receiver, receiverName, source, sup);
|
|
343
|
-
}
|
|
344
|
-
function findPriorNewConstructorInContainer(node, receiver, receiverName, source, sup) {
|
|
345
|
-
let constructor = null;
|
|
346
|
-
const visit = (current) => {
|
|
347
|
-
if (current.startIndex >= receiver.startIndex) {
|
|
348
|
-
return true;
|
|
349
|
-
}
|
|
350
|
-
if (current !== node && isSkippableBindingContainer(current, receiver)) {
|
|
351
|
-
return true;
|
|
352
|
-
}
|
|
353
|
-
if (current.type === "variable_declarator") {
|
|
354
|
-
const name = current.childForFieldName("name") ?? current.child(0);
|
|
355
|
-
const value = current.childForFieldName("value");
|
|
356
|
-
if (name &&
|
|
357
|
-
value &&
|
|
358
|
-
(value.type === "new_expression" ||
|
|
359
|
-
value.type === "object_creation_expression" ||
|
|
360
|
-
sup.nodeTypes.identifier.includes(value.type)) &&
|
|
361
|
-
sup.nodeTypes.identifier.includes(name.type) &&
|
|
362
|
-
sliceText(name, source) === receiverName) {
|
|
363
|
-
const candidate = constructorNameNode(value, sup);
|
|
364
|
-
if (!candidate) {
|
|
365
|
-
return true;
|
|
366
|
-
}
|
|
367
|
-
if (constructor && sliceText(constructor, source) !== sliceText(candidate, source)) {
|
|
368
|
-
constructor = null;
|
|
369
|
-
return false;
|
|
370
|
-
}
|
|
371
|
-
constructor = candidate;
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
if (current.type === "assignment" || current.type === "let_declaration") {
|
|
375
|
-
const candidate = constructorFromAssignmentLike(current, receiverName, source, sup);
|
|
376
|
-
if (candidate) {
|
|
377
|
-
if (constructor && sliceText(constructor, source) !== sliceText(candidate, source)) {
|
|
378
|
-
constructor = null;
|
|
379
|
-
return false;
|
|
380
|
-
}
|
|
381
|
-
constructor = candidate;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
if (current.type === "local_variable_declaration" ||
|
|
385
|
-
current.type === "local_declaration_statement" ||
|
|
386
|
-
current.type === "variable_declaration") {
|
|
387
|
-
const candidate = constructorFromTypedLocalDeclaration(current, receiverName, source, sup);
|
|
388
|
-
if (candidate) {
|
|
389
|
-
if (constructor && sliceText(constructor, source) !== sliceText(candidate, source)) {
|
|
390
|
-
constructor = null;
|
|
391
|
-
return false;
|
|
392
|
-
}
|
|
393
|
-
constructor = candidate;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
if (sup.id === "go" && (current.type === "short_var_declaration" || current.type === "var_spec")) {
|
|
397
|
-
const candidate = constructorFromGoBinding(current, receiverName, source, sup);
|
|
398
|
-
if (candidate) {
|
|
399
|
-
if (constructor && sliceText(constructor, source) !== sliceText(candidate, source)) {
|
|
400
|
-
constructor = null;
|
|
401
|
-
return false;
|
|
402
|
-
}
|
|
403
|
-
constructor = candidate;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
for (const child of current.namedChildren) {
|
|
407
|
-
if (!visit(child)) {
|
|
408
|
-
return false;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
return true;
|
|
412
|
-
};
|
|
413
|
-
visit(node);
|
|
414
|
-
return constructor;
|
|
415
|
-
}
|
|
416
|
-
function constructorFromTypedLocalDeclaration(node, receiverName, source, sup) {
|
|
417
|
-
if (sup.id !== "csharp" && sup.id !== "java")
|
|
418
|
-
return null;
|
|
419
|
-
const text = sliceText(node, source);
|
|
420
|
-
const typeNameSource = sup.id === "java" ? JAVA_CONSTANT_SOURCE : CSHARP_CONSTANT_SOURCE;
|
|
421
|
-
const match = text.match(new RegExp(String.raw `^\s*(${typeNameSource})\s+${escapeRegExp(receiverName)}\s*=\s*new\s+(${typeNameSource})(?![\p{L}\p{Nl}\p{Sc}\p{Pc}\p{Nd}\p{Mn}\p{Mc}\p{Cf}])`, "u"));
|
|
422
|
-
const typeName = match?.[2] ?? match?.[1];
|
|
423
|
-
return typeName ? findNamedChildText(node, typeName, source, sup) : null;
|
|
424
|
-
}
|
|
425
|
-
function bindingContainerDeclaresNameBefore(node, receiver, receiverName, source, sup) {
|
|
426
|
-
const visit = (current) => {
|
|
427
|
-
if (current.startIndex >= receiver.startIndex) {
|
|
428
|
-
return false;
|
|
429
|
-
}
|
|
430
|
-
if (current !== node && isSkippableBindingContainer(current, receiver)) {
|
|
431
|
-
return false;
|
|
432
|
-
}
|
|
433
|
-
if (BINDING_DECLARATION_TYPES.has(current.type)) {
|
|
434
|
-
if (goBindingDeclaresName(current, receiverName, source, sup))
|
|
435
|
-
return true;
|
|
436
|
-
const name = current.childForFieldName("name") ?? current.child(0);
|
|
437
|
-
if (name && sup.nodeTypes.identifier.includes(name.type) && sliceText(name, source) === receiverName) {
|
|
438
|
-
return true;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
for (const child of current.namedChildren) {
|
|
442
|
-
if (visit(child)) {
|
|
443
|
-
return true;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
return false;
|
|
447
|
-
};
|
|
448
|
-
return visit(node);
|
|
449
|
-
}
|
|
450
|
-
function isSkippableBindingContainer(node, receiver) {
|
|
451
|
-
return BINDING_CONTAINER_TYPES.has(node.type) && !nodeContainsIndex(node, receiver.startIndex);
|
|
452
|
-
}
|
|
453
|
-
function nodeContainsIndex(node, index) {
|
|
454
|
-
return node.startIndex <= index && node.endIndex >= index;
|
|
455
|
-
}
|
|
456
|
-
function constructorFromAssignmentLike(node, receiverName, source, sup) {
|
|
457
|
-
const text = sliceText(node, source);
|
|
458
|
-
if (!new RegExp(String.raw `(?<!${IDENTIFIER_BOUNDARY_SOURCE})${escapeRegExp(receiverName)}(?!${IDENTIFIER_BOUNDARY_SOURCE})`, "u").test(text))
|
|
459
|
-
return null;
|
|
460
|
-
if (sup.id === "ruby") {
|
|
461
|
-
const match = text.match(new RegExp(String.raw `^\s*${escapeRegExp(receiverName)}\s*=\s*(${RUBY_CONSTANT_SOURCE})\.new(?!${IDENTIFIER_BOUNDARY_SOURCE})`, "u"));
|
|
462
|
-
if (!match?.[1])
|
|
463
|
-
return null;
|
|
464
|
-
return findNamedChildText(node, match[1], source, sup);
|
|
465
|
-
}
|
|
466
|
-
if (sup.id === "rust") {
|
|
467
|
-
const match = text.match(new RegExp(String.raw `^\s*(?:let\s+)?${escapeRegExp(receiverName)}\s*=\s*(${RUST_CONSTANT_SOURCE})(?!${IDENTIFIER_BOUNDARY_SOURCE})`, "u"));
|
|
468
|
-
if (!match?.[1])
|
|
469
|
-
return null;
|
|
470
|
-
return findNamedChildText(node, match[1], source, sup);
|
|
471
|
-
}
|
|
472
|
-
if (sup.id === "python") {
|
|
473
|
-
return pythonConstructorFromAssignment(node, receiverName, source, sup);
|
|
474
|
-
}
|
|
475
|
-
return null;
|
|
476
|
-
}
|
|
477
|
-
function goBindingNameNodes(node) {
|
|
478
|
-
if (node.type === "short_var_declaration") {
|
|
479
|
-
const left = node.childForFieldName("left");
|
|
480
|
-
return (left?.namedChildren ?? []).filter((child) => child.type === "identifier");
|
|
481
|
-
}
|
|
482
|
-
if (node.type === "var_spec") {
|
|
483
|
-
return (node.namedChildren ?? []).filter((child) => child.type === "identifier");
|
|
484
|
-
}
|
|
485
|
-
return [];
|
|
486
|
-
}
|
|
487
|
-
function goBindingDeclaresName(node, receiverName, source, sup) {
|
|
488
|
-
if (sup.id !== "go")
|
|
489
|
-
return false;
|
|
490
|
-
return goBindingNameNodes(node).some((name) => sliceText(name, source) === receiverName);
|
|
491
|
-
}
|
|
492
|
-
function constructorFromGoBinding(node, receiverName, source, sup) {
|
|
493
|
-
if (!goBindingDeclaresName(node, receiverName, source, sup))
|
|
494
|
-
return null;
|
|
495
|
-
if (node.type === "short_var_declaration") {
|
|
496
|
-
const left = node.childForFieldName("left");
|
|
497
|
-
const right = node.childForFieldName("right");
|
|
498
|
-
if (!left || !right)
|
|
499
|
-
return null;
|
|
500
|
-
const names = (left.namedChildren ?? []).filter((child) => child.type === "identifier");
|
|
501
|
-
const values = right.namedChildren ?? [];
|
|
502
|
-
const index = names.findIndex((name) => sliceText(name, source) === receiverName);
|
|
503
|
-
if (index < 0)
|
|
504
|
-
return null;
|
|
505
|
-
const value = values[index] ?? null;
|
|
506
|
-
return value ? goCompositeLiteralTypeName(value, source) : null;
|
|
507
|
-
}
|
|
508
|
-
if (node.type !== "var_spec")
|
|
509
|
-
return null;
|
|
510
|
-
const value = node.childForFieldName("value");
|
|
511
|
-
if (value) {
|
|
512
|
-
const first = value.type === "expression_list" ? (value.namedChildren[0] ?? null) : value;
|
|
513
|
-
const fromValue = first ? goCompositeLiteralTypeName(first, source) : null;
|
|
514
|
-
if (fromValue)
|
|
515
|
-
return fromValue;
|
|
516
|
-
}
|
|
517
|
-
const typeNode = node.childForFieldName("type");
|
|
518
|
-
return typeNode ? unwrapGoConstructorType(typeNode) : null;
|
|
519
|
-
}
|
|
520
|
-
function goCompositeLiteralTypeName(expr, source) {
|
|
521
|
-
let current = expr;
|
|
522
|
-
if (current.type === "unary_expression") {
|
|
523
|
-
const operand = current.childForFieldName("operand");
|
|
524
|
-
if (!operand)
|
|
525
|
-
return null;
|
|
526
|
-
const operator = current.childForFieldName("operator");
|
|
527
|
-
let isAddr = sliceText(current, source).startsWith("&");
|
|
528
|
-
if (operator)
|
|
529
|
-
isAddr = sliceText(operator, source) === "&";
|
|
530
|
-
if (!isAddr)
|
|
531
|
-
return null;
|
|
532
|
-
current = operand;
|
|
533
|
-
}
|
|
534
|
-
if (current.type !== "composite_literal")
|
|
535
|
-
return null;
|
|
536
|
-
const typeNode = current.childForFieldName("type");
|
|
537
|
-
return typeNode ? unwrapGoConstructorType(typeNode) : null;
|
|
538
|
-
}
|
|
539
|
-
function unwrapGoConstructorType(node) {
|
|
540
|
-
let current = node;
|
|
541
|
-
while (current) {
|
|
542
|
-
if (current.type === "parenthesized_type" || current.type === "pointer_type") {
|
|
543
|
-
current = current.namedChildren[0] ?? null;
|
|
544
|
-
continue;
|
|
545
|
-
}
|
|
546
|
-
if (current.type === "generic_type") {
|
|
547
|
-
current = current.childForFieldName("type") ?? current.namedChildren[0] ?? null;
|
|
548
|
-
continue;
|
|
549
|
-
}
|
|
550
|
-
break;
|
|
551
|
-
}
|
|
552
|
-
return current?.type === "type_identifier" ? current : null;
|
|
553
|
-
}
|
|
554
|
-
function findNamedChildText(node, name, source, sup) {
|
|
555
|
-
const isNameNode = (candidate) => (sup.nodeTypes.identifier.includes(candidate.type) ||
|
|
556
|
-
candidate.type === "type_identifier" ||
|
|
557
|
-
candidate.type === "constant") &&
|
|
558
|
-
sliceText(candidate, source) === name;
|
|
559
|
-
const visit = (current) => {
|
|
560
|
-
if (isNameNode(current))
|
|
561
|
-
return current;
|
|
562
|
-
for (const child of current.namedChildren) {
|
|
563
|
-
const hit = visit(child);
|
|
564
|
-
if (hit)
|
|
565
|
-
return hit;
|
|
566
|
-
}
|
|
567
|
-
return null;
|
|
568
|
-
};
|
|
569
|
-
return visit(node);
|
|
570
|
-
}
|
|
571
256
|
async function resolveMemberDefinitionForBase(index, baseDef, member) {
|
|
572
257
|
const targetContext = await ensureParsedContext(baseDef.file, undefined, index.languageExtensions);
|
|
573
258
|
const start = baseDef.range.start;
|
|
@@ -593,16 +278,20 @@ async function resolveMemberDefinitionForBase(index, baseDef, member) {
|
|
|
593
278
|
function findReceiverMemberDefinition(locals, member, receiverDef, container, targetContext, normalizeIdentifier, memberScope = "any") {
|
|
594
279
|
const memberPredicate = memberScope === "any"
|
|
595
280
|
? undefined
|
|
596
|
-
: (local) =>
|
|
281
|
+
: (local) => matchesReceiverMemberScope(local, memberScope, targetContext, container);
|
|
597
282
|
const containerHit = memberScope === "any"
|
|
598
283
|
? findLocalWithinNode(locals, member, container, normalizeIdentifier)
|
|
599
284
|
: findDirectLocalWithinNode(locals, member, container, targetContext, normalizeIdentifier, memberPredicate);
|
|
600
285
|
if (containerHit)
|
|
601
286
|
return containerHit;
|
|
602
|
-
if (targetContext.sup.id
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
287
|
+
if (targetContext.sup.id === "rust") {
|
|
288
|
+
const implNode = findRustImplForType(targetContext.tree.rootNode, receiverDef.localName, targetContext.source);
|
|
289
|
+
return implNode ? findLocalWithinNode(locals, member, implNode, normalizeIdentifier) : undefined;
|
|
290
|
+
}
|
|
291
|
+
if (targetContext.sup.id === "go") {
|
|
292
|
+
return findGoReceiverMember(locals, member, receiverDef.localName, targetContext, normalizeIdentifier);
|
|
293
|
+
}
|
|
294
|
+
return undefined;
|
|
606
295
|
}
|
|
607
296
|
function findLocalWithinNode(locals, member, node, normalizeIdentifier = (name) => name, predicate) {
|
|
608
297
|
const containerStart = node.startIndex;
|
|
@@ -619,6 +308,28 @@ function findLocalWithinNode(locals, member, node, normalizeIdentifier = (name)
|
|
|
619
308
|
(!predicate || predicate(local)));
|
|
620
309
|
});
|
|
621
310
|
}
|
|
311
|
+
function matchesReceiverMemberScope(local, memberScope, targetContext, container) {
|
|
312
|
+
if (memberScope === "any")
|
|
313
|
+
return true;
|
|
314
|
+
return hasStaticModifier(local, targetContext, container) === (memberScope === "static");
|
|
315
|
+
}
|
|
316
|
+
function nodeDeclaresStatic(node, source) {
|
|
317
|
+
if (node.type === "static" || node.type === "static_modifier")
|
|
318
|
+
return true;
|
|
319
|
+
if (node.type === "storage_class_specifier" || node.type === "modifier" || node.type === "property_modifier") {
|
|
320
|
+
return sliceText(node, source).trim() === "static";
|
|
321
|
+
}
|
|
322
|
+
if (node.type === "modifiers") {
|
|
323
|
+
for (let childIndex = 0;; childIndex += 1) {
|
|
324
|
+
const child = node.child(childIndex);
|
|
325
|
+
if (!child)
|
|
326
|
+
break;
|
|
327
|
+
if (nodeDeclaresStatic(child, source))
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
622
333
|
function hasStaticModifier(local, targetContext, container) {
|
|
623
334
|
const position = {
|
|
624
335
|
row: local.range.start.line - 1,
|
|
@@ -630,7 +341,7 @@ function hasStaticModifier(local, targetContext, container) {
|
|
|
630
341
|
const child = current.child(childIndex);
|
|
631
342
|
if (!child)
|
|
632
343
|
break;
|
|
633
|
-
if (child.
|
|
344
|
+
if (nodeDeclaresStatic(child, targetContext.source))
|
|
634
345
|
return true;
|
|
635
346
|
}
|
|
636
347
|
current = current.parent;
|
|
@@ -713,18 +424,106 @@ function findRustImplForType(root, typeName, source) {
|
|
|
713
424
|
visit(root);
|
|
714
425
|
return found;
|
|
715
426
|
}
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
}
|
|
721
|
-
const right = node.childForFieldName("right");
|
|
722
|
-
if (!right || right.type !== "call")
|
|
427
|
+
const GO_EMBED_DEPTH = 16;
|
|
428
|
+
function goMethodReceiverTypeName(methodNode, source, sup) {
|
|
429
|
+
const receiver = methodNode.childForFieldName("receiver");
|
|
430
|
+
if (!receiver)
|
|
723
431
|
return null;
|
|
724
|
-
const
|
|
725
|
-
|
|
432
|
+
const parameter = receiver.namedChildren.find((child) => child.type === "parameter_declaration") ?? receiver.namedChildren[0] ?? null;
|
|
433
|
+
const typeNode = parameter?.childForFieldName("type") ?? null;
|
|
434
|
+
if (!typeNode)
|
|
726
435
|
return null;
|
|
727
|
-
|
|
436
|
+
const named = unwrapNamedType(typeNode, sup);
|
|
437
|
+
return named ? sliceText(named, source) : null;
|
|
438
|
+
}
|
|
439
|
+
function goTypeSpecNamed(root, typeName, source, normalizeIdentifier) {
|
|
440
|
+
const normalized = normalizeIdentifier(typeName);
|
|
441
|
+
let found = null;
|
|
442
|
+
const visit = (node) => {
|
|
443
|
+
if (node.type === "type_spec") {
|
|
444
|
+
const name = node.childForFieldName("name");
|
|
445
|
+
if (name && normalizeIdentifier(sliceText(name, source)) === normalized) {
|
|
446
|
+
found = node;
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
for (const child of node.namedChildren) {
|
|
451
|
+
if (!visit(child))
|
|
452
|
+
return false;
|
|
453
|
+
}
|
|
454
|
+
return true;
|
|
455
|
+
};
|
|
456
|
+
visit(root);
|
|
457
|
+
return found;
|
|
458
|
+
}
|
|
459
|
+
function goEmbeddedTypeNames(typeName, targetContext, normalizeIdentifier) {
|
|
460
|
+
const spec = goTypeSpecNamed(targetContext.tree.rootNode, typeName, targetContext.source, normalizeIdentifier);
|
|
461
|
+
if (!spec)
|
|
462
|
+
return [];
|
|
463
|
+
const typeNode = spec.childForFieldName("type");
|
|
464
|
+
if (!typeNode)
|
|
465
|
+
return [];
|
|
466
|
+
const names = [];
|
|
467
|
+
const visit = (node) => {
|
|
468
|
+
if (node.type === "field_declaration") {
|
|
469
|
+
if (node.childForFieldName("name"))
|
|
470
|
+
return;
|
|
471
|
+
const fieldType = node.childForFieldName("type");
|
|
472
|
+
const named = fieldType ? unwrapNamedType(fieldType, targetContext.sup) : null;
|
|
473
|
+
if (named)
|
|
474
|
+
names.push(sliceText(named, targetContext.source));
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
for (const child of node.namedChildren)
|
|
478
|
+
visit(child);
|
|
479
|
+
};
|
|
480
|
+
visit(typeNode);
|
|
481
|
+
return names;
|
|
482
|
+
}
|
|
483
|
+
function goMethodsNamedOnType(locals, member, typeName, targetContext, normalizeIdentifier) {
|
|
484
|
+
const matches = [];
|
|
485
|
+
const visit = (node) => {
|
|
486
|
+
if (node.type === "method_declaration") {
|
|
487
|
+
const receiverType = goMethodReceiverTypeName(node, targetContext.source, targetContext.sup);
|
|
488
|
+
if (receiverType && normalizeIdentifier(receiverType) === normalizeIdentifier(typeName)) {
|
|
489
|
+
const local = findLocalWithinNode(locals, member, node, normalizeIdentifier);
|
|
490
|
+
if (local && !matches.includes(local))
|
|
491
|
+
matches.push(local);
|
|
492
|
+
}
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
for (const child of node.namedChildren)
|
|
496
|
+
visit(child);
|
|
497
|
+
};
|
|
498
|
+
visit(targetContext.tree.rootNode);
|
|
499
|
+
return matches;
|
|
500
|
+
}
|
|
501
|
+
function findGoReceiverMember(locals, member, typeName, targetContext, normalizeIdentifier) {
|
|
502
|
+
const visited = new Set();
|
|
503
|
+
let level = [typeName];
|
|
504
|
+
for (let depth = 0; depth < GO_EMBED_DEPTH && level.length; depth += 1) {
|
|
505
|
+
const matches = [];
|
|
506
|
+
const next = [];
|
|
507
|
+
for (const currentType of level) {
|
|
508
|
+
if (visited.has(currentType))
|
|
509
|
+
continue;
|
|
510
|
+
visited.add(currentType);
|
|
511
|
+
for (const method of goMethodsNamedOnType(locals, member, currentType, targetContext, normalizeIdentifier)) {
|
|
512
|
+
if (!matches.includes(method))
|
|
513
|
+
matches.push(method);
|
|
514
|
+
}
|
|
515
|
+
for (const embedded of goEmbeddedTypeNames(currentType, targetContext, normalizeIdentifier)) {
|
|
516
|
+
if (!visited.has(embedded) && !next.includes(embedded))
|
|
517
|
+
next.push(embedded);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
if (matches.length === 1)
|
|
521
|
+
return matches[0];
|
|
522
|
+
if (matches.length > 1)
|
|
523
|
+
return undefined;
|
|
524
|
+
level = next;
|
|
525
|
+
}
|
|
526
|
+
return undefined;
|
|
728
527
|
}
|
|
729
528
|
const PYTHON_SUPERTYPE_DEPTH = 16;
|
|
730
529
|
function pythonClassKey(def) {
|