@shapeshift-labs/frontier-lang-compiler 0.2.117 → 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 +13 -0
- package/dist/declarations/native-project.d.ts +1 -0
- package/dist/internal/index-impl/createNativeProjectImportResult.js +2 -1
- package/dist/internal/index-impl/projectSymbolGraphModulePathCandidates.js +52 -0
- package/dist/internal/index-impl/projectSymbolGraphModuleResolution.js +7 -8
- 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
|
@@ -238,6 +238,12 @@ console.log(project.outputProjectSymbolGraph.importEdges[0].packageName); // "@p
|
|
|
238
238
|
console.log(project.outputProjectSymbolGraph.importEdges[0].packageExportCondition); // "import"
|
|
239
239
|
```
|
|
240
240
|
|
|
241
|
+
NodeNext-style JS extension specifiers can resolve to supplied TS source files.
|
|
242
|
+
For example, `import './runtime.js'` can resolve to `src/runtime.ts` when that is
|
|
243
|
+
the available project document. Graph edges record `resolutionPathVariant` as
|
|
244
|
+
`"extension-substitution"` so coordinators can distinguish exact source matches
|
|
245
|
+
from source-extension substitutions during stale checks and merge admission.
|
|
246
|
+
|
|
241
247
|
Package `imports` maps are also modeled for `#internal` specifiers. Top-level
|
|
242
248
|
`moduleResolution.imports` applies from `packageRoot`/`root`, while
|
|
243
249
|
`packages[name].imports` applies to the nearest configured package root. Graph
|
|
@@ -271,6 +277,13 @@ For `export * from './module.js'`, project graphs fan out re-export identities
|
|
|
271
277
|
for each named export in the resolved target document and omit `default`, which
|
|
272
278
|
matches JavaScript module semantics.
|
|
273
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
|
+
|
|
274
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.
|
|
275
288
|
|
|
276
289
|
```js
|
|
@@ -108,6 +108,7 @@ export interface NativeProjectSymbolGraphModuleEdgeRecord {
|
|
|
108
108
|
readonly targetDocumentId?: string;
|
|
109
109
|
readonly resolvedTargetSymbolId?: string;
|
|
110
110
|
readonly resolutionKind?: 'relative-source' | 'relative-missing' | 'alias-source' | 'alias-missing' | 'path-alias-source' | 'path-alias-missing' | 'base-url-source' | 'base-url-missing' | 'package-source' | 'package-missing' | 'package-external' | 'package-import-source' | 'package-import-missing' | 'package-import-external' | string;
|
|
111
|
+
readonly resolutionPathVariant?: 'exact' | 'extension-substitution' | 'extensionless' | 'index' | string;
|
|
111
112
|
readonly packageName?: string; readonly packageSubpath?: string; readonly packageExportCondition?: string;
|
|
112
113
|
readonly packageImportKey?: string; readonly packageImportCondition?: string; readonly packageImportTarget?: string;
|
|
113
114
|
readonly importKind?: string;
|
|
@@ -240,6 +240,7 @@ function moduleEdgeRecord(relation, moduleEdgeByRelation, symbolsById, documents
|
|
|
240
240
|
resolvedModulePath: resolution?.path,
|
|
241
241
|
targetDocumentId: resolution?.documentId,
|
|
242
242
|
resolutionKind: resolution?.kind,
|
|
243
|
+
resolutionPathVariant: resolution?.resolutionPathVariant,
|
|
243
244
|
packageName: resolution?.packageName,
|
|
244
245
|
packageSubpath: resolution?.packageSubpath,
|
|
245
246
|
packageExportCondition: resolution?.packageExportCondition,
|
|
@@ -253,7 +254,7 @@ function moduleEdgeRecord(relation, moduleEdgeByRelation, symbolsById, documents
|
|
|
253
254
|
localName: firstString(moduleEdge.localName, value.localName, symbolMetadata.localName),
|
|
254
255
|
namespace: firstString(moduleEdge.namespace, value.namespace, symbolMetadata.namespace),
|
|
255
256
|
exportStar: firstBoolean(moduleEdge.exportStar, value.exportStar, symbolMetadata.exportStar),
|
|
256
|
-
isTypeOnly: firstBoolean(moduleEdge.isTypeOnly, value.isTypeOnly),
|
|
257
|
+
isTypeOnly: firstBoolean(moduleEdge.isTypeOnly, value.isTypeOnly, symbolMetadata.isTypeOnly, symbolMetadata.typeOnly),
|
|
257
258
|
isReExport: firstBoolean(moduleEdge.isReExport, value.isReExport, symbolMetadata.reexport) ?? (relation.predicate === 'exports' && Boolean(moduleSpecifier)),
|
|
258
259
|
publicContract: firstBoolean(moduleEdge.publicContract, value.publicContract, metadata.publicContract),
|
|
259
260
|
evidenceIds: uniqueStrings([...(relation.evidenceIds ?? []), ...(fact?.evidenceIds ?? [])])
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export function modulePathCandidates(path) {
|
|
2
|
+
const normalized = String(path ?? '');
|
|
3
|
+
return uniqueCandidates([
|
|
4
|
+
candidate(normalized, 'exact'),
|
|
5
|
+
...extensionSubstitutionCandidates(normalized),
|
|
6
|
+
...extensionlessCandidates(normalized),
|
|
7
|
+
...indexCandidates(normalized)
|
|
8
|
+
]);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function extensionSubstitutionCandidates(path) {
|
|
12
|
+
const entries = [
|
|
13
|
+
['.js', ['.ts', '.tsx', '.d.ts', '.jsx']],
|
|
14
|
+
['.jsx', ['.tsx', '.ts', '.d.ts']],
|
|
15
|
+
['.mjs', ['.mts', '.ts', '.d.mts']],
|
|
16
|
+
['.cjs', ['.cts', '.ts', '.d.cts']]
|
|
17
|
+
];
|
|
18
|
+
for (const [from, targets] of entries) {
|
|
19
|
+
if (!path.endsWith(from)) continue;
|
|
20
|
+
const base = path.slice(0, -from.length);
|
|
21
|
+
return targets.map((target) => candidate(`${base}${target}`, 'extension-substitution'));
|
|
22
|
+
}
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function extensionlessCandidates(path) {
|
|
27
|
+
if (hasKnownExtension(path)) return [];
|
|
28
|
+
return ['.js', '.ts', '.tsx', '.jsx', '.mjs', '.mts', '.cjs', '.cts', '.d.ts']
|
|
29
|
+
.map((extension) => candidate(`${path}${extension}`, 'extensionless'));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function indexCandidates(path) {
|
|
33
|
+
return ['.js', '.ts', '.tsx', '.jsx', '.mjs', '.mts', '.cjs', '.cts', '.d.ts']
|
|
34
|
+
.map((extension) => candidate(`${path}/index${extension}`, 'index'));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function hasKnownExtension(path) {
|
|
38
|
+
return /\.(?:[cm]?[jt]sx?|d\.[cm]?ts)$/.test(path);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function candidate(path, variant) {
|
|
42
|
+
return { path, variant };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function uniqueCandidates(candidates) {
|
|
46
|
+
const seen = new Set();
|
|
47
|
+
return candidates.filter((entry) => {
|
|
48
|
+
if (!entry.path || seen.has(entry.path)) return false;
|
|
49
|
+
seen.add(entry.path);
|
|
50
|
+
return true;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { modulePathCandidates } from './projectSymbolGraphModulePathCandidates.js';
|
|
2
|
+
|
|
1
3
|
export function resolveRelativeProjectModule(sourcePath, moduleSpecifier, documentsByPath) {
|
|
2
4
|
if (!sourcePath || !moduleSpecifier || !moduleSpecifier.startsWith('.')) return undefined;
|
|
3
5
|
const base = sourcePath.includes('/') ? sourcePath.slice(0, sourcePath.lastIndexOf('/')) : '';
|
|
@@ -6,6 +8,7 @@ export function resolveRelativeProjectModule(sourcePath, moduleSpecifier, docume
|
|
|
6
8
|
return {
|
|
7
9
|
path: target?.path ?? unresolvedPath,
|
|
8
10
|
documentId: target?.id,
|
|
11
|
+
resolutionPathVariant: target?.resolutionPathVariant,
|
|
9
12
|
kind: target ? 'relative-source' : 'relative-missing'
|
|
10
13
|
};
|
|
11
14
|
}
|
|
@@ -69,7 +72,7 @@ function resolveConfiguredProjectModule(moduleSpecifier, documentsByPath, module
|
|
|
69
72
|
for (const candidate of candidates) {
|
|
70
73
|
const target = moduleTargetDocument(candidate.path, documentsByPath);
|
|
71
74
|
const packageFields = packageResolutionFields(candidate, packageInfo);
|
|
72
|
-
if (target) return { path: target.path, documentId: target.id, kind: `${candidate.kind}-source`, ...packageFields };
|
|
75
|
+
if (target) return { path: target.path, documentId: target.id, resolutionPathVariant: target.resolutionPathVariant, kind: `${candidate.kind}-source`, ...packageFields };
|
|
73
76
|
firstMissing ??= { path: candidate.path, kind: `${candidate.kind}-missing`, ...packageFields };
|
|
74
77
|
}
|
|
75
78
|
return firstMissing ?? (packageInfo ? { kind: 'package-external', ...packageInfo } : undefined);
|
|
@@ -95,7 +98,7 @@ function resolvePackageImportProjectModule(sourcePath, moduleSpecifier, document
|
|
|
95
98
|
packageImportTarget,
|
|
96
99
|
packageName: packageContext.packageName
|
|
97
100
|
};
|
|
98
|
-
if (resolved) return { path: resolved.path, documentId: resolved.id, kind: 'package-import-source', ...record };
|
|
101
|
+
if (resolved) return { path: resolved.path, documentId: resolved.id, resolutionPathVariant: resolved.resolutionPathVariant, kind: 'package-import-source', ...record };
|
|
99
102
|
firstMissing ??= { path: candidatePath, kind: 'package-import-missing', ...record };
|
|
100
103
|
}
|
|
101
104
|
return firstMissing ?? { kind: 'package-import-external', packageImportKey: match.key };
|
|
@@ -224,16 +227,12 @@ function packageFallbackTargets(options, subpath) {
|
|
|
224
227
|
|
|
225
228
|
function moduleTargetDocument(path, documentsByPath) {
|
|
226
229
|
for (const candidate of modulePathCandidates(path)) {
|
|
227
|
-
const document = documentsByPath.get(candidate);
|
|
228
|
-
if (document) return document;
|
|
230
|
+
const document = documentsByPath.get(candidate.path);
|
|
231
|
+
if (document) return { ...document, resolutionPathVariant: candidate.variant };
|
|
229
232
|
}
|
|
230
233
|
return undefined;
|
|
231
234
|
}
|
|
232
235
|
|
|
233
|
-
function modulePathCandidates(path) {
|
|
234
|
-
return [path, `${path}.js`, `${path}.ts`, `${path}.tsx`, `${path}.jsx`, `${path}.d.ts`, `${path}/index.js`, `${path}/index.ts`, `${path}/index.d.ts`];
|
|
235
|
-
}
|
|
236
|
-
|
|
237
236
|
function targetExportName(edge) {
|
|
238
237
|
const name = edge.importedName ?? edge.localName ?? edge.exportedName;
|
|
239
238
|
if (!name || name === '*') return undefined;
|
|
@@ -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