@shapeshift-labs/frontier-lang-compiler 0.2.65 → 0.2.67
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 +37 -8
- package/bench/smoke.mjs +15 -1
- package/bench/universal-fixture-suite.mjs +183 -0
- package/dist/declarations/import-adapter-core.d.ts +3 -0
- package/dist/declarations/native-project-admission.d.ts +133 -0
- package/dist/declarations/roundtrip-audit.d.ts +177 -0
- package/dist/declarations/roundtrip.d.ts +2 -53
- package/dist/declarations/semantic-history-records.d.ts +277 -0
- package/dist/declarations/semantic-history.d.ts +45 -92
- package/dist/declarations/semantic-merge-candidates.d.ts +200 -0
- package/dist/declarations/semantic-merge-conflicts.d.ts +12 -0
- package/dist/declarations/semantic-sidecar.d.ts +8 -3
- package/dist/declarations/semantic-slice-admission.d.ts +111 -0
- package/dist/declarations/semantic-slice.d.ts +36 -1
- package/dist/declarations/universal-conversion-plan.d.ts +59 -0
- package/dist/declarations/universal-runtime-capabilities.d.ts +171 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/internal/index-impl/attachExternalOwnership.js +18 -10
- package/dist/internal/index-impl/createNativeRoundtripEvidence.js +54 -49
- package/dist/internal/index-impl/createSemanticImportSidecar.js +6 -0
- package/dist/internal/index-impl/createSemanticSlice.js +4 -3
- package/dist/internal/index-impl/createSemanticSliceAdmissionRecord.js +10 -1
- package/dist/internal/index-impl/diffNativeSourceImports.js +3 -2
- package/dist/internal/index-impl/expandSemanticSliceSelection.js +0 -1
- package/dist/internal/index-impl/externalSemanticBase.js +1 -0
- package/dist/internal/index-impl/importExternalSemanticIndex.js +4 -0
- package/dist/internal/index-impl/nativeRoundtripAudit.js +217 -0
- package/dist/internal/index-impl/projectImportAdmissionImportEvidence.js +160 -0
- package/dist/internal/index-impl/projectImportAdmissionLanguageSummaries.js +247 -0
- package/dist/internal/index-impl/projectImportAdmissionRanks.js +52 -0
- package/dist/internal/index-impl/projectImportAdmissionSummaries.js +77 -117
- package/dist/internal/index-impl/projectImportAdmissionTasks.js +239 -0
- package/dist/internal/index-impl/semanticHistoryRecordNormalizers.js +151 -0
- package/dist/internal/index-impl/semanticHistoryRecordOverlaps.js +113 -0
- package/dist/internal/index-impl/semanticHistoryRecords.js +210 -149
- package/dist/internal/index-impl/semanticMergeCandidateRecordInternals.js +314 -0
- package/dist/internal/index-impl/semanticMergeCandidateRecords.js +241 -0
- package/dist/internal/index-impl/semanticSliceAdmissionSurface.js +142 -0
- package/dist/internal/index-impl/semanticSliceExpectationAssertions.js +100 -0
- package/dist/internal/index-impl/semanticSliceExpectationRecords.js +75 -0
- package/dist/internal/index-impl/semanticSliceExpectedAssertions.js +5 -2
- package/dist/internal/index-impl/testSemanticSlice.js +4 -1
- package/dist/internal/index-impl/withExternalEmptyLoss.js +1 -0
- package/dist/language-adapter-package-contracts.js +12 -57
- package/dist/language-adapter-package-rows.js +116 -0
- package/dist/lightweight-dependency-language.js +8 -0
- package/dist/native-region-scanner-core.js +42 -10
- package/dist/native-region-scanner-js-helpers.js +2 -0
- package/dist/native-region-scanner-js-imports.js +111 -0
- package/dist/native-region-scanner-js.js +111 -28
- package/dist/universal-conversion-plan-summary.js +42 -0
- package/dist/universal-conversion-plan.js +46 -40
- package/dist/universal-runtime-capabilities.js +92 -0
- package/dist/universal-runtime-host-selectors.js +192 -0
- package/dist/universal-runtime-profiles.js +109 -0
- package/dist/universal-runtime-route-records.js +162 -0
- package/examples/js-frontier-rust-workbench-adapters.mjs +89 -0
- package/examples/js-frontier-rust-workbench-bounds.mjs +4 -3
- package/examples/js-frontier-rust-workbench-client.mjs +135 -59
- package/examples/js-frontier-rust-workbench-convert.mjs +161 -0
- package/examples/js-frontier-rust-workbench-html.mjs +20 -13
- package/examples/js-frontier-rust-workbench-route-styles.mjs +126 -0
- package/examples/js-frontier-rust-workbench-route.mjs +190 -0
- package/examples/js-frontier-rust-workbench-styles.mjs +12 -54
- package/examples/js-frontier-rust-workbench.mjs +54 -214
- package/package.json +1 -1
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import{idFragment,uniqueStrings}from'../../native-import-utils.js';
|
|
2
|
+
|
|
3
|
+
export function semanticSliceAdmissionSelectedSurface(slice){
|
|
4
|
+
return{
|
|
5
|
+
entryRefs:[...(slice?.entryRefs??[])],
|
|
6
|
+
matchedEntryRefs:[...(slice?.matchedEntryRefs??[])],
|
|
7
|
+
unresolvedEntryRefs:[...(slice?.unresolvedEntryRefs??[])],
|
|
8
|
+
symbols:(slice?.symbols??[]).map(compactAdmissionSymbol),
|
|
9
|
+
ownershipRegions:(slice?.ownershipRegions??[]).map(compactAdmissionRegion),
|
|
10
|
+
nativeNodes:(slice?.nativeNodes??[]).map(compactAdmissionNativeNode),
|
|
11
|
+
relations:(slice?.relations??[]).map(compactAdmissionRelation),
|
|
12
|
+
occurrences:(slice?.occurrences??[]).map(compactAdmissionOccurrence),
|
|
13
|
+
sourceMapLinks:(slice?.sourceMapLinks??[]).map(compactAdmissionSourceMapLink),
|
|
14
|
+
sourceSpans:(slice?.sourceSpans??[]).map(compactAdmissionSpan),
|
|
15
|
+
sourceFiles:(slice?.sourceFiles??[]).map((file)=>({
|
|
16
|
+
path:file.path,
|
|
17
|
+
sourceHash:file.sourceHash,
|
|
18
|
+
spanCount:file.spanCount,
|
|
19
|
+
excerptCount:file.excerptCount,
|
|
20
|
+
sourceTextAvailable:file.sourceTextAvailable
|
|
21
|
+
})),
|
|
22
|
+
sourceHashes:slice?.mergeAdmission?.sourceHashes??[],
|
|
23
|
+
conflictKeys:uniqueStrings(slice?.mergeAdmission?.conflictKeys??[]),
|
|
24
|
+
ownershipKeys:uniqueStrings(slice?.mergeAdmission?.ownershipKeys??[])
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function semanticSliceSelectedSurfaceEvidence(slice,selectedSurface,testResult,readiness,action){
|
|
29
|
+
return{
|
|
30
|
+
id:`evidence_${idFragment(slice?.id??'slice')}_selected_surface`,
|
|
31
|
+
kind:'semantic-slice-selected-surface',
|
|
32
|
+
status:readiness==='blocked'||testResult?.status==='failed'?'failed':'passed',
|
|
33
|
+
path:slice?.sourcePath,
|
|
34
|
+
summary:`Semantic slice admission selected ${selectedSurface.symbols.length} symbol(s), ${selectedSurface.ownershipRegions.length} ownership region(s), ${selectedSurface.relations.length} relation(s), and ${selectedSurface.sourceFiles.length} source file(s).`,
|
|
35
|
+
metadata:{
|
|
36
|
+
sliceId:slice?.id,
|
|
37
|
+
action,
|
|
38
|
+
readiness,
|
|
39
|
+
testStatus:testResult?.status,
|
|
40
|
+
selectedSurface
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function compactAdmissionSymbol(symbol){
|
|
46
|
+
return{
|
|
47
|
+
id:symbol.id,
|
|
48
|
+
name:symbol.name,
|
|
49
|
+
displayName:symbol.displayName,
|
|
50
|
+
kind:symbol.kind,
|
|
51
|
+
signature:symbol.signature,
|
|
52
|
+
nativeAstNodeId:symbol.nativeAstNodeId,
|
|
53
|
+
sourcePath:symbol.sourcePath,
|
|
54
|
+
sourceSpan:compactAdmissionSpan(symbol.sourceSpan),
|
|
55
|
+
ownershipRegionId:symbol.ownershipRegionId??symbol.metadata?.ownershipRegionId,
|
|
56
|
+
ownershipRegionKey:symbol.ownershipRegionKey??symbol.metadata?.ownershipRegionKey,
|
|
57
|
+
ownershipRegionKind:symbol.ownershipRegionKind??symbol.metadata?.ownershipRegionKind
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function compactAdmissionRegion(region){
|
|
62
|
+
return{
|
|
63
|
+
id:region.id,
|
|
64
|
+
key:region.key,
|
|
65
|
+
conflictKey:region.conflictKey,
|
|
66
|
+
kind:region.kind??region.regionKind,
|
|
67
|
+
granularity:region.granularity,
|
|
68
|
+
symbolId:region.symbolId,
|
|
69
|
+
symbolName:region.symbolName,
|
|
70
|
+
nativeAstNodeId:region.nativeAstNodeId,
|
|
71
|
+
sourcePath:region.sourcePath,
|
|
72
|
+
sourceSpan:compactAdmissionSpan(region.sourceSpan)
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function compactAdmissionNativeNode(node){
|
|
77
|
+
return{
|
|
78
|
+
id:node.id,
|
|
79
|
+
kind:node.kind,
|
|
80
|
+
languageKind:node.languageKind,
|
|
81
|
+
sourcePath:node.sourcePath,
|
|
82
|
+
sourceSpan:compactAdmissionSpan(node.sourceSpan??node.span),
|
|
83
|
+
parentId:node.parentId,
|
|
84
|
+
childCount:(node.children??[]).length
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function compactAdmissionRelation(relation){
|
|
89
|
+
return{
|
|
90
|
+
id:relation.id,
|
|
91
|
+
predicate:relation.predicate,
|
|
92
|
+
kind:relation.kind,
|
|
93
|
+
sourceId:relation.sourceId,
|
|
94
|
+
targetId:relation.targetId
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function compactAdmissionOccurrence(occurrence){
|
|
99
|
+
return{
|
|
100
|
+
id:occurrence.id,
|
|
101
|
+
symbolId:occurrence.symbolId,
|
|
102
|
+
nativeAstNodeId:occurrence.nativeAstNodeId,
|
|
103
|
+
role:occurrence.role,
|
|
104
|
+
sourcePath:occurrence.sourcePath,
|
|
105
|
+
sourceSpan:compactAdmissionSpan(occurrence.sourceSpan??occurrence.span)
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function compactAdmissionSourceMapLink(link){
|
|
110
|
+
return{
|
|
111
|
+
id:link.id,
|
|
112
|
+
sourceMapId:link.sourceMapId,
|
|
113
|
+
sourcePath:link.sourcePath,
|
|
114
|
+
sourceHash:link.sourceHash,
|
|
115
|
+
targetPath:link.targetPath,
|
|
116
|
+
targetHash:link.targetHash,
|
|
117
|
+
semanticSymbolId:link.semanticSymbolId,
|
|
118
|
+
semanticOccurrenceId:link.semanticOccurrenceId,
|
|
119
|
+
semanticNodeId:link.semanticNodeId,
|
|
120
|
+
nativeAstNodeId:link.nativeAstNodeId,
|
|
121
|
+
ownershipRegionId:link.ownershipRegionId,
|
|
122
|
+
ownershipRegionKey:link.ownershipRegionKey,
|
|
123
|
+
ownershipRegionKind:link.ownershipRegionKind,
|
|
124
|
+
precision:link.precision,
|
|
125
|
+
sourceSpan:compactAdmissionSpan(link.sourceSpan)
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function compactAdmissionSpan(span){
|
|
130
|
+
if(!span)return undefined;
|
|
131
|
+
return{
|
|
132
|
+
path:span.path,
|
|
133
|
+
sourceId:span.sourceId,
|
|
134
|
+
sourceHash:span.sourceHash,
|
|
135
|
+
startLine:span.startLine,
|
|
136
|
+
startColumn:span.startColumn,
|
|
137
|
+
endLine:span.endLine,
|
|
138
|
+
endColumn:span.endColumn,
|
|
139
|
+
startOffset:span.startOffset,
|
|
140
|
+
endOffset:span.endOffset
|
|
141
|
+
};
|
|
142
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import{semanticSliceAssertion}from'./semanticSliceAssertion.js';import{semanticSliceExpectationRecords}from'./semanticSliceExpectationRecords.js';import{semanticSliceRegionMatchesRef}from'./semanticSliceRegionMatchesRef.js';import{semanticSliceSymbolMatchesRef}from'./semanticSliceSymbolMatchesRef.js';
|
|
2
|
+
|
|
3
|
+
export function semanticSliceExpectationAssertions(slice, options = {}) {
|
|
4
|
+
const assertions = [];
|
|
5
|
+
for (const expectation of semanticSliceTestExpectations(slice, options)) {
|
|
6
|
+
if (expectation.category === 'symbol') {
|
|
7
|
+
const ok = (slice?.symbols ?? []).some((symbol) => semanticSliceSymbolMatchesRef(symbol, expectation.ref));
|
|
8
|
+
assertions.push(semanticSliceAssertion(expectation.id, ok, ok ? `Expected symbol ${expectation.ref} is present.` : `Expected symbol ${expectation.ref} is missing.`, {
|
|
9
|
+
expectedRef: expectation.ref,
|
|
10
|
+
selectedSymbols: compactSymbols(slice?.symbols)
|
|
11
|
+
}));
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
if (expectation.category === 'region') {
|
|
15
|
+
const ok = (slice?.ownershipRegions ?? []).some((region) => semanticSliceRegionMatchesRef(region, expectation.ref));
|
|
16
|
+
assertions.push(semanticSliceAssertion(expectation.id, ok, ok ? `Expected region ${expectation.ref} is present.` : `Expected region ${expectation.ref} is missing.`, {
|
|
17
|
+
expectedRef: expectation.ref,
|
|
18
|
+
selectedRegions: compactRegions(slice?.ownershipRegions)
|
|
19
|
+
}));
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (expectation.category === 'sourceHash') {
|
|
23
|
+
const actual = semanticSliceActualSourceHash(slice, expectation.path);
|
|
24
|
+
const ok = Boolean(actual) && actual === expectation.expected;
|
|
25
|
+
assertions.push(semanticSliceAssertion(expectation.id, ok, ok ? `Expected source hash matched for ${expectation.path ?? 'the selected source file'}.` : `Expected source hash did not match for ${expectation.path ?? 'the selected source file'}.`, {
|
|
26
|
+
path: expectation.path,
|
|
27
|
+
expectedSourceHash: expectation.expected,
|
|
28
|
+
actualSourceHash: actual,
|
|
29
|
+
selectedSourceHashes: slice?.mergeAdmission?.sourceHashes ?? []
|
|
30
|
+
}));
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (expectation.category === 'summaryCount') {
|
|
34
|
+
const actual = semanticSliceSummaryCount(slice, expectation.key);
|
|
35
|
+
const ok = actual === expectation.expected;
|
|
36
|
+
assertions.push(semanticSliceAssertion(expectation.id, ok, ok ? `Expected ${expectation.key} count matched.` : `Expected ${expectation.key} count did not match.`, {
|
|
37
|
+
key: expectation.key,
|
|
38
|
+
expected: expectation.expected,
|
|
39
|
+
actual
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return assertions;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function semanticSliceTestExpectations(slice, options) {
|
|
47
|
+
const known = new Set(['symbol', 'region', 'sourceHash', 'summaryCount']);
|
|
48
|
+
const records = [
|
|
49
|
+
...(slice?.verification?.expectedAssertions ?? []).filter((record) => known.has(record?.category)),
|
|
50
|
+
...semanticSliceExpectationRecords(options)
|
|
51
|
+
];
|
|
52
|
+
const seen = new Set();
|
|
53
|
+
const result = [];
|
|
54
|
+
for (const record of records) {
|
|
55
|
+
const key = `${record.id}:${record.expected}`;
|
|
56
|
+
if (seen.has(key)) continue;
|
|
57
|
+
seen.add(key);
|
|
58
|
+
result.push(record);
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function semanticSliceActualSourceHash(slice, path) {
|
|
64
|
+
const hashes = slice?.mergeAdmission?.sourceHashes ?? [];
|
|
65
|
+
if (path) return hashes.find((entry) => entry.path === path)?.sourceHash ?? (slice?.sourceFiles ?? []).find((file) => file.path === path)?.sourceHash;
|
|
66
|
+
if (hashes.length === 1) return hashes[0]?.sourceHash;
|
|
67
|
+
if ((slice?.sourceFiles?.length ?? 0) === 1) return slice.sourceFiles[0]?.sourceHash;
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function semanticSliceSummaryCount(slice, key) {
|
|
72
|
+
if (key === 'symbols') return slice?.summary?.symbols ?? slice?.symbols?.length ?? 0;
|
|
73
|
+
if (key === 'ownershipRegions') return slice?.summary?.ownershipRegions ?? slice?.ownershipRegions?.length ?? 0;
|
|
74
|
+
if (key === 'sourceFiles') return slice?.summary?.sourceFiles ?? slice?.sourceFiles?.length ?? 0;
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function compactSymbols(symbols) {
|
|
79
|
+
return (symbols ?? []).map((symbol) => ({
|
|
80
|
+
id: symbol.id,
|
|
81
|
+
name: symbol.name,
|
|
82
|
+
displayName: symbol.displayName,
|
|
83
|
+
nativeAstNodeId: symbol.nativeAstNodeId,
|
|
84
|
+
ownershipRegionId: symbol.ownershipRegionId ?? symbol.metadata?.ownershipRegionId,
|
|
85
|
+
ownershipRegionKey: symbol.ownershipRegionKey ?? symbol.metadata?.ownershipRegionKey
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function compactRegions(regions) {
|
|
90
|
+
return (regions ?? []).map((region) => ({
|
|
91
|
+
id: region.id,
|
|
92
|
+
key: region.key,
|
|
93
|
+
kind: region.kind ?? region.regionKind,
|
|
94
|
+
granularity: region.granularity,
|
|
95
|
+
symbolId: region.symbolId,
|
|
96
|
+
symbolName: region.symbolName,
|
|
97
|
+
sourcePath: region.sourcePath,
|
|
98
|
+
nativeAstNodeId: region.nativeAstNodeId
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import{readStringArray}from'./readStringArray.js';
|
|
2
|
+
|
|
3
|
+
export function semanticSliceExpectationRecords(options={}) {
|
|
4
|
+
const records = [];
|
|
5
|
+
for (const ref of readStringArray(options.expectedSymbols ?? options.expectedSymbolRefs)) {
|
|
6
|
+
records.push({ id: `expectedSymbol:${ref}`, category: 'symbol', ref, expected: true });
|
|
7
|
+
}
|
|
8
|
+
for (const ref of readStringArray(options.expectedRegions ?? options.expectedRegionRefs)) {
|
|
9
|
+
records.push({ id: `expectedRegion:${ref}`, category: 'region', ref, expected: true });
|
|
10
|
+
}
|
|
11
|
+
for (const entry of semanticSliceSourceHashExpectationRecords(options.expectedSourceHashes)) {
|
|
12
|
+
records.push(entry);
|
|
13
|
+
}
|
|
14
|
+
addSummaryCount(records, 'symbols', options.expectedSymbolCount);
|
|
15
|
+
addSummaryCount(records, 'ownershipRegions', options.expectedRegionCount);
|
|
16
|
+
addSummaryCount(records, 'sourceFiles', options.expectedSourceFileCount);
|
|
17
|
+
return uniqueExpectationRecords(records);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function semanticSliceSourceHashExpectationRecords(value) {
|
|
21
|
+
const records = [];
|
|
22
|
+
const add = (path, sourceHash) => {
|
|
23
|
+
if (!sourceHash) return;
|
|
24
|
+
const normalizedPath = path === undefined || path === null || path === '' ? undefined : String(path);
|
|
25
|
+
records.push({
|
|
26
|
+
id: `expectedSourceHash:${normalizedPath ?? '*'}`,
|
|
27
|
+
category: 'sourceHash',
|
|
28
|
+
path: normalizedPath,
|
|
29
|
+
expected: String(sourceHash)
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
if (!value) return records;
|
|
33
|
+
if (Array.isArray(value)) {
|
|
34
|
+
for (const entry of value) {
|
|
35
|
+
if (Array.isArray(entry)) {
|
|
36
|
+
add(entry[0], entry[1]);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (entry && typeof entry === 'object') {
|
|
40
|
+
add(entry.path ?? entry.sourcePath, entry.sourceHash ?? entry.hash ?? entry.expected);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return records;
|
|
44
|
+
}
|
|
45
|
+
if (typeof value.entries === 'function') {
|
|
46
|
+
for (const [path, sourceHash] of value.entries()) add(path, sourceHash);
|
|
47
|
+
return records;
|
|
48
|
+
}
|
|
49
|
+
if (typeof value === 'object') {
|
|
50
|
+
for (const [path, sourceHash] of Object.entries(value)) add(path, sourceHash);
|
|
51
|
+
}
|
|
52
|
+
return records;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function addSummaryCount(records, key, value) {
|
|
56
|
+
if (!Number.isFinite(value)) return;
|
|
57
|
+
records.push({
|
|
58
|
+
id: `expectedCount:${key}`,
|
|
59
|
+
category: 'summaryCount',
|
|
60
|
+
key,
|
|
61
|
+
expected: Math.max(0, Math.floor(value))
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function uniqueExpectationRecords(records) {
|
|
66
|
+
const seen = new Set();
|
|
67
|
+
const result = [];
|
|
68
|
+
for (const record of records) {
|
|
69
|
+
const key = `${record.id}:${record.expected}`;
|
|
70
|
+
if (seen.has(key)) continue;
|
|
71
|
+
seen.add(key);
|
|
72
|
+
result.push(record);
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import{semanticSliceExpectationRecords}from'./semanticSliceExpectationRecords.js';
|
|
2
|
+
|
|
3
|
+
export function semanticSliceExpectedAssertions(selection, unresolvedEntryRefs, options = {}) {
|
|
2
4
|
return [
|
|
3
5
|
{ id: 'entryRefsResolved', expected: unresolvedEntryRefs.length === 0 },
|
|
4
6
|
{ id: 'nonEmptySelection', expected: selection.symbols.length + selection.regions.length + selection.nativeNodes.length > 0 },
|
|
5
7
|
{ id: 'sourceMapLinks', expected: selection.mappings.length > 0 },
|
|
6
|
-
{ id: 'conflictKeys', expected: true }
|
|
8
|
+
{ id: 'conflictKeys', expected: true },
|
|
9
|
+
...semanticSliceExpectationRecords(options)
|
|
7
10
|
];
|
|
8
11
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import{idFragment,maxSemanticMergeReadiness}from'../../native-import-utils.js';
|
|
2
|
-
import{semanticSliceAssertion}from'./semanticSliceAssertion.js';import{semanticSliceSourceHashAssertions}from'./semanticSliceSourceHashAssertions.js';
|
|
2
|
+
import{semanticSliceAssertion}from'./semanticSliceAssertion.js';import{semanticSliceExpectationAssertions}from'./semanticSliceExpectationAssertions.js';import{semanticSliceSourceHashAssertions}from'./semanticSliceSourceHashAssertions.js';
|
|
3
3
|
export function testSemanticSlice(slice, options = {}) {
|
|
4
4
|
const assertions = [];
|
|
5
5
|
assertions.push(semanticSliceAssertion('kind', slice?.kind === 'frontier.lang.semanticSlice', 'Input is a Frontier semantic slice.'));
|
|
@@ -11,6 +11,8 @@ export function testSemanticSlice(slice, options = {}) {
|
|
|
11
11
|
assertions.push(semanticSliceAssertion('conflictKeys', (slice?.mergeAdmission?.conflictKeys?.length ?? 0) > 0, 'Slice exposes merge-admission conflict keys.'));
|
|
12
12
|
const sourceHashAssertions = semanticSliceSourceHashAssertions(slice, options.currentSources);
|
|
13
13
|
assertions.push(...sourceHashAssertions);
|
|
14
|
+
const expectationAssertions = semanticSliceExpectationAssertions(slice, options);
|
|
15
|
+
assertions.push(...expectationAssertions);
|
|
14
16
|
const failed = assertions.filter((assertion) => assertion.status === 'failed');
|
|
15
17
|
const warnings = assertions.filter((assertion) => assertion.status === 'warning');
|
|
16
18
|
const readiness = failed.length
|
|
@@ -31,6 +33,7 @@ export function testSemanticSlice(slice, options = {}) {
|
|
|
31
33
|
warnings: warnings.length,
|
|
32
34
|
failed: failed.length,
|
|
33
35
|
sourceHashChecks: sourceHashAssertions.length,
|
|
36
|
+
expectedAssertions: expectationAssertions.length,
|
|
34
37
|
symbols: slice?.summary?.symbols ?? slice?.symbols?.length ?? 0,
|
|
35
38
|
ownershipRegions: slice?.summary?.ownershipRegions ?? slice?.ownershipRegions?.length ?? 0,
|
|
36
39
|
sourceMapLinks: slice?.summary?.sourceMapLinks ?? slice?.sourceMapLinks?.length ?? 0
|
|
@@ -26,6 +26,7 @@ export function withExternalEmptyLoss(result, context) {
|
|
|
26
26
|
result.occurrences = uniqueRecordsById(result.occurrences);
|
|
27
27
|
result.relations = uniqueRecordsById(result.relations);
|
|
28
28
|
result.facts = uniqueRecordsById(result.facts);
|
|
29
|
+
result.ownershipRegions = uniqueRecordsById(result.ownershipRegions);
|
|
29
30
|
result.losses = uniqueByLossId(result.losses);
|
|
30
31
|
result.evidence = uniqueByEvidenceId(result.evidence);
|
|
31
32
|
return result;
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
normalizeNativeLanguageId,
|
|
11
11
|
uniqueStrings
|
|
12
12
|
} from './native-import-utils.js';
|
|
13
|
+
import { packageRows } from './language-adapter-package-rows.js';
|
|
13
14
|
|
|
14
15
|
export const LanguageAdapterPackageReleaseReadinessStatuses = Object.freeze([
|
|
15
16
|
'ready',
|
|
@@ -18,23 +19,6 @@ export const LanguageAdapterPackageReleaseReadinessStatuses = Object.freeze([
|
|
|
18
19
|
'blocked'
|
|
19
20
|
]);
|
|
20
21
|
|
|
21
|
-
const packageRows = [
|
|
22
|
-
row('@shapeshift-labs/frontier-lang-typescript', '0.3.8', 'typescript', 'typescript-compiler-api', { target: 'typescript' }),
|
|
23
|
-
row('@shapeshift-labs/frontier-lang-javascript', '0.2.8', 'javascript', 'estree', { target: 'javascript', formats: ['estree', 'babel'] }),
|
|
24
|
-
row('@shapeshift-labs/frontier-lang-rust', '0.2.8', 'rust', 'rust-syn', { target: 'rust', proofKeys: ['parserAst', 'sourceMap', 'semanticSidecar', 'macroExpansionEvidence'] }),
|
|
25
|
-
row('@shapeshift-labs/frontier-lang-python', '0.2.8', 'python', 'python-ast', { target: 'python', formats: ['python-ast', 'libcst'] }),
|
|
26
|
-
row('@shapeshift-labs/frontier-lang-c', '0.2.8', 'c', 'clang-ast-json', { target: 'c', proofKeys: ['parserAst', 'sourceMap', 'semanticSidecar', 'compileCommandsHash', 'preprocessorRecordsHash'] }),
|
|
27
|
-
platform('@shapeshift-labs/frontier-lang-java', '0.1.8', 'java', 'java-ast', ['semanticdb', 'lsp']),
|
|
28
|
-
platform('@shapeshift-labs/frontier-lang-kotlin', '0.1.8', 'kotlin', 'kotlin-psi', ['semanticdb', 'lsp']),
|
|
29
|
-
platform('@shapeshift-labs/frontier-lang-swift', '0.1.8', 'swift', 'swift-syntax', ['sourcekit-lsp', 'lsp']),
|
|
30
|
-
platform('@shapeshift-labs/frontier-lang-csharp', '0.1.8', 'csharp', 'roslyn-csharp', ['lsp']),
|
|
31
|
-
platform('@shapeshift-labs/frontier-lang-go', '0.1.8', 'go', 'go-ast', ['lsp']),
|
|
32
|
-
platform('@shapeshift-labs/frontier-lang-clang', '0.1.8', 'c', 'clang-ast-json', ['lsp'], {
|
|
33
|
-
supportedLanguages: ['c', 'cpp'],
|
|
34
|
-
proofKeys: ['parserAst', 'semanticIndex', 'compileCommandsHash', 'preprocessorRecordsHash']
|
|
35
|
-
})
|
|
36
|
-
];
|
|
37
|
-
|
|
38
22
|
export const LanguageAdapterPackageContracts = Object.freeze(packageRows.map(createLanguageAdapterPackageContract));
|
|
39
23
|
|
|
40
24
|
export function createLanguageAdapterPackageContract(input = {}) {
|
|
@@ -131,7 +115,7 @@ export function getLanguageAdapterPackageContract(ref, contracts = LanguageAdapt
|
|
|
131
115
|
contract.packageName === text ||
|
|
132
116
|
contract.package.name === text ||
|
|
133
117
|
contract.package.adapterId === text ||
|
|
134
|
-
contract
|
|
118
|
+
(normalized && contractSupportsLanguage(contract, normalized))
|
|
135
119
|
);
|
|
136
120
|
}
|
|
137
121
|
|
|
@@ -142,7 +126,7 @@ export function queryLanguageAdapterPackageContracts(query = {}, contracts = Lan
|
|
|
142
126
|
return (contracts ?? []).filter((contract) =>
|
|
143
127
|
(!query.packageName || contract.packageName === query.packageName) &&
|
|
144
128
|
(!query.packageClass || contract.package.packageClass === query.packageClass) &&
|
|
145
|
-
(
|
|
129
|
+
contractSupportsLanguage(contract, language) &&
|
|
146
130
|
(!target || contract.targetProjection.targets.includes(target)) &&
|
|
147
131
|
(!semanticFormat || contract.semanticIndex.formats.map((format) => format.toLowerCase()).includes(semanticFormat)) &&
|
|
148
132
|
(query.releaseReady === undefined || contract.releaseReadiness.releaseReady === query.releaseReady) &&
|
|
@@ -168,44 +152,6 @@ export function summarizeLanguageAdapterPackageContracts(contracts = LanguageAda
|
|
|
168
152
|
});
|
|
169
153
|
}
|
|
170
154
|
|
|
171
|
-
function row(packageName, packageVersion, language, parser, input = {}) {
|
|
172
|
-
return {
|
|
173
|
-
packageName,
|
|
174
|
-
packageVersion,
|
|
175
|
-
language,
|
|
176
|
-
parser,
|
|
177
|
-
supportedFormats: input.formats,
|
|
178
|
-
target: input.target,
|
|
179
|
-
packageClass: 'target-projection',
|
|
180
|
-
releaseReadiness: { status: 'ready-with-losses', releaseReady: true, versionSource: 'package-json-dependency' },
|
|
181
|
-
semanticIndex: { formats: ['frontier-semantic-index', 'scip', 'lsif', 'lsp'], hostEvidenceRequired: false },
|
|
182
|
-
proofKeys: input.proofKeys
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function platform(packageName, packageVersion, language, parser, semanticFormats, input = {}) {
|
|
187
|
-
const published = packageVersion !== '0.0.0';
|
|
188
|
-
return {
|
|
189
|
-
packageName,
|
|
190
|
-
packageVersion,
|
|
191
|
-
language,
|
|
192
|
-
parser,
|
|
193
|
-
supportedLanguages: input.supportedLanguages,
|
|
194
|
-
supportedFormats: input.formats,
|
|
195
|
-
packageClass: 'platform-importer',
|
|
196
|
-
targetProjection: { targets: [], caveats: input.targetCaveats },
|
|
197
|
-
releaseReadiness: {
|
|
198
|
-
status: published ? 'ready-with-losses' : 'needs-review',
|
|
199
|
-
releaseReady: published,
|
|
200
|
-
versionSource: published ? 'static-package-catalog' : 'related-package-catalog-placeholder',
|
|
201
|
-
signals: input.signals
|
|
202
|
-
},
|
|
203
|
-
semanticIndex: { formats: ['frontier-semantic-index', ...semanticFormats], hostEvidenceRequired: true },
|
|
204
|
-
proofEvidence: { hostEvidenceRequired: true, requiredEvidenceKeys: input.proofKeys ?? ['parserAst', 'semanticIndex', 'buildGraphEvidence'] },
|
|
205
|
-
parserCaveats: input.parserCaveats
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
|
|
209
155
|
function projectionRows(input, language) {
|
|
210
156
|
const targets = input.targetProjection?.targets ?? input.targets ?? input.target ?? nativeProjectionTargetsForLanguage(language);
|
|
211
157
|
const normalizedTargets = freezeStrings(targets);
|
|
@@ -274,6 +220,15 @@ function targetProjectionCaveats(targetRows, packageClass) {
|
|
|
274
220
|
return caveats;
|
|
275
221
|
}
|
|
276
222
|
|
|
223
|
+
function contractSupportsLanguage(contract, language) {
|
|
224
|
+
if (!language) return true;
|
|
225
|
+
const languageIds = [
|
|
226
|
+
contract.sourceParser?.language,
|
|
227
|
+
...(contract.sourceParser?.supportedLanguages ?? [])
|
|
228
|
+
].map(normalizeNativeLanguageId).filter(Boolean);
|
|
229
|
+
return languageIds.includes(language);
|
|
230
|
+
}
|
|
231
|
+
|
|
277
232
|
function adapterFamily(language, parser) {
|
|
278
233
|
if (language === 'javascript' || language === 'typescript') return 'javascript-typescript';
|
|
279
234
|
if (language === 'java' || language === 'kotlin') return 'jvm';
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
const packageRows = [
|
|
2
|
+
row('@shapeshift-labs/frontier-lang-typescript', '0.3.8', 'typescript', 'typescript-compiler-api', { target: 'typescript' }),
|
|
3
|
+
row('@shapeshift-labs/frontier-lang-javascript', '0.2.8', 'javascript', 'estree', { target: 'javascript', formats: ['estree', 'babel'] }),
|
|
4
|
+
row('@shapeshift-labs/frontier-lang-rust', '0.2.8', 'rust', 'rust-syn', { target: 'rust', proofKeys: ['parserAst', 'sourceMap', 'semanticSidecar', 'macroExpansionEvidence'] }),
|
|
5
|
+
row('@shapeshift-labs/frontier-lang-python', '0.2.8', 'python', 'python-ast', { target: 'python', formats: ['python-ast', 'libcst'] }),
|
|
6
|
+
row('@shapeshift-labs/frontier-lang-c', '0.2.8', 'c', 'clang-ast-json', { target: 'c', proofKeys: ['parserAst', 'sourceMap', 'semanticSidecar', 'compileCommandsHash', 'preprocessorRecordsHash'] }),
|
|
7
|
+
platform('@shapeshift-labs/frontier-lang-java', '0.1.8', 'java', 'java-ast', ['semanticdb', 'lsp']),
|
|
8
|
+
platform('@shapeshift-labs/frontier-lang-kotlin', '0.1.8', 'kotlin', 'kotlin-psi', ['semanticdb', 'lsp']),
|
|
9
|
+
platform('@shapeshift-labs/frontier-lang-swift', '0.1.8', 'swift', 'swift-syntax', ['sourcekit-lsp', 'lsp']),
|
|
10
|
+
platform('@shapeshift-labs/frontier-lang-csharp', '0.1.8', 'csharp', 'roslyn-csharp', ['lsp']),
|
|
11
|
+
platform('@shapeshift-labs/frontier-lang-go', '0.1.8', 'go', 'go-ast', ['lsp']),
|
|
12
|
+
platform('@shapeshift-labs/frontier-lang-clang', '0.1.8', 'c', 'clang-ast-json', ['lsp'], {
|
|
13
|
+
supportedLanguages: ['c', 'cpp'],
|
|
14
|
+
proofKeys: ['parserAst', 'semanticIndex', 'compileCommandsHash', 'preprocessorRecordsHash']
|
|
15
|
+
}),
|
|
16
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-lisp', 'lisp', 'tree-sitter-lisp', ['lsp'], {
|
|
17
|
+
supportedLanguages: ['lisp', 'common-lisp', 'scheme', 'racket'],
|
|
18
|
+
formats: ['tree-sitter'],
|
|
19
|
+
family: 'lisp-scheme',
|
|
20
|
+
parserCaveats: ['Lisp and Scheme contracts need host evidence for reader conditionals, package/module systems, macros, quoting semantics, source ranges, and comment/trivia preservation.']
|
|
21
|
+
}),
|
|
22
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-haskell', 'haskell', 'ghc-api', ['lsp'], {
|
|
23
|
+
parserCaveats: ['GHC API parse trees require host evidence for CPP, Template Haskell, quasiquotes, package flags, renamer/typechecker facts, source ranges, and layout-sensitive source preservation.']
|
|
24
|
+
}),
|
|
25
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-erlang', 'erlang', 'erl_parse', ['lsp'], {
|
|
26
|
+
parserCaveats: ['Erlang parser contracts require host evidence for include paths, record definitions, macros, parse transforms, specs, source ranges, and comments/trivia preservation.']
|
|
27
|
+
}),
|
|
28
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-elixir', 'elixir', 'elixir-quoted', ['lsp'], {
|
|
29
|
+
parserCaveats: ['Elixir quoted AST contracts require host evidence for macro expansion, aliases/imports, protocols, Mix compile context, generated code, source ranges, and formatter trivia.']
|
|
30
|
+
}),
|
|
31
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-ruby', 'ruby', 'prism', ['lsp'], {
|
|
32
|
+
parserCaveats: ['Ruby parser contracts require host evidence for dynamic constant lookup, refinements, metaprogramming, comments/trivia, source ranges, and optional type signature ecosystems.']
|
|
33
|
+
}),
|
|
34
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-php', 'php', 'php-parser', ['lsp'], {
|
|
35
|
+
parserCaveats: ['PHP parser contracts require host evidence for Composer/autoload context, conditional declarations, attributes, PHPDoc, generated code, source ranges, and comments/trivia.']
|
|
36
|
+
}),
|
|
37
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-lua', 'lua', 'luaparse', ['lsp'], {
|
|
38
|
+
parserCaveats: ['Lua parser contracts require host evidence for dynamic module loading, metatables, embedded DSLs, comments/trivia, source ranges, and version-specific syntax.']
|
|
39
|
+
}),
|
|
40
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-r', 'r', 'r-parser', ['lsp'], {
|
|
41
|
+
parserCaveats: ['R parser contracts require host evidence for non-standard evaluation, library search paths, generated code, comments/trivia, source ranges, and version-specific syntax.']
|
|
42
|
+
}),
|
|
43
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-julia', 'julia', 'julia-syntax', ['lsp'], {
|
|
44
|
+
parserCaveats: ['Julia parser contracts require host evidence for macro expansion, generated functions, multiple dispatch/type facts, package environments, source ranges, and comments/trivia.']
|
|
45
|
+
}),
|
|
46
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-zig', 'zig', 'zig-ast', ['lsp'], {
|
|
47
|
+
parserCaveats: ['Zig parser contracts require host evidence for comptime evaluation, build.zig context, imports, generated code, source ranges, and comments/trivia preservation.']
|
|
48
|
+
}),
|
|
49
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-ocaml', 'ocaml', 'ocaml-parsetree', ['lsp'], {
|
|
50
|
+
parserCaveats: ['OCaml parsetree contracts require host evidence for PPX rewrites, module/functor resolution, typedtree facts, Dune context, source ranges, and comments/trivia.']
|
|
51
|
+
}),
|
|
52
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-scala', 'scala', 'scalameta', ['semanticdb', 'lsp'], {
|
|
53
|
+
parserCaveats: ['Scala parser contracts require host evidence for Scala 2/3 dialects, macros, givens/implicits, SemanticDB/TASTy facts, build targets, source ranges, and comments/trivia.']
|
|
54
|
+
}),
|
|
55
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-dart', 'dart', 'dart-analyzer', ['lsp'], {
|
|
56
|
+
parserCaveats: ['Dart analyzer contracts require host evidence for analysis context, null-safety mode, package config, build_runner generated sources, source ranges, and comments/trivia.']
|
|
57
|
+
}),
|
|
58
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-sql', 'sql', 'sqlparser', ['lsp'], {
|
|
59
|
+
supportedLanguages: ['sql', 'postgresql', 'postgres', 'mysql', 'sqlite', 'tsql'],
|
|
60
|
+
parserCaveats: ['SQL parser contracts require host evidence for dialect selection, schema/catalog metadata, migrations, vendor extensions, procedural SQL blocks, source ranges, and comments/trivia.']
|
|
61
|
+
}),
|
|
62
|
+
plannedPlatform('@shapeshift-labs/frontier-lang-shader', 'shader', 'tree-sitter-shader', ['lsp', 'spirv-reflect'], {
|
|
63
|
+
supportedLanguages: ['shader', 'glsl', 'hlsl', 'wgsl', 'slang'],
|
|
64
|
+
formats: ['tree-sitter'],
|
|
65
|
+
family: 'shader',
|
|
66
|
+
parserCaveats: ['Shader parser contracts require host evidence for dialect selection, preprocessor/includes, entry points, resource layouts, generated variants, source ranges, and reflection data.']
|
|
67
|
+
})
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
export { packageRows };
|
|
71
|
+
|
|
72
|
+
function row(packageName, packageVersion, language, parser, input = {}) {
|
|
73
|
+
return {
|
|
74
|
+
packageName,
|
|
75
|
+
packageVersion,
|
|
76
|
+
language,
|
|
77
|
+
parser,
|
|
78
|
+
supportedFormats: input.formats,
|
|
79
|
+
target: input.target,
|
|
80
|
+
packageClass: 'target-projection',
|
|
81
|
+
releaseReadiness: { status: 'ready-with-losses', releaseReady: true, versionSource: 'package-json-dependency' },
|
|
82
|
+
semanticIndex: { formats: ['frontier-semantic-index', 'scip', 'lsif', 'lsp'], hostEvidenceRequired: false },
|
|
83
|
+
proofKeys: input.proofKeys
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function platform(packageName, packageVersion, language, parser, semanticFormats, input = {}) {
|
|
88
|
+
const published = packageVersion !== '0.0.0';
|
|
89
|
+
return {
|
|
90
|
+
packageName,
|
|
91
|
+
packageVersion,
|
|
92
|
+
language,
|
|
93
|
+
parser,
|
|
94
|
+
family: input.family,
|
|
95
|
+
supportedLanguages: input.supportedLanguages,
|
|
96
|
+
supportedFormats: input.formats,
|
|
97
|
+
packageClass: 'platform-importer',
|
|
98
|
+
targetProjection: { targets: [], caveats: input.targetCaveats },
|
|
99
|
+
releaseReadiness: {
|
|
100
|
+
status: published ? 'ready-with-losses' : 'needs-review',
|
|
101
|
+
releaseReady: published,
|
|
102
|
+
versionSource: published ? 'static-package-catalog' : 'related-package-catalog-placeholder',
|
|
103
|
+
signals: input.signals
|
|
104
|
+
},
|
|
105
|
+
semanticIndex: { formats: ['frontier-semantic-index', ...semanticFormats], hostEvidenceRequired: true },
|
|
106
|
+
proofEvidence: { hostEvidenceRequired: true, requiredEvidenceKeys: input.proofKeys ?? ['parserAst', 'semanticIndex', 'buildGraphEvidence'] },
|
|
107
|
+
parserCaveats: input.parserCaveats
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function plannedPlatform(packageName, language, parser, semanticFormats, input = {}) {
|
|
112
|
+
return platform(packageName, '0.0.0', language, parser, semanticFormats, {
|
|
113
|
+
proofKeys: ['parserAst', 'semanticIndex', 'sourceMap', 'sourcePreservationEvidence', 'projectionCaveats'],
|
|
114
|
+
...input
|
|
115
|
+
});
|
|
116
|
+
}
|
|
@@ -11,6 +11,14 @@ const ignoredIdentifiers = new Set([
|
|
|
11
11
|
|
|
12
12
|
export function dependencyIdentifiers(input, declaration, line) {
|
|
13
13
|
const identifiers = new Set();
|
|
14
|
+
if (declaration.role === 'import' && declaration.fields?.moduleOnly && Array.isArray(declaration.fields.importBindings) && declaration.fields.importBindings.length > 0) {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
if (declaration.role === 'import' && declaration.fields?.localName) {
|
|
18
|
+
addIdentifier(identifiers, declaration.fields.localName);
|
|
19
|
+
addIdentifier(identifiers, declaration.fields.importedName);
|
|
20
|
+
return [...identifiers];
|
|
21
|
+
}
|
|
14
22
|
addIdentifier(identifiers, declaration.name);
|
|
15
23
|
for (const part of splitIdentifierPath(declaration.name)) addIdentifier(identifiers, part);
|
|
16
24
|
for (const field of ['methodName', 'propertyName', 'owner']) addIdentifier(identifiers, declaration.fields?.[field]);
|