@shapeshift-labs/frontier-lang-compiler 0.2.113 → 0.2.115

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
@@ -238,6 +238,13 @@ console.log(project.outputProjectSymbolGraph.importEdges[0].packageName); // "@p
238
238
  console.log(project.outputProjectSymbolGraph.importEdges[0].packageExportCondition); // "import"
239
239
  ```
240
240
 
241
+ Named re-export identities also include symbol links when the project graph has
242
+ enough evidence. For `export { thing as renamedThing } from './thing.js'`,
243
+ `reExportIdentities[]` records the source module, imported/exported names,
244
+ `originSymbolId`, `exportedSymbolId`, and `localSymbolId`.
245
+ Public contract regions include `apiSurfaceKind`, `signatureHash`, and
246
+ `contractHash`, giving merge admission a stable API surface fingerprint.
247
+
241
248
  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.
242
249
 
243
250
  ```js
@@ -82,9 +82,6 @@ export type NativeProjectSymbolGraphRemainingField =
82
82
  | 'reExportIdentities[].originSymbolId'
83
83
  | 'reExportIdentities[].exportedSymbolId'
84
84
  | 'reExportIdentities[].localSymbolId'
85
- | 'publicContractRegions[].apiSurfaceKind'
86
- | 'publicContractRegions[].signatureHash'
87
- | 'publicContractRegions[].contractHash'
88
85
  | string;
89
86
 
90
87
  export interface NativeProjectSymbolGraphFileHashRecord {
@@ -138,10 +135,10 @@ export interface NativeProjectSymbolGraphReExportIdentityRecord {
138
135
  readonly localName?: string;
139
136
  readonly namespace?: string;
140
137
  readonly isTypeOnly?: boolean;
141
- readonly symbolId?: string;
138
+ readonly symbolId?: string; readonly originSymbolId?: string;
139
+ readonly exportedSymbolId?: string; readonly localSymbolId?: string;
142
140
  readonly relationId?: string;
143
- readonly ownershipRegionId?: string;
144
- readonly ownershipRegionKey?: string;
141
+ readonly ownershipRegionId?: string; readonly ownershipRegionKey?: string;
145
142
  readonly publicContract?: boolean;
146
143
  readonly factId?: string;
147
144
  }
@@ -158,6 +155,9 @@ export interface NativeProjectSymbolGraphPublicContractRegionRecord {
158
155
  readonly symbolId?: string;
159
156
  readonly symbolName?: string;
160
157
  readonly symbolKind?: string;
158
+ readonly apiSurfaceKind?: string;
159
+ readonly signatureHash?: string;
160
+ readonly contractHash?: string;
161
161
  readonly nativeAstNodeId?: string;
162
162
  readonly sourceSpan?: SourceSpan;
163
163
  readonly precision?: string;
@@ -1,6 +1,8 @@
1
1
  import{idFragment,uniqueByEvidenceId,uniqueByLossId,uniqueStrings}from'../../native-import-utils.js';import{createDocument,createPatch,createUniversalAstEnvelope}from'@shapeshift-labs/frontier-lang-kernel';
2
2
  import{createNativeImportResultContract}from'./createNativeImportResultContract.js';import{createProjectImportAdmissionRecord}from'./createProjectImportAdmissionRecord.js';import{mergeSemanticIndexes}from'./mergeSemanticIndexes.js';import{summarizeNativeImportLosses}from'./summarizeNativeImportLosses.js';import{summarizeProjectSourcePreservation}from'./summarizeProjectSourcePreservation.js';
3
- import{createProjectModuleSymbolResolver,resolveProjectModule}from'./projectSymbolGraphModuleResolution.js';
3
+ import{createProjectDocumentExportSymbolResolver,createProjectModuleSymbolResolver,resolveProjectModule}from'./projectSymbolGraphModuleResolution.js';
4
+ import{publicContractRegionRecord}from'./projectSymbolGraphPublicContracts.js';
5
+ import{isReExportImportEdge,reExportIdentityInputFromEdge,reExportIdentityRecord}from'./projectSymbolGraphReExports.js';
4
6
  export function createNativeProjectImportResult(input, imports) {
5
7
  const idPart = idFragment(input.id ?? input.projectRoot ?? 'native_project');
6
8
  const nodes = {};
@@ -143,10 +145,7 @@ export function createNativeProjectImportResult(input, imports) {
143
145
  const PROJECT_SYMBOL_GRAPH_REMAINING_FIELDS = Object.freeze([
144
146
  'reExportIdentities[].originSymbolId',
145
147
  'reExportIdentities[].exportedSymbolId',
146
- 'reExportIdentities[].localSymbolId',
147
- 'publicContractRegions[].apiSurfaceKind',
148
- 'publicContractRegions[].signatureHash',
149
- 'publicContractRegions[].contractHash'
148
+ 'reExportIdentities[].localSymbolId'
150
149
  ]);
151
150
 
152
151
  function createProjectSymbolGraphSummary(semanticIndex, imports, input) {
@@ -156,6 +155,7 @@ function createProjectSymbolGraphSummary(semanticIndex, imports, input) {
156
155
  const documentsByPath = new Map(documents.filter((document) => document.path).map((document) => [document.path, document]));
157
156
  const moduleResolution = input.moduleResolution ?? input.tsconfig;
158
157
  const resolveTargetSymbolId = createProjectModuleSymbolResolver(semanticIndex?.symbols ?? [], documents);
158
+ const resolveDocumentExportSymbolId = createProjectDocumentExportSymbolResolver(semanticIndex?.symbols ?? [], documents);
159
159
  const facts = semanticIndex?.facts ?? [];
160
160
  const moduleEdgeFacts = facts.filter((fact) => fact.predicate === 'moduleEdge');
161
161
  const moduleEdgeByRelation = new Map(moduleEdgeFacts.map((fact) => [fact.subjectId, fact]));
@@ -166,26 +166,21 @@ function createProjectSymbolGraphSummary(semanticIndex, imports, input) {
166
166
  const exportEdges = relations
167
167
  .filter((relation) => relation.predicate === 'exports')
168
168
  .map((relation) => moduleEdgeRecord(relation, moduleEdgeByRelation, symbolsById, documentsById, documentsByPath, moduleResolution, resolveTargetSymbolId));
169
+ const moduleEdgeById = new Map([...importEdges, ...exportEdges].map((edge) => [edge.id, edge]));
169
170
  const reExportIdentities = uniqueRecords([
170
171
  ...facts
171
172
  .filter((fact) => fact.predicate === 'reExportIdentity' && fact.value)
172
- .map((fact) => ({ ...objectValue(fact.value), factId: fact.id })),
173
+ .map((fact) => reExportIdentityRecord(objectValue(fact.value), moduleEdgeById.get(objectValue(fact.value).relationId ?? fact.objectId), resolveDocumentExportSymbolId, { factId: fact.id })),
173
174
  ...exportEdges
174
175
  .filter((edge) => edge.isReExport)
175
- .map((edge) => compactRecord({
176
- id: `reexport_${idFragment(edge.id)}`,
177
- sourceDocumentId: edge.sourceDocumentId,
178
- sourcePath: edge.sourcePath,
179
- sourceHash: edge.sourceHash,
180
- moduleSpecifier: edge.moduleSpecifier,
181
- symbolId: edge.targetSymbolId,
182
- relationId: edge.id,
183
- publicContract: edge.publicContract
184
- }))
176
+ .map((edge) => reExportIdentityRecord(reExportIdentityInputFromEdge(edge, `reexport_${idFragment(edge.id)}`), edge, resolveDocumentExportSymbolId)),
177
+ ...importEdges
178
+ .filter((edge) => isReExportImportEdge(edge))
179
+ .map((edge) => reExportIdentityRecord(reExportIdentityInputFromEdge(edge, `reexport_${idFragment(edge.id)}`), edge, resolveDocumentExportSymbolId))
185
180
  ]);
186
181
  const publicContractRegions = uniqueRecords(facts
187
182
  .filter((fact) => fact.predicate === 'publicContractRegion' && fact.value)
188
- .map((fact) => ({ ...objectValue(fact.value), factId: fact.id, symbolId: fact.subjectId })));
183
+ .map((fact) => publicContractRegionRecord(objectValue(fact.value), fact, symbolsById.get(fact.subjectId))));
189
184
  const fileHashes = uniqueRecords([
190
185
  ...documents.map((document) => fileHashRecord(document)),
191
186
  ...facts
@@ -17,14 +17,7 @@ export function resolveProjectModule(sourcePath, moduleSpecifier, documentsByPat
17
17
  }
18
18
 
19
19
  export function createProjectModuleSymbolResolver(symbols, documents) {
20
- const documentsByPath = new Map(documents.filter((document) => document.path).map((document) => [document.path, document]));
21
- const exportedByDocumentAndName = new Map();
22
- for (const symbol of symbols ?? []) {
23
- if (symbol?.kind !== 'export' || !symbol.name) continue;
24
- const document = documentsByPath.get(symbol.definitionSpan?.path);
25
- if (!document) continue;
26
- exportedByDocumentAndName.set(symbolKey(document.id, symbol.name), symbol);
27
- }
20
+ const exportedByDocumentAndName = projectExportSymbolMap(symbols, documents);
28
21
  return function resolveProjectModuleSymbol(edge) {
29
22
  if (!edge?.targetDocumentId) return undefined;
30
23
  const targetName = targetExportName(edge);
@@ -33,6 +26,25 @@ export function createProjectModuleSymbolResolver(symbols, documents) {
33
26
  };
34
27
  }
35
28
 
29
+ export function createProjectDocumentExportSymbolResolver(symbols, documents) {
30
+ const exportedByDocumentAndName = projectExportSymbolMap(symbols, documents);
31
+ return function resolveDocumentExportSymbol(documentId, name) {
32
+ if (!documentId || !name) return undefined;
33
+ return exportedByDocumentAndName.get(symbolKey(documentId, name))?.id;
34
+ };
35
+ }
36
+
37
+ function projectExportSymbolMap(symbols, documents) {
38
+ const documentsByPath = new Map(documents.filter((document) => document.path).map((document) => [document.path, document]));
39
+ const exportedByDocumentAndName = new Map();
40
+ for (const symbol of symbols ?? []) {
41
+ if (symbol?.kind !== 'export' || !symbol.name) continue;
42
+ const document = documentsByPath.get(symbol.definitionSpan?.path);
43
+ if (document) exportedByDocumentAndName.set(symbolKey(document.id, symbol.name), symbol);
44
+ }
45
+ return exportedByDocumentAndName;
46
+ }
47
+
36
48
  function resolveConfiguredProjectModule(moduleSpecifier, documentsByPath, moduleResolution) {
37
49
  const packageInfo = packageSpecifierInfo(moduleSpecifier);
38
50
  const candidates = configuredModuleCandidates(moduleSpecifier, moduleResolution, packageInfo);
@@ -0,0 +1,41 @@
1
+ import{hashSemanticValue}from'@shapeshift-labs/frontier-lang-kernel';
2
+
3
+ export function publicContractRegionRecord(value, fact, symbol) {
4
+ const record = {
5
+ ...value,
6
+ factId: fact.id,
7
+ symbolId: fact.subjectId,
8
+ apiSurfaceKind: value.apiSurfaceKind ?? apiSurfaceKind(value, symbol),
9
+ signatureHash: value.signatureHash ?? symbol?.signatureHash
10
+ };
11
+ return compactRecord({
12
+ ...record,
13
+ contractHash: value.contractHash ?? publicContractHash(record)
14
+ });
15
+ }
16
+
17
+ function apiSurfaceKind(region, symbol) {
18
+ if (region.edgeKind === 're-export') return 'module-re-export';
19
+ if (region.edgeKind === 'export') return 'module-export';
20
+ if (symbol?.kind === 'export') return 'named-export';
21
+ return region.symbolKind ?? symbol?.kind ?? region.regionKind;
22
+ }
23
+
24
+ function publicContractHash(region) {
25
+ return hashSemanticValue({
26
+ kind: 'frontier.lang.publicContractRegionHash',
27
+ sourceHash: region.sourceHash,
28
+ symbolId: region.symbolId,
29
+ symbolName: region.symbolName,
30
+ symbolKind: region.symbolKind,
31
+ signatureHash: region.signatureHash,
32
+ moduleSpecifier: region.moduleSpecifier,
33
+ exportedName: region.exportedName,
34
+ edgeKind: region.edgeKind,
35
+ apiSurfaceKind: region.apiSurfaceKind
36
+ });
37
+ }
38
+
39
+ function compactRecord(record) {
40
+ return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));
41
+ }
@@ -0,0 +1,43 @@
1
+ export function reExportIdentityRecord(identity, edge, resolveDocumentExportSymbolId, extra = {}) {
2
+ const exportedName = firstString(identity.exportedName, edge?.exportedName, edge?.importedName === '*' ? undefined : (edge?.exportedName ?? edge?.importedName));
3
+ const importedName = firstString(identity.importedName, edge?.importedName);
4
+ const localName = firstString(identity.localName, edge?.localName, exportedName);
5
+ return compactRecord({
6
+ ...identity,
7
+ exportedName,
8
+ importedName,
9
+ localName,
10
+ originSymbolId: firstString(identity.originSymbolId, edge?.resolvedTargetSymbolId),
11
+ exportedSymbolId: firstString(identity.exportedSymbolId, resolveDocumentExportSymbolId(edge?.sourceDocumentId, exportedName), edge?.predicate === 'exports' ? edge?.targetSymbolId : undefined),
12
+ localSymbolId: firstString(identity.localSymbolId, edge?.targetSymbolId),
13
+ ...extra
14
+ });
15
+ }
16
+
17
+ export function isReExportImportEdge(edge) {
18
+ return edge.importKind === 'reexport' || edge.importKind === 'namespace-reexport';
19
+ }
20
+
21
+ export function reExportIdentityInputFromEdge(edge, id) {
22
+ return compactRecord({
23
+ id,
24
+ sourceDocumentId: edge.sourceDocumentId,
25
+ sourcePath: edge.sourcePath,
26
+ sourceHash: edge.sourceHash,
27
+ moduleSpecifier: edge.moduleSpecifier,
28
+ symbolId: edge.targetSymbolId,
29
+ relationId: edge.id,
30
+ publicContract: edge.publicContract
31
+ });
32
+ }
33
+
34
+ function compactRecord(record) {
35
+ return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));
36
+ }
37
+
38
+ function firstString(...values) {
39
+ for (const value of values) {
40
+ if (value !== undefined && value !== null && String(value)) return String(value);
41
+ }
42
+ return undefined;
43
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-compiler",
3
- "version": "0.2.113",
3
+ "version": "0.2.115",
4
4
  "description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",