homegraph 1.1.3 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -18
- package/dist/arkts/ohos-api-index.d.ts +15 -0
- package/dist/arkts/ohos-api-index.d.ts.map +1 -0
- package/dist/arkts/ohos-api-index.js +190 -0
- package/dist/arkts/ohos-api-index.js.map +1 -0
- package/dist/arkts/ohos-sdk-input.d.ts +36 -0
- package/dist/arkts/ohos-sdk-input.d.ts.map +1 -0
- package/dist/arkts/ohos-sdk-input.js +214 -0
- package/dist/arkts/ohos-sdk-input.js.map +1 -0
- package/dist/bin/command-supervision.d.ts +12 -0
- package/dist/bin/command-supervision.d.ts.map +1 -0
- package/dist/bin/command-supervision.js +86 -0
- package/dist/bin/command-supervision.js.map +1 -0
- package/dist/bin/homegraph.d.ts +1 -1
- package/dist/bin/homegraph.js +706 -168
- package/dist/bin/homegraph.js.map +1 -1
- package/dist/db/index.d.ts +20 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +39 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +40 -1
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/queries.d.ts +14 -0
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +174 -3
- package/dist/db/queries.js.map +1 -1
- package/dist/db/schema.sql +20 -0
- package/dist/directory.d.ts +32 -0
- package/dist/directory.d.ts.map +1 -1
- package/dist/directory.js +83 -0
- package/dist/directory.js.map +1 -1
- package/dist/extraction/arkts-batch-worker.d.ts +2 -0
- package/dist/extraction/arkts-batch-worker.d.ts.map +1 -0
- package/dist/extraction/arkts-batch-worker.js +28 -0
- package/dist/extraction/arkts-batch-worker.js.map +1 -0
- package/dist/extraction/context.d.ts +11 -0
- package/dist/extraction/context.d.ts.map +1 -1
- package/dist/extraction/context.js +20 -0
- package/dist/extraction/context.js.map +1 -1
- package/dist/extraction/index.d.ts +16 -2
- package/dist/extraction/index.d.ts.map +1 -1
- package/dist/extraction/index.js +619 -380
- package/dist/extraction/index.js.map +1 -1
- package/dist/extraction/languages/arkts-state-decorators.d.ts +13 -0
- package/dist/extraction/languages/arkts-state-decorators.d.ts.map +1 -0
- package/dist/extraction/languages/arkts-state-decorators.js +26 -0
- package/dist/extraction/languages/arkts-state-decorators.js.map +1 -0
- package/dist/extraction/languages/arkts-viewtree.d.ts +4 -2
- package/dist/extraction/languages/arkts-viewtree.d.ts.map +1 -1
- package/dist/extraction/languages/arkts-viewtree.js +21 -6
- package/dist/extraction/languages/arkts-viewtree.js.map +1 -1
- package/dist/extraction/languages/arkts.d.ts +98 -2
- package/dist/extraction/languages/arkts.d.ts.map +1 -1
- package/dist/extraction/languages/arkts.js +1290 -61
- package/dist/extraction/languages/arkts.js.map +1 -1
- package/dist/extraction/languages/c-cpp.d.ts +56 -0
- package/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/dist/extraction/languages/c-cpp.js +198 -1
- package/dist/extraction/languages/c-cpp.js.map +1 -1
- package/dist/extraction/languages/ohos-api-consumer.d.ts +34 -0
- package/dist/extraction/languages/ohos-api-consumer.d.ts.map +1 -0
- package/dist/extraction/languages/ohos-api-consumer.js +283 -0
- package/dist/extraction/languages/ohos-api-consumer.js.map +1 -0
- package/dist/extraction/parse-pool.d.ts +126 -0
- package/dist/extraction/parse-pool.d.ts.map +1 -0
- package/dist/extraction/parse-pool.js +319 -0
- package/dist/extraction/parse-pool.js.map +1 -0
- package/dist/extraction/tree-sitter-types.d.ts +17 -0
- package/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.d.ts +21 -0
- package/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.js +198 -27
- package/dist/extraction/tree-sitter.js.map +1 -1
- package/dist/graph/traversal.d.ts.map +1 -1
- package/dist/graph/traversal.js +76 -17
- package/dist/graph/traversal.js.map +1 -1
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +78 -4
- package/dist/index.js.map +1 -1
- package/dist/mcp/daemon-paths.d.ts +30 -3
- package/dist/mcp/daemon-paths.d.ts.map +1 -1
- package/dist/mcp/daemon-paths.js +50 -10
- package/dist/mcp/daemon-paths.js.map +1 -1
- package/dist/mcp/daemon-registry.d.ts.map +1 -1
- package/dist/mcp/daemon-registry.js +7 -3
- package/dist/mcp/daemon-registry.js.map +1 -1
- package/dist/mcp/daemon.d.ts +48 -0
- package/dist/mcp/daemon.d.ts.map +1 -1
- package/dist/mcp/daemon.js +196 -32
- package/dist/mcp/daemon.js.map +1 -1
- package/dist/mcp/engine.d.ts +17 -0
- package/dist/mcp/engine.d.ts.map +1 -1
- package/dist/mcp/engine.js +73 -1
- package/dist/mcp/engine.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +25 -43
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/ppid-watchdog.d.ts +18 -0
- package/dist/mcp/ppid-watchdog.d.ts.map +1 -1
- package/dist/mcp/ppid-watchdog.js +37 -0
- package/dist/mcp/ppid-watchdog.js.map +1 -1
- package/dist/mcp/query-cache.d.ts +25 -0
- package/dist/mcp/query-cache.d.ts.map +1 -0
- package/dist/mcp/query-cache.js +191 -0
- package/dist/mcp/query-cache.js.map +1 -0
- package/dist/mcp/query-pool.d.ts +94 -0
- package/dist/mcp/query-pool.d.ts.map +1 -0
- package/dist/mcp/query-pool.js +297 -0
- package/dist/mcp/query-pool.js.map +1 -0
- package/dist/mcp/query-worker.d.ts +24 -0
- package/dist/mcp/query-worker.d.ts.map +1 -0
- package/dist/mcp/query-worker.js +87 -0
- package/dist/mcp/query-worker.js.map +1 -0
- package/dist/mcp/server-instructions.d.ts +5 -7
- package/dist/mcp/server-instructions.d.ts.map +1 -1
- package/dist/mcp/server-instructions.js +12 -14
- package/dist/mcp/server-instructions.js.map +1 -1
- package/dist/mcp/tools.d.ts +77 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +696 -60
- package/dist/mcp/tools.js.map +1 -1
- package/dist/project-config.d.ts +20 -0
- package/dist/project-config.d.ts.map +1 -1
- package/dist/project-config.js +42 -2
- package/dist/project-config.js.map +1 -1
- package/dist/reasoning/login.js +1 -1
- package/dist/reasoning/login.js.map +1 -1
- package/dist/resolution/c-fnptr-synthesizer.d.ts +0 -28
- package/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
- package/dist/resolution/c-fnptr-synthesizer.js +765 -79
- package/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
- package/dist/resolution/callback-synthesizer.d.ts +1 -1
- package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/dist/resolution/callback-synthesizer.js +72 -11
- package/dist/resolution/callback-synthesizer.js.map +1 -1
- package/dist/resolution/cooperative-yield.d.ts +32 -0
- package/dist/resolution/cooperative-yield.d.ts.map +1 -0
- package/dist/resolution/cooperative-yield.js +42 -0
- package/dist/resolution/cooperative-yield.js.map +1 -0
- package/dist/resolution/index.d.ts +11 -2
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +72 -4
- package/dist/resolution/index.js.map +1 -1
- package/dist/resolution/name-matcher.d.ts +22 -0
- package/dist/resolution/name-matcher.d.ts.map +1 -1
- package/dist/resolution/name-matcher.js +317 -20
- package/dist/resolution/name-matcher.js.map +1 -1
- package/dist/spec/config.d.ts +7 -11
- package/dist/spec/config.d.ts.map +1 -1
- package/dist/spec/config.js +77 -48
- package/dist/spec/config.js.map +1 -1
- package/dist/spec/db/fragment-node.d.ts +1 -0
- package/dist/spec/db/fragment-node.d.ts.map +1 -1
- package/dist/spec/db/fragment-node.js +8 -0
- package/dist/spec/db/fragment-node.js.map +1 -1
- package/dist/spec/db/fts.d.ts +14 -0
- package/dist/spec/db/fts.d.ts.map +1 -1
- package/dist/spec/db/fts.js +43 -4
- package/dist/spec/db/fts.js.map +1 -1
- package/dist/spec/db/schema.d.ts +6 -3
- package/dist/spec/db/schema.d.ts.map +1 -1
- package/dist/spec/db/schema.js +36 -4
- package/dist/spec/db/schema.js.map +1 -1
- package/dist/spec/db/schema.sql +11 -1
- package/dist/spec/evolve/logic-checker.d.ts +2 -2
- package/dist/spec/evolve/logic-checker.d.ts.map +1 -1
- package/dist/spec/evolve/logic-checker.js +3 -27
- package/dist/spec/evolve/logic-checker.js.map +1 -1
- package/dist/spec/evolve/pipeline.d.ts +21 -19
- package/dist/spec/evolve/pipeline.d.ts.map +1 -1
- package/dist/spec/evolve/pipeline.js +284 -31
- package/dist/spec/evolve/pipeline.js.map +1 -1
- package/dist/spec/evolve/spec-rewriter.d.ts +2 -2
- package/dist/spec/evolve/spec-rewriter.d.ts.map +1 -1
- package/dist/spec/evolve/spec-rewriter.js +7 -31
- package/dist/spec/evolve/spec-rewriter.js.map +1 -1
- package/dist/spec/graph/queries.d.ts +97 -0
- package/dist/spec/graph/queries.d.ts.map +1 -1
- package/dist/spec/graph/queries.js +225 -0
- package/dist/spec/graph/queries.js.map +1 -1
- package/dist/spec/llm/client.d.ts +29 -0
- package/dist/spec/llm/client.d.ts.map +1 -0
- package/dist/spec/llm/client.js +123 -0
- package/dist/spec/llm/client.js.map +1 -0
- package/dist/spec/llm/index.d.ts +3 -0
- package/dist/spec/llm/index.d.ts.map +1 -0
- package/dist/spec/llm/index.js +11 -0
- package/dist/spec/llm/index.js.map +1 -0
- package/dist/spec/llm/prompts.d.ts +13 -0
- package/dist/spec/llm/prompts.d.ts.map +1 -0
- package/dist/spec/llm/prompts.js +75 -0
- package/dist/spec/llm/prompts.js.map +1 -0
- package/dist/spec/mining/git-scanner.d.ts +12 -0
- package/dist/spec/mining/git-scanner.d.ts.map +1 -1
- package/dist/spec/mining/git-scanner.js +41 -0
- package/dist/spec/mining/git-scanner.js.map +1 -1
- package/dist/spec/mining/pipeline.d.ts.map +1 -1
- package/dist/spec/mining/pipeline.js +14 -1
- package/dist/spec/mining/pipeline.js.map +1 -1
- package/dist/spec/utils.d.ts +2 -1
- package/dist/spec/utils.d.ts.map +1 -1
- package/dist/spec/utils.js +3 -1
- package/dist/spec/utils.js.map +1 -1
- package/dist/sync/worktree.d.ts +9 -0
- package/dist/sync/worktree.d.ts.map +1 -1
- package/dist/sync/worktree.js +40 -0
- package/dist/sync/worktree.js.map +1 -1
- package/dist/types.d.ts +6 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/shimmer-progress.d.ts +2 -0
- package/dist/ui/shimmer-progress.d.ts.map +1 -1
- package/dist/ui/shimmer-progress.js +19 -2
- package/dist/ui/shimmer-progress.js.map +1 -1
- package/dist/upgrade/index.js +1 -1
- package/dist/upgrade/index.js.map +1 -1
- package/package.json +3 -3
- package/scripts/agent-eval/repro-concurrent-explore.mjs +119 -0
- package/scripts/agent-eval/repro-daemon-clients.mjs +125 -0
- package/scripts/exp_boundary_eval/README.md +247 -0
- package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/deveco_arm.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/setup.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/_test_mcp_chain.py +78 -0
- package/scripts/exp_boundary_eval/_test_stdin.py +8 -0
- package/scripts/exp_boundary_eval/_utils.py +1116 -0
- package/scripts/exp_boundary_eval/analyze.py +1313 -0
- package/scripts/exp_boundary_eval/data/agents.json +109 -0
- package/scripts/exp_boundary_eval/data/experiments.json +140 -0
- package/scripts/exp_boundary_eval/deveco_arm.py +519 -0
- package/scripts/exp_boundary_eval/run_all.py +378 -0
- package/scripts/exp_boundary_eval/run_one.py +165 -0
- package/scripts/exp_boundary_eval/run_session.py +158 -0
- package/scripts/exp_boundary_eval/setup.py +120 -0
- package/scripts/exp_boundary_eval/win_mcp_launcher.py +73 -0
- package/scripts/exp_boundary_eval/win_mcp_stdio_wrap.js +36 -0
- package/scripts/exp_boundary_eval/win_node_launcher.py +24 -0
- package/scripts/npm-shim.js +25 -3
- package/scripts/ohos-sdk-publish.mjs +133 -0
- package/scripts/qa_eval/README.md +1 -1
- package/scripts/qa_eval/agent_runner.py +1 -1
|
@@ -46,6 +46,7 @@ const tree_sitter_helpers_1 = require("./tree-sitter-helpers");
|
|
|
46
46
|
const function_ref_1 = require("./function-ref");
|
|
47
47
|
const generated_detection_1 = require("./generated-detection");
|
|
48
48
|
const languages_1 = require("./languages");
|
|
49
|
+
const c_cpp_1 = require("./languages/c-cpp");
|
|
49
50
|
const liquid_extractor_1 = require("./liquid-extractor");
|
|
50
51
|
const razor_extractor_1 = require("./razor-extractor");
|
|
51
52
|
const svelte_extractor_1 = require("./svelte-extractor");
|
|
@@ -81,20 +82,43 @@ const VUE_STORE_FILE_SIGNAL = /\bdefineStore\b|\bcreateStore\b|\bVuex\b|\bmutati
|
|
|
81
82
|
* Extract the name from a node based on language
|
|
82
83
|
*/
|
|
83
84
|
function extractName(node, source, extractor) {
|
|
85
|
+
const name = extractNameRaw(node, source, extractor);
|
|
86
|
+
// Universal fallback: recover a real identifier from a name still mangled by a
|
|
87
|
+
// macro the pre-parse didn't blank (C/C++ only — see recoverMangledName). A
|
|
88
|
+
// no-op on well-formed names, so a clean name is never altered.
|
|
89
|
+
return extractor.recoverMangledName ? extractor.recoverMangledName(name) : name;
|
|
90
|
+
}
|
|
91
|
+
function extractNameRaw(node, source, extractor) {
|
|
84
92
|
const hookName = extractor.resolveName?.(node, source);
|
|
85
93
|
if (hookName)
|
|
86
94
|
return hookName;
|
|
87
95
|
// Try field name first
|
|
88
96
|
const nameNode = (0, tree_sitter_helpers_1.getChildByField)(node, extractor.nameField);
|
|
89
97
|
if (nameNode) {
|
|
90
|
-
// Unwrap pointer_declarator
|
|
98
|
+
// Unwrap pointer_declarator / reference_declarator for C/C++ pointer and
|
|
99
|
+
// reference return types (`int* f()`, `int& f()`, `int&& f()`). Without
|
|
100
|
+
// unwrapping the reference wrapper an inline reference-returning method is
|
|
101
|
+
// named "& f() const" instead of "f" — common in Unreal Engine gameplay
|
|
102
|
+
// headers (`const FGameplayTagContainer& GetActiveTags() const`). Out-of-line
|
|
103
|
+
// defs (`T& C::f()`) already resolve via the qualified-name hook. A
|
|
104
|
+
// pointer_declarator exposes its inner through a `declarator` field; a
|
|
105
|
+
// reference_declarator has none, so it's reached via namedChild(0).
|
|
91
106
|
let resolved = nameNode;
|
|
92
|
-
while (resolved.type === 'pointer_declarator') {
|
|
107
|
+
while (resolved.type === 'pointer_declarator' || resolved.type === 'reference_declarator') {
|
|
93
108
|
const inner = (0, tree_sitter_helpers_1.getChildByField)(resolved, 'declarator') || resolved.namedChild(0);
|
|
94
109
|
if (!inner)
|
|
95
110
|
break;
|
|
96
111
|
resolved = inner;
|
|
97
112
|
}
|
|
113
|
+
// C++ user-defined conversion operator: the declarator is an `operator_cast`
|
|
114
|
+
// whose first child is the target type and second is the `() const` tail. Name
|
|
115
|
+
// it `operator <type>` (the conventional spelling) rather than the whole
|
|
116
|
+
// `operator EALSMovementState() const` declarator, so it matches symbolic
|
|
117
|
+
// overloads (`operator+`) and is findable by the type name.
|
|
118
|
+
if (resolved.type === 'operator_cast') {
|
|
119
|
+
const typeNode = resolved.namedChild(0);
|
|
120
|
+
return typeNode ? `operator ${(0, tree_sitter_helpers_1.getNodeText)(typeNode, source).trim()}` : (0, tree_sitter_helpers_1.getNodeText)(resolved, source);
|
|
121
|
+
}
|
|
98
122
|
// Handle complex declarators (C/C++)
|
|
99
123
|
if (resolved.type === 'function_declarator' || resolved.type === 'declarator') {
|
|
100
124
|
const innerName = (0, tree_sitter_helpers_1.getChildByField)(resolved, 'declarator') || resolved.namedChild(0);
|
|
@@ -980,29 +1004,44 @@ class TreeSitterExtractor {
|
|
|
980
1004
|
this.scanFnRefSubtree(node, 0);
|
|
981
1005
|
skipChildren = true; // extractVariable handles children
|
|
982
1006
|
}
|
|
983
|
-
// Swift
|
|
984
|
-
//
|
|
985
|
-
// (
|
|
986
|
-
//
|
|
987
|
-
//
|
|
988
|
-
//
|
|
1007
|
+
// Swift properties inside a type. A stored instance property becomes a `field`
|
|
1008
|
+
// node; a `static let`/`static var` member becomes `constant`/`variable`
|
|
1009
|
+
// (Swift's `static`-namespacing idiom — value-reference edges can then target
|
|
1010
|
+
// it); a COMPUTED property (getter block, no stored value) becomes a `property`
|
|
1011
|
+
// node whose getter is walked below so its calls attribute to it. A property's
|
|
1012
|
+
// PROPERTY WRAPPER (`@Argument`/`@Published`/`@State`/custom) and declared type
|
|
1013
|
+
// are dependencies attributed to the enclosing type. (Other languages extract
|
|
1014
|
+
// properties via property/field types.)
|
|
989
1015
|
else if (this.language === 'swift' &&
|
|
990
|
-
nodeType === 'property_declaration' &&
|
|
1016
|
+
(nodeType === 'property_declaration' || nodeType === 'protocol_property_declaration') &&
|
|
991
1017
|
this.isInsideClassLikeNode()) {
|
|
992
1018
|
const ownerId = this.nodeStack[this.nodeStack.length - 1];
|
|
993
|
-
// A `static let`/`static var` member is a SHARED constant of the type
|
|
994
|
-
// (Swift's `static`-namespacing idiom, esp. in `enum`/`struct`) — extract
|
|
995
|
-
// it as `constant`/`variable` so value-reference edges can target it. An
|
|
996
|
-
// instance stored property stays a `field` (per-instance; Swift instance
|
|
997
|
-
// properties otherwise aren't own nodes — that's unchanged). A *computed*
|
|
998
|
-
// property (getter, no stored value) is never a constant — skip the node.
|
|
999
1019
|
const { nameNode, isLet, isComputed } = swiftPropertyInfo(node, this.source);
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1020
|
+
let computedPropId;
|
|
1021
|
+
if (nameNode) {
|
|
1022
|
+
if (isComputed) {
|
|
1023
|
+
// Computed property — accessed like a property but its getter holds real
|
|
1024
|
+
// logic. Index as `property` so search/explore find it (#1020: computed
|
|
1025
|
+
// props such as a heavily-read `var isCloudProxy: Bool` returned "No
|
|
1026
|
+
// results found"); pushed below so the getter's calls attribute to it
|
|
1027
|
+
// rather than flattening onto the owning type (SwiftUI `var body: some
|
|
1028
|
+
// View { … }` — the whole subview tree — is the canonical case).
|
|
1029
|
+
const prop = this.createNode('property', (0, tree_sitter_helpers_1.getNodeText)(nameNode, this.source), node, {
|
|
1030
|
+
visibility: this.extractor.getVisibility?.(node),
|
|
1031
|
+
isStatic: this.extractor.isStatic?.(node) ?? false,
|
|
1032
|
+
});
|
|
1033
|
+
computedPropId = prop?.id;
|
|
1034
|
+
}
|
|
1035
|
+
else {
|
|
1036
|
+
// A `static let`/`static var` member is a SHARED constant of the type
|
|
1037
|
+
// (esp. in `enum`/`struct`); an instance stored property stays a `field`
|
|
1038
|
+
// (per-instance — Swift instance properties otherwise aren't own nodes).
|
|
1039
|
+
const isStatic = this.extractor.isStatic?.(node) ?? false;
|
|
1040
|
+
this.createNode(isStatic ? (isLet ? 'constant' : 'variable') : 'field', (0, tree_sitter_helpers_1.getNodeText)(nameNode, this.source), node, {
|
|
1041
|
+
visibility: this.extractor.getVisibility?.(node),
|
|
1042
|
+
isStatic,
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1006
1045
|
}
|
|
1007
1046
|
if (ownerId) {
|
|
1008
1047
|
this.extractDecoratorsFor(node, ownerId);
|
|
@@ -1028,6 +1067,20 @@ class TreeSitterExtractor {
|
|
|
1028
1067
|
walkAttrArgs(modifiers);
|
|
1029
1068
|
}
|
|
1030
1069
|
}
|
|
1070
|
+
// A computed property's getter holds real logic — walk it with the property
|
|
1071
|
+
// node pushed so its calls/instantiations attribute to the property (a
|
|
1072
|
+
// SwiftUI `body`'s subview tree becomes the property's callees). skipChildren
|
|
1073
|
+
// then stops the generic walker from re-walking the getter (and the
|
|
1074
|
+
// modifiers/type annotation already handled above).
|
|
1075
|
+
if (computedPropId) {
|
|
1076
|
+
const getter = node.namedChildren.find((c) => c.type === 'computed_property' || c.type === 'protocol_property_requirements');
|
|
1077
|
+
if (getter) {
|
|
1078
|
+
this.nodeStack.push(computedPropId);
|
|
1079
|
+
this.visitFunctionBody(getter, '');
|
|
1080
|
+
this.nodeStack.pop();
|
|
1081
|
+
}
|
|
1082
|
+
skipChildren = true;
|
|
1083
|
+
}
|
|
1031
1084
|
}
|
|
1032
1085
|
// `export_statement` itself is not extracted — the walker descends
|
|
1033
1086
|
// into children, where the inner declaration (lexical_declaration,
|
|
@@ -1455,6 +1508,15 @@ class TreeSitterExtractor {
|
|
|
1455
1508
|
extractClass(node, kind = 'class') {
|
|
1456
1509
|
if (!this.extractor)
|
|
1457
1510
|
return;
|
|
1511
|
+
// Skip forward declarations / elaborated type references (`class Foo;`) in
|
|
1512
|
+
// languages that opt in — bodiless there means "not a definition", so it
|
|
1513
|
+
// would otherwise mint a phantom node competing with the real definition
|
|
1514
|
+
// (#1093). Languages where a bodiless class is complete (Kotlin, Scala)
|
|
1515
|
+
// leave the flag unset. Resolved once here and reused for the body walk.
|
|
1516
|
+
const resolvedBody = this.extractor.resolveBody?.(node, this.extractor.bodyField)
|
|
1517
|
+
?? (0, tree_sitter_helpers_1.getChildByField)(node, this.extractor.bodyField);
|
|
1518
|
+
if (this.extractor.skipBodilessClass && !resolvedBody)
|
|
1519
|
+
return;
|
|
1458
1520
|
const name = extractName(node, this.source, this.extractor);
|
|
1459
1521
|
const docstring = (0, tree_sitter_helpers_1.getPrecedingDocstring)(node, this.source);
|
|
1460
1522
|
const visibility = this.extractor.getVisibility?.(node);
|
|
@@ -1474,10 +1536,7 @@ class TreeSitterExtractor {
|
|
|
1474
1536
|
this.extractDecoratorsFor(node, classNode.id);
|
|
1475
1537
|
// Push to stack and visit body
|
|
1476
1538
|
this.nodeStack.push(classNode.id);
|
|
1477
|
-
|
|
1478
|
-
?? (0, tree_sitter_helpers_1.getChildByField)(node, this.extractor.bodyField);
|
|
1479
|
-
if (!body)
|
|
1480
|
-
body = node;
|
|
1539
|
+
const body = resolvedBody ?? node;
|
|
1481
1540
|
// Visit all children for methods and properties
|
|
1482
1541
|
for (let i = 0; i < body.namedChildCount; i++) {
|
|
1483
1542
|
const child = body.namedChild(i);
|
|
@@ -3391,6 +3450,63 @@ class TreeSitterExtractor {
|
|
|
3391
3450
|
const callerId = this.nodeStack[this.nodeStack.length - 1];
|
|
3392
3451
|
if (!callerId)
|
|
3393
3452
|
return;
|
|
3453
|
+
// Ruby `call` nodes use `receiver` + `method` fields (tree-sitter-ruby), not
|
|
3454
|
+
// the `object`/`name`/`function` fields the branches below expect — so
|
|
3455
|
+
// without this they fell through to the generic path, which took the
|
|
3456
|
+
// receiver as the callee and DROPPED the method name: `lg.log()` produced a
|
|
3457
|
+
// `calls` ref to `lg` (unresolvable) and no method edge was ever recorded,
|
|
3458
|
+
// so a Ruby method's callers/impact were invisible (#1108 follow-up). Build
|
|
3459
|
+
// `receiver.method` so the resolver — and local-variable type inference —
|
|
3460
|
+
// can link it; `Foo.new` stays an instantiation.
|
|
3461
|
+
if (this.language === 'ruby' && (node.type === 'call' || node.type === 'method_call')) {
|
|
3462
|
+
const methodNode = (0, tree_sitter_helpers_1.getChildByField)(node, 'method');
|
|
3463
|
+
const methodName = methodNode ? (0, tree_sitter_helpers_1.getNodeText)(methodNode, this.source) : '';
|
|
3464
|
+
if (!methodName)
|
|
3465
|
+
return; // operator/element-reference call with no method name
|
|
3466
|
+
const receiverNode = (0, tree_sitter_helpers_1.getChildByField)(node, 'receiver');
|
|
3467
|
+
const line = node.startPosition.row + 1;
|
|
3468
|
+
const column = node.startPosition.column;
|
|
3469
|
+
if (!receiverNode) {
|
|
3470
|
+
// Bare `foo(...)` — just the method name (unchanged behavior).
|
|
3471
|
+
this.unresolvedReferences.push({ fromNodeId: callerId, referenceName: methodName, referenceKind: 'calls', line, column });
|
|
3472
|
+
return;
|
|
3473
|
+
}
|
|
3474
|
+
const receiverName = (0, tree_sitter_helpers_1.getNodeText)(receiverNode, this.source);
|
|
3475
|
+
// `Foo.new` / `Foo::Bar.new` is construction — emit an `instantiates` ref to
|
|
3476
|
+
// the class (last `::` segment), preserving the "what creates X" edge.
|
|
3477
|
+
if (methodName === 'new') {
|
|
3478
|
+
const className = receiverName.includes('::')
|
|
3479
|
+
? receiverName.slice(receiverName.lastIndexOf('::') + 2)
|
|
3480
|
+
: receiverName;
|
|
3481
|
+
if (/^[A-Z]/.test(className)) {
|
|
3482
|
+
this.unresolvedReferences.push({ fromNodeId: callerId, referenceName: className, referenceKind: 'instantiates', line, column });
|
|
3483
|
+
return;
|
|
3484
|
+
}
|
|
3485
|
+
}
|
|
3486
|
+
const SKIP_RECEIVERS = new Set(['self', 'super']);
|
|
3487
|
+
const skip = SKIP_RECEIVERS.has(receiverName);
|
|
3488
|
+
this.unresolvedReferences.push({
|
|
3489
|
+
fromNodeId: callerId,
|
|
3490
|
+
referenceName: skip ? methodName : `${receiverName}.${methodName}`,
|
|
3491
|
+
referenceKind: 'calls',
|
|
3492
|
+
line,
|
|
3493
|
+
column,
|
|
3494
|
+
});
|
|
3495
|
+
// A capitalized (constant) receiver — `Foo.bar`, a class/module method call
|
|
3496
|
+
// — is itself a dependency on that constant; emit a `references` ref so a
|
|
3497
|
+
// class used only via its class methods still records a dependent (the edge
|
|
3498
|
+
// the old receiver-only callee happened to provide, now made explicit).
|
|
3499
|
+
if (!skip && receiverNode.type === 'constant') {
|
|
3500
|
+
this.unresolvedReferences.push({
|
|
3501
|
+
fromNodeId: callerId,
|
|
3502
|
+
referenceName: receiverName,
|
|
3503
|
+
referenceKind: 'references',
|
|
3504
|
+
line: receiverNode.startPosition.row + 1,
|
|
3505
|
+
column: receiverNode.startPosition.column,
|
|
3506
|
+
});
|
|
3507
|
+
}
|
|
3508
|
+
return;
|
|
3509
|
+
}
|
|
3394
3510
|
// Get the function/method being called
|
|
3395
3511
|
let calleeName = '';
|
|
3396
3512
|
// Java/Kotlin method_invocation has 'object' + 'name' fields instead of 'function'
|
|
@@ -3822,6 +3938,45 @@ class TreeSitterExtractor {
|
|
|
3822
3938
|
});
|
|
3823
3939
|
}
|
|
3824
3940
|
}
|
|
3941
|
+
/**
|
|
3942
|
+
* Is this C++ `declaration` a stack/direct-initialization object construction
|
|
3943
|
+
* that invokes a constructor — `Calculator calc(0)` (direct-init) or
|
|
3944
|
+
* `Widget w{1, 2}` (brace-init) — as opposed to a plain variable or a
|
|
3945
|
+
* function declaration? Used to emit an `instantiates` edge for the
|
|
3946
|
+
* call-less construction syntax (#1035); heap `new T(...)` is handled
|
|
3947
|
+
* separately by INSTANTIATION_KINDS.
|
|
3948
|
+
*
|
|
3949
|
+
* Two signals, both required:
|
|
3950
|
+
* - the `type` field is a class-like NAMED type (`type_identifier`,
|
|
3951
|
+
* `template_type`, or `qualified_identifier`). Primitives (`int x(0)`),
|
|
3952
|
+
* `auto` (`placeholder_type_specifier` — that form always carries a real
|
|
3953
|
+
* `call_expression`, already handled), and sized specifiers are excluded —
|
|
3954
|
+
* they construct no class; and
|
|
3955
|
+
* - a declarator carries constructor arguments: an `init_declarator` whose
|
|
3956
|
+
* `value` is an `argument_list` (`(args)`) or `initializer_list` (`{args}`).
|
|
3957
|
+
* This skips default construction `Calculator c;` (no value) and the
|
|
3958
|
+
* most-vexing-parse `Calculator c();` (a bodyless `function_declarator`,
|
|
3959
|
+
* a function decl — not a construction).
|
|
3960
|
+
*/
|
|
3961
|
+
isCppStackConstruction(node) {
|
|
3962
|
+
const typeNode = (0, tree_sitter_helpers_1.getChildByField)(node, 'type');
|
|
3963
|
+
if (!typeNode ||
|
|
3964
|
+
(typeNode.type !== 'type_identifier' &&
|
|
3965
|
+
typeNode.type !== 'template_type' &&
|
|
3966
|
+
typeNode.type !== 'qualified_identifier')) {
|
|
3967
|
+
return false;
|
|
3968
|
+
}
|
|
3969
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
3970
|
+
const child = node.namedChild(i);
|
|
3971
|
+
if (child?.type !== 'init_declarator')
|
|
3972
|
+
continue;
|
|
3973
|
+
const value = (0, tree_sitter_helpers_1.getChildByField)(child, 'value');
|
|
3974
|
+
if (value && (value.type === 'argument_list' || value.type === 'initializer_list')) {
|
|
3975
|
+
return true;
|
|
3976
|
+
}
|
|
3977
|
+
}
|
|
3978
|
+
return false;
|
|
3979
|
+
}
|
|
3825
3980
|
/**
|
|
3826
3981
|
* Static-member / value-read pass. A type/enum/class used only via a member
|
|
3827
3982
|
* VALUE — `Enum.value`, `Type.CONST`, `Colors.red`, `Foo::BAR` — recorded no
|
|
@@ -4202,6 +4357,18 @@ class TreeSitterExtractor {
|
|
|
4202
4357
|
}
|
|
4203
4358
|
}
|
|
4204
4359
|
}
|
|
4360
|
+
// C++ stack / direct-initialization construction — `Calculator calc(0)`
|
|
4361
|
+
// and `Widget w{1, 2}`. Unlike heap `new Calculator(0)` (a new_expression
|
|
4362
|
+
// handled above), these carry the constructor arguments directly on the
|
|
4363
|
+
// declarator with NO call/new node, so the body walker saw no constructor
|
|
4364
|
+
// invocation and recorded no `instantiates` edge (#1035). A declaration's
|
|
4365
|
+
// `type` field IS the constructed class name, so reuse extractInstantiation
|
|
4366
|
+
// (which strips template args / namespace and emits the `instantiates`
|
|
4367
|
+
// ref). Children still recurse below, so a nested ctor-arg call
|
|
4368
|
+
// (`Calculator calc(make())`) keeps its own `calls` ref.
|
|
4369
|
+
if (nodeType === 'declaration' && this.language === 'cpp' && this.isCppStackConstruction(node)) {
|
|
4370
|
+
this.extractInstantiation(node);
|
|
4371
|
+
}
|
|
4205
4372
|
// Static-member / value-read: `Enum.value`, `Type.CONST`, `Foo::BAR`.
|
|
4206
4373
|
this.extractStaticMemberRef(node);
|
|
4207
4374
|
// Local variable type annotations inside a body — `const items: Foo[] = []`,
|
|
@@ -4396,7 +4563,11 @@ class TreeSitterExtractor {
|
|
|
4396
4563
|
}
|
|
4397
4564
|
// C++ base classes: `class Derived : public Base, private Other` →
|
|
4398
4565
|
// base_class_clause holds access specifiers + base type(s). Emit an extends
|
|
4399
|
-
// ref per base type (skip the public/private/protected keywords).
|
|
4566
|
+
// ref per base type (skip the public/private/protected keywords). A
|
|
4567
|
+
// templated base (`Base<int>`, `ns::Tpl<int>`) arrives as a `template_type`
|
|
4568
|
+
// or a `qualified_identifier` wrapping one; strip the `<…>` args so the ref
|
|
4569
|
+
// matches the bare class the template was defined as — `Base`, `ns::Tpl` —
|
|
4570
|
+
// instead of never resolving (#1043).
|
|
4400
4571
|
if (child.type === 'base_class_clause') {
|
|
4401
4572
|
for (const t of child.namedChildren) {
|
|
4402
4573
|
if (t.type === 'type_identifier' ||
|
|
@@ -4404,7 +4575,7 @@ class TreeSitterExtractor {
|
|
|
4404
4575
|
t.type === 'template_type') {
|
|
4405
4576
|
this.unresolvedReferences.push({
|
|
4406
4577
|
fromNodeId: classId,
|
|
4407
|
-
referenceName: (0, tree_sitter_helpers_1.getNodeText)(t, this.source),
|
|
4578
|
+
referenceName: (0, c_cpp_1.stripCppTemplateArgs)((0, tree_sitter_helpers_1.getNodeText)(t, this.source)),
|
|
4408
4579
|
referenceKind: 'extends',
|
|
4409
4580
|
line: t.startPosition.row + 1,
|
|
4410
4581
|
column: t.startPosition.column,
|