@shapeshift-labs/frontier-lang-compiler 0.2.56 → 0.2.58
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 +6 -1
- package/dist/declarations/roundtrip.d.ts +39 -0
- package/dist/internal/index-impl/createLightweightSemanticLayers.js +134 -0
- package/dist/internal/index-impl/createNativeRoundtripEvidence.js +75 -3
- package/dist/internal/index-impl/importNativeSource.js +3 -0
- package/examples/js-frontier-rust-workbench-html.mjs +8 -4
- package/examples/js-frontier-rust-workbench-styles.mjs +76 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -455,15 +455,20 @@ console.log(rustCandidate.sourceMap.mappings[0]?.semanticSymbolId); // generated
|
|
|
455
455
|
|
|
456
456
|
`compileNativeSource` returns the import result, projection, target loss matrix cell, combined losses, readiness, evidence, output hash, and generated-output source maps. Same-language preserved output uses exact source mappings when the hash matches; generated stubs use declaration-level spans; adapter output uses adapter-supplied maps when present and otherwise gets an estimated fallback. Admission queues should treat `ok` as "code was emitted", not as merge approval; `readiness`, `targetCoverage`, and source-map precision carry the merge signal.
|
|
457
457
|
|
|
458
|
-
Native projections and compile results also carry a `frontier.lang.nativeRoundtripEvidence` record under `evidence[].metadata.roundtripEvidence` and `metadata.roundtripEvidence`. That payload records import readiness/loss counts, universal AST validation and source-map precision, projection mode/hash verification, target adapter identity, target coverage, output source-map precision,
|
|
458
|
+
Native projections and compile results also carry a `frontier.lang.nativeRoundtripEvidence` record under `evidence[].metadata.roundtripEvidence` and `metadata.roundtripEvidence`. That payload records import readiness/loss counts, universal AST validation and source-map precision, projection mode/hash verification, target adapter identity, target coverage, output source-map precision, blocking/review loss ids, and a compact audit signal in one coordinator-sortable JSON shape:
|
|
459
459
|
|
|
460
460
|
```js
|
|
461
461
|
const roundtrip = rustCandidate.metadata.roundtripEvidence;
|
|
462
462
|
console.log(roundtrip.status); // "blocked", "stub-only", "preserved-source", or "target-adapter"
|
|
463
|
+
console.log(roundtrip.audit.disposition); // "reversible", "preserved-source", "stub-only", or "adapter-projected"
|
|
464
|
+
console.log(roundtrip.audit.claim); // bounded evidence label, not a semantic equivalence proof
|
|
465
|
+
console.log(roundtrip.audit.semanticEquivalenceClaim); // false
|
|
463
466
|
console.log(roundtrip.output.sourceMaps.precision); // "exact", "declaration", "estimated", or "none"
|
|
464
467
|
console.log(roundtrip.losses.blockingLossIds);
|
|
465
468
|
```
|
|
466
469
|
|
|
470
|
+
`roundtrip.audit` separates what was emitted from whether it can be merged: hash-verified same-language output with exact generated source maps is marked `reversible`, preserved source without generated exact maps stays `preserved-source`, generated declarations are `stub-only`, and host-owned target adapters are `adapter-projected`. Blocked and needs-review readiness still flow through `status`, `semanticMergeReadiness`, `reviewRequired`, loss ids, and source-map precision; the audit signal always keeps `autoMergeClaim: false` and `semanticEquivalenceClaim: false`.
|
|
471
|
+
|
|
467
472
|
Provide a target projection adapter when the host owns real native-to-target translation semantics:
|
|
468
473
|
|
|
469
474
|
```js
|
|
@@ -107,6 +107,20 @@ export type NativeRoundtripEvidenceStatus = NativeImportRoundtripReadinessStatus
|
|
|
107
107
|
|
|
108
108
|
export type NativeRoundtripSourceMapPrecision = SourceMapMappingRecord['precision'] | 'line' | 'declaration' | 'estimated' | 'unknown' | 'none' | string;
|
|
109
109
|
|
|
110
|
+
export type NativeRoundtripAuditDisposition =
|
|
111
|
+
| 'reversible'
|
|
112
|
+
| 'preserved-source'
|
|
113
|
+
| 'stub-only'
|
|
114
|
+
| 'adapter-projected'
|
|
115
|
+
| 'review-required';
|
|
116
|
+
|
|
117
|
+
export type NativeRoundtripAuditClaim =
|
|
118
|
+
| 'source-text-reversible'
|
|
119
|
+
| 'source-preserved'
|
|
120
|
+
| 'declaration-stubs-only'
|
|
121
|
+
| 'host-adapter-projected'
|
|
122
|
+
| 'review-required';
|
|
123
|
+
|
|
110
124
|
export interface NativeRoundtripSourceMapEvidence {
|
|
111
125
|
readonly total: number;
|
|
112
126
|
readonly ids: readonly string[];
|
|
@@ -120,6 +134,30 @@ export interface NativeRoundtripSourceMapEvidence {
|
|
|
120
134
|
readonly targetPaths: readonly string[];
|
|
121
135
|
}
|
|
122
136
|
|
|
137
|
+
export interface NativeRoundtripAuditSignal {
|
|
138
|
+
readonly schema: 'frontier.lang.nativeRoundtripAuditSignal';
|
|
139
|
+
readonly version: 1;
|
|
140
|
+
readonly disposition: NativeRoundtripAuditDisposition;
|
|
141
|
+
readonly claim: NativeRoundtripAuditClaim;
|
|
142
|
+
readonly sourceLanguage?: FrontierSourceLanguage | string;
|
|
143
|
+
readonly target?: CompileTarget | string;
|
|
144
|
+
readonly sameLanguage: boolean;
|
|
145
|
+
readonly outputMode?: NativeSourceCompileOutputMode;
|
|
146
|
+
readonly projectionMode?: NativeSourceProjectionMode;
|
|
147
|
+
readonly sourceHashVerified: boolean;
|
|
148
|
+
readonly outputSourceMapPrecision: NativeRoundtripSourceMapPrecision;
|
|
149
|
+
readonly universalSourceMapPrecision: NativeRoundtripSourceMapPrecision;
|
|
150
|
+
readonly targetProjectionAdapterId?: string;
|
|
151
|
+
readonly targetCoverageLossClass?: ProjectionTargetLossClass | string;
|
|
152
|
+
readonly reviewRequired: boolean;
|
|
153
|
+
readonly semanticMergeReadiness: SemanticMergeReadiness;
|
|
154
|
+
readonly semanticEquivalenceClaim: false;
|
|
155
|
+
readonly autoMergeClaim: false;
|
|
156
|
+
readonly blockingLossCount: number;
|
|
157
|
+
readonly reviewLossCount: number;
|
|
158
|
+
readonly reasonCodes: readonly string[];
|
|
159
|
+
}
|
|
160
|
+
|
|
123
161
|
export interface NativeRoundtripEvidenceMetadata {
|
|
124
162
|
readonly status: NativeRoundtripEvidenceStatus;
|
|
125
163
|
readonly semanticMergeReadiness: SemanticMergeReadiness;
|
|
@@ -127,6 +165,7 @@ export interface NativeRoundtripEvidenceMetadata {
|
|
|
127
165
|
readonly sourcePath?: string;
|
|
128
166
|
readonly language?: FrontierSourceLanguage | string;
|
|
129
167
|
readonly target?: CompileTarget | string;
|
|
168
|
+
readonly audit: NativeRoundtripAuditSignal;
|
|
130
169
|
readonly import: {
|
|
131
170
|
readonly id?: string;
|
|
132
171
|
readonly readiness: SemanticMergeReadiness;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import{createParadigmSemanticsLayer,createProofSpecLayer}from'@shapeshift-labs/frontier-lang-kernel';
|
|
2
|
+
|
|
3
|
+
export function createLightweightSemanticLayers(input) {
|
|
4
|
+
const evidenceIds = (input.evidence ?? []).map((record) => record.id).filter(Boolean);
|
|
5
|
+
const symbols = input.semanticIndex?.symbols ?? [];
|
|
6
|
+
const mappings = (input.sourceMaps ?? []).flatMap((sourceMap) => sourceMap.mappings ?? []);
|
|
7
|
+
const lossIds = (input.losses ?? []).map((loss) => loss.id).filter(Boolean);
|
|
8
|
+
const firstSubject = symbols[0]?.id ?? input.nativeSource?.id ?? input.nativeAst?.id;
|
|
9
|
+
const firstSubjectKind = symbols[0]?.id ? 'semanticSymbol' : input.nativeSource?.id ? 'nativeSource' : 'nativeAst';
|
|
10
|
+
const proof = createProofSpecLayer({
|
|
11
|
+
id: `proof_lightweight_${input.importIdPart}`,
|
|
12
|
+
invariants: [proofInvariant(input, firstSubject, firstSubjectKind, evidenceIds, lossIds)],
|
|
13
|
+
obligations: proofObligations(input, firstSubject, firstSubjectKind, evidenceIds, lossIds),
|
|
14
|
+
artifacts: [{
|
|
15
|
+
id: `proof_artifact_review_${input.importIdPart}`,
|
|
16
|
+
kind: 'manualReview',
|
|
17
|
+
evidenceIds,
|
|
18
|
+
lossIds,
|
|
19
|
+
summary: 'Lightweight import requires host parser, checker, tests, or human review before semantic merge.'
|
|
20
|
+
}],
|
|
21
|
+
assumptions: [{
|
|
22
|
+
id: `proof_assumption_lightweight_${input.importIdPart}`,
|
|
23
|
+
scope: 'native-import',
|
|
24
|
+
subjectId: input.nativeSource?.id,
|
|
25
|
+
subjectKind: 'nativeSource',
|
|
26
|
+
evidenceIds,
|
|
27
|
+
statement: 'Native source text and scanner evidence are preserved, but executable semantics are not proven.'
|
|
28
|
+
}],
|
|
29
|
+
evidence: input.evidence ?? []
|
|
30
|
+
});
|
|
31
|
+
const paradigmSemantics = createParadigmSemanticsLayer({
|
|
32
|
+
id: `paradigm_lightweight_${input.importIdPart}`,
|
|
33
|
+
bindingScopes: [{
|
|
34
|
+
id: `binding_scope_${input.importIdPart}`,
|
|
35
|
+
kind: 'moduleScope',
|
|
36
|
+
nativeSourceId: input.nativeSource?.id,
|
|
37
|
+
evidenceIds,
|
|
38
|
+
sourcePath: input.sourcePath,
|
|
39
|
+
sourceHash: input.sourceHash
|
|
40
|
+
}],
|
|
41
|
+
bindings: symbols.slice(0, 40).map((symbol) => ({
|
|
42
|
+
id: `binding_${symbol.id}`,
|
|
43
|
+
kind: 'nativeDeclarationBinding',
|
|
44
|
+
bindingScopeId: `binding_scope_${input.importIdPart}`,
|
|
45
|
+
semanticSymbolId: symbol.id,
|
|
46
|
+
nativeSourceId: input.nativeSource?.id,
|
|
47
|
+
evidenceIds
|
|
48
|
+
})),
|
|
49
|
+
evaluationModels: [evaluationModel(input, evidenceIds)],
|
|
50
|
+
effectRegions: effectRegions(input, evidenceIds),
|
|
51
|
+
loweringRecords: mappings.slice(0, 40).map((mapping) => ({
|
|
52
|
+
id: `lowering_${mapping.id}`,
|
|
53
|
+
kind: 'nativeSourceToFrontierSemanticIndex',
|
|
54
|
+
sourceMapId: mapping.sourceMapId,
|
|
55
|
+
sourceMapMappingId: mapping.id,
|
|
56
|
+
semanticSymbolId: mapping.semanticSymbolId,
|
|
57
|
+
nativeAstNodeId: mapping.nativeAstNodeId,
|
|
58
|
+
evidenceIds,
|
|
59
|
+
lossIds
|
|
60
|
+
})),
|
|
61
|
+
macroExpansions: macroBoundaryRecords(input, evidenceIds, lossIds),
|
|
62
|
+
reflectionBoundaries: reflectionBoundaryRecords(input, evidenceIds, lossIds),
|
|
63
|
+
evidence: input.evidence ?? []
|
|
64
|
+
});
|
|
65
|
+
return { proof, paradigmSemantics };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function proofInvariant(input, subjectId, subjectKind, evidenceIds, lossIds) {
|
|
69
|
+
return {
|
|
70
|
+
id: `proof_invariant_source_hash_${input.importIdPart}`,
|
|
71
|
+
kind: 'sourceHashFreshness',
|
|
72
|
+
subjectId,
|
|
73
|
+
subjectKind,
|
|
74
|
+
evidenceIds,
|
|
75
|
+
lossIds,
|
|
76
|
+
statement: 'Semantic merge candidates must match the preserved source hash before admission.'
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function proofObligations(input, subjectId, subjectKind, evidenceIds, lossIds) {
|
|
81
|
+
return [
|
|
82
|
+
{
|
|
83
|
+
id: `proof_obligation_review_${input.importIdPart}`,
|
|
84
|
+
kind: 'semanticMergeReview',
|
|
85
|
+
status: 'open',
|
|
86
|
+
subjectId,
|
|
87
|
+
subjectKind,
|
|
88
|
+
contractIds: [`proof_invariant_source_hash_${input.importIdPart}`],
|
|
89
|
+
evidenceIds,
|
|
90
|
+
lossIds,
|
|
91
|
+
statement: 'Review ownership, source maps, losses, and focused tests before applying this semantic patch.'
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: `proof_obligation_external_semantics_${input.importIdPart}`,
|
|
95
|
+
kind: 'externalSemanticEquivalence',
|
|
96
|
+
status: 'external-tool-required',
|
|
97
|
+
subjectId,
|
|
98
|
+
subjectKind,
|
|
99
|
+
evidenceIds,
|
|
100
|
+
lossIds,
|
|
101
|
+
statement: 'Cross-language executable equivalence requires a target checker, oracle, or proof artifact.'
|
|
102
|
+
}
|
|
103
|
+
];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function evaluationModel(input, evidenceIds) {
|
|
107
|
+
const language = String(input.language ?? 'unknown').toLowerCase();
|
|
108
|
+
const kind = ['javascript', 'typescript', 'python', 'ruby', 'php', 'lua'].includes(language)
|
|
109
|
+
? 'dynamicRuntime'
|
|
110
|
+
: ['rust', 'c', 'cpp', 'c++', 'zig'].includes(language)
|
|
111
|
+
? 'compileTimeOwnershipRuntime'
|
|
112
|
+
: 'languageRuntime';
|
|
113
|
+
return { id: `evaluation_model_${input.importIdPart}`, kind, nativeSourceId: input.nativeSource?.id, evidenceIds };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function effectRegions(input, evidenceIds) {
|
|
117
|
+
const predicates = new Set((input.semanticIndex?.relations ?? []).map((relation) => relation.predicate));
|
|
118
|
+
return [...predicates].filter((predicate) => ['calls', 'imports', 'uses', 'requires'].includes(predicate)).map((predicate) => ({
|
|
119
|
+
id: `effect_region_${input.importIdPart}_${predicate}`,
|
|
120
|
+
kind: `${predicate}DependencyEffect`,
|
|
121
|
+
nativeSourceId: input.nativeSource?.id,
|
|
122
|
+
evidenceIds
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function macroBoundaryRecords(input, evidenceIds, lossIds) {
|
|
127
|
+
const hasMacroLoss = (input.losses ?? []).some((loss) => ['macroExpansion', 'preprocessor', 'metaprogramming'].includes(loss.kind));
|
|
128
|
+
return hasMacroLoss ? [{ id: `macro_boundary_${input.importIdPart}`, kind: 'reviewRequiredMacroBoundary', nativeSourceId: input.nativeSource?.id, evidenceIds, lossIds }] : [];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function reflectionBoundaryRecords(input, evidenceIds, lossIds) {
|
|
132
|
+
const hasReflectionLoss = (input.losses ?? []).some((loss) => ['dynamicRuntime', 'reflection', 'opaqueNative'].includes(loss.kind));
|
|
133
|
+
return hasReflectionLoss ? [{ id: `reflection_boundary_${input.importIdPart}`, kind: 'reviewRequiredDynamicBoundary', nativeSourceId: input.nativeSource?.id, evidenceIds, lossIds }] : [];
|
|
134
|
+
}
|
|
@@ -24,7 +24,26 @@ export function createNativeRoundtripEvidence(importResult,options={}) {
|
|
|
24
24
|
const outputMode=options.outputMode??options.targetProjection?.outputMode??projection?.mode;
|
|
25
25
|
const sourceHashVerified=Boolean(projection?.sourceHash&&projection?.outputHash===projection.sourceHash)||projection?.metadata?.sourceHashVerified===true;
|
|
26
26
|
const status=semanticMerge==='blocked'?'blocked':outputMode==='target-adapter'?'target-adapter':projection?.mode==='native-source-stubs'||outputMode==='target-stubs'?'stub-only':sourceHashVerified?'preserved-source':'needs-review';
|
|
27
|
+
const universalSourceMapEvidence=summarizeSourceMaps(universalSourceMaps);
|
|
27
28
|
const sourceMapEvidence=summarizeSourceMaps(hasOutputSourceMaps?outputSourceMaps:universalSourceMaps);
|
|
29
|
+
const sourceLanguage=projection?.language??importResult.language;
|
|
30
|
+
const target=options.target??options.targetCoverage?.target??options.targetProjection?.target;
|
|
31
|
+
const audit=createRoundtripAudit({
|
|
32
|
+
status,
|
|
33
|
+
semanticMerge,
|
|
34
|
+
sourceLanguage,
|
|
35
|
+
target,
|
|
36
|
+
sameLanguage:Boolean(sourceLanguage&&target&&String(sourceLanguage)===String(target)),
|
|
37
|
+
outputMode,
|
|
38
|
+
projectionMode:projection?.mode,
|
|
39
|
+
sourceHashVerified,
|
|
40
|
+
hasOutputSourceMaps,
|
|
41
|
+
sourceMapEvidence,
|
|
42
|
+
universalSourceMapEvidence,
|
|
43
|
+
targetProjection:options.targetProjection,
|
|
44
|
+
targetCoverage:options.targetCoverage,
|
|
45
|
+
lossSummary
|
|
46
|
+
});
|
|
28
47
|
const metadata={
|
|
29
48
|
schema:'frontier.lang.nativeRoundtripEvidence',
|
|
30
49
|
version:1,
|
|
@@ -33,8 +52,9 @@ export function createNativeRoundtripEvidence(importResult,options={}) {
|
|
|
33
52
|
semanticMergeReadiness:semanticMerge,
|
|
34
53
|
reviewRequired:semanticMerge!=='ready',
|
|
35
54
|
sourcePath:projection?.sourcePath??importResult.sourcePath,
|
|
36
|
-
language:
|
|
37
|
-
target
|
|
55
|
+
language:sourceLanguage,
|
|
56
|
+
target,
|
|
57
|
+
audit,
|
|
38
58
|
import:{
|
|
39
59
|
id:importResult.id,
|
|
40
60
|
readiness:importReadiness,
|
|
@@ -49,7 +69,7 @@ export function createNativeRoundtripEvidence(importResult,options={}) {
|
|
|
49
69
|
issues:universalIssues,
|
|
50
70
|
nativeSources:universalAst?.nativeSources?.length??importResult.nativeSources?.length??(importResult.nativeSource?1:0),
|
|
51
71
|
semanticSymbols:(importResult.semanticIndex??universalAst?.semanticIndex)?.symbols?.length??0,
|
|
52
|
-
sourceMaps:
|
|
72
|
+
sourceMaps:universalSourceMapEvidence
|
|
53
73
|
},
|
|
54
74
|
projection:{
|
|
55
75
|
id:projection?.id,
|
|
@@ -115,3 +135,55 @@ function summarizeSourceMaps(sourceMaps){
|
|
|
115
135
|
}
|
|
116
136
|
function normalizePrecision(value){const precision=String(value??'unknown');return Object.prototype.hasOwnProperty.call(precisionRank,precision)?precision:'unknown';}
|
|
117
137
|
function worstPrecision(precisions){if(!precisions.length)return'none';return precisions.reduce((worst,next)=>precisionRank[next]>precisionRank[worst]?next:worst,'exact');}
|
|
138
|
+
function createRoundtripAudit(input){
|
|
139
|
+
const disposition=roundtripAuditDisposition(input);
|
|
140
|
+
return{
|
|
141
|
+
schema:'frontier.lang.nativeRoundtripAuditSignal',
|
|
142
|
+
version:1,
|
|
143
|
+
disposition,
|
|
144
|
+
claim:roundtripAuditClaim(disposition),
|
|
145
|
+
sourceLanguage:input.sourceLanguage,
|
|
146
|
+
target:input.target,
|
|
147
|
+
sameLanguage:input.sameLanguage,
|
|
148
|
+
outputMode:input.outputMode,
|
|
149
|
+
projectionMode:input.projectionMode,
|
|
150
|
+
sourceHashVerified:input.sourceHashVerified,
|
|
151
|
+
outputSourceMapPrecision:input.sourceMapEvidence.precision,
|
|
152
|
+
universalSourceMapPrecision:input.universalSourceMapEvidence.precision,
|
|
153
|
+
targetProjectionAdapterId:input.targetProjection?.adapter?.id,
|
|
154
|
+
targetCoverageLossClass:input.targetCoverage?.lossClass,
|
|
155
|
+
reviewRequired:input.semanticMerge!=='ready',
|
|
156
|
+
semanticMergeReadiness:input.semanticMerge,
|
|
157
|
+
semanticEquivalenceClaim:false,
|
|
158
|
+
autoMergeClaim:false,
|
|
159
|
+
blockingLossCount:input.lossSummary.blockingLossIds.length,
|
|
160
|
+
reviewLossCount:input.lossSummary.reviewLossIds.length,
|
|
161
|
+
reasonCodes:uniqueStrings([
|
|
162
|
+
`status:${input.status}`,
|
|
163
|
+
`semantic:${input.semanticMerge}`,
|
|
164
|
+
`output:${input.outputMode??'unknown'}`,
|
|
165
|
+
`projection:${input.projectionMode??'unknown'}`,
|
|
166
|
+
input.sourceHashVerified?'source-hash:verified':'source-hash:unverified',
|
|
167
|
+
`output-source-map:${input.sourceMapEvidence.precision}`,
|
|
168
|
+
`universal-source-map:${input.universalSourceMapEvidence.precision}`,
|
|
169
|
+
input.targetCoverage?.lossClass?`target-loss:${input.targetCoverage.lossClass}`:undefined,
|
|
170
|
+
input.targetProjection?.adapter?.id?`target-adapter:${input.targetProjection.adapter.id}`:undefined,
|
|
171
|
+
input.lossSummary.blockingLossIds.length?'losses:blocking':undefined,
|
|
172
|
+
input.lossSummary.reviewLossIds.length?'losses:review':undefined
|
|
173
|
+
])
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function roundtripAuditDisposition(input){
|
|
177
|
+
if(input.outputMode==='target-adapter')return'adapter-projected';
|
|
178
|
+
if(input.projectionMode==='native-source-stubs'||input.outputMode==='target-stubs')return'stub-only';
|
|
179
|
+
if(input.sourceHashVerified&&input.outputMode==='preserved-source'&&input.hasOutputSourceMaps&&input.sourceMapEvidence.precision==='exact')return'reversible';
|
|
180
|
+
if(input.sourceHashVerified||input.projectionMode==='preserved-source')return'preserved-source';
|
|
181
|
+
return'review-required';
|
|
182
|
+
}
|
|
183
|
+
function roundtripAuditClaim(disposition){
|
|
184
|
+
if(disposition==='reversible')return'source-text-reversible';
|
|
185
|
+
if(disposition==='preserved-source')return'source-preserved';
|
|
186
|
+
if(disposition==='stub-only')return'declaration-stubs-only';
|
|
187
|
+
if(disposition==='adapter-projected')return'host-adapter-projected';
|
|
188
|
+
return'review-required';
|
|
189
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import{commonGeneratedTargetPath,idFragment}from'../../native-import-utils.js';import{inferSourceMapMappings,normalizeSourceMapMappings,normalizeSourceMaps}from'../../native-source-maps.js';import{createKernelSourcePreservationRecords,summarizeKernelSourcePreservationRecords}from'../../semantic-import-source-preservation.js';import{createDocument,createImportResult,createNativeAstRecord,createPatch,createSourceMapRecord,createUniversalAstEnvelope,hashSemanticValue,nativeSourceNode}from'@shapeshift-labs/frontier-lang-kernel';
|
|
2
2
|
import{attachInputUniversalDialectRegistry}from'../../universal-dialect-registry.js';
|
|
3
|
+
import{createLightweightSemanticLayers}from'./createLightweightSemanticLayers.js';
|
|
3
4
|
import{attachNativeImportLossSummary}from'./attachNativeImportLossSummary.js';import{createLightweightNativeImport}from'./createLightweightNativeImport.js';import{createNativeSourcePreservation}from'./createNativeSourcePreservation.js';import{hasNativeExactAstEvidence}from'./hasNativeExactAstEvidence.js';import{normalizeNativeLossRecords}from'./normalizeNativeLossRecords.js';import{summarizeNativeImportLosses}from'./summarizeNativeImportLosses.js';import{unverifiedNativeAstLosses}from'./unverifiedNativeAstLosses.js';import{withNativeImportReadiness}from'./withNativeImportReadiness.js';
|
|
4
5
|
export function importNativeSource(input) {
|
|
5
6
|
const language = input.language ?? input.nativeAst?.language;
|
|
@@ -216,6 +217,7 @@ export function importNativeSource(input) {
|
|
|
216
217
|
});
|
|
217
218
|
const kernelSourcePreservationSummary = summarizeKernelSourcePreservationRecords(sourcePreservationRecords);
|
|
218
219
|
const resultSourceMapMappings = sourceMaps.flatMap((sourceMap) => sourceMap.mappings ?? []);
|
|
220
|
+
const semanticLayers=input.semanticLayers??createLightweightSemanticLayers({importIdPart,language,sourcePath,sourceHash,nativeSource,nativeAst,semanticIndex,sourceMaps,losses,evidence,sourcePreservationRecords});
|
|
219
221
|
let universalAst = createUniversalAstEnvelope({
|
|
220
222
|
id: input.universalAstId ?? `universal_ast_${importIdPart}`,
|
|
221
223
|
document,
|
|
@@ -224,6 +226,7 @@ export function importNativeSource(input) {
|
|
|
224
226
|
sourceMaps,
|
|
225
227
|
losses,
|
|
226
228
|
evidence,
|
|
229
|
+
proof:input.proof??input.universalAstProof??semanticLayers.proof,paradigmSemantics:input.paradigmSemantics??input.universalAstParadigmSemantics??semanticLayers.paradigmSemantics,
|
|
227
230
|
metadata: {
|
|
228
231
|
sourceLanguage: language,
|
|
229
232
|
sourcePath,
|
|
@@ -41,7 +41,9 @@ export function renderWorkbenchHtml(initialState) {
|
|
|
41
41
|
<h2>TypeScript</h2>
|
|
42
42
|
<span id="typescriptStatus">source</span>
|
|
43
43
|
</div>
|
|
44
|
-
<
|
|
44
|
+
<div class="paneBody editorBody">
|
|
45
|
+
<textarea id="typescriptInput" spellcheck="false" aria-label="TypeScript source"></textarea>
|
|
46
|
+
</div>
|
|
45
47
|
</section>
|
|
46
48
|
|
|
47
49
|
<section class="pane graphPane" data-view-panel="frontier">
|
|
@@ -52,8 +54,8 @@ export function renderWorkbenchHtml(initialState) {
|
|
|
52
54
|
<button data-frontier-tab="json" aria-pressed="false">JSON</button>
|
|
53
55
|
</div>
|
|
54
56
|
</div>
|
|
55
|
-
<div id="graphView" class="graphView"></div>
|
|
56
|
-
<pre id="frontierJson" class="codeBlock" hidden></pre>
|
|
57
|
+
<div id="graphView" class="paneBody graphView"></div>
|
|
58
|
+
<pre id="frontierJson" class="paneBody codeBlock" hidden></pre>
|
|
57
59
|
</section>
|
|
58
60
|
|
|
59
61
|
<section class="pane outputPane" data-view-panel="rust">
|
|
@@ -61,7 +63,9 @@ export function renderWorkbenchHtml(initialState) {
|
|
|
61
63
|
<h2>Rust</h2>
|
|
62
64
|
<span id="rustStatus">target</span>
|
|
63
65
|
</div>
|
|
64
|
-
<
|
|
66
|
+
<div class="paneBody editorBody">
|
|
67
|
+
<textarea id="rustInput" spellcheck="false" aria-label="Rust source"></textarea>
|
|
68
|
+
</div>
|
|
65
69
|
</section>
|
|
66
70
|
</section>
|
|
67
71
|
</main>
|
|
@@ -2,6 +2,9 @@ export function workbenchStyles() {
|
|
|
2
2
|
return `
|
|
3
3
|
:root {
|
|
4
4
|
color-scheme: dark;
|
|
5
|
+
--topbar-height: 58px;
|
|
6
|
+
--status-height: 46px;
|
|
7
|
+
--chrome-height: calc(var(--topbar-height) + var(--status-height));
|
|
5
8
|
--bg: #08090a;
|
|
6
9
|
--panel: #111417;
|
|
7
10
|
--panel-2: #171b20;
|
|
@@ -22,6 +25,7 @@ export function workbenchStyles() {
|
|
|
22
25
|
* { box-sizing: border-box; }
|
|
23
26
|
html, body { height: 100%; margin: 0; }
|
|
24
27
|
body {
|
|
28
|
+
width: 100%;
|
|
25
29
|
background: var(--bg);
|
|
26
30
|
color: var(--text);
|
|
27
31
|
font-family: var(--ui);
|
|
@@ -29,9 +33,9 @@ body {
|
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
.appShell {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
height: 100vh;
|
|
37
|
+
height: 100dvh;
|
|
38
|
+
overflow: hidden;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
.topbar, .statusStrip, .paneHeader {
|
|
@@ -41,6 +45,10 @@ body {
|
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
.topbar {
|
|
48
|
+
position: fixed;
|
|
49
|
+
inset: 0 0 auto 0;
|
|
50
|
+
z-index: 20;
|
|
51
|
+
height: var(--topbar-height);
|
|
44
52
|
justify-content: space-between;
|
|
45
53
|
padding: 0 14px;
|
|
46
54
|
background: #0c0e10;
|
|
@@ -84,38 +92,75 @@ body {
|
|
|
84
92
|
.iconButton:hover, .segmented button:hover, .modeGroup button:hover, .runButton:hover { background: var(--panel-3); }
|
|
85
93
|
|
|
86
94
|
.statusStrip {
|
|
95
|
+
position: fixed;
|
|
96
|
+
inset: var(--topbar-height) 0 auto 0;
|
|
97
|
+
z-index: 19;
|
|
98
|
+
height: var(--status-height);
|
|
87
99
|
display: grid;
|
|
88
100
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
89
101
|
background: #0f1214;
|
|
102
|
+
overflow: hidden;
|
|
90
103
|
}
|
|
91
104
|
.statusStrip div {
|
|
92
105
|
min-width: 0;
|
|
106
|
+
min-height: 0;
|
|
93
107
|
padding: 8px 14px;
|
|
94
108
|
border-right: 1px solid var(--line);
|
|
109
|
+
overflow: hidden;
|
|
95
110
|
}
|
|
96
111
|
.label {
|
|
97
112
|
display: block;
|
|
98
113
|
color: var(--faint);
|
|
99
114
|
font-size: 10px;
|
|
115
|
+
line-height: 1.1;
|
|
100
116
|
text-transform: uppercase;
|
|
101
117
|
}
|
|
102
|
-
.statusStrip strong {
|
|
118
|
+
.statusStrip strong {
|
|
119
|
+
display: block;
|
|
120
|
+
overflow: hidden;
|
|
121
|
+
text-overflow: ellipsis;
|
|
122
|
+
white-space: nowrap;
|
|
123
|
+
font-size: 13px;
|
|
124
|
+
font-weight: 650;
|
|
125
|
+
line-height: 1.2;
|
|
126
|
+
}
|
|
103
127
|
|
|
104
128
|
.workspace {
|
|
129
|
+
position: fixed;
|
|
130
|
+
inset: var(--chrome-height) 0 0 0;
|
|
131
|
+
height: calc(100vh - var(--chrome-height));
|
|
132
|
+
height: calc(100dvh - var(--chrome-height));
|
|
105
133
|
min-height: 0;
|
|
106
134
|
display: grid;
|
|
107
135
|
grid-template-columns: minmax(270px, 0.95fr) minmax(330px, 1.1fr) minmax(300px, 1fr);
|
|
136
|
+
overflow: hidden;
|
|
108
137
|
}
|
|
109
138
|
.pane {
|
|
110
139
|
min-width: 0;
|
|
111
140
|
min-height: 0;
|
|
141
|
+
height: 100%;
|
|
112
142
|
display: grid;
|
|
113
143
|
grid-template-rows: 44px minmax(0, 1fr);
|
|
114
144
|
border-right: 1px solid var(--line);
|
|
115
145
|
background: var(--panel);
|
|
146
|
+
overflow: hidden;
|
|
116
147
|
}
|
|
117
148
|
.pane:last-child { border-right: 0; }
|
|
118
149
|
.pane.isSource .paneHeader { box-shadow: inset 0 -2px 0 var(--green); }
|
|
150
|
+
.paneBody {
|
|
151
|
+
grid-row: 2;
|
|
152
|
+
grid-column: 1;
|
|
153
|
+
min-width: 0;
|
|
154
|
+
min-height: 0;
|
|
155
|
+
height: 100%;
|
|
156
|
+
max-height: 100%;
|
|
157
|
+
overflow: auto;
|
|
158
|
+
overscroll-behavior: contain;
|
|
159
|
+
scrollbar-gutter: stable;
|
|
160
|
+
}
|
|
161
|
+
.editorBody {
|
|
162
|
+
overflow: hidden;
|
|
163
|
+
}
|
|
119
164
|
.paneHeader {
|
|
120
165
|
justify-content: space-between;
|
|
121
166
|
padding: 0 12px;
|
|
@@ -125,9 +170,11 @@ body {
|
|
|
125
170
|
.paneHeader span { color: var(--muted); font-size: 12px; font-family: var(--mono); }
|
|
126
171
|
|
|
127
172
|
textarea, .codeBlock {
|
|
173
|
+
display: block;
|
|
128
174
|
width: 100%;
|
|
129
175
|
height: 100%;
|
|
130
176
|
min-height: 0;
|
|
177
|
+
max-height: 100%;
|
|
131
178
|
margin: 0;
|
|
132
179
|
border: 0;
|
|
133
180
|
resize: none;
|
|
@@ -139,14 +186,16 @@ textarea, .codeBlock {
|
|
|
139
186
|
line-height: 1.48;
|
|
140
187
|
padding: 14px;
|
|
141
188
|
overflow: auto;
|
|
189
|
+
overscroll-behavior: contain;
|
|
142
190
|
white-space: pre;
|
|
143
191
|
}
|
|
144
192
|
|
|
145
193
|
.graphView {
|
|
146
|
-
min-height: 0;
|
|
147
|
-
overflow: auto;
|
|
148
194
|
padding: 12px;
|
|
149
195
|
}
|
|
196
|
+
#graphView[hidden], #frontierJson[hidden] {
|
|
197
|
+
display: none;
|
|
198
|
+
}
|
|
150
199
|
.graphGrid {
|
|
151
200
|
display: grid;
|
|
152
201
|
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
|
@@ -230,12 +279,28 @@ textarea, .codeBlock {
|
|
|
230
279
|
.segmented button[aria-pressed="true"] { background: #213127; color: var(--green); }
|
|
231
280
|
|
|
232
281
|
@media (max-width: 980px) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
282
|
+
:root {
|
|
283
|
+
--topbar-height: 96px;
|
|
284
|
+
--status-height: 88px;
|
|
285
|
+
}
|
|
286
|
+
body { overflow: hidden; }
|
|
287
|
+
.topbar {
|
|
288
|
+
align-items: flex-start;
|
|
289
|
+
gap: 10px;
|
|
290
|
+
padding: 10px 14px;
|
|
291
|
+
}
|
|
292
|
+
.workspace {
|
|
293
|
+
grid-template-columns: 1fr;
|
|
294
|
+
grid-template-rows: repeat(3, minmax(0, 1fr));
|
|
295
|
+
overflow: hidden;
|
|
296
|
+
}
|
|
297
|
+
.pane {
|
|
298
|
+
height: 100%;
|
|
299
|
+
min-height: 0;
|
|
300
|
+
border-right: 0;
|
|
301
|
+
border-bottom: 1px solid var(--line);
|
|
302
|
+
}
|
|
237
303
|
.statusStrip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
238
|
-
.topbar { align-items: flex-start; gap: 10px; padding: 10px 14px; }
|
|
239
304
|
.topActions { flex-wrap: wrap; justify-content: flex-end; }
|
|
240
305
|
.boundsGrid { grid-template-columns: 1fr; }
|
|
241
306
|
}
|
package/package.json
CHANGED