feat(extraction): add ArkTS language support with ArkUI dispatch bridges (#396, #512, #890 via #648) (#1186)
Adds ArkTS (.ets, HarmonyOS/OpenHarmony) as a first-class language: full TypeScript-grade extraction via the harmony-contrib tree-sitter grammar (MIT, vendored byte-identical from the tree-sitter-arkts 0.2.0 npm tarball), plus the ArkUI constructs that make HarmonyOS apps traceable: - @Component/@ComponentV2 structs with decorators from both grammar positions; members extract as class members with qualified names. - build() component trees: child instantiation edges via arkui_component_expression, no synthesizer needed. - Attribute chains emitted dot-prefixed and resolved ONLY against @Extend/@Styles/@AnimatableExtend/@Builder helpers (unique-or-drop) — bare-name fallthrough produced 36,840 wrong edges (17% of calls) on the OpenHarmony samples monorepo. All four grammar chain shapes handled, including the detached-chain forms. - .onClick(this.handler) method-reference bindings. - ohpm workspace modules: bare imports follow oh-package.json5 file: deps (ambiguous names dropped), honoring each module's main entry — which also lets .ts consumers resolve .ets modules. - ArkUI dynamic-dispatch bridges, all provenance:'heuristic' with wiring-site metadata: assignment-gated state->build() re-render (V1 @State family + V2 @Local/@Provider/@Consumer), @ohos.events.emitter emit->subscriber pairing on static event keys (numeric ids same-file, named constants same-module, fan-out capped), and router.pushUrl literal urls -> the target page's @Entry struct. - $r/$rawfile resource intrinsics treated as built-ins; arkts joins the web language family, value-reference edges, re-export chase, and the other TS-applicable gates. Also ships a language-agnostic index-completeness guard: indexAll stamps index_state (indexing -> complete/partial/failed), reconciles discovered vs accounted files (a loaded run silently dropped 37 files), and codegraph status surfaces truncated/partial indexes in human and --json output. Validated on HarmoneyOpenEye (82 files), CoolMallArkTS (528, modular ohpm + ArkUI V2), and openharmony/applications_app_samples (11,693 files, 202,890 nodes stable across re-index, attribute false-positive audit 36,840 -> 588 residual all-plausible). Supersedes PRs #656 and #988 with credit — both informed this implementation. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
f8cdbe3c67
commit
99152212a9
@@ -354,6 +354,14 @@ function printIndexResult(clack: typeof import('@clack/prompts'), result: IndexR
|
||||
clack.log.success(`Indexed ${formatNumber(result.filesIndexed)} files`);
|
||||
}
|
||||
clack.log.info(`${formatNumber(result.nodesCreated)} nodes, ${formatNumber(result.edgesCreated)} edges in ${formatDuration(result.durationMs)}`);
|
||||
// A PARTIAL index (files silently dropped mid-pipeline) must not pass
|
||||
// as a clean run — it's the difference between "indexed the repo" and
|
||||
// "indexed most of the repo, quietly". Only the completeness
|
||||
// reconciliation warning; per-file extractor warnings stay in the
|
||||
// error-code summary below.
|
||||
for (const w of result.errors.filter((e) => e.code === 'index_partial')) {
|
||||
clack.log.warn(w.message);
|
||||
}
|
||||
} else if (hasErrors) {
|
||||
clack.log.error(`Indexing failed ${getGlyphs().dash} all ${formatNumber(result.filesErrored)} files had errors`);
|
||||
} else {
|
||||
@@ -798,6 +806,7 @@ program
|
||||
|
||||
const buildInfo = cg.getIndexBuildInfo();
|
||||
const reindexRecommended = cg.isIndexStale();
|
||||
const indexState = cg.getIndexState();
|
||||
|
||||
// JSON output mode
|
||||
if (options.json) {
|
||||
@@ -829,6 +838,10 @@ program
|
||||
builtWithExtractionVersion: buildInfo.extractionVersion,
|
||||
currentExtractionVersion: EXTRACTION_VERSION,
|
||||
reindexRecommended,
|
||||
// 'complete' | 'partial' (files silently dropped) | 'indexing'
|
||||
// (a run was killed mid-index — the index is truncated) |
|
||||
// 'failed' | null (predates the marker).
|
||||
state: indexState,
|
||||
},
|
||||
}));
|
||||
cg.destroy();
|
||||
@@ -842,6 +855,13 @@ program
|
||||
if (worktreeMismatch) {
|
||||
warn(worktreeMismatchWarning(worktreeMismatch));
|
||||
}
|
||||
if (indexState === 'indexing') {
|
||||
warn('The last index run never finished (killed mid-index?) — the index is truncated. Re-run "codegraph index".');
|
||||
} else if (indexState === 'partial') {
|
||||
warn('The last index run silently dropped files — the index is partial. Re-run "codegraph index".');
|
||||
} else if (indexState === 'failed') {
|
||||
warn('The last index run failed — results may be incomplete. Re-run "codegraph index".');
|
||||
}
|
||||
console.log();
|
||||
|
||||
// Index stats
|
||||
|
||||
Reference in New Issue
Block a user