@shapeshift-labs/frontier-lang-compiler 0.2.118 → 0.2.119
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 +7 -0
- package/dist/internal/index-impl/createNativeProjectImportResult.js +1 -1
- package/dist/internal/index-impl/semanticIndexFromNativeDeclarations.js +17 -11
- package/dist/internal/index-impl/typeScriptDeclaration.js +15 -5
- package/dist/internal/index-impl/typeScriptExportedDeclarationEntries.js +104 -0
- package/dist/internal/index-impl/typeScriptModuleDeclarationEntries.js +279 -0
- package/dist/internal/index-impl/visitTypeScriptAstNode.js +7 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -277,6 +277,13 @@ For `export * from './module.js'`, project graphs fan out re-export identities
|
|
|
277
277
|
for each named export in the resolved target document and omit `default`, which
|
|
278
278
|
matches JavaScript module semantics.
|
|
279
279
|
|
|
280
|
+
When using `createTypeScriptCompilerNativeImporterAdapter`, compiler AST imports
|
|
281
|
+
emit the same binding-level module facts instead of only statement-level module
|
|
282
|
+
edges. Default, namespace, named, type-only, side-effect, re-export, export-star,
|
|
283
|
+
local export, `export default`, and `export =` declarations carry `importKind`,
|
|
284
|
+
`exportKind`, `localName`, `importedName`, `exportedName`, `isTypeOnly`, and
|
|
285
|
+
public-contract metadata into the semantic index and project symbol graph.
|
|
286
|
+
|
|
280
287
|
High-risk native features also have explicit evidence policies. These policies are advisory in this package: they tell a swarm or admission queue what evidence is missing without silently changing the existing readiness classification.
|
|
281
288
|
|
|
282
289
|
```js
|
|
@@ -254,7 +254,7 @@ function moduleEdgeRecord(relation, moduleEdgeByRelation, symbolsById, documents
|
|
|
254
254
|
localName: firstString(moduleEdge.localName, value.localName, symbolMetadata.localName),
|
|
255
255
|
namespace: firstString(moduleEdge.namespace, value.namespace, symbolMetadata.namespace),
|
|
256
256
|
exportStar: firstBoolean(moduleEdge.exportStar, value.exportStar, symbolMetadata.exportStar),
|
|
257
|
-
isTypeOnly: firstBoolean(moduleEdge.isTypeOnly, value.isTypeOnly),
|
|
257
|
+
isTypeOnly: firstBoolean(moduleEdge.isTypeOnly, value.isTypeOnly, symbolMetadata.isTypeOnly, symbolMetadata.typeOnly),
|
|
258
258
|
isReExport: firstBoolean(moduleEdge.isReExport, value.isReExport, symbolMetadata.reexport) ?? (relation.predicate === 'exports' && Boolean(moduleSpecifier)),
|
|
259
259
|
publicContract: firstBoolean(moduleEdge.publicContract, value.publicContract, metadata.publicContract),
|
|
260
260
|
evidenceIds: uniqueStrings([...(relation.evidenceIds ?? []), ...(fact?.evidenceIds ?? [])])
|
|
@@ -15,7 +15,7 @@ export function semanticIndexFromNativeDeclarations(declarations, input, options
|
|
|
15
15
|
symbolId,
|
|
16
16
|
regionKind: declarationRegionKind(declaration)
|
|
17
17
|
};
|
|
18
|
-
const occurrenceId = `occ_${idFragment(declaration.nativeNode.id)}_${declaration.role ?? 'definition'}`;
|
|
18
|
+
const occurrenceId = `occ_${idFragment(declaration.nativeNode.id)}_${idFragment(symbolId)}_${declaration.role ?? 'definition'}`;
|
|
19
19
|
const ownershipRegion = semanticOwnershipRegionForDeclaration(input, {
|
|
20
20
|
...normalizedDeclaration,
|
|
21
21
|
nodeId: declaration.nativeNode.id,
|
|
@@ -24,7 +24,7 @@ export function semanticIndexFromNativeDeclarations(declarations, input, options
|
|
|
24
24
|
span: declaration.nativeNode.span,
|
|
25
25
|
symbolId
|
|
26
26
|
}, documentId);
|
|
27
|
-
const relationId = `rel_${idFragment(documentId)}_${idFragment(declaration.nativeNode.id)}`;
|
|
27
|
+
const relationId = `rel_${idFragment(documentId)}_${idFragment(declaration.nativeNode.id)}_${idFragment(symbolId)}`;
|
|
28
28
|
const moduleEdge = moduleEdgeForDeclaration(normalizedDeclaration, input, documentId, relationId, ownershipRegion);
|
|
29
29
|
const publicContractRegion = publicContractRegionForDeclaration(normalizedDeclaration, ownershipRegion, moduleEdge);
|
|
30
30
|
const reExportIdentity = reExportIdentityForDeclaration(normalizedDeclaration, input, documentId, relationId, ownershipRegion, moduleEdge);
|
|
@@ -76,17 +76,17 @@ export function semanticIndexFromNativeDeclarations(declarations, input, options
|
|
|
76
76
|
...(Object.keys(graphMetadata).length ? { metadata: graphMetadata } : {})
|
|
77
77
|
});
|
|
78
78
|
facts.push({
|
|
79
|
-
id: `fact_${idFragment(declaration.nativeNode.id)}_kind`,
|
|
79
|
+
id: `fact_${idFragment(declaration.nativeNode.id)}_${idFragment(symbolId)}_kind`,
|
|
80
80
|
predicate: 'nativeKind',
|
|
81
81
|
subjectId: symbolId,
|
|
82
82
|
value: declaration.nativeNode.languageKind
|
|
83
83
|
}, {
|
|
84
|
-
id: `fact_${idFragment(declaration.nativeNode.id)}_ownership_region`,
|
|
84
|
+
id: `fact_${idFragment(declaration.nativeNode.id)}_${idFragment(symbolId)}_ownership_region`,
|
|
85
85
|
predicate: 'semanticOwnershipRegion',
|
|
86
86
|
subjectId: symbolId,
|
|
87
87
|
value: ownershipRegion
|
|
88
88
|
}, {
|
|
89
|
-
id: `fact_${idFragment(declaration.nativeNode.id)}_ownership_region_taxonomy`,
|
|
89
|
+
id: `fact_${idFragment(declaration.nativeNode.id)}_${idFragment(symbolId)}_ownership_region_taxonomy`,
|
|
90
90
|
predicate: 'semanticOwnershipRegionTaxonomy',
|
|
91
91
|
subjectId: symbolId,
|
|
92
92
|
value: {
|
|
@@ -96,7 +96,7 @@ export function semanticIndexFromNativeDeclarations(declarations, input, options
|
|
|
96
96
|
}
|
|
97
97
|
}, ...projectSymbolGraphFacts({ moduleEdge, publicContractRegion, reExportIdentity, relationId, symbolId, evidenceId }));
|
|
98
98
|
mappings.push({
|
|
99
|
-
id: `map_${idFragment(declaration.nativeNode.id)}`,
|
|
99
|
+
id: `map_${idFragment(declaration.nativeNode.id)}_${idFragment(symbolId)}`,
|
|
100
100
|
nativeAstNodeId: declaration.nativeNode.id,
|
|
101
101
|
semanticSymbolId: symbolId,
|
|
102
102
|
semanticOccurrenceId: occurrenceId,
|
|
@@ -197,7 +197,8 @@ function moduleEdgeForDeclaration(declaration, input, documentId, relationId, ow
|
|
|
197
197
|
exportedName: declaration.exportedName ?? declaration.metadata?.exportedName,
|
|
198
198
|
localName: declaration.localName ?? declaration.metadata?.localName,
|
|
199
199
|
namespace: declaration.namespace ?? declaration.metadata?.namespace,
|
|
200
|
-
isTypeOnly: declaration.isTypeOnly ?? declaration.metadata?.isTypeOnly,
|
|
200
|
+
isTypeOnly: declaration.isTypeOnly ?? declaration.metadata?.isTypeOnly ?? declaration.metadata?.typeOnly,
|
|
201
|
+
exportStar: declaration.exportStar ?? declaration.metadata?.exportStar,
|
|
201
202
|
isReExport: edgeKind === 're-export',
|
|
202
203
|
publicContract: publicContractForDeclaration(declaration, edgeKind)
|
|
203
204
|
});
|
|
@@ -255,7 +256,8 @@ function reExportIdentityForDeclaration(declaration, input, documentId, relation
|
|
|
255
256
|
importedName: declaration.importedName ?? declaration.metadata?.importedName,
|
|
256
257
|
localName: declaration.localName ?? declaration.metadata?.localName,
|
|
257
258
|
namespace: declaration.namespace ?? declaration.metadata?.namespace,
|
|
258
|
-
isTypeOnly: declaration.isTypeOnly ?? declaration.metadata?.isTypeOnly,
|
|
259
|
+
isTypeOnly: declaration.isTypeOnly ?? declaration.metadata?.isTypeOnly ?? declaration.metadata?.typeOnly,
|
|
260
|
+
exportStar: declaration.exportStar ?? declaration.metadata?.exportStar,
|
|
259
261
|
symbolId: declaration.symbolId,
|
|
260
262
|
relationId,
|
|
261
263
|
ownershipRegionId: ownershipRegion.id,
|
|
@@ -267,7 +269,7 @@ function reExportIdentityForDeclaration(declaration, input, documentId, relation
|
|
|
267
269
|
function projectSymbolGraphFacts({ moduleEdge, publicContractRegion, reExportIdentity, relationId, symbolId, evidenceId }) {
|
|
268
270
|
return [
|
|
269
271
|
moduleEdge ? {
|
|
270
|
-
id:
|
|
272
|
+
id: graphFactId(relationId, symbolId, 'module_edge'),
|
|
271
273
|
predicate: 'moduleEdge',
|
|
272
274
|
subjectId: relationId,
|
|
273
275
|
objectId: symbolId,
|
|
@@ -275,7 +277,7 @@ function projectSymbolGraphFacts({ moduleEdge, publicContractRegion, reExportIde
|
|
|
275
277
|
evidenceIds: [evidenceId]
|
|
276
278
|
} : undefined,
|
|
277
279
|
reExportIdentity ? {
|
|
278
|
-
id:
|
|
280
|
+
id: graphFactId(relationId, symbolId, 're_export_identity'),
|
|
279
281
|
predicate: 'reExportIdentity',
|
|
280
282
|
subjectId: symbolId,
|
|
281
283
|
objectId: relationId,
|
|
@@ -283,7 +285,7 @@ function projectSymbolGraphFacts({ moduleEdge, publicContractRegion, reExportIde
|
|
|
283
285
|
evidenceIds: [evidenceId]
|
|
284
286
|
} : undefined,
|
|
285
287
|
publicContractRegion ? {
|
|
286
|
-
id:
|
|
288
|
+
id: graphFactId(relationId, symbolId, 'public_contract_region'),
|
|
287
289
|
predicate: 'publicContractRegion',
|
|
288
290
|
subjectId: symbolId,
|
|
289
291
|
objectId: publicContractRegion.id,
|
|
@@ -302,6 +304,10 @@ function hashParts(sourceHash) {
|
|
|
302
304
|
};
|
|
303
305
|
}
|
|
304
306
|
|
|
307
|
+
function graphFactId(relationId, symbolId, suffix) {
|
|
308
|
+
return `fact_${idFragment(hashSemanticValue([relationId, symbolId, suffix]))}_${suffix}`;
|
|
309
|
+
}
|
|
310
|
+
|
|
305
311
|
function compactRecord(record) {
|
|
306
312
|
return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));
|
|
307
313
|
}
|
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
import{hashSemanticValue}from'@shapeshift-labs/frontier-lang-kernel';import{idFragment}from'../../native-import-utils.js';
|
|
2
|
-
import{declarationRecord}from'./declarationRecord.js';import{
|
|
2
|
+
import{declarationRecord}from'./declarationRecord.js';import{namedDeclaration}from'./namedDeclaration.js';import{stringFromTsExpression}from'./stringFromTsExpression.js';import{typeScriptExportedDeclarationEntries}from'./typeScriptExportedDeclarationEntries.js';import{typeScriptModuleDeclarationEntries}from'./typeScriptModuleDeclarationEntries.js';
|
|
3
3
|
export function typeScriptDeclaration(node, kind, nativeNodeId, input, options = {}) {
|
|
4
4
|
const enrich = (declaration, symbolNode = node.name ?? node) => enrichTypeScriptDeclaration(node, symbolNode, declaration, input, options);
|
|
5
|
+
const moduleEntries = typeScriptModuleDeclarationEntries(node, kind, nativeNodeId, input);
|
|
6
|
+
if (moduleEntries?.length) return moduleEntries.map((entry) => enrich(entry.declaration, entry.symbolNode ?? node));
|
|
7
|
+
const exportedEntries = typeScriptExportedDeclarationEntries(node, kind, nativeNodeId, input, options);
|
|
8
|
+
if (exportedEntries.length && Array.isArray(node.declarationList?.declarations)) return exportedEntries.map((entry) => enrich(entry.declaration, entry.symbolNode ?? node));
|
|
5
9
|
if (kind === 'ImportDeclaration' || kind === 'ImportEqualsDeclaration') {
|
|
6
10
|
const name = stringFromTsExpression(node.moduleSpecifier) ?? stringFromTsExpression(node.externalModuleReference?.expression);
|
|
7
11
|
if (name) return enrich(declarationRecord(input, nativeNodeId, name, 'module', 'import'), node.moduleSpecifier ?? node.externalModuleReference?.expression ?? node);
|
|
8
12
|
}
|
|
9
|
-
if (kind === 'FunctionDeclaration') return enrich(namedDeclaration(input, nativeNodeId, node.name, 'function'));
|
|
10
|
-
if (kind === 'ClassDeclaration') return enrich(namedDeclaration(input, nativeNodeId, node.name, 'class'));
|
|
11
|
-
if (kind === 'InterfaceDeclaration') return enrich(namedDeclaration(input, nativeNodeId, node.name, 'interface'));
|
|
12
|
-
if (kind === 'TypeAliasDeclaration' || kind === 'EnumDeclaration') return enrich(namedDeclaration(input, nativeNodeId, node.name, 'type'));
|
|
13
|
+
if (kind === 'FunctionDeclaration') return declarationWithExports(enrich(namedDeclaration(input, nativeNodeId, node.name, 'function')), exportedEntries, enrich, node);
|
|
14
|
+
if (kind === 'ClassDeclaration') return declarationWithExports(enrich(namedDeclaration(input, nativeNodeId, node.name, 'class')), exportedEntries, enrich, node);
|
|
15
|
+
if (kind === 'InterfaceDeclaration') return declarationWithExports(enrich(namedDeclaration(input, nativeNodeId, node.name, 'interface')), exportedEntries, enrich, node);
|
|
16
|
+
if (kind === 'TypeAliasDeclaration' || kind === 'EnumDeclaration') return declarationWithExports(enrich(namedDeclaration(input, nativeNodeId, node.name, 'type')), exportedEntries, enrich, node);
|
|
13
17
|
if (kind === 'VariableDeclaration') return enrich(namedDeclaration(input, nativeNodeId, node.name, 'variable'));
|
|
14
18
|
if (kind === 'MethodDeclaration' || kind === 'MethodSignature') return enrich(namedDeclaration(input, nativeNodeId, node.name, 'method'));
|
|
15
19
|
return undefined;
|
|
16
20
|
}
|
|
17
21
|
|
|
22
|
+
function declarationWithExports(declaration, exportedEntries, enrich, node) {
|
|
23
|
+
const exports = exportedEntries.map((entry) => enrich(entry.declaration, entry.symbolNode ?? node));
|
|
24
|
+
if (!declaration) return exports.length ? exports : undefined;
|
|
25
|
+
return exports.length ? [declaration, ...exports] : declaration;
|
|
26
|
+
}
|
|
27
|
+
|
|
18
28
|
function enrichTypeScriptDeclaration(node, symbolNode, declaration, input, options) {
|
|
19
29
|
if (!declaration) return declaration;
|
|
20
30
|
const checker = options.typeChecker ?? options.checker ?? options.program?.getTypeChecker?.();
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import{idFragment}from'../../native-import-utils.js';
|
|
2
|
+
import{declarationRecord}from'./declarationRecord.js';import{identifierName}from'./identifierName.js';
|
|
3
|
+
export function typeScriptExportedDeclarationEntries(node, kind, nativeNodeId, input, options = {}) {
|
|
4
|
+
const modifiers = declarationModifiers(node, options.ts);
|
|
5
|
+
if (!modifiers.exported) return [];
|
|
6
|
+
if (isVariableStatement(node, kind)) return variableStatementExportEntries(node, nativeNodeId, input, modifiers);
|
|
7
|
+
const localName = identifierName(node.name);
|
|
8
|
+
const symbolKind = exportedSymbolKind(kind);
|
|
9
|
+
if (!symbolKind && !modifiers.defaulted) return [];
|
|
10
|
+
return [exportEntry(input, nativeNodeId, {
|
|
11
|
+
localName,
|
|
12
|
+
exportedName: modifiers.defaulted ? 'default' : localName,
|
|
13
|
+
exportKind: modifiers.defaulted ? 'default' : exportKindForDeclaration(kind),
|
|
14
|
+
isTypeOnly: typeOnlyDeclarationKind(kind),
|
|
15
|
+
symbolNode: node.name ?? node
|
|
16
|
+
})];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function variableStatementExportEntries(node, nativeNodeId, input, modifiers) {
|
|
20
|
+
const declarations = node.declarationList?.declarations ?? [];
|
|
21
|
+
return declarations
|
|
22
|
+
.map((declaration) => {
|
|
23
|
+
const localName = identifierName(declaration.name);
|
|
24
|
+
if (!localName) return undefined;
|
|
25
|
+
return exportEntry(input, nativeNodeId, {
|
|
26
|
+
localName,
|
|
27
|
+
exportedName: modifiers.defaulted ? 'default' : localName,
|
|
28
|
+
exportKind: modifiers.defaulted ? 'default' : 'named',
|
|
29
|
+
isTypeOnly: false,
|
|
30
|
+
symbolNode: declaration.name
|
|
31
|
+
});
|
|
32
|
+
})
|
|
33
|
+
.filter(Boolean);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function exportEntry(input, nativeNodeId, binding) {
|
|
37
|
+
return {
|
|
38
|
+
declaration: {
|
|
39
|
+
...declarationRecord(input, nativeNodeId, binding.exportedName, 'export', 'export'),
|
|
40
|
+
symbolId: `symbol:${input.language}:export:${idFragment(binding.exportedName)}`,
|
|
41
|
+
localName: binding.localName,
|
|
42
|
+
exportedName: binding.exportedName,
|
|
43
|
+
exportKind: binding.exportKind,
|
|
44
|
+
isTypeOnly: binding.isTypeOnly,
|
|
45
|
+
publicContract: true,
|
|
46
|
+
metadata: {
|
|
47
|
+
scan: 'typescript-exported-declaration',
|
|
48
|
+
localName: binding.localName,
|
|
49
|
+
exportedName: binding.exportedName,
|
|
50
|
+
exportKind: binding.exportKind,
|
|
51
|
+
isTypeOnly: binding.isTypeOnly,
|
|
52
|
+
typeOnly: binding.isTypeOnly,
|
|
53
|
+
publicContract: true
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
symbolNode: binding.symbolNode
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function declarationModifiers(node, ts) {
|
|
61
|
+
const helperModifiers = safeModifiers(node, ts);
|
|
62
|
+
const names = new Set([...(node.modifiers ?? []), ...helperModifiers].map((modifier) => modifierName(modifier, ts)));
|
|
63
|
+
return {
|
|
64
|
+
exported: names.has('ExportKeyword') || names.has('export'),
|
|
65
|
+
defaulted: names.has('DefaultKeyword') || names.has('default')
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function safeModifiers(node, ts) {
|
|
70
|
+
try {
|
|
71
|
+
if (typeof ts?.canHaveModifiers === 'function' && !ts.canHaveModifiers(node)) return [];
|
|
72
|
+
return typeof ts?.getModifiers === 'function' ? [...(ts.getModifiers(node) ?? [])] : [];
|
|
73
|
+
} catch {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function isVariableStatement(node, kind) {
|
|
79
|
+
return kind === 'VariableStatement' || Array.isArray(node.declarationList?.declarations);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function modifierName(modifier, ts) {
|
|
83
|
+
if (typeof modifier.kindName === 'string') return modifier.kindName;
|
|
84
|
+
if (ts?.SyntaxKind && modifier.kind !== undefined) return ts.SyntaxKind[modifier.kind] ?? String(modifier.kind);
|
|
85
|
+
if (typeof modifier.text === 'string') return modifier.text;
|
|
86
|
+
if (typeof modifier.name === 'string') return modifier.name;
|
|
87
|
+
return String(modifier.kind ?? '');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function exportedSymbolKind(kind) {
|
|
91
|
+
if (kind === 'FunctionDeclaration') return 'function';
|
|
92
|
+
if (kind === 'ClassDeclaration') return 'class';
|
|
93
|
+
if (kind === 'InterfaceDeclaration') return 'interface';
|
|
94
|
+
if (kind === 'TypeAliasDeclaration' || kind === 'EnumDeclaration') return 'type';
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function exportKindForDeclaration(kind) {
|
|
99
|
+
return typeOnlyDeclarationKind(kind) ? 'type-named' : 'named';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function typeOnlyDeclarationKind(kind) {
|
|
103
|
+
return kind === 'InterfaceDeclaration' || kind === 'TypeAliasDeclaration';
|
|
104
|
+
}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import{idFragment}from'../../native-import-utils.js';
|
|
2
|
+
import{declarationRecord}from'./declarationRecord.js';import{identifierName}from'./identifierName.js';import{stringFromTsExpression}from'./stringFromTsExpression.js';
|
|
3
|
+
export function typeScriptModuleDeclarationEntries(node, kind, nativeNodeId, input) {
|
|
4
|
+
if (kind === 'ImportDeclaration') return importDeclarationEntries(node, nativeNodeId, input);
|
|
5
|
+
if (kind === 'ImportEqualsDeclaration') return importEqualsDeclarationEntries(node, nativeNodeId, input);
|
|
6
|
+
if (kind === 'ExportDeclaration') return exportDeclarationEntries(node, nativeNodeId, input);
|
|
7
|
+
if (kind === 'ExportAssignment') return exportAssignmentEntries(node, nativeNodeId, input);
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function importDeclarationEntries(node, nativeNodeId, input) {
|
|
12
|
+
const moduleSpecifier = stringFromTsExpression(node.moduleSpecifier);
|
|
13
|
+
if (!moduleSpecifier) return [];
|
|
14
|
+
const typeOnly = Boolean(node.importClause?.isTypeOnly);
|
|
15
|
+
const bindings = importClauseBindings(node.importClause, typeOnly);
|
|
16
|
+
return importModuleEntries(input, nativeNodeId, moduleSpecifier, 'ImportDeclaration', bindings, {
|
|
17
|
+
typeOnly,
|
|
18
|
+
sideEffectOnly: bindings.length === 0,
|
|
19
|
+
importKind: bindings.length === 0 ? 'side-effect' : 'module'
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function importEqualsDeclarationEntries(node, nativeNodeId, input) {
|
|
24
|
+
const moduleSpecifier = stringFromTsExpression(node.moduleReference?.expression ?? node.externalModuleReference?.expression);
|
|
25
|
+
const localName = identifierName(node.name);
|
|
26
|
+
if (!moduleSpecifier || !localName) return [];
|
|
27
|
+
const typeOnly = Boolean(node.isTypeOnly);
|
|
28
|
+
return importModuleEntries(input, nativeNodeId, moduleSpecifier, 'ImportEqualsDeclaration', [{
|
|
29
|
+
localName,
|
|
30
|
+
importedName: 'default',
|
|
31
|
+
importKind: 'commonjs-require',
|
|
32
|
+
isTypeOnly: typeOnly,
|
|
33
|
+
symbolNode: node.name
|
|
34
|
+
}], { typeOnly, importKind: 'commonjs-require' });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function exportDeclarationEntries(node, nativeNodeId, input) {
|
|
38
|
+
const moduleSpecifier = stringFromTsExpression(node.moduleSpecifier);
|
|
39
|
+
const typeOnly = Boolean(node.isTypeOnly);
|
|
40
|
+
const exportStar = moduleSpecifier && !node.exportClause;
|
|
41
|
+
const bindings = exportClauseBindings(node.exportClause, { typeOnly, reExport: Boolean(moduleSpecifier) });
|
|
42
|
+
return [
|
|
43
|
+
...(moduleSpecifier ? importModuleEntries(input, nativeNodeId, moduleSpecifier, 'ExportFromDeclaration', reExportImportBindings(bindings, exportStar), {
|
|
44
|
+
typeOnly,
|
|
45
|
+
reexport: true,
|
|
46
|
+
exportStar,
|
|
47
|
+
importKind: exportStar ? 'reexport' : 'reexport'
|
|
48
|
+
}) : []),
|
|
49
|
+
...exportModuleEntries(input, nativeNodeId, moduleSpecifier, bindings, {
|
|
50
|
+
typeOnly,
|
|
51
|
+
exportStar,
|
|
52
|
+
reExport: Boolean(moduleSpecifier),
|
|
53
|
+
exportKind: exportStar ? 'export-star' : 'named'
|
|
54
|
+
})
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function exportAssignmentEntries(node, nativeNodeId, input) {
|
|
59
|
+
const exportedName = node.isExportEquals ? 'module.exports' : 'default';
|
|
60
|
+
const localName = stringFromTsExpression(node.expression);
|
|
61
|
+
return [{
|
|
62
|
+
declaration: compactRecord({
|
|
63
|
+
...declarationRecord(input, nativeNodeId, exportedName, 'export', 'export'),
|
|
64
|
+
exportedName,
|
|
65
|
+
localName,
|
|
66
|
+
exportKind: node.isExportEquals ? 'assignment' : 'default',
|
|
67
|
+
publicContract: true,
|
|
68
|
+
metadata: compactRecord({
|
|
69
|
+
exportKind: node.isExportEquals ? 'assignment' : 'default',
|
|
70
|
+
exportedName,
|
|
71
|
+
localName,
|
|
72
|
+
publicContract: true
|
|
73
|
+
})
|
|
74
|
+
}),
|
|
75
|
+
symbolNode: node.expression ?? node
|
|
76
|
+
}];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function importClauseBindings(importClause, typeOnly) {
|
|
80
|
+
if (!importClause) return [];
|
|
81
|
+
const bindings = [];
|
|
82
|
+
const defaultName = identifierName(importClause.name);
|
|
83
|
+
if (defaultName) bindings.push({
|
|
84
|
+
localName: defaultName,
|
|
85
|
+
importedName: 'default',
|
|
86
|
+
importKind: typeOnly ? 'type-default' : 'default',
|
|
87
|
+
isTypeOnly: typeOnly,
|
|
88
|
+
symbolNode: importClause.name
|
|
89
|
+
});
|
|
90
|
+
const named = importClause.namedBindings;
|
|
91
|
+
if (!named) return bindings;
|
|
92
|
+
if (Array.isArray(named.elements)) {
|
|
93
|
+
bindings.push(...named.elements.map((element) => importSpecifierBinding(element, typeOnly)).filter(Boolean));
|
|
94
|
+
} else {
|
|
95
|
+
const namespace = identifierName(named.name);
|
|
96
|
+
if (namespace) bindings.push({ localName: namespace, importedName: '*', namespace, importKind: 'namespace', isTypeOnly: typeOnly, symbolNode: named.name });
|
|
97
|
+
}
|
|
98
|
+
return bindings;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function importSpecifierBinding(element, parentTypeOnly) {
|
|
102
|
+
const localName = identifierName(element.name);
|
|
103
|
+
if (!localName) return undefined;
|
|
104
|
+
const typeOnly = Boolean(parentTypeOnly || element.isTypeOnly);
|
|
105
|
+
const importedName = identifierName(element.propertyName) ?? localName;
|
|
106
|
+
return {
|
|
107
|
+
localName,
|
|
108
|
+
importedName,
|
|
109
|
+
importKind: typeOnly ? 'type-named' : 'named',
|
|
110
|
+
isTypeOnly: typeOnly,
|
|
111
|
+
symbolNode: element.name
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function exportClauseBindings(exportClause, options) {
|
|
116
|
+
if (!exportClause) return [];
|
|
117
|
+
if (Array.isArray(exportClause.elements)) {
|
|
118
|
+
return exportClause.elements.map((element) => exportSpecifierBinding(element, options)).filter(Boolean);
|
|
119
|
+
}
|
|
120
|
+
const exportedName = identifierName(exportClause.name);
|
|
121
|
+
if (!exportedName) return [];
|
|
122
|
+
return [{
|
|
123
|
+
localName: exportedName,
|
|
124
|
+
importedName: '*',
|
|
125
|
+
exportedName,
|
|
126
|
+
namespace: exportedName,
|
|
127
|
+
importKind: 'namespace-reexport',
|
|
128
|
+
exportKind: 'namespace-reexport',
|
|
129
|
+
isTypeOnly: Boolean(options.typeOnly),
|
|
130
|
+
reExport: Boolean(options.reExport),
|
|
131
|
+
symbolNode: exportClause.name
|
|
132
|
+
}];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function exportSpecifierBinding(element, options) {
|
|
136
|
+
const exportedName = identifierName(element.name);
|
|
137
|
+
if (!exportedName) return undefined;
|
|
138
|
+
const typeOnly = Boolean(options.typeOnly || element.isTypeOnly);
|
|
139
|
+
const localName = identifierName(element.propertyName) ?? exportedName;
|
|
140
|
+
return {
|
|
141
|
+
localName,
|
|
142
|
+
importedName: options.reExport ? localName : undefined,
|
|
143
|
+
exportedName,
|
|
144
|
+
importKind: options.reExport ? typeOnly ? 'type-reexport' : 'reexport' : undefined,
|
|
145
|
+
exportKind: typeOnly ? 'type-named' : 'named',
|
|
146
|
+
isTypeOnly: typeOnly,
|
|
147
|
+
reExport: Boolean(options.reExport),
|
|
148
|
+
symbolNode: element.name
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function reExportImportBindings(bindings, exportStar) {
|
|
153
|
+
if (exportStar) return [];
|
|
154
|
+
return bindings.map((binding) => ({
|
|
155
|
+
localName: binding.exportedName ?? binding.localName,
|
|
156
|
+
importedName: binding.importedName ?? binding.localName,
|
|
157
|
+
exportedName: binding.exportedName,
|
|
158
|
+
namespace: binding.namespace,
|
|
159
|
+
importKind: binding.importKind ?? 'reexport',
|
|
160
|
+
isTypeOnly: binding.isTypeOnly,
|
|
161
|
+
symbolNode: binding.symbolNode
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function importModuleEntries(input, nativeNodeId, moduleSpecifier, _languageKind, bindings, metadata) {
|
|
166
|
+
const moduleEntry = {
|
|
167
|
+
declaration: compactRecord({
|
|
168
|
+
...declarationRecord(input, nativeNodeId, moduleSpecifier, 'module', 'import'),
|
|
169
|
+
importPath: moduleSpecifier,
|
|
170
|
+
moduleSpecifier,
|
|
171
|
+
importKind: metadata.importKind,
|
|
172
|
+
isTypeOnly: metadata.typeOnly,
|
|
173
|
+
exportStar: metadata.exportStar,
|
|
174
|
+
metadata: moduleMetadata('typescript-import', bindings, metadata)
|
|
175
|
+
})
|
|
176
|
+
};
|
|
177
|
+
return [moduleEntry, ...bindings.map((binding) => importBindingEntry(input, nativeNodeId, moduleSpecifier, binding))];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function importBindingEntry(input, nativeNodeId, moduleSpecifier, binding) {
|
|
181
|
+
const declaration = compactRecord({
|
|
182
|
+
...declarationRecord(input, nativeNodeId, binding.localName, 'import', 'import'),
|
|
183
|
+
symbolId: `symbol:${input.language}:import:${idFragment(`${moduleSpecifier}:${binding.localName}:${binding.importedName}`)}`,
|
|
184
|
+
importPath: moduleSpecifier,
|
|
185
|
+
moduleSpecifier,
|
|
186
|
+
localName: binding.localName,
|
|
187
|
+
importedName: binding.importedName,
|
|
188
|
+
exportedName: binding.exportedName,
|
|
189
|
+
namespace: binding.namespace,
|
|
190
|
+
importKind: binding.importKind,
|
|
191
|
+
isTypeOnly: binding.isTypeOnly,
|
|
192
|
+
metadata: compactRecord({
|
|
193
|
+
scan: 'typescript-import-binding',
|
|
194
|
+
moduleSpecifier,
|
|
195
|
+
importPath: moduleSpecifier,
|
|
196
|
+
localName: binding.localName,
|
|
197
|
+
importedName: binding.importedName,
|
|
198
|
+
exportedName: binding.exportedName,
|
|
199
|
+
namespace: binding.namespace,
|
|
200
|
+
importKind: binding.importKind,
|
|
201
|
+
isTypeOnly: binding.isTypeOnly,
|
|
202
|
+
typeOnly: binding.isTypeOnly
|
|
203
|
+
})
|
|
204
|
+
});
|
|
205
|
+
return { declaration, symbolNode: binding.symbolNode };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function exportModuleEntries(input, nativeNodeId, moduleSpecifier, bindings, metadata) {
|
|
209
|
+
const statementName = metadata.exportStar
|
|
210
|
+
? `* from ${moduleSpecifier}`
|
|
211
|
+
: moduleSpecifier ? `{${bindings.map((binding) => binding.exportedName).join(',')}} from ${moduleSpecifier}` : `{${bindings.map((binding) => binding.exportedName).join(',')}}`;
|
|
212
|
+
const statement = {
|
|
213
|
+
declaration: compactRecord({
|
|
214
|
+
...declarationRecord(input, nativeNodeId, statementName, 'module', 'export'),
|
|
215
|
+
exportPath: moduleSpecifier,
|
|
216
|
+
moduleSpecifier,
|
|
217
|
+
exportKind: metadata.exportKind,
|
|
218
|
+
exportStar: metadata.exportStar,
|
|
219
|
+
isTypeOnly: metadata.typeOnly,
|
|
220
|
+
reExport: metadata.reExport,
|
|
221
|
+
publicContract: true,
|
|
222
|
+
metadata: moduleMetadata('typescript-export', bindings, metadata)
|
|
223
|
+
})
|
|
224
|
+
};
|
|
225
|
+
return [statement, ...bindings.map((binding) => exportBindingEntry(input, nativeNodeId, moduleSpecifier, binding))];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function exportBindingEntry(input, nativeNodeId, moduleSpecifier, binding) {
|
|
229
|
+
const declaration = compactRecord({
|
|
230
|
+
...declarationRecord(input, nativeNodeId, binding.exportedName, 'export', 'export'),
|
|
231
|
+
symbolId: `symbol:${input.language}:export:${idFragment(`${moduleSpecifier ?? 'local'}:${binding.exportedName}:${binding.localName}`)}`,
|
|
232
|
+
exportPath: moduleSpecifier,
|
|
233
|
+
moduleSpecifier,
|
|
234
|
+
localName: binding.localName,
|
|
235
|
+
importedName: binding.importedName,
|
|
236
|
+
exportedName: binding.exportedName,
|
|
237
|
+
namespace: binding.namespace,
|
|
238
|
+
exportKind: binding.exportKind,
|
|
239
|
+
isTypeOnly: binding.isTypeOnly,
|
|
240
|
+
reExport: binding.reExport,
|
|
241
|
+
publicContract: true,
|
|
242
|
+
metadata: compactRecord({
|
|
243
|
+
scan: 'typescript-export-binding',
|
|
244
|
+
moduleSpecifier,
|
|
245
|
+
exportPath: moduleSpecifier,
|
|
246
|
+
localName: binding.localName,
|
|
247
|
+
importedName: binding.importedName,
|
|
248
|
+
exportedName: binding.exportedName,
|
|
249
|
+
namespace: binding.namespace,
|
|
250
|
+
exportKind: binding.exportKind,
|
|
251
|
+
isTypeOnly: binding.isTypeOnly,
|
|
252
|
+
typeOnly: binding.isTypeOnly,
|
|
253
|
+
reExport: binding.reExport,
|
|
254
|
+
publicContract: true
|
|
255
|
+
})
|
|
256
|
+
});
|
|
257
|
+
return { declaration, symbolNode: binding.symbolNode };
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function moduleMetadata(scan, bindings, metadata) {
|
|
261
|
+
return compactRecord({
|
|
262
|
+
scan,
|
|
263
|
+
moduleOnly: true,
|
|
264
|
+
bindingCount: bindings.length,
|
|
265
|
+
importKind: metadata.importKind,
|
|
266
|
+
exportKind: metadata.exportKind,
|
|
267
|
+
isTypeOnly: metadata.typeOnly,
|
|
268
|
+
typeOnly: metadata.typeOnly,
|
|
269
|
+
sideEffectOnly: metadata.sideEffectOnly,
|
|
270
|
+
reexport: metadata.reexport,
|
|
271
|
+
reExport: metadata.reExport,
|
|
272
|
+
exportStar: metadata.exportStar,
|
|
273
|
+
publicContract: metadata.reExport || metadata.exportKind
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function compactRecord(record) {
|
|
278
|
+
return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));
|
|
279
|
+
}
|
|
@@ -23,17 +23,20 @@ export function visitTypeScriptAstNode(node, sourceFile, context, propertyPath,
|
|
|
23
23
|
} else if (Array.isArray(node.children)) {
|
|
24
24
|
node.children.forEach(visitChild);
|
|
25
25
|
}
|
|
26
|
-
const
|
|
26
|
+
const declarationResult = typeScriptDeclaration(node, kind, id, context.input, context.options);
|
|
27
|
+
const declarations = Array.isArray(declarationResult) ? declarationResult.filter(Boolean) : declarationResult ? [declarationResult] : [];
|
|
28
|
+
const primaryDeclaration = declarations[0];
|
|
27
29
|
const nativeNode = {
|
|
28
30
|
id,
|
|
29
31
|
kind,
|
|
30
32
|
languageKind: `${context.input.language}.${kind}`,
|
|
31
33
|
span,
|
|
32
|
-
value:
|
|
34
|
+
value: primaryDeclaration?.name ?? typeScriptNodeValue(node),
|
|
33
35
|
fields: primitiveTypeScriptFields(node, kind),
|
|
34
36
|
children,
|
|
35
37
|
metadata: {
|
|
36
|
-
...
|
|
38
|
+
...primaryDeclaration?.metadata,
|
|
39
|
+
...(declarations.length > 1 ? { declarationCount: declarations.length } : {}),
|
|
37
40
|
astFormat: context.options.astFormat,
|
|
38
41
|
propertyPath,
|
|
39
42
|
pos: numberOrUndefined(node.pos),
|
|
@@ -41,6 +44,6 @@ export function visitTypeScriptAstNode(node, sourceFile, context, propertyPath,
|
|
|
41
44
|
}
|
|
42
45
|
};
|
|
43
46
|
context.nodes[id] = nativeNode;
|
|
44
|
-
|
|
47
|
+
for (const declaration of declarations) context.declarations.push({ ...declaration, nativeNode });
|
|
45
48
|
return id;
|
|
46
49
|
}
|
package/package.json
CHANGED