@shapeshift-labs/frontier-lang-compiler 0.2.145 → 0.2.146
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/internal/index-impl/syntaxDeclaration.js +23 -0
- package/dist/internal/index-impl/typeScriptDeclaration.js +14 -0
- package/dist/internal/index-impl/typeScriptExportedDeclarationEntries.js +1 -0
- package/dist/js-ts-safe-project-merge-graph.js +30 -7
- package/dist/js-ts-safe-project-merge-public-contracts.js +117 -0
- package/package.json +1 -1
|
@@ -15,6 +15,29 @@ export function syntaxDeclaration(node, nativeNodeId, input) {
|
|
|
15
15
|
if (kind === 'ClassDeclaration') return namedDeclaration(input, nativeNodeId, node.id, 'class');
|
|
16
16
|
if (kind === 'TSInterfaceDeclaration' || kind === 'InterfaceDeclaration') return namedDeclaration(input, nativeNodeId, node.id, 'interface');
|
|
17
17
|
if (kind === 'TSTypeAliasDeclaration' || kind === 'TypeAliasDeclaration') return namedDeclaration(input, nativeNodeId, node.id, 'type');
|
|
18
|
+
if (kind === 'TSModuleDeclaration' || kind === 'ModuleDeclaration') return syntaxModuleDeclaration(input, nativeNodeId, node);
|
|
18
19
|
if (kind === 'VariableDeclarator') return namedDeclaration(input, nativeNodeId, node.id, 'variable');
|
|
19
20
|
return undefined;
|
|
20
21
|
}
|
|
22
|
+
|
|
23
|
+
function syntaxModuleDeclaration(input, nativeNodeId, node) {
|
|
24
|
+
const name = syntaxName(node.id ?? node.name);
|
|
25
|
+
if (!name) return undefined;
|
|
26
|
+
return {
|
|
27
|
+
...declarationRecord(input, nativeNodeId, name, 'module', 'definition'),
|
|
28
|
+
metadata: {
|
|
29
|
+
scan: 'syntax-module-declaration',
|
|
30
|
+
moduleName: name,
|
|
31
|
+
namespace: name
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function syntaxName(node) {
|
|
37
|
+
if (!node) return undefined;
|
|
38
|
+
if (typeof node === 'string') return node;
|
|
39
|
+
if (typeof node.name === 'string') return node.name;
|
|
40
|
+
if (typeof node.value === 'string') return node.value;
|
|
41
|
+
if (typeof node.text === 'string') return node.text;
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
@@ -14,6 +14,7 @@ export function typeScriptDeclaration(node, kind, nativeNodeId, input, options =
|
|
|
14
14
|
if (kind === 'ClassDeclaration') return declarationWithExports(enrich(namedDeclaration(input, nativeNodeId, node.name, 'class')), exportedEntries, enrich, node);
|
|
15
15
|
if (kind === 'InterfaceDeclaration') return declarationWithExports(enrich(namedDeclaration(input, nativeNodeId, node.name, 'interface')), exportedEntries, enrich, node);
|
|
16
16
|
if (kind === 'TypeAliasDeclaration' || kind === 'EnumDeclaration') return declarationWithExports(enrich(namedDeclaration(input, nativeNodeId, node.name, 'type')), exportedEntries, enrich, node);
|
|
17
|
+
if (kind === 'ModuleDeclaration') return declarationWithExports(enrich(moduleDeclaration(input, nativeNodeId, node), node.name ?? node), exportedEntries, enrich, node);
|
|
17
18
|
if (kind === 'VariableDeclaration') return enrich(namedDeclaration(input, nativeNodeId, node.name, 'variable'));
|
|
18
19
|
if (kind === 'MethodDeclaration' || kind === 'MethodSignature') return enrich(namedDeclaration(input, nativeNodeId, node.name, 'method'));
|
|
19
20
|
return undefined;
|
|
@@ -25,6 +26,19 @@ function declarationWithExports(declaration, exportedEntries, enrich, node) {
|
|
|
25
26
|
return exports.length ? [declaration, ...exports] : declaration;
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
function moduleDeclaration(input, nativeNodeId, node) {
|
|
30
|
+
const name = stringFromTsExpression(node.name);
|
|
31
|
+
if (!name) return undefined;
|
|
32
|
+
return {
|
|
33
|
+
...declarationRecord(input, nativeNodeId, name, 'module', 'definition'),
|
|
34
|
+
metadata: compactRecord({
|
|
35
|
+
scan: 'typescript-module-declaration',
|
|
36
|
+
moduleName: name,
|
|
37
|
+
namespace: name
|
|
38
|
+
})
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
28
42
|
function enrichTypeScriptDeclaration(node, symbolNode, declaration, input, options) {
|
|
29
43
|
if (!declaration) return declaration;
|
|
30
44
|
const checker = options.typeChecker ?? options.checker ?? options.program?.getTypeChecker?.();
|
|
@@ -92,6 +92,7 @@ function exportedSymbolKind(kind) {
|
|
|
92
92
|
if (kind === 'ClassDeclaration') return 'class';
|
|
93
93
|
if (kind === 'InterfaceDeclaration') return 'interface';
|
|
94
94
|
if (kind === 'TypeAliasDeclaration' || kind === 'EnumDeclaration') return 'type';
|
|
95
|
+
if (kind === 'ModuleDeclaration') return 'module';
|
|
95
96
|
return undefined;
|
|
96
97
|
}
|
|
97
98
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { idFragment } from './native-import-utils.js';
|
|
2
2
|
import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
|
|
3
3
|
import { compactRecord } from './js-ts-safe-merge-context.js';
|
|
4
|
+
import { augmentProjectSymbolGraphPublicContracts } from './js-ts-safe-project-merge-public-contracts.js';
|
|
4
5
|
import { createNativeProjectImportResult } from './internal/index-impl/createNativeProjectImportResult.js';
|
|
5
6
|
import { importNativeSource } from './internal/index-impl/importNativeSource.js';
|
|
6
7
|
import {
|
|
@@ -92,22 +93,26 @@ function createProjectGraphStageArtifacts(input, files, mergeId, stageName, stag
|
|
|
92
93
|
...(stageName === 'output' ? { outputProjectImportSource: projectGraphImportSource } : {})
|
|
93
94
|
}
|
|
94
95
|
}, imports);
|
|
95
|
-
const
|
|
96
|
+
const projectSymbolGraph = augmentProjectSymbolGraphPublicContracts(projectImport.projectSymbolGraph, files, input, stageName);
|
|
97
|
+
const stageProjectImport = projectSymbolGraph === projectImport.projectSymbolGraph
|
|
98
|
+
? projectImport
|
|
99
|
+
: attachProjectSymbolGraph(projectImport, projectSymbolGraph);
|
|
100
|
+
const edgeLimitConflicts = projectGraphEdgeLimitConflicts(limits, stageName, projectSymbolGraph);
|
|
96
101
|
const serialized = projectGraphSerializedLimitConflict(limits, stageName, {
|
|
97
|
-
projectImport,
|
|
98
|
-
projectSymbolGraph
|
|
102
|
+
projectImport: stageProjectImport,
|
|
103
|
+
projectSymbolGraph
|
|
99
104
|
});
|
|
100
105
|
const limitConflicts = [...edgeLimitConflicts, serialized.conflict].filter(Boolean);
|
|
101
106
|
if (limitConflicts.length) {
|
|
102
|
-
return limitedProjectGraphStage(stageName, projectGraphImportSource, sourceStats,
|
|
107
|
+
return limitedProjectGraphStage(stageName, projectGraphImportSource, sourceStats, projectSymbolGraph, limitConflicts, serialized.serializedBytes);
|
|
103
108
|
}
|
|
104
109
|
return {
|
|
105
110
|
kind: 'frontier.lang.jsTsProjectGraphStage',
|
|
106
111
|
version: 1,
|
|
107
112
|
stage: stageName,
|
|
108
|
-
projectImport,
|
|
109
|
-
projectSymbolGraph
|
|
110
|
-
summary: projectGraphStageSummary(stageName,
|
|
113
|
+
projectImport: stageProjectImport,
|
|
114
|
+
projectSymbolGraph,
|
|
115
|
+
summary: projectGraphStageSummary(stageName, projectSymbolGraph, projectGraphImportSource, sourceStats, serialized.serializedBytes, [])
|
|
111
116
|
};
|
|
112
117
|
}
|
|
113
118
|
|
|
@@ -215,6 +220,24 @@ function stageFile(file, sourceText, input) {
|
|
|
215
220
|
});
|
|
216
221
|
}
|
|
217
222
|
|
|
223
|
+
function attachProjectSymbolGraph(projectImport, projectSymbolGraph) {
|
|
224
|
+
return {
|
|
225
|
+
...projectImport,
|
|
226
|
+
projectSymbolGraph,
|
|
227
|
+
semanticIndex: projectImport.semanticIndex ? {
|
|
228
|
+
...projectImport.semanticIndex,
|
|
229
|
+
metadata: {
|
|
230
|
+
...projectImport.semanticIndex.metadata,
|
|
231
|
+
projectSymbolGraph
|
|
232
|
+
}
|
|
233
|
+
} : projectImport.semanticIndex,
|
|
234
|
+
metadata: {
|
|
235
|
+
...projectImport.metadata,
|
|
236
|
+
projectSymbolGraph
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
218
241
|
function hashText(sourceText) {
|
|
219
242
|
return hashSemanticValue(sourceText);
|
|
220
243
|
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
|
|
2
|
+
import { compactRecord } from './js-ts-safe-merge-context.js';
|
|
3
|
+
import { findContainer, normalizeKind, normalizeMemberText, parseMembers } from './js-ts-semantic-merge-parse.js';
|
|
4
|
+
import { idFragment } from './native-import-utils.js';
|
|
5
|
+
|
|
6
|
+
function augmentProjectSymbolGraphPublicContracts(projectSymbolGraph, files, input, stageName) {
|
|
7
|
+
const existingRegions = Array.isArray(projectSymbolGraph?.publicContractRegions) ? projectSymbolGraph.publicContractRegions : [];
|
|
8
|
+
const seenKeys = new Set(existingRegions.map((region) => region?.key).filter(Boolean));
|
|
9
|
+
const syntheticRegions = [];
|
|
10
|
+
for (const file of files) {
|
|
11
|
+
syntheticRegions.push(...syntheticPublicContractRegions(file, input, stageName, seenKeys));
|
|
12
|
+
}
|
|
13
|
+
if (!syntheticRegions.length) return projectSymbolGraph;
|
|
14
|
+
return {
|
|
15
|
+
...projectSymbolGraph,
|
|
16
|
+
publicContractRegions: [...existingRegions, ...syntheticRegions]
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function syntheticPublicContractRegions(file, input, stageName, seenKeys) {
|
|
21
|
+
if (typeof file?.sourceText !== 'string' || !file.sourcePath) return [];
|
|
22
|
+
const records = [];
|
|
23
|
+
for (const region of publicContractPolicyRegionsForPath(input, file.sourcePath)) {
|
|
24
|
+
const kind = normalizeKind(region?.kind);
|
|
25
|
+
if (!['interface', 'type', 'class'].includes(kind) || typeof region?.name !== 'string') continue;
|
|
26
|
+
const container = findContainer(file.sourceText, region);
|
|
27
|
+
if (container.reasonCodes.length || !isExportedContainer(file.sourceText, container.value)) continue;
|
|
28
|
+
const members = parseMembers(container.value.body, kind);
|
|
29
|
+
if (members.reasonCodes.length) continue;
|
|
30
|
+
const key = `source#${file.sourcePath}#export#${region.name}`;
|
|
31
|
+
if (seenKeys.has(key)) continue;
|
|
32
|
+
seenKeys.add(key);
|
|
33
|
+
records.push(syntheticPublicContractRegion(file, input, stageName, kind, region.name, key, members.members));
|
|
34
|
+
}
|
|
35
|
+
return records;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function syntheticPublicContractRegion(file, input, stageName, kind, name, key, members) {
|
|
39
|
+
const language = file.language ?? input.language ?? languageForPath(file.sourcePath);
|
|
40
|
+
const memberRecords = members.map((member) => compactRecord({
|
|
41
|
+
key: member.key,
|
|
42
|
+
memberKind: member.memberKind,
|
|
43
|
+
signature: normalizeMemberText(member.text, kind)
|
|
44
|
+
}));
|
|
45
|
+
const signatureHash = hashSemanticValue({
|
|
46
|
+
kind: 'frontier.lang.syntheticPublicContractSignature',
|
|
47
|
+
language,
|
|
48
|
+
sourcePath: file.sourcePath,
|
|
49
|
+
symbolName: name,
|
|
50
|
+
sourceKind: kind,
|
|
51
|
+
members: memberRecords
|
|
52
|
+
});
|
|
53
|
+
const contractHash = hashSemanticValue({
|
|
54
|
+
kind: 'frontier.lang.syntheticPublicContractRegionHash',
|
|
55
|
+
language,
|
|
56
|
+
sourcePath: file.sourcePath,
|
|
57
|
+
key,
|
|
58
|
+
symbolName: name,
|
|
59
|
+
symbolKind: 'export',
|
|
60
|
+
apiSurfaceKind: 'module-export',
|
|
61
|
+
exportedName: name,
|
|
62
|
+
edgeKind: 'export',
|
|
63
|
+
signatureHash
|
|
64
|
+
});
|
|
65
|
+
return compactRecord({
|
|
66
|
+
id: `region_${idFragment(stageName)}_${idFragment(key)}`,
|
|
67
|
+
key,
|
|
68
|
+
regionKind: 'export',
|
|
69
|
+
granularity: 'symbol',
|
|
70
|
+
language,
|
|
71
|
+
sourcePath: file.sourcePath,
|
|
72
|
+
sourceHash: file.sourceHash,
|
|
73
|
+
symbolId: `symbol:${language}:export:${idFragment(name)}`,
|
|
74
|
+
symbolName: name,
|
|
75
|
+
symbolKind: 'export',
|
|
76
|
+
publicContract: true,
|
|
77
|
+
exportedName: name,
|
|
78
|
+
edgeKind: 'export',
|
|
79
|
+
apiSurfaceKind: 'module-export',
|
|
80
|
+
signatureHash,
|
|
81
|
+
contractHash,
|
|
82
|
+
metadata: {
|
|
83
|
+
source: 'js-ts-safe-project-merge-policy',
|
|
84
|
+
projectGraphStage: stageName,
|
|
85
|
+
sourceKind: kind,
|
|
86
|
+
memberKeys: memberRecords.map((member) => member.key)
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function publicContractPolicyRegionsForPath(input, sourcePath) {
|
|
92
|
+
const policy = input.policyByPath?.[sourcePath]
|
|
93
|
+
?? input.mergePolicyByPath?.[sourcePath]
|
|
94
|
+
?? input.policy
|
|
95
|
+
?? input.mergePolicy;
|
|
96
|
+
const regions = Array.isArray(policy)
|
|
97
|
+
? policy
|
|
98
|
+
: policy?.unorderedRegions
|
|
99
|
+
?? policy?.unorderedMemberRegions
|
|
100
|
+
?? policy?.safeList
|
|
101
|
+
?? policy?.safeMembers
|
|
102
|
+
?? [];
|
|
103
|
+
return Array.isArray(regions) ? regions : [];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function isExportedContainer(sourceText, container) {
|
|
107
|
+
if (!container) return false;
|
|
108
|
+
return /^\s*export\b/.test(sourceText.slice(container.start, container.openStart));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function languageForPath(sourcePath) {
|
|
112
|
+
const path = String(sourcePath ?? '').toLowerCase();
|
|
113
|
+
if (path.endsWith('.js') || path.endsWith('.jsx') || path.endsWith('.mjs') || path.endsWith('.cjs')) return 'javascript';
|
|
114
|
+
return 'typescript';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export { augmentProjectSymbolGraphPublicContracts };
|
package/package.json
CHANGED