@shapeshift-labs/frontier-lang-compiler 0.2.119 → 0.2.120

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -277,12 +277,14 @@ 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.
280
+ When using `createTypeScriptCompilerNativeImporterAdapter`,
281
+ `createEstreeNativeImporterAdapter`, or `createBabelNativeImporterAdapter`,
282
+ parser AST imports emit the same binding-level module facts instead of only
283
+ statement-level module edges. Default, namespace, named, type-only, side-effect,
284
+ re-export, export-star, local export, `export default`, and TypeScript
285
+ `export =` declarations carry `importKind`, `exportKind`, `localName`,
286
+ `importedName`, `exportedName`, `isTypeOnly`, and public-contract metadata into
287
+ the semantic index and project symbol graph.
286
288
 
287
289
  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.
288
290
 
@@ -43,11 +43,11 @@ export function createProjectDocumentExportSymbolsResolver(symbols, documents) {
43
43
  const exportsByDocumentId = new Map();
44
44
  for (const symbol of symbols ?? []) {
45
45
  if (symbol?.kind !== 'export' || !symbol.name) continue;
46
- const document = documentsByPath.get(symbol.definitionSpan?.path);
47
- if (!document) continue;
48
- const exports = exportsByDocumentId.get(document.id) ?? [];
46
+ const documentId = symbolDocumentId(symbol, documentsByPath);
47
+ if (!documentId) continue;
48
+ const exports = exportsByDocumentId.get(documentId) ?? [];
49
49
  exports.push(symbol);
50
- exportsByDocumentId.set(document.id, exports);
50
+ exportsByDocumentId.set(documentId, exports);
51
51
  }
52
52
  return function resolveDocumentExports(documentId) {
53
53
  return exportsByDocumentId.get(documentId) ?? [];
@@ -59,12 +59,16 @@ function projectExportSymbolMap(symbols, documents) {
59
59
  const exportedByDocumentAndName = new Map();
60
60
  for (const symbol of symbols ?? []) {
61
61
  if (symbol?.kind !== 'export' || !symbol.name) continue;
62
- const document = documentsByPath.get(symbol.definitionSpan?.path);
63
- if (document) exportedByDocumentAndName.set(symbolKey(document.id, symbol.name), symbol);
62
+ const documentId = symbolDocumentId(symbol, documentsByPath);
63
+ if (documentId) exportedByDocumentAndName.set(symbolKey(documentId, symbol.name), symbol);
64
64
  }
65
65
  return exportedByDocumentAndName;
66
66
  }
67
67
 
68
+ function symbolDocumentId(symbol, documentsByPath) {
69
+ return symbol?.metadata?.moduleEdge?.sourceDocumentId ?? documentsByPath.get(symbol.definitionSpan?.path)?.id;
70
+ }
71
+
68
72
  function resolveConfiguredProjectModule(moduleSpecifier, documentsByPath, moduleResolution) {
69
73
  const packageInfo = packageSpecifierInfo(moduleSpecifier);
70
74
  const candidates = configuredModuleCandidates(moduleSpecifier, moduleResolution, packageInfo);
@@ -1,6 +1,8 @@
1
- import{declarationRecord}from'./declarationRecord.js';import{namedDeclaration}from'./namedDeclaration.js';import{nativeNodeId}from'./nativeNodeId.js';
1
+ import{declarationRecord}from'./declarationRecord.js';import{namedDeclaration}from'./namedDeclaration.js';import{nativeNodeId}from'./nativeNodeId.js';import{syntaxModuleDeclarationEntries}from'./syntaxModuleDeclarationEntries.js';
2
2
  export function syntaxDeclaration(node, nativeNodeId, input) {
3
3
  const kind = String(node.type ?? node.kind ?? '');
4
+ const moduleEntries = syntaxModuleDeclarationEntries(node, nativeNodeId, input);
5
+ if (moduleEntries.length) return moduleEntries.map((entry) => entry.declaration);
4
6
  if (kind === 'ImportDeclaration') {
5
7
  const name = node.source?.value;
6
8
  if (typeof name === 'string') return declarationRecord(input, nativeNodeId, name, 'module', 'import');
@@ -0,0 +1,279 @@
1
+ import{idFragment}from'../../native-import-utils.js';
2
+ import{declarationRecord}from'./declarationRecord.js';
3
+ export function syntaxModuleDeclarationEntries(node, nativeNodeId, input) {
4
+ const kind = String(node.type ?? node.kind ?? '');
5
+ if (kind === 'ImportDeclaration') return importDeclarationEntries(node, nativeNodeId, input);
6
+ if (kind === 'ExportNamedDeclaration') return exportNamedDeclarationEntries(node, nativeNodeId, input);
7
+ if (kind === 'ExportAllDeclaration') return exportAllDeclarationEntries(node, nativeNodeId, input);
8
+ if (kind === 'ExportDefaultDeclaration') return exportDefaultDeclarationEntries(node, nativeNodeId, input);
9
+ return [];
10
+ }
11
+
12
+ function importDeclarationEntries(node, nativeNodeId, input) {
13
+ const moduleSpecifier = sourceValue(node.source);
14
+ if (!moduleSpecifier) return [];
15
+ const typeOnly = node.importKind === 'type';
16
+ const bindings = (node.specifiers ?? []).map((specifier) => importSpecifierBinding(specifier, typeOnly)).filter(Boolean);
17
+ return importModuleEntries(input, nativeNodeId, moduleSpecifier, bindings, {
18
+ typeOnly,
19
+ sideEffectOnly: bindings.length === 0,
20
+ importKind: bindings.length === 0 ? 'side-effect' : 'module'
21
+ });
22
+ }
23
+
24
+ function exportNamedDeclarationEntries(node, nativeNodeId, input) {
25
+ const moduleSpecifier = sourceValue(node.source);
26
+ const typeOnly = node.exportKind === 'type';
27
+ const bindings = [
28
+ ...(node.specifiers ?? []).map((specifier) => exportSpecifierBinding(specifier, { typeOnly, reExport: Boolean(moduleSpecifier) })).filter(Boolean),
29
+ ...declarationExportBindings(node.declaration, { typeOnly })
30
+ ];
31
+ return [
32
+ ...(moduleSpecifier ? importModuleEntries(input, nativeNodeId, moduleSpecifier, reExportImportBindings(bindings), {
33
+ typeOnly,
34
+ reexport: true,
35
+ importKind: 'reexport'
36
+ }) : []),
37
+ ...exportModuleEntries(input, nativeNodeId, moduleSpecifier, bindings, {
38
+ typeOnly,
39
+ reExport: Boolean(moduleSpecifier),
40
+ exportKind: typeOnly ? 'type-named' : 'named'
41
+ })
42
+ ];
43
+ }
44
+
45
+ function exportAllDeclarationEntries(node, nativeNodeId, input) {
46
+ const moduleSpecifier = sourceValue(node.source);
47
+ if (!moduleSpecifier) return [];
48
+ const exportedName = identifierName(node.exported);
49
+ const typeOnly = node.exportKind === 'type';
50
+ const bindings = exportedName ? [{
51
+ localName: exportedName,
52
+ importedName: '*',
53
+ exportedName,
54
+ namespace: exportedName,
55
+ importKind: 'namespace-reexport',
56
+ exportKind: 'namespace-reexport',
57
+ isTypeOnly: typeOnly,
58
+ reExport: true
59
+ }] : [];
60
+ return [
61
+ ...importModuleEntries(input, nativeNodeId, moduleSpecifier, reExportImportBindings(bindings), {
62
+ typeOnly,
63
+ reexport: true,
64
+ exportStar: !exportedName,
65
+ importKind: exportedName ? 'namespace-reexport' : 'reexport'
66
+ }),
67
+ ...exportModuleEntries(input, nativeNodeId, moduleSpecifier, bindings, {
68
+ typeOnly,
69
+ reExport: true,
70
+ exportStar: !exportedName,
71
+ exportKind: exportedName ? 'namespace-reexport' : 'export-star'
72
+ })
73
+ ];
74
+ }
75
+
76
+ function exportDefaultDeclarationEntries(node, nativeNodeId, input) {
77
+ const localName = declarationName(node.declaration) ?? identifierName(node.declaration);
78
+ return [exportBindingEntry(input, nativeNodeId, undefined, {
79
+ localName,
80
+ exportedName: 'default',
81
+ exportKind: 'default',
82
+ isTypeOnly: false
83
+ })];
84
+ }
85
+
86
+ function importSpecifierBinding(specifier, parentTypeOnly) {
87
+ const kind = String(specifier.type ?? specifier.kind ?? '');
88
+ const localName = identifierName(specifier.local);
89
+ if (!localName) return undefined;
90
+ const typeOnly = Boolean(parentTypeOnly || specifier.importKind === 'type');
91
+ if (kind === 'ImportDefaultSpecifier') return { localName, importedName: 'default', importKind: typeOnly ? 'type-default' : 'default', isTypeOnly: typeOnly };
92
+ if (kind === 'ImportNamespaceSpecifier') return { localName, importedName: '*', namespace: localName, importKind: 'namespace', isTypeOnly: typeOnly };
93
+ return {
94
+ localName,
95
+ importedName: identifierName(specifier.imported) ?? localName,
96
+ importKind: typeOnly ? 'type-named' : 'named',
97
+ isTypeOnly: typeOnly
98
+ };
99
+ }
100
+
101
+ function exportSpecifierBinding(specifier, options) {
102
+ const kind = String(specifier.type ?? specifier.kind ?? '');
103
+ const typeOnly = Boolean(options.typeOnly || specifier.exportKind === 'type');
104
+ const exportedName = identifierName(specifier.exported) ?? identifierName(specifier.local);
105
+ if (!exportedName) return undefined;
106
+ if (kind === 'ExportNamespaceSpecifier') return {
107
+ localName: exportedName,
108
+ importedName: '*',
109
+ exportedName,
110
+ namespace: exportedName,
111
+ importKind: 'namespace-reexport',
112
+ exportKind: 'namespace-reexport',
113
+ isTypeOnly: typeOnly,
114
+ reExport: Boolean(options.reExport)
115
+ };
116
+ const localName = identifierName(specifier.local) ?? exportedName;
117
+ return {
118
+ localName,
119
+ importedName: options.reExport ? localName : undefined,
120
+ exportedName,
121
+ importKind: options.reExport ? typeOnly ? 'type-reexport' : 'reexport' : undefined,
122
+ exportKind: typeOnly ? 'type-named' : 'named',
123
+ isTypeOnly: typeOnly,
124
+ reExport: Boolean(options.reExport)
125
+ };
126
+ }
127
+
128
+ function declarationExportBindings(declaration, options) {
129
+ const kind = String(declaration?.type ?? declaration?.kind ?? '');
130
+ if (!kind) return [];
131
+ if (kind === 'VariableDeclaration') {
132
+ return (declaration.declarations ?? []).map((entry) => identifierName(entry.id)).filter(Boolean).map((name) => exportBinding(name, name, 'named', false));
133
+ }
134
+ const name = declarationName(declaration);
135
+ if (!name) return [];
136
+ return [exportBinding(name, name, declarationTypeOnly(kind) || options.typeOnly ? 'type-named' : 'named', declarationTypeOnly(kind) || options.typeOnly)];
137
+ }
138
+
139
+ function exportBinding(localName, exportedName, exportKind, isTypeOnly) {
140
+ return { localName, exportedName, exportKind, isTypeOnly, reExport: false };
141
+ }
142
+
143
+ function reExportImportBindings(bindings) {
144
+ return bindings.map((binding) => ({
145
+ localName: binding.exportedName ?? binding.localName,
146
+ importedName: binding.importedName ?? binding.localName,
147
+ exportedName: binding.exportedName,
148
+ namespace: binding.namespace,
149
+ importKind: binding.importKind ?? 'reexport',
150
+ isTypeOnly: binding.isTypeOnly
151
+ }));
152
+ }
153
+
154
+ function importModuleEntries(input, nativeNodeId, moduleSpecifier, bindings, metadata) {
155
+ return [{
156
+ declaration: compactRecord({
157
+ ...declarationRecord(input, nativeNodeId, moduleSpecifier, 'module', 'import'),
158
+ importPath: moduleSpecifier,
159
+ moduleSpecifier,
160
+ importKind: metadata.importKind,
161
+ isTypeOnly: metadata.typeOnly,
162
+ exportStar: metadata.exportStar,
163
+ metadata: moduleMetadata('syntax-import', bindings, metadata)
164
+ })
165
+ }, ...bindings.map((binding) => importBindingEntry(input, nativeNodeId, moduleSpecifier, binding))];
166
+ }
167
+
168
+ function importBindingEntry(input, nativeNodeId, moduleSpecifier, binding) {
169
+ return {
170
+ declaration: compactRecord({
171
+ ...declarationRecord(input, nativeNodeId, binding.localName, 'import', 'import'),
172
+ symbolId: `symbol:${input.language}:import:${idFragment(`${moduleSpecifier}:${binding.localName}:${binding.importedName}`)}`,
173
+ importPath: moduleSpecifier,
174
+ moduleSpecifier,
175
+ localName: binding.localName,
176
+ importedName: binding.importedName,
177
+ exportedName: binding.exportedName,
178
+ namespace: binding.namespace,
179
+ importKind: binding.importKind,
180
+ isTypeOnly: binding.isTypeOnly,
181
+ metadata: bindingMetadata('syntax-import-binding', moduleSpecifier, binding)
182
+ })
183
+ };
184
+ }
185
+
186
+ function exportModuleEntries(input, nativeNodeId, moduleSpecifier, bindings, metadata) {
187
+ const statementName = metadata.exportStar
188
+ ? `* from ${moduleSpecifier}`
189
+ : moduleSpecifier ? `{${bindings.map((binding) => binding.exportedName).join(',')}} from ${moduleSpecifier}` : `{${bindings.map((binding) => binding.exportedName).join(',')}}`;
190
+ return [{
191
+ declaration: compactRecord({
192
+ ...declarationRecord(input, nativeNodeId, statementName, 'module', 'export'),
193
+ exportPath: moduleSpecifier,
194
+ moduleSpecifier,
195
+ exportKind: metadata.exportKind,
196
+ exportStar: metadata.exportStar,
197
+ isTypeOnly: metadata.typeOnly,
198
+ reExport: metadata.reExport,
199
+ publicContract: true,
200
+ metadata: moduleMetadata('syntax-export', bindings, metadata)
201
+ })
202
+ }, ...bindings.map((binding) => exportBindingEntry(input, nativeNodeId, moduleSpecifier, binding))];
203
+ }
204
+
205
+ function exportBindingEntry(input, nativeNodeId, moduleSpecifier, binding) {
206
+ return {
207
+ declaration: compactRecord({
208
+ ...declarationRecord(input, nativeNodeId, binding.exportedName, 'export', 'export'),
209
+ symbolId: `symbol:${input.language}:export:${idFragment(binding.exportedName)}`,
210
+ exportPath: moduleSpecifier,
211
+ moduleSpecifier,
212
+ localName: binding.localName,
213
+ importedName: binding.importedName,
214
+ exportedName: binding.exportedName,
215
+ namespace: binding.namespace,
216
+ exportKind: binding.exportKind,
217
+ isTypeOnly: binding.isTypeOnly,
218
+ reExport: binding.reExport,
219
+ publicContract: true,
220
+ metadata: bindingMetadata('syntax-export-binding', moduleSpecifier, binding, true)
221
+ })
222
+ };
223
+ }
224
+
225
+ function moduleMetadata(scan, bindings, metadata) {
226
+ return compactRecord({
227
+ scan,
228
+ moduleOnly: true,
229
+ bindingCount: bindings.length,
230
+ importKind: metadata.importKind,
231
+ exportKind: metadata.exportKind,
232
+ isTypeOnly: metadata.typeOnly,
233
+ typeOnly: metadata.typeOnly,
234
+ sideEffectOnly: metadata.sideEffectOnly,
235
+ reexport: metadata.reexport,
236
+ reExport: metadata.reExport,
237
+ exportStar: metadata.exportStar,
238
+ publicContract: metadata.reExport || metadata.exportKind
239
+ });
240
+ }
241
+
242
+ function bindingMetadata(scan, moduleSpecifier, binding, publicContract = false) {
243
+ return compactRecord({
244
+ scan,
245
+ moduleSpecifier,
246
+ importPath: moduleSpecifier,
247
+ exportPath: moduleSpecifier,
248
+ localName: binding.localName,
249
+ importedName: binding.importedName,
250
+ exportedName: binding.exportedName,
251
+ namespace: binding.namespace,
252
+ importKind: binding.importKind,
253
+ exportKind: binding.exportKind,
254
+ isTypeOnly: binding.isTypeOnly,
255
+ typeOnly: binding.isTypeOnly,
256
+ reExport: binding.reExport,
257
+ publicContract
258
+ });
259
+ }
260
+
261
+ function sourceValue(source) {
262
+ return typeof source?.value === 'string' ? source.value : undefined;
263
+ }
264
+
265
+ function identifierName(node) {
266
+ return typeof node?.name === 'string' ? node.name : typeof node?.value === 'string' ? node.value : undefined;
267
+ }
268
+
269
+ function declarationName(node) {
270
+ return identifierName(node?.id) ?? identifierName(node?.name);
271
+ }
272
+
273
+ function declarationTypeOnly(kind) {
274
+ return kind === 'TSInterfaceDeclaration' || kind === 'TSTypeAliasDeclaration' || kind === 'InterfaceDeclaration' || kind === 'TypeAliasDeclaration';
275
+ }
276
+
277
+ function compactRecord(record) {
278
+ return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));
279
+ }
@@ -23,16 +23,20 @@ export function visitSyntaxAstNode(node, context, propertyPath) {
23
23
  if (childId) children.push(childId);
24
24
  }
25
25
  }
26
- const declaration = syntaxDeclaration(node, id, context.input, context.options);
26
+ const declarationResult = syntaxDeclaration(node, 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: String(node.type ?? node.kind ?? 'Node'),
30
32
  languageKind: `${context.input.language}.${node.type ?? node.kind ?? 'Node'}`,
31
33
  span: spanFromLoc(node.loc, context.input),
32
- value: declaration?.name ?? literalSyntaxValue(node),
34
+ value: primaryDeclaration?.name ?? literalSyntaxValue(node),
33
35
  fields,
34
36
  children,
35
37
  metadata: {
38
+ ...primaryDeclaration?.metadata,
39
+ ...(declarations.length > 1 ? { declarationCount: declarations.length } : {}),
36
40
  astFormat: context.options.astFormat,
37
41
  propertyPath,
38
42
  start: numberOrUndefined(node.start),
@@ -41,6 +45,6 @@ export function visitSyntaxAstNode(node, context, propertyPath) {
41
45
  }
42
46
  };
43
47
  context.nodes[id] = nativeNode;
44
- if (declaration) context.declarations.push({ ...declaration, nativeNode });
48
+ for (const declaration of declarations) context.declarations.push({ ...declaration, nativeNode });
45
49
  return id;
46
50
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-compiler",
3
- "version": "0.2.119",
3
+ "version": "0.2.120",
4
4
  "description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",