@shapeshift-labs/frontier-lang-compiler 0.2.188 → 0.2.190

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 CHANGED
@@ -557,8 +557,8 @@ Current JS/TS semantic-merge status matrix:
557
557
  | CSS dependency graph evidence | bounded-evidence | CSS dependency graph proof uses `cssDependencySurfaceFiles`, `cssDependencyGraphEvidenceFiles`, missing-proof/blocker counters, and the `css-dependency-graph` proof status for custom property, `var()` fallback, animation, font, asset, `@property`, and `@page` dependency surfaces. It is absent when no dependency surface is present and does not claim cascade/browser equivalence. |
558
558
  | CSS runtime descriptor evidence | bounded-evidence | CSS runtime descriptor proof uses `cssRuntimeDescriptorFiles`, `cssRuntimeDescriptorEvidenceFiles`, property/page descriptor counters, and the `css-runtime-descriptor-evidence` proof status for parser-backed `@property` syntax/inherits/initial-value evidence plus `@page` descriptor and margin-box records. It is source/shape-key evidence only; browser cascade, render, and runtime equivalence remain in the separate browser proof row. |
559
559
  | HTML/CSS browser runtime proof | bounded-evidence | HTML/CSS browser proof is an explicit separate row tracked by `htmlCssBrowserRuntimeProofs`, the `html-css-browser-runtime-proof` surface, and the `browser-runtime-proof` proof status. Structural source merges keep browser/render/cascade equivalence claims false unless a bounded browser proof bundle is attached; HTML runtime-boundary proofs and CSS cascade runtime proofs must include source hashes, a runtime command, probe id, evidence hash, and the required runtime signal. Missing proof routes to `prove-html-css-browser-runtime`. |
560
- | Parser/source-span/trivia evidence | Partial | Source preservation, source hashes, runtime directive-prologue entries, directives, comments/trivia summaries, project `sourceFileRecords` / `sourceSpanRecords`, protected-span hashes, shebang file-entrypoint directive ownership anchors, `sourceMappingURL` and `sourceURL` generated-boundary source-map spans, deterministic source-map generated-boundary ownership keys from supplied exact source/generated spans and hashes, generated-boundary position conflict evidence, deterministic ownership anchors, source-span/trivia ownership blockers, exact parser-trivia ownership records for directive prologues plus leading/trailing comments and JSDoc/block-comment spans when parser evidence matches the source hash, TypeScript `SourceFile` compiler-scanner exact token/trivia source-preservation evidence for JS/TS/JSX/TSX imports, ESTree/Babel parser token/comment range evidence when the supplied AST covers every non-whitespace byte of the current source, fail-closed scanner/ledger spoof blockers, source-span delta conflicts, parser roundtrip proof records, failed source-span roundtrip proof admission blockers, project-merge stage parser-trivia evidence from supplied parser-backed imports for base/worker/head/output, metadata-only exactness blockers for scanner fallbacks, and fixture corpus checks. Parser-backed exactness also requires contiguous current-source token/comment/trivia coverage with no gaps, overlaps, truncation, or text mismatches; truncated coverage blocks exact token/comment ownership. Adapters without token/comment ranges remain approximate/caller evidence, not exact parser trivia. |
561
- | Scope/use-def graph | Partial | Lightweight lexical scope/use-def scans, destructuring alias binding records, object/array/nested/rest/default-initializer parameter binding evidence for function and arrow parameters, default import alias reads through re-export chains when a stable default-export local binding is observed, fail-closed `lexical-scope-import-alias-target-unresolved` records when an alias target cannot be tied to a lexical binding, namespace import dot and literal/static-template computed member-read evidence, blocked evidence for ambiguous computed namespace reads and namespace member writes, `this`/`super` receiver member read/write evidence including computed string and static-template members, optional chaining markers, and TypeScript checker-backed receiver-member reference proof for full `this`/`super` access spans including private identifiers, template-literal interpolation live-reference records with expression hashes plus tagged-template site/tag root/member metadata, caller-supplied ESTree/scope-manager structural evidence normalization, closure-capture depth/owner/reference hashes, binding-level closure capture hashes, project `scopeBindingRecords` / `scopeReferenceRecords`, public owner use hashes, public scope-use and reference-site delta conflicts with alias target route/use-hash evidence, TypeScript compiler reference relations when a checker is supplied, exact compiler reference-site proof hashes on scope reference records, fail-closed `typescript-compiler-reference-site-ambiguous`, `typescript-compiler-reference-lexical-binding-mismatch`, and `typescript-compiler-reference-import-alias-target-mismatch` records when compiler alias evidence cannot be reconciled with the lexical route or re-export/import target, and dependency-sensitive fixture coverage. Full whole-program binding/control-flow resolution is still caller/compiler-evidence bounded. |
560
+ | Parser/source-span/trivia evidence | Partial | Source preservation, source hashes, runtime directive-prologue entries, directives, comments/trivia summaries, project `sourceFileRecords` / `sourceSpanRecords`, protected-span hashes, shebang file-entrypoint directive ownership anchors, `sourceMappingURL` and `sourceURL` generated-boundary source-map spans, deterministic source-map generated-boundary ownership keys from supplied exact source/generated spans and hashes, generated-boundary position conflict evidence, deterministic ownership anchors, source-span/trivia ownership blockers, exact parser-trivia ownership records for directive prologues plus leading/trailing comments and JSDoc/block-comment spans when parser evidence matches the source hash, TypeScript `SourceFile` compiler-scanner exact token/trivia source-preservation evidence for JS/TS/JSX/TSX imports, ESTree/Babel parser token/comment range evidence plus first-class `parserSpanCoverageProof` records when the supplied AST covers every non-whitespace byte of the current source, project source file/span parser-span coverage status/evidence fields, fail-closed scanner/ledger spoof blockers, source-span delta conflicts, parser roundtrip proof records, failed source-span roundtrip proof admission blockers, project-merge stage parser-trivia evidence from supplied parser-backed imports for base/worker/head/output, metadata-only exactness blockers for scanner fallbacks, and fixture corpus checks. Parser-backed exactness also requires contiguous current-source token/comment/trivia coverage with no gaps, overlaps, truncation, or text mismatches; truncated coverage blocks exact token/comment ownership. Adapters without token/comment ranges remain approximate/caller evidence, not exact parser trivia. |
561
+ | Scope/use-def graph | Partial | Lightweight lexical scope/use-def scans, destructuring alias binding records, object/array/nested/rest/default-initializer parameter binding evidence for function and arrow parameters, default import alias reads through re-export chains when a stable default-export local binding is observed, source-bound anonymous default export fallback evidence for resolved default re-export chains with source hash/span and source symbol hashes, fail-closed `lexical-scope-import-alias-target-unresolved` records when an alias target cannot be tied to either lexical binding or source-bound anonymous default evidence, namespace import dot and literal/static-template computed member-read evidence, blocked evidence for ambiguous computed namespace reads and namespace member writes, `this`/`super` receiver member read/write evidence including computed string and static-template members, optional chaining markers, and TypeScript checker-backed receiver-member reference proof for full `this`/`super` access spans including private identifiers, template-literal interpolation live-reference records with expression hashes plus tagged-template site/tag root/member metadata, caller-supplied ESTree/scope-manager structural evidence normalization, closure-capture depth/owner/reference hashes, binding-level closure capture hashes, project `scopeBindingRecords` / `scopeReferenceRecords`, public owner use hashes, public scope-use and reference-site delta conflicts with alias target route/use-hash evidence, TypeScript compiler reference relations when a checker is supplied, exact compiler reference-site proof hashes on scope reference records, fail-closed `typescript-compiler-reference-site-ambiguous`, `typescript-compiler-reference-lexical-binding-mismatch`, and `typescript-compiler-reference-import-alias-target-mismatch` records when compiler alias evidence cannot be reconciled with the lexical route or re-export/import target, and dependency-sensitive fixture coverage. Full whole-program binding/control-flow resolution is still caller/compiler-evidence bounded. |
562
562
  | Module/export/import graph | Partial | Project graph stages, module resolution, runtime-neutral package manifest conversion from in-memory `package.json` objects/text, duplicate workspace-root package-name ambiguity diagnostics and fail-closed `package-workspace-root-ambiguous-missing` edges with `packageWorkspaceRoots` evidence, package exports/imports including wildcard package export key/target evidence, fail-closed package `imports` condition misses, runtime-ambiguous `import`/`require` condition blockers, caller-supplied package type runtime-condition evidence for `.js`/`.ts` package exports/imports, caller-supplied package environment-condition evidence such as `browser`, fail-closed `package-export-environment-ambiguous-missing` / `package-import-environment-ambiguous-missing` blockers with condition candidates when environment targets such as `browser` and `node` diverge without explicit evidence, and fail-closed host-runtime ambiguity blockers for non-resolver host package specifiers with divergent `import`/`require` targets, re-export identities including static TypeScript-style CommonJS bare and `tslib_1.__...` member-form `__exportStar(require("./dep"), exports)` fanout and `__createBinding(exports, require("./dep"), "name", "alias")` named re-export fanout, same-document CommonJS require-alias getter re-export identities for descriptor `get: function () { return dep.name; }`, named descriptor `get: function getName() { return dep.name; }`, shorthand `get() { return dep.name; }`, and block-bodied arrow `get: () => { return dep.name; }`, TypeScript-style CommonJS bare and `tslib_1.__...` member-form `__importDefault(require("./dep"))` and `__importStar(require("./dep"))` helper import edges, CommonJS `module.exports` default-import interop when no direct `default` export exists, literal computed CommonJS export properties such as `exports["default"]`, static `module.exports = { named }`, `Object.assign(exports, { named })`, `Object.defineProperty(exports, "named", { value/get })`, and `Object.defineProperties(exports, { named: { value/get } })` export maps in lightweight and AST-backed imports, ESTree/Babel no-expression `TemplateLiteral` normalization for CommonJS `require`, computed export keys, descriptor export specifiers, dynamic `import()`, CommonJS helper re-export specifiers, and host dependency specifiers while expression-bearing templates stay unresolved, TypeScript compiler no-substitution dynamic import and host dependency template evidence, `exports.__esModule` marker filtering, import-target deltas for head-introduced CommonJS export assignments, namespace/ambient module/global augmentation/export-assignment static shape records with proof hashes and no runtime-equivalence claim, fail-closed namespace/export-assignment shape delta conflicts, non-literal dynamic `import()` pseudo-specifiers with expression kind/text/hash evidence and fail-closed resolution evidence, static `new URL(specifier, import.meta.url)`, `Worker`, `SharedWorker`, `serviceWorker.register`, worklet `addModule`, `importScripts`, `import.meta.resolve`, and `require.resolve` host dependency edges with expression hashes and no runtime-resolution claim, dynamic host dependency targets emitted as `<host-dependency>` with expression hashes, `hostDependencyStaticSpecifierEvidence: false`, and proof-required unresolved evidence, import-attribute/import-assertion normalized key/value/count/hash evidence on static imports, dynamic imports, and re-exports, import-attribute delta conflicts, output graph unresolved-module conflicts that preserve edge-level fail-closed package, host, dynamic import, and import-attribute value evidence, and output graph resolved-module missing-export conflicts that preserve edge-level package and import-attribute evidence. Host filesystem/package graph crawling, namespace runtime evaluation, ambient/global compatibility, and CommonJS runtime interop equivalence remain out of the root API. |
563
563
  | Type/public API graph | Partial | Public-contract regions, signature/contract hashes, TypeScript compiler symbol/type records, source-bound checker proof source path/hash requirements, compiler-backed type-reference target proof that binds public API type references to resolved target symbols, declaration spans, and declaration source text hashes, inferred exported factory call-signature evidence, compiler-backed public call/construct signature shape evidence and proof hashes, exported overload declaration/signature counts, compiler-backed overload signature-set proof, compiler-backed generic type-parameter/default proof, compiler-backed public member property/method property-set proof, compiler-backed public index-signature key/value/readonly evidence and proof hashes, stable public-surface hashes that ignore transient TypeScript symbol flags, compiler-backed class heritage and constructor-signature evidence/proof hashes, compiler-backed private class member and accessor-field static shape records/proof hashes plus source- and required-signal-bound private/accessor runtime proof binding with command/trace/evidence hashes, private brand, private method, private accessor, static private, subclass brand-boundary, and accessor descriptor trace slots, and false claim flags, compiler-backed class/member/parameter decorator target and expression static metadata records/proof hashes plus source-bound decorator runtime execution proof binding with trace hashes and false claim flags, compiler-backed enum runtime-shape/member-value evidence and proof hashes, TypeScript compiler importer support for source-bound computed enum evaluated-value traces with emitted-shape hashes, trace/evidence hashes, and false claim flags, compiler-backed conditional, indexed-access, mapped, `keyof`, template-literal, `infer`, union, intersection, tuple, and mixed known advanced/composite type-shape proof hashes, static compiler-backed inference syntax evidence/proof hashes for `satisfies`, `as const`, and const type parameters, bounded TypeChecker `isTypeAssignableTo` oracle proof for simple public type aliases with source path/hash binding and fail-closed `typescript-public-api-type-equivalence-proof-missing` for missing or ambiguous oracle evidence, class private/accessor/decorator/class/enum/advanced-shape/composite-shape/inference-syntax/index-signature/callable-signature/type-reference-target hashes in public compiler-type delta fingerprints, fail-closed missing-proof blockers for missing public API source hashes, type-reference target proof hashes, call/construct signature return/parameter evidence, constructor/class-heritage/private-class-member/accessor-field/index-signature value-type/enum runtime-shape/conditional-branch/indexed-access object-index-result/mapped constraint-value/`keyof` target/template-literal span/`infer` type-parameter/union member/intersection member/tuple element evidence, fail-closed computed enum runtime-value blockers when source-bound evaluated-value proof is missing, stale, trace-incomplete, value-incomplete, or claim-bearing, fail-closed private/accessor and decorator runtime execution blockers when source-bound trace proof is missing, stale, trace-incomplete, schema/kind-mismatched, required-signal-incomplete, commandless, or claim-bearing, fail-closed unknown advanced type-shape evidence, unsupported type-equivalence reason codes, public compiler-type delta conflicts, declaration-output gate, TypeScript declaration emit parity proof for worker/head/output public boundaries, and project graph delta conflicts. Full type-equivalence, broad decorator execution equivalence beyond source-bound trace proofs, broad enum runtime evaluation beyond source-bound computed-value traces, broad runtime equivalence for private/accessor execution beyond source-bound trace proofs, or broad inference-semantics proof beyond these focused compiler-backed cases is not claimed. |
564
564
  | JSX/TSX element and prop graph | Partial | JSX attribute/child-expression safe-merge fallbacks, conditional child-expression blockers, keyed-child insertion evidence, keyed named Fragment insertion evidence, planned-output duplicate-key checks, top-level `key` attribute scanning that does not treat `data-key` as stable identity, deterministic shorthand-fragment/spread/reorder/same-gap blockers, spread-attribute records/expression hashes, spread/explicit prop precedence blockers, component prop diagnostic gates, project `jsxElementRecords` / `jsxPropRecords`, public owner prop and keyed child-order hashes, typed public key/fragment evidence, literal/shorthand/reference/static optional-chain JSX prop-value callsite records/hashes with `jsx-render-prop-value-literal-evidence`, `jsx-render-prop-value-static-reference-evidence`, and `jsx-render-prop-value-static-optional-reference-evidence`, dynamic prop-value blockers such as `jsx-render-prop-value-computed-reference-unsupported`, `jsx-render-prop-value-call-expression-unsupported`, and `jsx-render-prop-value-optional-reference-unsupported`, same-file plain/member and project-local named/default/barrel-import plain/member static component prop passthrough evidence with `jsx-render-component-prop-flow-static-passthrough-evidence`, dynamic component prop passthrough blockers with `jsx-render-component-prop-flow-dynamic-value-unsupported`, component prop render-flow blockers with `jsx-render-component-prop-flow-unsupported`, provider ancestor path/count/hash evidence for context-provider nesting, context provider value prop records/hashes with literal provider value evidence, static identifier/member reference-binding evidence, static optional-chain reference-binding evidence, static call-free object/array value evidence, or `jsx-render-context-provider-value-unsupported` plus provider-value dynamic blocker metadata (`dynamicBlockerReasonCode` values such as `jsx-render-context-provider-value-call-expression-unsupported` and `jsx-render-context-provider-value-computed-reference-unsupported`) for call/computed/optional/spread values, context consumer target records/hashes with static identifier/member target evidence, static optional target evidence, or `jsx-render-context-consumer-target-unsupported` plus dynamic-target blockers for computed/call targets, static lexical provider-ancestor lookup records/hashes for matching context consumers with `jsx-render-context-consumer-provider-lookup-static-evidence`, same-file direct component provider lookup evidence for plain identifier callsites and same-file member component provider lookup evidence for static object-literal callsites such as `UI.Child` with `jsx-render-context-consumer-provider-component-lookup-static-evidence`, same-file `{children}` / `props.children` / `this.props.children` provider-flow evidence for components that render children directly inside a static provider with `jsx-render-context-consumer-provider-component-flow-static-evidence`, project-local named/aliased named/default component-import and member-object provider lookup evidence plus explicit named/default, member-object, and unique star barrel re-export component evidence with `jsx-render-context-consumer-provider-project-component-lookup-static-evidence`, project-import children-flow evidence with `jsx-render-context-consumer-provider-project-component-flow-static-evidence`, while dynamic/ambiguous member, unresolved, external-runtime, and ambiguous-star component targets emit `jsx-render-context-consumer-provider-component-target-unsupported`, hook call-order/count/hash render-risk evidence, hook dependency-array records/counts/hashes with per-item literal/reference/static optional-reference evidence, dynamic computed/call blocker reason codes, static dependency-set evidence, or `jsx-render-hook-dependency-array-unsupported` for dynamic dependency expressions, effect-hook callback/cleanup records/counts/hashes with static callback/cleanup source evidence, callback reference-path metadata, static optional callback/cleanup evidence, dynamic callback/cleanup blocker reason codes, runtime-equivalence-unproved evidence, or `jsx-render-hook-effect-unsupported` for dynamic effect factories and cleanup returns, public component render-return records/counts/hashes with static return-expression evidence, static array/fragment return collection child records/hashes, plus `jsx-render-return-branch-unsupported` for branchy/conditional returns, static `memo` / `forwardRef` / `observer` / `React.lazy` component-wrapper render-risk records including lazy import-factory evidence and lazy-load/runtime proof gaps, event-handler prop records/counts/hashes with static handler-reference evidence, static optional handler-reference evidence, static inline handler expression evidence, same-owner local handler declaration hashes via `jsx-render-event-handler-local-declaration-evidence`, or `jsx-render-event-handler-prop-unsupported` with computed/call blocker metadata for handler factory/call expressions, and public JSX prop/spread/child-order/render-risk delta conflicts produce review/blocking evidence with reason codes such as `jsx-render-context-provider-nesting-unsupported`, `jsx-render-prop-value-literal-evidence`, `jsx-render-prop-value-static-reference-evidence`, `jsx-render-prop-value-static-optional-reference-evidence`, `jsx-render-prop-value-unsupported`, `jsx-render-component-prop-flow-static-passthrough-evidence`, `jsx-render-component-prop-flow-dynamic-value-unsupported`, `jsx-render-component-prop-flow-unsupported`, `jsx-render-context-provider-value-literal-evidence`, `jsx-render-context-provider-value-static-reference-evidence`, `jsx-render-context-provider-value-static-optional-reference-evidence`, `jsx-render-context-provider-value-static-data-evidence`, `jsx-render-context-provider-value-unsupported`, `jsx-render-context-consumer-target-static-evidence`, `jsx-render-context-consumer-target-static-optional-reference-evidence`, `jsx-render-context-consumer-provider-lookup-static-evidence`, `jsx-render-context-consumer-provider-component-lookup-static-evidence`, `jsx-render-context-consumer-provider-component-flow-static-evidence`, `jsx-render-context-consumer-provider-project-component-lookup-static-evidence`, `jsx-render-context-consumer-provider-project-component-flow-static-evidence`, `jsx-render-context-consumer-provider-component-target-unsupported`, `jsx-render-context-consumer-target-unsupported`, `jsx-render-hook-call-order-unsupported`, `jsx-render-hook-dependency-array-static-evidence`, `jsx-render-hook-dependency-array-unsupported`, `jsx-render-hook-effect-static-callback-evidence`, `jsx-render-hook-effect-static-optional-callback-evidence`, `jsx-render-hook-effect-static-cleanup-evidence`, `jsx-render-hook-effect-static-optional-cleanup-evidence`, `jsx-render-hook-effect-runtime-equivalence-unproved`, `jsx-render-hook-effect-unsupported`, `jsx-render-return-static-evidence`, `jsx-render-return-array-static-evidence`, `jsx-render-return-fragment-static-evidence`, `jsx-render-return-branch-unsupported`, `jsx-render-component-wrapper-lazy-boundary-evidence`, `jsx-render-component-wrapper-lazy-runtime-equivalence-unproved`, `jsx-render-event-handler-prop-static-evidence`, `jsx-render-event-handler-prop-static-optional-reference-evidence`, `jsx-render-event-handler-prop-static-inline-evidence`, `jsx-render-event-handler-local-declaration-evidence`, and `jsx-render-event-handler-prop-unsupported`. Full component render equivalence, lazy-load/runtime equivalence, dynamic context value semantics beyond value-expression identity, provider lookup across external/runtime/ambiguous imported component boundaries, arbitrary prop/render flow beyond bounded static passthrough evidence, optional-chain render equivalence beyond callsite identity evidence, executable hook effect equivalence, and framework template semantics are not proved. |
@@ -598,6 +598,7 @@ Recent residual closures represented in the matrix shards:
598
598
  - Project admission now exposes `admission.routes` / `routeSummary` records for structural apply/review/reject/rerun/rebase decisions across cross-file symbol rename, symbol move, split/merge, replay-proof, and missing-evidence paths, while keeping `autoMergeClaim: false` and `semanticEquivalenceClaim: false`.
599
599
  - Semantic equivalence proof now accepts source/output/gate-bound external proof records for exact JS/TS project bindings, removes the external-proof missing route only when the proof validates, and keeps stale, malformed, or overclaiming proofs fail-closed with `semantic-equivalence-unknown`.
600
600
  - Parser/source-span/trivia now requires contiguous parser-backed current-source token/comment/trivia coverage with no gaps, overlaps, truncation, or text mismatches before claiming exact token/comment ownership, including distinct JSDoc and block-comment ownership relations.
601
+ - Parser/source-span/trivia now emits first-class ESTree/Babel `parserSpanCoverageProof` evidence from token/comment ranges, threads it into parser-trivia exactness, source file/span records, ownership anchors, and source-span roundtrip summaries, and keeps truncated syntax-AST coverage fail-closed.
601
602
  - Scope/use-def graph now blocks compiler/lexical import-alias re-export target disagreement with `typescript-compiler-reference-import-alias-target-mismatch`.
602
603
  - Scope/use-def graph now treats no-expression template literals in namespace-import and `this`/`super` computed member reads as static member evidence while expression templates remain blocked.
603
604
  - Module/export/import graph now treats duplicate package names across different workspace roots as `ambiguous-package-workspace-root` and emits fail-closed `package-workspace-root-ambiguous-missing` edges.
@@ -0,0 +1,111 @@
1
+ import { idFragment } from '../../native-import-utils.js';
2
+ import { resolveRelativeProjectModule } from './projectSymbolGraphModuleResolution.js';
3
+
4
+ function importAliasRecords(semanticIndex, documentsByPath) {
5
+ return (semanticIndex?.symbols ?? []).flatMap((symbol) => {
6
+ if (symbol?.kind !== 'import') return [];
7
+ const metadata = objectValue(symbol.metadata);
8
+ const sourcePath = symbol.definitionSpan?.path ?? metadata.sourcePath;
9
+ const moduleSpecifier = firstString(metadata.moduleSpecifier, metadata.importPath, metadata.source);
10
+ const localName = firstString(metadata.localName, symbol.name);
11
+ if (!sourcePath || !localName || !moduleSpecifier) return [];
12
+ const importedName = firstString(metadata.importedName, metadata.exportedName, localName);
13
+ const resolved = moduleSpecifier.startsWith('.')
14
+ ? resolveRelativeProjectModule(sourcePath, moduleSpecifier, documentsByPath)
15
+ : undefined;
16
+ return [compactRecord({
17
+ symbolId: symbol.id,
18
+ sourcePath,
19
+ localName,
20
+ importedName,
21
+ exportedName: firstString(metadata.exportedName),
22
+ moduleSpecifier,
23
+ importKind: firstString(metadata.importKind),
24
+ isTypeOnly: metadata.isTypeOnly === true || metadata.typeOnly === true || undefined,
25
+ resolvedSourcePath: resolved?.path,
26
+ targetDocumentId: resolved?.documentId,
27
+ resolutionKind: resolved?.kind,
28
+ resolutionPathVariant: resolved?.resolutionPathVariant
29
+ })];
30
+ });
31
+ }
32
+
33
+ function exportAliasRecords(semanticIndex, documentsByPath, sourceTextsByPath) {
34
+ const symbols = semanticIndex?.symbols ?? [];
35
+ const declarationsByLocalKey = groupFirst(
36
+ symbols.filter((symbol) => symbol?.kind !== 'import' && symbol?.kind !== 'export' && symbol?.name),
37
+ (symbol) => localKey(symbol.definitionSpan?.path ?? symbol.metadata?.sourcePath, symbol.name)
38
+ );
39
+ return symbols.flatMap((symbol) => {
40
+ if (symbol?.kind !== 'export') return [];
41
+ const metadata = objectValue(symbol.metadata);
42
+ const sourcePath = symbol.definitionSpan?.path ?? metadata.sourcePath;
43
+ const exportedName = firstString(metadata.exportedName, symbol.name);
44
+ if (!sourcePath || !exportedName || exportedName.startsWith('{')) return [];
45
+ const moduleSpecifier = firstString(metadata.moduleSpecifier, metadata.importPath, metadata.exportPath, metadata.source);
46
+ const resolved = moduleSpecifier?.startsWith('.')
47
+ ? resolveRelativeProjectModule(sourcePath, moduleSpecifier, documentsByPath)
48
+ : undefined;
49
+ const localName = firstString(metadata.localName, defaultExportLocalName(sourceTextsByPath.get(sourcePath), exportedName, moduleSpecifier), exportedName);
50
+ const declaration = declarationsByLocalKey.get(localKey(sourcePath, localName));
51
+ const document = documentsByPath.get(sourcePath);
52
+ return [compactRecord({
53
+ symbolId: symbol.id,
54
+ sourcePath,
55
+ sourceHash: document?.sourceHash ?? symbol.definitionSpan?.sourceId ?? declaration?.definitionSpan?.sourceId,
56
+ sourceSpan: declaration?.definitionSpan ?? symbol.definitionSpan,
57
+ signatureHash: symbol.signatureHash,
58
+ sourceSymbolId: declaration?.id,
59
+ sourceSymbolKind: declaration?.kind,
60
+ sourceSymbolSignatureHash: declaration?.signatureHash,
61
+ localName,
62
+ importedName: firstString(metadata.importedName, metadata.localName, exportedName),
63
+ exportedName,
64
+ exportKind: firstString(metadata.exportKind),
65
+ moduleSpecifier,
66
+ resolvedSourcePath: resolved?.path,
67
+ targetDocumentId: resolved?.documentId,
68
+ resolutionKind: resolved?.kind,
69
+ resolutionPathVariant: resolved?.resolutionPathVariant,
70
+ isTypeOnly: metadata.isTypeOnly === true || metadata.typeOnly === true || undefined
71
+ })];
72
+ });
73
+ }
74
+
75
+ function defaultExportLocalName(sourceText, exportedName, moduleSpecifier) {
76
+ if (exportedName !== 'default' || moduleSpecifier || typeof sourceText !== 'string') return undefined;
77
+ return firstString(
78
+ sourceText.match(/\bexport\s+default\s+(?:async\s+)?function\*?\s+([A-Za-z_$][\w$]*)/)?.[1],
79
+ sourceText.match(/\bexport\s+default\s+(?:abstract\s+)?class\s+([A-Za-z_$][\w$]*)/)?.[1],
80
+ sourceText.match(/\bexport\s+default\s+([A-Za-z_$][\w$]*)\s*;(?=\s*(?:$|\n))/)?.[1],
81
+ sourceText.match(/\bexport\s+default\s+([A-Za-z_$][\w$]*)\s*(?=$)/)?.[1]
82
+ );
83
+ }
84
+
85
+ function nativeImportSourceText(imported) {
86
+ return imported?.metadata?.sourcePreservation?.sourceText
87
+ ?? imported?.nativeSource?.metadata?.sourcePreservation?.sourceText
88
+ ?? imported?.nativeAst?.metadata?.sourcePreservation?.sourceText
89
+ ?? imported?.universalAst?.metadata?.sourcePreservation?.sourceText
90
+ ?? imported?.sourceText;
91
+ }
92
+
93
+ function localKey(sourcePath, name) { return sourcePath && name ? `${sourcePath}\0${name}` : undefined; }
94
+ function compactRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined)); }
95
+ function objectValue(value) { return value && typeof value === 'object' && !Array.isArray(value) ? value : {}; }
96
+
97
+ function firstString(...values) {
98
+ for (const value of values) if (value !== undefined && value !== null && String(value)) return String(value);
99
+ return undefined;
100
+ }
101
+
102
+ function groupFirst(records, keyFn) {
103
+ const result = new Map();
104
+ for (const record of records) {
105
+ const key = keyFn(record);
106
+ if (key && !result.has(key)) result.set(key, record);
107
+ }
108
+ return result;
109
+ }
110
+
111
+ export { exportAliasRecords, importAliasRecords, nativeImportSourceText };
@@ -1,7 +1,11 @@
1
1
  import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
2
2
  import { idFragment } from '../../native-import-utils.js';
3
3
  import { LexicalUseDefReasonCodes } from '../../js-ts-semantic-scope-use-def-utils.js';
4
- import { resolveRelativeProjectModule } from './projectSymbolGraphModuleResolution.js';
4
+ import {
5
+ exportAliasRecords,
6
+ importAliasRecords,
7
+ nativeImportSourceText
8
+ } from './projectSymbolGraphScopeUseDefAliasRecords.js';
5
9
 
6
10
  function createScopeGraphContext(semanticIndex, imports, publicKeys) {
7
11
  const sourceTextsByPath = new Map(imports
@@ -32,63 +36,6 @@ function createScopeGraphContext(semanticIndex, imports, publicKeys) {
32
36
  };
33
37
  }
34
38
 
35
- function importAliasRecords(semanticIndex, documentsByPath) {
36
- return (semanticIndex?.symbols ?? []).flatMap((symbol) => {
37
- if (symbol?.kind !== 'import') return [];
38
- const metadata = objectValue(symbol.metadata);
39
- const sourcePath = symbol.definitionSpan?.path ?? metadata.sourcePath;
40
- const moduleSpecifier = firstString(metadata.moduleSpecifier, metadata.importPath, metadata.source);
41
- const localName = firstString(metadata.localName, symbol.name);
42
- if (!sourcePath || !localName || !moduleSpecifier) return [];
43
- const importedName = firstString(metadata.importedName, metadata.exportedName, localName);
44
- const resolved = moduleSpecifier.startsWith('.')
45
- ? resolveRelativeProjectModule(sourcePath, moduleSpecifier, documentsByPath)
46
- : undefined;
47
- return [compactRecord({
48
- symbolId: symbol.id,
49
- sourcePath,
50
- localName,
51
- importedName,
52
- exportedName: firstString(metadata.exportedName),
53
- moduleSpecifier,
54
- importKind: firstString(metadata.importKind),
55
- isTypeOnly: metadata.isTypeOnly === true || metadata.typeOnly === true || undefined,
56
- resolvedSourcePath: resolved?.path,
57
- targetDocumentId: resolved?.documentId,
58
- resolutionKind: resolved?.kind,
59
- resolutionPathVariant: resolved?.resolutionPathVariant
60
- })];
61
- });
62
- }
63
-
64
- function exportAliasRecords(semanticIndex, documentsByPath, sourceTextsByPath) {
65
- return (semanticIndex?.symbols ?? []).flatMap((symbol) => {
66
- if (symbol?.kind !== 'export') return [];
67
- const metadata = objectValue(symbol.metadata);
68
- const sourcePath = symbol.definitionSpan?.path ?? metadata.sourcePath;
69
- const exportedName = firstString(metadata.exportedName, symbol.name);
70
- if (!sourcePath || !exportedName || exportedName.startsWith('{')) return [];
71
- const moduleSpecifier = firstString(metadata.moduleSpecifier, metadata.importPath, metadata.exportPath, metadata.source);
72
- const resolved = moduleSpecifier?.startsWith('.')
73
- ? resolveRelativeProjectModule(sourcePath, moduleSpecifier, documentsByPath)
74
- : undefined;
75
- return [compactRecord({
76
- symbolId: symbol.id,
77
- sourcePath,
78
- localName: firstString(metadata.localName, defaultExportLocalName(sourceTextsByPath.get(sourcePath), exportedName, moduleSpecifier), exportedName),
79
- importedName: firstString(metadata.importedName, metadata.localName, exportedName),
80
- exportedName,
81
- exportKind: firstString(metadata.exportKind),
82
- moduleSpecifier,
83
- resolvedSourcePath: resolved?.path,
84
- targetDocumentId: resolved?.documentId,
85
- resolutionKind: resolved?.kind,
86
- resolutionPathVariant: resolved?.resolutionPathVariant,
87
- isTypeOnly: metadata.isTypeOnly === true || metadata.typeOnly === true || undefined
88
- })];
89
- });
90
- }
91
-
92
39
  function attachAliasMetadata(bindings, directUseHashes, context) {
93
40
  const bindingsByLocal = groupFirst(bindings, (binding) => localKey(binding.sourcePath, binding.name));
94
41
  return bindings.map((binding) => {
@@ -107,13 +54,20 @@ function attachAliasMetadata(bindings, directUseHashes, context) {
107
54
  importAlias: aliasHashRecord(importAlias),
108
55
  exportAliases: exportAliases.map(aliasHashRecord).sort(compareJson)
109
56
  }) : undefined;
110
- const resolvedUseHash = resolved?.resolvedBindingUseHash ? hashSemanticValue({
57
+ const resolvedUseEvidenceHash = resolved?.resolvedBindingUseHash ?? resolved?.resolvedExportUseHash;
58
+ const resolvedUseHash = resolvedUseEvidenceHash ? hashSemanticValue({
111
59
  kind: 'frontier.lang.projectScopeImportResolvedUseHash',
112
60
  binding: binding.signatureHash,
113
61
  moduleSpecifier: importAlias.moduleSpecifier,
114
62
  importedName: importAlias.importedName,
115
63
  resolvedBinding: resolved.resolvedBindingSignatureHash,
116
- resolvedUseHash: resolved.resolvedBindingUseHash
64
+ resolvedBindingUseHash: resolved.resolvedBindingUseHash,
65
+ resolvedExportUseHash: resolved.resolvedExportUseHash,
66
+ resolvedUseHash: resolvedUseEvidenceHash,
67
+ originSourcePath: resolved.originSourcePath,
68
+ originSourceHash: resolved.originSourceHash,
69
+ originExportedName: resolved.originExportedName,
70
+ aliasResolutionEvidenceKind: resolved.aliasResolutionEvidenceKind
117
71
  }) : undefined;
118
72
  return compactRecord({
119
73
  ...binding,
@@ -145,6 +99,8 @@ function resolveImportAliasBinding(importAlias, bindingsByLocal, directUseHashes
145
99
  if (!importAlias.resolvedSourcePath || !importAlias.importedName || importAlias.importedName === '*') return undefined;
146
100
  const origin = resolveExportOrigin(context, importAlias.resolvedSourcePath, importAlias.importedName);
147
101
  const target = bindingsByLocal.get(localKey(origin?.sourcePath ?? importAlias.resolvedSourcePath, origin?.localName ?? importAlias.importedName));
102
+ const sourceBoundOrigin = target ? undefined : sourceBoundDefaultExportOrigin(origin, importAlias);
103
+ if (sourceBoundOrigin) return sourceBoundOrigin;
148
104
  if (!target) return compactRecord({
149
105
  resolvedExportName: importAlias.importedName,
150
106
  originSourcePath: origin?.sourcePath,
@@ -167,6 +123,40 @@ function resolveImportAliasBinding(importAlias, bindingsByLocal, directUseHashes
167
123
  });
168
124
  }
169
125
 
126
+ function sourceBoundDefaultExportOrigin(origin, importAlias) {
127
+ if (importAlias.importedName !== 'default' || origin?.exportedName !== 'default') return undefined;
128
+ if (!origin.sourcePath || !origin.sourceHash || !origin.sourceSpan || !origin.sourceSymbolId || !origin.sourceSymbolSignatureHash) return undefined;
129
+ const resolvedExportUseHash = hashSemanticValue({
130
+ kind: 'frontier.lang.projectScopeImportResolvedSourceBoundDefaultExportUseHash',
131
+ moduleSpecifier: importAlias.moduleSpecifier,
132
+ importedName: importAlias.importedName,
133
+ resolvedSourcePath: importAlias.resolvedSourcePath,
134
+ originSourcePath: origin.sourcePath,
135
+ originSourceHash: origin.sourceHash,
136
+ originExportedName: origin.exportedName,
137
+ originSymbolId: origin.symbolId,
138
+ originSignatureHash: origin.signatureHash,
139
+ originSourceSymbolId: origin.sourceSymbolId,
140
+ originSourceSymbolKind: origin.sourceSymbolKind,
141
+ originSourceSymbolSignatureHash: origin.sourceSymbolSignatureHash,
142
+ originSourceSpan: semanticSourceSpanForHash(origin.sourceSpan)
143
+ });
144
+ return compactRecord({
145
+ resolvedExportName: importAlias.importedName,
146
+ originSourcePath: origin.sourcePath,
147
+ originSourceHash: origin.sourceHash,
148
+ originSourceSpan: origin.sourceSpan,
149
+ originExportedName: origin.exportedName,
150
+ originSymbolId: origin.symbolId,
151
+ originSignatureHash: origin.signatureHash,
152
+ originSourceSymbolId: origin.sourceSymbolId,
153
+ originSourceSymbolKind: origin.sourceSymbolKind,
154
+ originSourceSymbolSignatureHash: origin.sourceSymbolSignatureHash,
155
+ aliasResolutionEvidenceKind: 'source-bound-default-export',
156
+ resolvedExportUseHash
157
+ });
158
+ }
159
+
170
160
  function exportAliasesForBinding(binding, context) {
171
161
  const directAliases = context.exportAliasesByLocalKey.get(localKey(binding.sourcePath, binding.name)) ?? [];
172
162
  const reExportAliases = context.exportAliases
@@ -194,7 +184,18 @@ function resolveExportOrigin(context, sourcePath, exportedName, seen = new Set()
194
184
  if (alias.moduleSpecifier && alias.resolvedSourcePath) {
195
185
  return resolveExportOrigin(context, alias.resolvedSourcePath, alias.importedName ?? alias.localName, seen);
196
186
  }
197
- return { sourcePath, localName: alias.localName ?? alias.exportedName, exportedName: alias.exportedName, symbolId: alias.symbolId };
187
+ return {
188
+ sourcePath,
189
+ sourceHash: alias.sourceHash,
190
+ sourceSpan: alias.sourceSpan,
191
+ localName: alias.localName ?? alias.exportedName,
192
+ exportedName: alias.exportedName,
193
+ symbolId: alias.symbolId,
194
+ signatureHash: alias.signatureHash,
195
+ sourceSymbolId: alias.sourceSymbolId,
196
+ sourceSymbolKind: alias.sourceSymbolKind,
197
+ sourceSymbolSignatureHash: alias.sourceSymbolSignatureHash
198
+ };
198
199
  }
199
200
 
200
201
  function attachReferenceAliasMetadata(references, bindings) {
@@ -215,11 +216,19 @@ function attachReferenceAliasMetadata(references, bindings) {
215
216
  importedName: binding?.importedName,
216
217
  resolvedSourcePath: binding?.resolvedSourcePath,
217
218
  originSourcePath: binding?.originSourcePath,
219
+ originSourceHash: binding?.originSourceHash,
220
+ originSourceSpan: binding?.originSourceSpan,
221
+ originSignatureHash: binding?.originSignatureHash,
222
+ originSourceSymbolId: binding?.originSourceSymbolId,
223
+ originSourceSymbolKind: binding?.originSourceSymbolKind,
224
+ originSourceSymbolSignatureHash: binding?.originSourceSymbolSignatureHash,
218
225
  resolvedExportName: binding?.resolvedExportName,
226
+ resolvedExportUseHash: binding?.resolvedExportUseHash,
219
227
  resolvedBindingId: binding?.resolvedBindingId,
220
228
  resolvedBindingName: binding?.resolvedBindingName,
221
229
  resolvedBindingUseHash: binding?.resolvedBindingUseHash,
222
230
  aliasResolutionStatus: binding?.aliasResolutionStatus,
231
+ aliasResolutionEvidenceKind: binding?.aliasResolutionEvidenceKind,
223
232
  aliasResolutionReasonCodes: binding?.aliasResolutionReasonCodes,
224
233
  status: binding?.aliasResolutionStatus ?? reference.status,
225
234
  reasonCodes: reasonCodes.length ? reasonCodes : undefined,
@@ -228,24 +237,6 @@ function attachReferenceAliasMetadata(references, bindings) {
228
237
  });
229
238
  }
230
239
 
231
- function defaultExportLocalName(sourceText, exportedName, moduleSpecifier) {
232
- if (exportedName !== 'default' || moduleSpecifier || typeof sourceText !== 'string') return undefined;
233
- return firstString(
234
- sourceText.match(/\bexport\s+default\s+(?:async\s+)?function\*?\s+([A-Za-z_$][\w$]*)/)?.[1],
235
- sourceText.match(/\bexport\s+default\s+(?:abstract\s+)?class\s+([A-Za-z_$][\w$]*)/)?.[1],
236
- sourceText.match(/\bexport\s+default\s+([A-Za-z_$][\w$]*)\s*;(?=\s*(?:$|\n))/)?.[1],
237
- sourceText.match(/\bexport\s+default\s+([A-Za-z_$][\w$]*)\s*(?=$)/)?.[1]
238
- );
239
- }
240
-
241
- function nativeImportSourceText(imported) {
242
- return imported?.metadata?.sourcePreservation?.sourceText
243
- ?? imported?.nativeSource?.metadata?.sourcePreservation?.sourceText
244
- ?? imported?.nativeAst?.metadata?.sourcePreservation?.sourceText
245
- ?? imported?.universalAst?.metadata?.sourcePreservation?.sourceText
246
- ?? imported?.sourceText;
247
- }
248
-
249
240
  function aliasHashRecord(alias) {
250
241
  return alias ? JSON.stringify(compactRecord({
251
242
  sourcePath: alias.sourcePath,
@@ -258,18 +249,24 @@ function aliasHashRecord(alias) {
258
249
  })) : undefined;
259
250
  }
260
251
 
252
+ function semanticSourceSpanForHash(span) {
253
+ return span ? compactRecord({
254
+ path: span.path,
255
+ start: span.start,
256
+ end: span.end,
257
+ startLine: span.startLine,
258
+ startColumn: span.startColumn,
259
+ endLine: span.endLine,
260
+ endColumn: span.endColumn
261
+ }) : undefined;
262
+ }
263
+
261
264
  function localKey(sourcePath, name) { return sourcePath && name ? `${sourcePath}\0${name}` : undefined; }
262
265
  function exportKey(sourcePath, name) { return sourcePath && name ? `${sourcePath}\0${name}` : undefined; }
263
266
  function compactRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined)); }
264
- function objectValue(value) { return value && typeof value === 'object' && !Array.isArray(value) ? value : {}; }
265
267
  function compareJson(left, right) { return left < right ? -1 : left > right ? 1 : 0; }
266
268
  function uniqueStrings(values) { return [...new Set(values.filter((value) => typeof value === 'string' && value.length > 0))]; }
267
269
 
268
- function firstString(...values) {
269
- for (const value of values) if (value !== undefined && value !== null && String(value)) return String(value);
270
- return undefined;
271
- }
272
-
273
270
  function groupByKey(records, keyFn) {
274
271
  const result = new Map();
275
272
  for (const record of records) {
@@ -70,6 +70,10 @@ function sourceFileRecord(context) {
70
70
  exactParserTrivia: parserTriviaExactness.exactParserTrivia,
71
71
  parserTriviaEvidenceId: parserTriviaExactness.evidenceId,
72
72
  parserTriviaAdapterId: parserTriviaExactness.adapterId,
73
+ parserSpanCoverageStatus: parserTriviaExactness.parserSpanCoverageStatus,
74
+ parserSpanCoverageEvidenceId: parserTriviaExactness.parserSpanCoverageEvidenceId,
75
+ parserSpanCoverageReasonCodes: parserTriviaExactness.parserSpanCoverageReasonCodes,
76
+ parserSpanCoverageBlockReasonCodes: parserTriviaExactness.parserSpanCoverageBlockReasonCodes,
73
77
  parserTriviaExactnessReasonCodes: parserTriviaExactness.reasonCodes,
74
78
  parserTriviaExactnessBlockReasonCodes: parserTriviaExactness.blockReasonCodes,
75
79
  sourceLedgerAvailable: ownership.sourceLedgerAvailable,
@@ -159,6 +163,10 @@ function sourceSpanRecord(span, index, context, identity) {
159
163
  exactParserTrivia: parserTriviaExactness.exactParserTrivia,
160
164
  parserTriviaEvidenceId: parserTriviaExactness.evidenceId,
161
165
  parserTriviaAdapterId: parserTriviaExactness.adapterId,
166
+ parserSpanCoverageStatus: parserTriviaExactness.parserSpanCoverageStatus,
167
+ parserSpanCoverageEvidenceId: parserTriviaExactness.parserSpanCoverageEvidenceId,
168
+ parserSpanCoverageReasonCodes: parserTriviaExactness.parserSpanCoverageReasonCodes,
169
+ parserSpanCoverageBlockReasonCodes: parserTriviaExactness.parserSpanCoverageBlockReasonCodes,
162
170
  parserTriviaExactnessReasonCodes: parserTriviaExactness.reasonCodes,
163
171
  parserTriviaExactnessBlockReasonCodes: parserTriviaExactness.blockReasonCodes,
164
172
  parserTriviaOwnershipStatus,
@@ -218,6 +226,7 @@ function parserTriviaExactnessForPreservation(preservation) {
218
226
  sourceHash: preservation?.sourceHash,
219
227
  parserEvidence: tokenTriviaParserEvidence,
220
228
  parserTokenTriviaEvidence: tokenTriviaParserEvidence,
229
+ parserSpanCoverageProof: preservation?.metadata?.parserSpanCoverageProof,
221
230
  truncated: preservation?.summary?.truncated === true
222
231
  });
223
232
  }
@@ -67,6 +67,10 @@ function sourceSpanOwnershipAnchor(span, role, context, spans, index) {
67
67
  exactParserTrivia: parserTriviaExactness.exactParserTrivia,
68
68
  parserTriviaEvidenceId: parserTriviaExactness.evidenceId,
69
69
  parserTriviaAdapterId: parserTriviaExactness.adapterId,
70
+ parserSpanCoverageStatus: parserTriviaExactness.parserSpanCoverageStatus,
71
+ parserSpanCoverageEvidenceId: parserTriviaExactness.parserSpanCoverageEvidenceId,
72
+ parserSpanCoverageReasonCodes: parserTriviaExactness.parserSpanCoverageReasonCodes,
73
+ parserSpanCoverageBlockReasonCodes: parserTriviaExactness.parserSpanCoverageBlockReasonCodes,
70
74
  parserTriviaExactnessReasonCodes: parserTriviaExactness.reasonCodes,
71
75
  parserTriviaExactnessBlockReasonCodes: parserTriviaExactness.blockReasonCodes,
72
76
  ...parserTriviaOwnership
@@ -94,6 +98,7 @@ function parserTriviaExactnessForContext(context) {
94
98
  sourceHash: context.sourceHash,
95
99
  parserEvidence,
96
100
  parserTokenTriviaEvidence: parserEvidence,
101
+ parserSpanCoverageProof: context.preservation.metadata?.parserSpanCoverageProof,
97
102
  truncated: context.preservation.summary?.truncated === true
98
103
  });
99
104
  }
@@ -102,6 +107,7 @@ function parserTriviaExactnessForContext(context) {
102
107
  sourceHash: context.sourceHash,
103
108
  parserEvidence,
104
109
  parserTokenTriviaEvidence: parserEvidence,
110
+ parserSpanCoverageProof: context.preservation.metadata?.parserSpanCoverageProof,
105
111
  truncated: context.preservation.summary?.truncated === true
106
112
  });
107
113
  }
@@ -0,0 +1,54 @@
1
+ import { idFragment } from '../../native-import-utils.js';
2
+ import { createParserSpanCoverageProof } from '../../native-source-preservation-ownership.js';
3
+
4
+ export function createSyntaxAstParserSpanCoverageEvidence(input) {
5
+ const parserSpanCoverageProof = createParserSpanCoverageProof({
6
+ sourceText: input.sourceText,
7
+ sourcePath: input.sourcePath,
8
+ sourceHash: input.sourceHash,
9
+ segments: input.segments,
10
+ tokenCount: input.tokenCount,
11
+ triviaCount: input.triviaCount,
12
+ commentCount: input.commentCount,
13
+ parserEvidence: input.parserEvidence,
14
+ adapterId: input.adapterId,
15
+ evidenceId: `${input.adapterId}:parser-span-coverage:${idFragment(input.sourcePath ?? input.sourceHash)}`,
16
+ languageMode: sourceLanguageMode(input),
17
+ boundedLanguages: ['javascript', 'typescript', 'jsx', 'tsx'],
18
+ truncated: input.truncated
19
+ });
20
+ return {
21
+ parserSpanCoverageProof,
22
+ parserTriviaEvidence: parserTriviaEvidenceForSpanCoverage(parserSpanCoverageProof, input)
23
+ };
24
+ }
25
+
26
+ function parserTriviaEvidenceForSpanCoverage(parserSpanCoverageProof, input) {
27
+ const exact = parserSpanCoverageProof?.status === 'exact';
28
+ const blockReasonCodes = exact ? [] : [
29
+ 'exact-parser-trivia-span-coverage-blocked',
30
+ ...(parserSpanCoverageProof?.blockReasonCodes ?? []),
31
+ input.truncated ? 'source-preservation-truncated' : undefined
32
+ ].filter(Boolean);
33
+ return {
34
+ status: exact ? 'exact' : 'blocked',
35
+ exactParserTrivia: exact,
36
+ losslessCst: exact,
37
+ sourceHash: input.sourceHash,
38
+ adapterId: input.adapterId,
39
+ evidenceId: `${input.adapterId}:parser-token-comment:${idFragment(input.sourcePath ?? input.sourceHash)}`,
40
+ parserEvidence: input.parserEvidence,
41
+ parserSpanCoverageProof,
42
+ ...(exact ? {} : { blockReasonCodes })
43
+ };
44
+ }
45
+
46
+ function sourceLanguageMode(input) {
47
+ const sourcePath = String(input.sourcePath ?? '').toLowerCase();
48
+ if (sourcePath.endsWith('.tsx')) return 'tsx';
49
+ if (sourcePath.endsWith('.jsx')) return 'jsx';
50
+ if (sourcePath.endsWith('.ts') || sourcePath.endsWith('.mts') || sourcePath.endsWith('.cts')) return 'typescript';
51
+ if (sourcePath.endsWith('.js') || sourcePath.endsWith('.mjs') || sourcePath.endsWith('.cjs')) return 'javascript';
52
+ const language = String(input.language ?? '').toLowerCase();
53
+ return language === 'typescript' ? 'typescript' : 'javascript';
54
+ }
@@ -6,20 +6,22 @@ import {
6
6
  preservedSourceSegmentRole
7
7
  } from '../../native-source-preservation-ownership.js';
8
8
  import { createNativeSourcePreservation } from './createNativeSourcePreservation.js';
9
+ import { createSyntaxAstParserSpanCoverageEvidence } from './syntaxAstParserSpanCoverage.js';
9
10
 
10
11
  export function createSyntaxAstSourcePreservation(ast, input, options = {}) {
11
12
  if (!ast || typeof input.sourceText !== 'string') return undefined;
12
13
  const sourceText = input.sourceText;
13
14
  const sourceHash = hashSemanticValue(sourceText);
14
15
  const parserEvidence = `${options.parser ?? input.parser ?? 'syntax-ast'}-parser-token-comment-ranges`;
16
+ const adapterId = input.adapterId ?? options.adapterId ?? `${options.parser ?? input.parser ?? 'syntax'}-native-importer`;
15
17
  const tokensAndTrivia = syntaxAstTokensAndTrivia(ast, input, {
16
18
  ...options,
19
+ adapterId,
17
20
  parserEvidence,
18
21
  sourceHash,
19
22
  sourceText
20
23
  });
21
24
  if (!tokensAndTrivia?.exact) return undefined;
22
- const adapterId = input.adapterId ?? options.adapterId ?? `${options.parser ?? input.parser ?? 'syntax'}-native-importer`;
23
25
  return createNativeSourcePreservation({
24
26
  language: input.language ?? options.language ?? 'javascript',
25
27
  sourcePath: input.sourcePath,
@@ -28,15 +30,8 @@ export function createSyntaxAstSourcePreservation(ast, input, options = {}) {
28
30
  tokensAndTrivia,
29
31
  includeTokens: options.includeTokens !== false,
30
32
  includeTrivia: options.includeTrivia !== false,
31
- parserTriviaEvidence: {
32
- status: 'exact',
33
- exactParserTrivia: true,
34
- losslessCst: true,
35
- sourceHash,
36
- adapterId,
37
- evidenceId: `${adapterId}:parser-token-comment:${idFragment(input.sourcePath ?? sourceHash)}`,
38
- parserEvidence
39
- },
33
+ parserSpanCoverageProof: tokensAndTrivia.parserSpanCoverageProof,
34
+ parserTriviaEvidence: tokensAndTrivia.parserTriviaEvidence,
40
35
  metadata: {
41
36
  parserTokenTriviaEvidence: parserEvidence,
42
37
  parserTokenTriviaSource: options.astFormat ?? options.parser ?? 'syntax-ast'
@@ -56,14 +51,30 @@ function syntaxAstTokensAndTrivia(ast, input, options) {
56
51
  const whitespaceSegments = whitespaceTriviaSegments(parserSegments, input, options);
57
52
  const allTrivia = [...parserSegments.filter((segment) => segment.role === 'trivia'), ...whitespaceSegments]
58
53
  .sort((left, right) => left.span.start - right.span.start || left.span.end - right.span.end);
59
- const tokens = limitRecords(parserSegments.filter((segment) => segment.role !== 'trivia'), options.maxTokens);
60
- const trivia = limitRecords(allTrivia, options.maxTrivia);
54
+ const tokenLimit = limitRecords(parserSegments.filter((segment) => segment.role !== 'trivia'), options.maxTokens);
55
+ const triviaLimit = limitRecords(allTrivia, options.maxTrivia);
56
+ const truncated = tokenLimit.truncated || triviaLimit.truncated;
57
+ const coverage = createSyntaxAstParserSpanCoverageEvidence({
58
+ sourceText,
59
+ sourcePath: input.sourcePath,
60
+ language: input.language ?? options.language,
61
+ sourceHash: options.sourceHash,
62
+ segments: [...tokenLimit.records, ...triviaLimit.records],
63
+ tokenCount: tokenLimit.records.length,
64
+ triviaCount: triviaLimit.records.length,
65
+ commentCount: triviaLimit.records.filter((entry) => isCommentKind(entry.kind)).length,
66
+ parserEvidence: options.parserEvidence,
67
+ adapterId: options.adapterId,
68
+ truncated
69
+ });
61
70
  return {
62
71
  exact: true,
63
- tokens: tokens.records,
64
- trivia: trivia.records,
65
- truncated: tokens.truncated || trivia.truncated,
66
- parserEvidence: options.parserEvidence
72
+ tokens: tokenLimit.records.map((entry) => withParserTriviaEvidence(entry, coverage.parserTriviaEvidence)),
73
+ trivia: triviaLimit.records.map((entry) => withParserTriviaEvidence(entry, coverage.parserTriviaEvidence)),
74
+ truncated,
75
+ parserEvidence: options.parserEvidence,
76
+ parserSpanCoverageProof: coverage.parserSpanCoverageProof,
77
+ parserTriviaEvidence: coverage.parserTriviaEvidence
67
78
  };
68
79
  }
69
80
 
@@ -172,6 +183,29 @@ function preservedParserSegment(input) {
172
183
  };
173
184
  }
174
185
 
186
+ function withParserTriviaEvidence(record, parserTriviaEvidence) {
187
+ const role = preservedSourceSegmentRole(record.kind);
188
+ return {
189
+ ...record,
190
+ ownershipAnchor: createPreservedSourceOwnershipAnchor({
191
+ kind: record.kind,
192
+ role,
193
+ text: record.text,
194
+ textHash: record.textHash,
195
+ sourcePath: record.span.path,
196
+ sourceHash: record.span.sourceId,
197
+ span: record.span,
198
+ anchorKind: preservedOwnershipAnchorKind(record.kind, role),
199
+ parserEvidence: parserTriviaEvidence.parserEvidence,
200
+ parserTriviaEvidence
201
+ }),
202
+ metadata: {
203
+ ...record.metadata,
204
+ parserSpanCoverageStatus: parserTriviaEvidence.parserSpanCoverageProof?.status
205
+ }
206
+ };
207
+ }
208
+
175
209
  function parserSegmentsCoverSource(segments, sourceText) {
176
210
  let cursor = 0;
177
211
  for (const segment of segments) {
@@ -243,6 +277,10 @@ function preservedCommentKind(text) {
243
277
  return 'comment';
244
278
  }
245
279
 
280
+ function isCommentKind(kind) {
281
+ return kind === 'comment' || kind === 'jsdoc-comment' || kind === 'block-comment' || kind === 'source-map-comment';
282
+ }
283
+
246
284
  function limitRecords(records, maxValue) {
247
285
  const max = Number.isFinite(maxValue) ? Math.max(0, maxValue) : 20000;
248
286
  return { records: records.slice(0, max), truncated: records.length > max };
@@ -171,6 +171,7 @@ function scopeReferenceFingerprint(record) {
171
171
  record.signatureHash,
172
172
  record.resolvedUseHash,
173
173
  record.resolvedBindingUseHash,
174
+ record.resolvedExportUseHash,
174
175
  record.moduleSpecifier,
175
176
  record.importedName,
176
177
  record.resolvedSourcePath,
@@ -189,7 +190,11 @@ function scopeReferenceFingerprint(record) {
189
190
  record.status,
190
191
  record.reasonCodes?.join('|'),
191
192
  record.aliasResolutionStatus,
193
+ record.aliasResolutionEvidenceKind,
192
194
  record.originSourcePath,
195
+ record.originSourceHash,
196
+ record.originSourceSymbolId,
197
+ record.originSourceSymbolSignatureHash,
193
198
  record.resolvedBindingName,
194
199
  record.compilerReferenceStatus,
195
200
  record.compilerReferenceReasonCodes?.join('|'),
@@ -223,8 +228,15 @@ function scopeDetails(record) {
223
228
  moduleSpecifier: record.moduleSpecifier,
224
229
  resolvedSourcePath: record.resolvedSourcePath,
225
230
  originSourcePath: record.originSourcePath,
231
+ originSourceHash: record.originSourceHash,
232
+ originSignatureHash: record.originSignatureHash,
233
+ originSourceSymbolId: record.originSourceSymbolId,
234
+ originSourceSymbolKind: record.originSourceSymbolKind,
235
+ originSourceSymbolSignatureHash: record.originSourceSymbolSignatureHash,
226
236
  resolvedBindingName: record.resolvedBindingName,
227
237
  resolvedBindingUseHash: record.resolvedBindingUseHash,
238
+ resolvedExportUseHash: record.resolvedExportUseHash,
239
+ aliasResolutionEvidenceKind: record.aliasResolutionEvidenceKind,
228
240
  exportedNames: record.exportedNames,
229
241
  reExportedNames: record.reExportedNames,
230
242
  sourceHash: record.sourceHash
@@ -267,8 +279,15 @@ function scopeReferenceDetails(record) {
267
279
  status: record.status,
268
280
  reasonCodes: record.reasonCodes,
269
281
  aliasResolutionStatus: record.aliasResolutionStatus,
282
+ aliasResolutionEvidenceKind: record.aliasResolutionEvidenceKind,
270
283
  originSourcePath: record.originSourcePath,
284
+ originSourceHash: record.originSourceHash,
285
+ originSignatureHash: record.originSignatureHash,
286
+ originSourceSymbolId: record.originSourceSymbolId,
287
+ originSourceSymbolKind: record.originSourceSymbolKind,
288
+ originSourceSymbolSignatureHash: record.originSourceSymbolSignatureHash,
271
289
  resolvedBindingName: record.resolvedBindingName,
290
+ resolvedExportUseHash: record.resolvedExportUseHash,
272
291
  compilerReferenceStatus: record.compilerReferenceStatus,
273
292
  compilerReferenceReasonCodes: record.compilerReferenceReasonCodes,
274
293
  compilerReferenceSymbolId: record.compilerReferenceSymbolId,
@@ -96,7 +96,11 @@ function parserTriviaExactnessForFile(file, artifacts) {
96
96
  {
97
97
  sourcePath: file.sourcePath,
98
98
  sourceHash: file.outputHash,
99
- parserEvidence: artifacts?.metadata?.parserEvidence
99
+ parserEvidence: artifacts?.metadata?.parserEvidence,
100
+ parserSpanCoverageProof: file.parserSpanCoverageProof
101
+ ?? file.metadata?.parserSpanCoverageProof
102
+ ?? file.result?.metadata?.parserSpanCoverageProof
103
+ ?? artifacts?.metadata?.parserSpanCoverageProof
100
104
  }
101
105
  );
102
106
  }
@@ -207,6 +207,10 @@ function createPreservedSourceOwnershipAnchor(input = {}) {
207
207
  exactParserTrivia: parserTriviaExactness.exactParserTrivia,
208
208
  parserTriviaEvidenceId: parserTriviaExactness.evidenceId,
209
209
  parserTriviaAdapterId: parserTriviaExactness.adapterId,
210
+ parserSpanCoverageStatus: parserTriviaExactness.parserSpanCoverageStatus,
211
+ parserSpanCoverageEvidenceId: parserTriviaExactness.parserSpanCoverageEvidenceId,
212
+ parserSpanCoverageReasonCodes: parserTriviaExactness.parserSpanCoverageReasonCodes,
213
+ parserSpanCoverageBlockReasonCodes: parserTriviaExactness.parserSpanCoverageBlockReasonCodes,
210
214
  parserTriviaExactnessReasonCodes: parserTriviaExactness.reasonCodes,
211
215
  parserTriviaExactnessBlockReasonCodes: parserTriviaExactness.blockReasonCodes
212
216
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-compiler",
3
- "version": "0.2.188",
3
+ "version": "0.2.190",
4
4
  "description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",