@rozie/cli 0.1.0 → 0.1.1
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/dist/bin.cjs +1 -1
- package/dist/bin.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-WZKv4m5y.mjs → src-DrhJa-BU.mjs} +1020 -29
- package/dist/{src-CIv3UOaa.cjs → src-hZQruhgd.cjs} +1020 -29
- package/package.json +16 -11
|
@@ -10075,6 +10075,66 @@ function subtreeReads(node, accessor, name) {
|
|
|
10075
10075
|
return found;
|
|
10076
10076
|
}
|
|
10077
10077
|
/**
|
|
10078
|
+
* Returns true if the subtree rooted at `node` contains a BARE Identifier READ of
|
|
10079
|
+
* `name` — the exact shape the Vue `$computed` lowering wraps to `<name>.value`.
|
|
10080
|
+
*
|
|
10081
|
+
* The Vue trigger condition for the `$computed` shadow bug: a `$computed` name is
|
|
10082
|
+
* read as a BARE identifier in source (there is NO `$computed.<name>` accessor
|
|
10083
|
+
* member to gate on), and the downstream Identifier visitor `.value`-wraps every
|
|
10084
|
+
* such bare read. A colliding param/local only mis-captures that wrap when it
|
|
10085
|
+
* actually performs a bare read of `name` within its scope — so a `binding`
|
|
10086
|
+
* trigger (mere existence) would over-apply (renaming an unused same-named param
|
|
10087
|
+
* → corpus drift), and the `accessor` trigger cannot fire (no member access).
|
|
10088
|
+
*
|
|
10089
|
+
* Excludes the SAME non-read positions the Vue Identifier visitor skips, so the
|
|
10090
|
+
* gate matches the rewrite exactly: declaration ids, non-computed member
|
|
10091
|
+
* properties, object keys (shorthand or not), TS type positions, function names,
|
|
10092
|
+
* function params, and import/export specifier ids. A computed member property
|
|
10093
|
+
* (`obj[name]`) IS a bare read and counts.
|
|
10094
|
+
*
|
|
10095
|
+
* Hand-rolled own-child walk (the `subtreeReads` twin): a direct walk with
|
|
10096
|
+
* parent-context tracking is simpler than a Program-rooted Babel traverse and
|
|
10097
|
+
* has no rooting constraint.
|
|
10098
|
+
*/
|
|
10099
|
+
function subtreeReadsBareIdentifier(node, name) {
|
|
10100
|
+
if (!node) return false;
|
|
10101
|
+
let found = false;
|
|
10102
|
+
function walk(n, parent) {
|
|
10103
|
+
if (found || !n || typeof n !== "object" || !("type" in n)) return;
|
|
10104
|
+
if (_babel_types.isIdentifier(n) && n.name === name) {
|
|
10105
|
+
if (isBareRead(n, parent)) {
|
|
10106
|
+
found = true;
|
|
10107
|
+
return;
|
|
10108
|
+
}
|
|
10109
|
+
}
|
|
10110
|
+
if (n.type.startsWith("TS") && n.type !== "TSNonNullExpression" && n.type !== "TSAsExpression" && n.type !== "TSSatisfiesExpression" && n.type !== "TSTypeAssertion") return;
|
|
10111
|
+
for (const key of Object.keys(n)) {
|
|
10112
|
+
if (key === "loc" || key === "start" || key === "end" || key === "leadingComments" || key === "trailingComments" || key === "innerComments") continue;
|
|
10113
|
+
const v = n[key];
|
|
10114
|
+
if (Array.isArray(v)) {
|
|
10115
|
+
for (const item of v) if (item && typeof item === "object" && "type" in item) walk(item, n);
|
|
10116
|
+
} else if (v && typeof v === "object" && "type" in v) walk(v, n);
|
|
10117
|
+
}
|
|
10118
|
+
}
|
|
10119
|
+
function isBareRead(id, parent) {
|
|
10120
|
+
if (!parent) return true;
|
|
10121
|
+
if (_babel_types.isVariableDeclarator(parent) && parent.id === id) return false;
|
|
10122
|
+
if ((_babel_types.isMemberExpression(parent) || _babel_types.isOptionalMemberExpression(parent)) && parent.property === id && !parent.computed) return false;
|
|
10123
|
+
if (_babel_types.isObjectProperty(parent) && parent.key === id && !parent.computed) return false;
|
|
10124
|
+
if (_babel_types.isFunctionDeclaration(parent) && parent.id === id) return false;
|
|
10125
|
+
if (_babel_types.isFunctionExpression(parent) && parent.id === id) return false;
|
|
10126
|
+
if (_babel_types.isFunction(parent) && parent.params.includes(id)) return false;
|
|
10127
|
+
if (_babel_types.isImportSpecifier(parent)) return false;
|
|
10128
|
+
if (_babel_types.isImportDefaultSpecifier(parent)) return false;
|
|
10129
|
+
if (_babel_types.isImportNamespaceSpecifier(parent)) return false;
|
|
10130
|
+
if (_babel_types.isExportSpecifier(parent)) return false;
|
|
10131
|
+
if (_babel_types.isLabeledStatement(parent) && parent.label === id) return false;
|
|
10132
|
+
return true;
|
|
10133
|
+
}
|
|
10134
|
+
walk(node, null);
|
|
10135
|
+
return found;
|
|
10136
|
+
}
|
|
10137
|
+
/**
|
|
10078
10138
|
* THE UNIFIED PASS. Renames any USER binding (function param or
|
|
10079
10139
|
* `const`/`let`/`var` declarator) that collides with a generated symbol to
|
|
10080
10140
|
* `<name>$local`, atomically across its binding scope, gated only-on-collision
|
|
@@ -10094,6 +10154,7 @@ function deconflictGeneratedSymbols(program, groups, protectedNames = /* @__PURE
|
|
|
10094
10154
|
if (!group.names.has(name)) return false;
|
|
10095
10155
|
if (protectedNames.has(name)) return false;
|
|
10096
10156
|
if (group.trigger.kind === "binding") return true;
|
|
10157
|
+
if (group.trigger.kind === "bare-read") return subtreeReadsBareIdentifier(scopeBlock, name);
|
|
10097
10158
|
return subtreeReads(scopeBlock, group.trigger.accessor, name);
|
|
10098
10159
|
};
|
|
10099
10160
|
traverse$19(program, {
|
|
@@ -10107,6 +10168,7 @@ function deconflictGeneratedSymbols(program, groups, protectedNames = /* @__PURE
|
|
|
10107
10168
|
if (!patternIntroducesBinding$3(id, name)) continue;
|
|
10108
10169
|
const binding = path.scope.getBinding(name);
|
|
10109
10170
|
const ownerScope = binding ? binding.scope : path.scope;
|
|
10171
|
+
if (group.trigger.kind === "bare-read" && _babel_types.isProgram(ownerScope.block)) continue;
|
|
10110
10172
|
if (collides(group, name, ownerScope.block)) ownerScope.rename(name, alias(name));
|
|
10111
10173
|
}
|
|
10112
10174
|
},
|
|
@@ -18732,17 +18794,53 @@ function bindingNames(stmt) {
|
|
|
18732
18794
|
function importLocalNames(imp) {
|
|
18733
18795
|
return imp.specifiers.map((s) => s.local.name);
|
|
18734
18796
|
}
|
|
18797
|
+
/**
|
|
18798
|
+
* Root identifier of a TS entity name (`Foo` or `Foo.Bar.Baz` → `Foo`). A
|
|
18799
|
+
* `TSImportType` (`import('pkg').Foo`) has no root local identifier — returns
|
|
18800
|
+
* null (its module surface is already self-contained, never a hoist target).
|
|
18801
|
+
*/
|
|
18802
|
+
function rootTypeIdentifier(name) {
|
|
18803
|
+
let node = name;
|
|
18804
|
+
while (node && _babel_types.isTSQualifiedName(node)) node = node.left;
|
|
18805
|
+
return node && _babel_types.isIdentifier(node) ? node.name : null;
|
|
18806
|
+
}
|
|
18735
18807
|
/** Referenced identifier names within a statement (excludes bindings/keys). */
|
|
18736
18808
|
function referencedNames(stmt) {
|
|
18737
18809
|
const out = /* @__PURE__ */ new Set();
|
|
18738
18810
|
try {
|
|
18739
|
-
traverse$18(_babel_types.file(_babel_types.program([stmt])), {
|
|
18740
|
-
|
|
18741
|
-
|
|
18811
|
+
traverse$18(_babel_types.file(_babel_types.program([stmt])), {
|
|
18812
|
+
ReferencedIdentifier(path) {
|
|
18813
|
+
out.add(path.node.name);
|
|
18814
|
+
},
|
|
18815
|
+
TSTypeReference(path) {
|
|
18816
|
+
const root = rootTypeIdentifier(path.node.typeName);
|
|
18817
|
+
if (root) out.add(root);
|
|
18818
|
+
},
|
|
18819
|
+
TSTypeQuery(path) {
|
|
18820
|
+
const root = rootTypeIdentifier(path.node.exprName);
|
|
18821
|
+
if (root) out.add(root);
|
|
18822
|
+
}
|
|
18823
|
+
});
|
|
18742
18824
|
} catch {}
|
|
18743
18825
|
return out;
|
|
18744
18826
|
}
|
|
18745
18827
|
/**
|
|
18828
|
+
* Effective import kind of a single specifier. A specifier is type-only when
|
|
18829
|
+
* EITHER the declaration is `import type { … }` (declKind === 'type', in which
|
|
18830
|
+
* case Babel reports the per-specifier `importKind` as `'value'`) OR the
|
|
18831
|
+
* specifier itself is the inline `import { type X }` form (spec.importKind ===
|
|
18832
|
+
* 'type'). The old `spec.importKind ? spec.importKind : declKind` form let the
|
|
18833
|
+
* `'value'` per-specifier kind of a declaration-level `import type` mask the
|
|
18834
|
+
* declaration's type-ness, so a hoisted `import type { T }` lost its type-only
|
|
18835
|
+
* marker and emitted as a runtime `import { T }` (IN-02). Value imports are
|
|
18836
|
+
* unaffected (both kinds are `'value'`).
|
|
18837
|
+
*/
|
|
18838
|
+
function effectiveImportKind(declKind, spec) {
|
|
18839
|
+
if (declKind === "type") return "type";
|
|
18840
|
+
if (_babel_types.isImportSpecifier(spec) && spec.importKind === "type") return "type";
|
|
18841
|
+
return "value";
|
|
18842
|
+
}
|
|
18843
|
+
/**
|
|
18746
18844
|
* Dedup key for a single import specifier per the R4 tuple:
|
|
18747
18845
|
* (source, importKind, default|namespace|named:imported, local). Including the
|
|
18748
18846
|
* LOCAL name keeps `import { thing }` and `import { thing as aliased }` distinct
|
|
@@ -18750,7 +18848,7 @@ function referencedNames(stmt) {
|
|
|
18750
18848
|
* host and partial collapses to ONE statement.
|
|
18751
18849
|
*/
|
|
18752
18850
|
function specifierKey(source, declKind, spec) {
|
|
18753
|
-
const kind = (
|
|
18851
|
+
const kind = effectiveImportKind(declKind, spec);
|
|
18754
18852
|
if (_babel_types.isImportDefaultSpecifier(spec)) return `${source}\0${kind}\0default\0${spec.local.name}`;
|
|
18755
18853
|
if (_babel_types.isImportNamespaceSpecifier(spec)) return `${source}\0${kind}\0namespace\0${spec.local.name}`;
|
|
18756
18854
|
return `${source}\0${kind}\0named:${_babel_types.isIdentifier(spec.imported) ? spec.imported.name : spec.imported.value}\0${spec.local.name}`;
|
|
@@ -18760,12 +18858,12 @@ function specifierKey(source, declKind, spec) {
|
|
|
18760
18858
|
* deduped by {@link specifierKey} and grouped by (source, importKind) so the
|
|
18761
18859
|
* splice produces idiomatic merged `import { a, b } from 'src'` statements.
|
|
18762
18860
|
*/
|
|
18763
|
-
function hoistSpecifier(ctx, sourceNode, declKind, spec) {
|
|
18861
|
+
function hoistSpecifier(ctx, sourceNode, declKind, spec, sourceImport) {
|
|
18764
18862
|
const source = sourceNode.value;
|
|
18765
18863
|
const key = specifierKey(source, declKind, spec);
|
|
18766
18864
|
if (ctx.hoistKeys.has(key)) return;
|
|
18767
18865
|
ctx.hoistKeys.add(key);
|
|
18768
|
-
const groupKind = (
|
|
18866
|
+
const groupKind = effectiveImportKind(declKind, spec);
|
|
18769
18867
|
const groupKey = `${source}\0${groupKind}`;
|
|
18770
18868
|
const existing = ctx.hoistGroups.get(groupKey);
|
|
18771
18869
|
if (existing) {
|
|
@@ -18774,9 +18872,427 @@ function hoistSpecifier(ctx, sourceNode, declKind, spec) {
|
|
|
18774
18872
|
}
|
|
18775
18873
|
const decl = _babel_types.importDeclaration([spec], sourceNode);
|
|
18776
18874
|
if (groupKind === "type") decl.importKind = "type";
|
|
18875
|
+
if (sourceImport) {
|
|
18876
|
+
if (sourceImport.loc) decl.loc = sourceImport.loc;
|
|
18877
|
+
if (sourceImport.trailingComments) decl.trailingComments = sourceImport.trailingComments;
|
|
18878
|
+
if (sourceImport.innerComments) decl.innerComments = sourceImport.innerComments;
|
|
18879
|
+
}
|
|
18777
18880
|
ctx.hoistGroups.set(groupKey, decl);
|
|
18778
18881
|
ctx.hoistImports.push(decl);
|
|
18779
18882
|
}
|
|
18883
|
+
/**
|
|
18884
|
+
* Shift a single Babel `Position` object's `.line` by `offset`, exactly once.
|
|
18885
|
+
*
|
|
18886
|
+
* CRITICAL (Phase 55-04 bug fix): `@babel/parser` SHARES one `Position` object
|
|
18887
|
+
* across the `loc.start`/`loc.end` of nested nodes that begin/end at the same
|
|
18888
|
+
* source position — e.g. a `const f = () => {...}` shares ONE `loc.end` object
|
|
18889
|
+
* between the VariableDeclaration, VariableDeclarator, ArrowFunctionExpression
|
|
18890
|
+
* and BlockStatement (verified: all four `.loc.end` are `===`). The earlier
|
|
18891
|
+
* `seen`-keyed-on-the-`loc`-WRAPPER dedupe therefore shifted such a shared
|
|
18892
|
+
* `Position` once PER wrapping node (4× for the example above), corrupting
|
|
18893
|
+
* `loc.end.line` to `original + 4·offset` (~13985 for a host-line-3502 decl).
|
|
18894
|
+
* That blew the trailing-comment delta hugely negative, collapsing a between-
|
|
18895
|
+
* declaration comment onto the prior closing brace (`}; // comment`). Deduping on
|
|
18896
|
+
* the `Position` object itself shifts each unique position exactly once. Never
|
|
18897
|
+
* throws (D-04).
|
|
18898
|
+
*/
|
|
18899
|
+
function shiftPositionLine(pos, offset, shifted) {
|
|
18900
|
+
if (!pos || shifted.has(pos)) return;
|
|
18901
|
+
shifted.add(pos);
|
|
18902
|
+
pos.line += offset;
|
|
18903
|
+
}
|
|
18904
|
+
/**
|
|
18905
|
+
* Stash a node's `.rzts` origin (once, idempotent) then shift its `loc` lines by
|
|
18906
|
+
* `offset`. Byte offsets (`loc.start.index`/`loc.end.index`) and `loc.filename`
|
|
18907
|
+
* are NEVER touched. `shifted` dedupes shared `Position` objects (see
|
|
18908
|
+
* {@link shiftPositionLine}) so a position aliased across nested nodes — or a
|
|
18909
|
+
* comment attached to two adjacent statements — is shifted exactly once
|
|
18910
|
+
* (Pitfall 2). Never throws (D-04).
|
|
18911
|
+
*/
|
|
18912
|
+
function stashAndShiftNode(node, offset, shifted) {
|
|
18913
|
+
const loc = node.loc;
|
|
18914
|
+
if (!loc) return;
|
|
18915
|
+
const extra = node.extra ?? {};
|
|
18916
|
+
if (!("__roziePartialOrigin" in extra)) {
|
|
18917
|
+
const startAlreadyShifted = shifted.has(loc.start);
|
|
18918
|
+
node.extra = {
|
|
18919
|
+
...extra,
|
|
18920
|
+
__roziePartialOrigin: {
|
|
18921
|
+
line: loc.start.line - (startAlreadyShifted ? offset : 0),
|
|
18922
|
+
column: loc.start.column,
|
|
18923
|
+
filename: loc.filename
|
|
18924
|
+
}
|
|
18925
|
+
};
|
|
18926
|
+
}
|
|
18927
|
+
shiftPositionLine(loc.start, offset, shifted);
|
|
18928
|
+
shiftPositionLine(loc.end, offset, shifted);
|
|
18929
|
+
}
|
|
18930
|
+
/** As {@link stashAndShiftNode} but for a comment (origin stashed on the comment). */
|
|
18931
|
+
function stashAndShiftComment(comment, offset, shifted) {
|
|
18932
|
+
const loc = comment.loc;
|
|
18933
|
+
if (!loc) return;
|
|
18934
|
+
const c = comment;
|
|
18935
|
+
if (c.__roziePartialOrigin === void 0) {
|
|
18936
|
+
const startAlreadyShifted = shifted.has(loc.start);
|
|
18937
|
+
c.__roziePartialOrigin = {
|
|
18938
|
+
line: loc.start.line - (startAlreadyShifted ? offset : 0),
|
|
18939
|
+
column: loc.start.column,
|
|
18940
|
+
filename: loc.filename
|
|
18941
|
+
};
|
|
18942
|
+
}
|
|
18943
|
+
shiftPositionLine(loc.start, offset, shifted);
|
|
18944
|
+
shiftPositionLine(loc.end, offset, shifted);
|
|
18945
|
+
}
|
|
18946
|
+
/** Shift every leading/trailing/inner comment attached to `node`. */
|
|
18947
|
+
function shiftAttachedComments(node, offset, shifted) {
|
|
18948
|
+
for (const c of node.leadingComments ?? []) stashAndShiftComment(c, offset, shifted);
|
|
18949
|
+
for (const c of node.trailingComments ?? []) stashAndShiftComment(c, offset, shifted);
|
|
18950
|
+
for (const c of node.innerComments ?? []) stashAndShiftComment(c, offset, shifted);
|
|
18951
|
+
}
|
|
18952
|
+
/** The line a block's first emitted token occupies: its banner comment if it has
|
|
18953
|
+
* leading comments, else the node itself. */
|
|
18954
|
+
function blockFirstEmitLine(firstNode) {
|
|
18955
|
+
const firstLeading = firstNode.leadingComments?.[0]?.loc;
|
|
18956
|
+
return firstLeading ? firstLeading.start.line : firstNode.loc.start.line;
|
|
18957
|
+
}
|
|
18958
|
+
/**
|
|
18959
|
+
* Phase 56-R10 — true when `stmt` is a sigil DIRECTIVE that every target's residual-body
|
|
18960
|
+
* emit STRIPS (it is consumed into a non-residual section: lifecycle / context / computed /
|
|
18961
|
+
* expose / watch). Mirrors the strip lists in each `emitResidualScriptBody`
|
|
18962
|
+
* (`$onMount`/`$onUnmount`/`$onUpdate`/`$watch`/`$expose`/`$provide` ExpressionStatements,
|
|
18963
|
+
* and `$computed`/`$inject` VariableDeclarations).
|
|
18964
|
+
*
|
|
18965
|
+
* USED ONLY to decide whether a spliced LEADING-comment run's IMMEDIATE source predecessor
|
|
18966
|
+
* survives in the residual body. When that predecessor is STRIPPED (e.g. the real DataTable
|
|
18967
|
+
* `exposeStateVerbs` run sits below a `$provide(...)`), the inline-authored form attaches the
|
|
18968
|
+
* boundary comment to the predecessor's `trailingComments` + the spliced decl's
|
|
18969
|
+
* `leadingComments` (shared object), but per-statement generation drops the predecessor's
|
|
18970
|
+
* trailing copy WITH the stripped statement → the comment SINGLE-emits. The vue/svelte splice
|
|
18971
|
+
* mirror would otherwise re-create that prev-trailing copy and DOUBLE it (the R10 bug). When
|
|
18972
|
+
* the predecessor SURVIVES (a plain `let`/`const`, e.g. `let expandedTouched` above
|
|
18973
|
+
* `groupingActiveDefault`), both copies survive → the inline form DOUBLES and the mirror must
|
|
18974
|
+
* keep doing so. Never throws.
|
|
18975
|
+
*/
|
|
18976
|
+
function isStrippedSigilDirective(stmt) {
|
|
18977
|
+
if (_babel_types.isExpressionStatement(stmt) && _babel_types.isCallExpression(stmt.expression)) {
|
|
18978
|
+
const callee = stmt.expression.callee;
|
|
18979
|
+
if (_babel_types.isIdentifier(callee)) return callee.name === "$onMount" || callee.name === "$onUnmount" || callee.name === "$onUpdate" || callee.name === "$watch" || callee.name === "$expose" || callee.name === "$provide";
|
|
18980
|
+
return false;
|
|
18981
|
+
}
|
|
18982
|
+
if (_babel_types.isVariableDeclaration(stmt) && stmt.declarations.length > 0) return stmt.declarations.every((d) => d.init !== null && d.init !== void 0 && _babel_types.isCallExpression(d.init) && _babel_types.isIdentifier(d.init.callee) && (d.init.callee.name === "$computed" || d.init.callee.name === "$inject"));
|
|
18983
|
+
return false;
|
|
18984
|
+
}
|
|
18985
|
+
/**
|
|
18986
|
+
* Measure the ORIGINAL source gap above a decl run's first emit token (D-02, R2).
|
|
18987
|
+
*
|
|
18988
|
+
* Returns the `prevEnd + gap` delta the run should flow at: the distance, in source
|
|
18989
|
+
* lines, from the run's first emit token (its banner comment if any, else its first
|
|
18990
|
+
* node) DOWN from the END of the nearest preceding node IN THE SAME SOURCE FILE — a
|
|
18991
|
+
* same-file freshly-hoisted import (`sameFileHoists`) or the prior same-file decl run's
|
|
18992
|
+
* last node (`prevRunLastNode`). `gap = firstEmitLine − precedingEnd` so a zero-blank
|
|
18993
|
+
* adjacency yields `1` (next line) and N blanks yield `N+1` (no clamp). All `loc`s are
|
|
18994
|
+
* still PARTIAL-LOCAL here (the normalize shift runs later), so this reproduces the
|
|
18995
|
+
* partial's own pre-extraction layout — which, by the extraction rule, equals the host
|
|
18996
|
+
* adjacency the inline oracle has (Pitfall 3: measure source-side, NOT the host seam).
|
|
18997
|
+
*
|
|
18998
|
+
* When the run's first decl has NO same-file predecessor (a file-top nested-partial
|
|
18999
|
+
* decl, e.g. HostD's `inner` at the top of its own file), there is no source delta to
|
|
19000
|
+
* measure, so this falls back to the legacy default `2` — preserving the pre-D-02
|
|
19001
|
+
* behavior for that shape (no regression). Never throws.
|
|
19002
|
+
*/
|
|
19003
|
+
function measureOriginalGap(firstNode, sameFileHoists, prevRunLastNode) {
|
|
19004
|
+
const loc = firstNode.loc;
|
|
19005
|
+
if (!loc) return 2;
|
|
19006
|
+
const firstEmitLine = blockFirstEmitLine(firstNode);
|
|
19007
|
+
const fname = loc.filename;
|
|
19008
|
+
let precedingEnd = 0;
|
|
19009
|
+
for (const h of sameFileHoists) {
|
|
19010
|
+
const hl = h.loc;
|
|
19011
|
+
if (hl && hl.filename === fname && hl.end.line < firstEmitLine) precedingEnd = Math.max(precedingEnd, hl.end.line);
|
|
19012
|
+
}
|
|
19013
|
+
const pl = prevRunLastNode?.loc;
|
|
19014
|
+
if (pl && pl.filename === fname && pl.end.line < firstEmitLine) precedingEnd = Math.max(precedingEnd, pl.end.line);
|
|
19015
|
+
if (precedingEnd === 0) return 2;
|
|
19016
|
+
return Math.max(1, firstEmitLine - precedingEnd);
|
|
19017
|
+
}
|
|
19018
|
+
/**
|
|
19019
|
+
* Shift every node + attached comment in a block by `offset`, deduping on the
|
|
19020
|
+
* underlying `Position` objects (see {@link shiftPositionLine}). Never throws.
|
|
19021
|
+
*
|
|
19022
|
+
* WR-01: `shifted` is supplied by the CALLER and SHARED across every block in one
|
|
19023
|
+
* normalize pass. A between-statement comment can be aliased across two blocks —
|
|
19024
|
+
* `@babel/parser` attaches the comment between a hoisted import and the first decl
|
|
19025
|
+
* to BOTH the import's `trailingComments` and the decl's `leadingComments` (the
|
|
19026
|
+
* SAME `Position` objects). When the hoist and that decl run land in separate
|
|
19027
|
+
* blocks, a per-block `shifted` set would shift the aliased comment TWICE (once per
|
|
19028
|
+
* block), corrupting its emit line. A shared set shifts each unique `Position`
|
|
19029
|
+
* exactly once. The adjacent hoist/decl offsets are equal by construction (the
|
|
19030
|
+
* sequential decl anchor is derived from the shifted hoist end + the same gap the
|
|
19031
|
+
* partial's import→decl delta encodes), so first-touch-wins is the correct offset.
|
|
19032
|
+
*/
|
|
19033
|
+
function shiftBlock(block, offset, shifted) {
|
|
19034
|
+
for (const top of block.nodes) {
|
|
19035
|
+
stashAndShiftNode(top, offset, shifted);
|
|
19036
|
+
shiftAttachedComments(top, offset, shifted);
|
|
19037
|
+
try {
|
|
19038
|
+
traverse$18(_babel_types.file(_babel_types.program([top])), { enter(path) {
|
|
19039
|
+
stashAndShiftNode(path.node, offset, shifted);
|
|
19040
|
+
shiftAttachedComments(path.node, offset, shifted);
|
|
19041
|
+
} });
|
|
19042
|
+
} catch {}
|
|
19043
|
+
}
|
|
19044
|
+
}
|
|
19045
|
+
/** Shift a single comment's loc lines by `offset` WITHOUT stashing a partial origin. */
|
|
19046
|
+
function shiftCommentLinesOnly(comment, offset, shifted) {
|
|
19047
|
+
const loc = comment.loc;
|
|
19048
|
+
if (!loc) return;
|
|
19049
|
+
shiftPositionLine(loc.start, offset, shifted);
|
|
19050
|
+
shiftPositionLine(loc.end, offset, shifted);
|
|
19051
|
+
}
|
|
19052
|
+
/**
|
|
19053
|
+
* Phase 56-R8 — shift a HOST node's loc + attached/nested comments by `offset`,
|
|
19054
|
+
* deduping on the underlying `Position` objects (shared `shifted` set, like
|
|
19055
|
+
* {@link shiftBlock}). Never throws (D-04).
|
|
19056
|
+
*
|
|
19057
|
+
* Unlike {@link shiftBlock} / {@link stashAndShiftNode}, this does NOT stash a
|
|
19058
|
+
* `__roziePartialOrigin`: a host statement belongs to the HOST `.rozie` file, so its
|
|
19059
|
+
* `loc` is the host source-map anchor and must NOT be re-keyed onto a partial origin
|
|
19060
|
+
* (`buildPartialLineOffsets` is per-FILE first-stash-wins and would mis-offset every
|
|
19061
|
+
* other host segment). This is invoked ONLY for an after-side host run that carries a
|
|
19062
|
+
* GENUINE intended blank below a spliced run (`afterGap >= 2`) — the gap-1 trailing
|
|
19063
|
+
* seam. Such runs never appear in any built source-map gate today (dist-parity compiles
|
|
19064
|
+
* with `sourceMap: false`; the R5 smoke fixtures have no `afterGap >= 2` host run), so
|
|
19065
|
+
* the line shift is invisible to the source-map gates while making the @babel/generator
|
|
19066
|
+
* blank-line delta reproduce the source's after-side blank on vue/svelte/solid. The
|
|
19067
|
+
* host node's residual source-map LINE imperfection for such runs is the same class of
|
|
19068
|
+
* `userCodeLineOffset` limitation already documented in deferred-items.md (#1).
|
|
19069
|
+
*/
|
|
19070
|
+
function shiftHostNodeLines(node, offset, shifted) {
|
|
19071
|
+
if (offset === 0) return;
|
|
19072
|
+
const apply = (n) => {
|
|
19073
|
+
if (n.loc) {
|
|
19074
|
+
shiftPositionLine(n.loc.start, offset, shifted);
|
|
19075
|
+
shiftPositionLine(n.loc.end, offset, shifted);
|
|
19076
|
+
}
|
|
19077
|
+
for (const c of n.leadingComments ?? []) shiftCommentLinesOnly(c, offset, shifted);
|
|
19078
|
+
for (const c of n.trailingComments ?? []) shiftCommentLinesOnly(c, offset, shifted);
|
|
19079
|
+
for (const c of n.innerComments ?? []) shiftCommentLinesOnly(c, offset, shifted);
|
|
19080
|
+
};
|
|
19081
|
+
apply(node);
|
|
19082
|
+
try {
|
|
19083
|
+
traverse$18(_babel_types.file(_babel_types.program([node])), { enter(path) {
|
|
19084
|
+
apply(path.node);
|
|
19085
|
+
} });
|
|
19086
|
+
} catch {}
|
|
19087
|
+
}
|
|
19088
|
+
/**
|
|
19089
|
+
* FINAL inline-pass step (Phase 55) — decouple the line `@babel/generator` reads
|
|
19090
|
+
* for blank-line/comment placement from the line it reads for the source-map
|
|
19091
|
+
* origin, for every spliced partial node.
|
|
19092
|
+
*
|
|
19093
|
+
* Rationale (RESEARCH Key Finding 1): under `retainLines:false` the generator's
|
|
19094
|
+
* comment-adjacency + blank-line math reads `node.loc.start.line` and
|
|
19095
|
+
* `comment.loc.start.line` only as DELTAS; only the host↔partial (and
|
|
19096
|
+
* partial↔partial) BOUNDARY deltas are wrong (a spliced node carries a small
|
|
19097
|
+
* `.rzts`-local line discontinuous with its host neighbour). A CONSTANT per-block
|
|
19098
|
+
* offset preserves each block's intra deltas; the right boundary delta is restored
|
|
19099
|
+
* by anchoring each block SEQUENTIALLY in residual-body order.
|
|
19100
|
+
*
|
|
19101
|
+
* SEQUENTIAL ANCHOR (Phase 55-04): each block's first emitted line (its banner
|
|
19102
|
+
* comment, else its first node) is anchored ONE blank line below the PRECEDING
|
|
19103
|
+
* statement in the final body. Anchoring every block at its own replaced import
|
|
19104
|
+
* line (Plan 02's approach) collapsed multi-partial hosts: three consecutive
|
|
19105
|
+
* mid-body imports made expand/group/facet pile onto adjacent host lines, so each
|
|
19106
|
+
* 30-45-line block overlapped the next and the partial↔partial comment deltas went
|
|
19107
|
+
* negative (`}; // banner` collapse). Flowing the blocks sequentially reproduces the
|
|
19108
|
+
* inline-authored contiguous layout. The first block (or any block preceded only by
|
|
19109
|
+
* un-located content) falls back to its replaced import's host line.
|
|
19110
|
+
*
|
|
19111
|
+
* WR-01 (whole-program byte-identity): the walk runs over the FULL emit body
|
|
19112
|
+
* (`[...hoistImports, ...residualBody]`), NOT just the residual body, so a
|
|
19113
|
+
* freshly-hoisted import flows in true emit order ahead of the decls. Consecutive
|
|
19114
|
+
* IMPORT blocks anchor CONTIGUOUSLY (gap 1 — no blank between imports); every other
|
|
19115
|
+
* run anchors one blank line below the preceding statement (gap 2). Because each
|
|
19116
|
+
* source-file decl run is now its OWN block (see {@link SplicedEmitBlock}), a
|
|
19117
|
+
* nested-partial decl run flows one blank line below the parent decl run rather than
|
|
19118
|
+
* inheriting the hoist's incommensurate file-top offset.
|
|
19119
|
+
*
|
|
19120
|
+
* TWO PASSES (WR-01): a between-statement comment is aliased across blocks — the
|
|
19121
|
+
* `Position` that is a hoisted import's `trailingComments[i]` is the SAME object as
|
|
19122
|
+
* the next decl's `leadingComments[i]`. If offsets were applied while walking, the
|
|
19123
|
+
* hoist block would shift that comment, and the decl block's `blockFirstEmitLine`
|
|
19124
|
+
* would then read the ALREADY-SHIFTED comment line and derive a wrong offset
|
|
19125
|
+
* (collapsing the comment onto the decl). So PASS 1 MEASURES every block's offset
|
|
19126
|
+
* from ORIGINAL (unmutated) lines, tracking the running emit end arithmetically;
|
|
19127
|
+
* PASS 2 MUTATES, applying every offset with ONE shared dedup set so each aliased
|
|
19128
|
+
* `Position` shifts exactly once (adjacent hoist/decl offsets are equal by
|
|
19129
|
+
* construction, so first-touch-wins is the correct line).
|
|
19130
|
+
*
|
|
19131
|
+
* Runs AFTER all diagnostics are collected (they captured true `.rzts` byte loc via
|
|
19132
|
+
* `nodeLoc`, which reads `node.start`/`node.end`, NOT `loc.{line,column}`), so the
|
|
19133
|
+
* R7 error-frame path is untouched (Pitfall 1). Never throws (D-04).
|
|
19134
|
+
*/
|
|
19135
|
+
function normalizeSplicedEmitLines(body, blocks) {
|
|
19136
|
+
const nodeToBlock = /* @__PURE__ */ new Map();
|
|
19137
|
+
for (const b of blocks) for (const n of b.nodes) nodeToBlock.set(n, b);
|
|
19138
|
+
const measured = /* @__PURE__ */ new Set();
|
|
19139
|
+
const plan = [];
|
|
19140
|
+
let prevEnd = 0;
|
|
19141
|
+
let prevWasImport = false;
|
|
19142
|
+
let prevWasBlock = false;
|
|
19143
|
+
let prevBlockAnchorLine = 0;
|
|
19144
|
+
let hostRunOffset = 0;
|
|
19145
|
+
let seamAfterGap;
|
|
19146
|
+
let prevWasHostStmt = false;
|
|
19147
|
+
let prevHostOrigEnd = 0;
|
|
19148
|
+
let prevHostStmt = null;
|
|
19149
|
+
for (const stmt of body) {
|
|
19150
|
+
const block = nodeToBlock.get(stmt);
|
|
19151
|
+
if (block) {
|
|
19152
|
+
if (measured.has(block)) continue;
|
|
19153
|
+
measured.add(block);
|
|
19154
|
+
const firstNode = block.nodes.find((n) => n.loc);
|
|
19155
|
+
if (!firstNode?.loc) continue;
|
|
19156
|
+
const isImportBlock = _babel_types.isImportDeclaration(block.nodes[0]);
|
|
19157
|
+
let gap = isImportBlock && prevWasImport ? 1 : block.originalGap;
|
|
19158
|
+
let stampLeadingSeamStripped = false;
|
|
19159
|
+
if (!isImportBlock && prevWasHostStmt) {
|
|
19160
|
+
const beforeGap = block.anchorLine - prevHostOrigEnd;
|
|
19161
|
+
if (blockFirstEmitLine(firstNode) < firstNode.loc.start.line) {
|
|
19162
|
+
if (beforeGap >= 1 && beforeGap < gap) gap = beforeGap;
|
|
19163
|
+
if (prevHostStmt && isStrippedSigilDirective(prevHostStmt)) stampLeadingSeamStripped = true;
|
|
19164
|
+
}
|
|
19165
|
+
}
|
|
19166
|
+
const offset = (prevEnd > 0 ? prevEnd + gap : block.anchorLine) - blockFirstEmitLine(firstNode);
|
|
19167
|
+
let maxEnd = 0;
|
|
19168
|
+
for (const n of block.nodes) if (n.loc) maxEnd = Math.max(maxEnd, n.loc.end.line);
|
|
19169
|
+
prevEnd = maxEnd + offset;
|
|
19170
|
+
prevWasImport = isImportBlock;
|
|
19171
|
+
prevWasBlock = true;
|
|
19172
|
+
prevWasHostStmt = false;
|
|
19173
|
+
prevHostStmt = null;
|
|
19174
|
+
prevBlockAnchorLine = block.anchorLine;
|
|
19175
|
+
plan.push(stampLeadingSeamStripped ? {
|
|
19176
|
+
block,
|
|
19177
|
+
offset,
|
|
19178
|
+
leadingSeamPrevStripped: true
|
|
19179
|
+
} : {
|
|
19180
|
+
block,
|
|
19181
|
+
offset
|
|
19182
|
+
});
|
|
19183
|
+
continue;
|
|
19184
|
+
}
|
|
19185
|
+
if (stmt.loc) {
|
|
19186
|
+
const firstEmit = blockFirstEmitLine(stmt);
|
|
19187
|
+
let offset;
|
|
19188
|
+
if (prevWasBlock) {
|
|
19189
|
+
const afterGap = firstEmit - prevBlockAnchorLine;
|
|
19190
|
+
if (afterGap >= 2) {
|
|
19191
|
+
offset = prevEnd + afterGap - firstEmit;
|
|
19192
|
+
seamAfterGap = afterGap;
|
|
19193
|
+
} else offset = 0;
|
|
19194
|
+
hostRunOffset = offset;
|
|
19195
|
+
} else offset = hostRunOffset;
|
|
19196
|
+
if (offset !== 0) plan.push(seamAfterGap !== void 0 ? {
|
|
19197
|
+
hostNode: stmt,
|
|
19198
|
+
offset,
|
|
19199
|
+
afterGap: seamAfterGap
|
|
19200
|
+
} : {
|
|
19201
|
+
hostNode: stmt,
|
|
19202
|
+
offset
|
|
19203
|
+
});
|
|
19204
|
+
prevEnd = stmt.loc.end.line + offset;
|
|
19205
|
+
seamAfterGap = void 0;
|
|
19206
|
+
prevWasImport = _babel_types.isImportDeclaration(stmt);
|
|
19207
|
+
prevWasBlock = false;
|
|
19208
|
+
prevWasHostStmt = true;
|
|
19209
|
+
prevHostOrigEnd = stmt.loc.end.line;
|
|
19210
|
+
prevHostStmt = stmt;
|
|
19211
|
+
}
|
|
19212
|
+
}
|
|
19213
|
+
for (const block of blocks) {
|
|
19214
|
+
if (measured.has(block)) continue;
|
|
19215
|
+
measured.add(block);
|
|
19216
|
+
const firstNode = block.nodes.find((n) => n.loc);
|
|
19217
|
+
if (!firstNode?.loc) continue;
|
|
19218
|
+
plan.push({
|
|
19219
|
+
block,
|
|
19220
|
+
offset: block.anchorLine - blockFirstEmitLine(firstNode)
|
|
19221
|
+
});
|
|
19222
|
+
}
|
|
19223
|
+
const shifted = /* @__PURE__ */ new Set();
|
|
19224
|
+
for (const entry of plan) if ("block" in entry) {
|
|
19225
|
+
shiftBlock(entry.block, entry.offset, shifted);
|
|
19226
|
+
if (entry.leadingSeamPrevStripped) {
|
|
19227
|
+
const firstNode = entry.block.nodes.find((n) => n.loc);
|
|
19228
|
+
if (firstNode) firstNode.extra = {
|
|
19229
|
+
...firstNode.extra ?? {},
|
|
19230
|
+
__rozieLeadingSeamPrevStripped: true
|
|
19231
|
+
};
|
|
19232
|
+
}
|
|
19233
|
+
} else {
|
|
19234
|
+
shiftHostNodeLines(entry.hostNode, entry.offset, shifted);
|
|
19235
|
+
if (entry.afterGap !== void 0) {
|
|
19236
|
+
const extra = entry.hostNode.extra ?? {};
|
|
19237
|
+
entry.hostNode.extra = {
|
|
19238
|
+
...extra,
|
|
19239
|
+
__rozieAfterGap: entry.afterGap
|
|
19240
|
+
};
|
|
19241
|
+
}
|
|
19242
|
+
}
|
|
19243
|
+
}
|
|
19244
|
+
/**
|
|
19245
|
+
* Phase 56 (Shape-3, R4) — un-FLOAT a hoisted import's between-statement comment that
|
|
19246
|
+
* has separated from its owning declaration.
|
|
19247
|
+
*
|
|
19248
|
+
* `hoistSpecifier` copies a partial import's `trailingComments` onto the HOISTED import
|
|
19249
|
+
* node so a comment authored BETWEEN that import and the next surviving decl rides the
|
|
19250
|
+
* import to the host module-top (Phase 55 byte-identity). @babel/parser attaches such a
|
|
19251
|
+
* between-statement comment to BOTH neighbours: the import's `trailingComments` AND the
|
|
19252
|
+
* following decl's `leadingComments` (the SAME comment object). That copy is CORRECT
|
|
19253
|
+
* only when the import and its decl stay ADJACENT in the final body (e.g. HostC: the
|
|
19254
|
+
* hoisted `clamp` import is immediately followed by the `double` decl it shares the
|
|
19255
|
+
* comment with — the inline oracle ALSO has the comment on both neighbours, so
|
|
19256
|
+
* per-statement targets double it identically).
|
|
19257
|
+
*
|
|
19258
|
+
* When the spliced decl lands NON-adjacent to its hoisted import — a host statement
|
|
19259
|
+
* (e.g. a reassigned module-`let`) sits between them (HostH/the DataTable P15
|
|
19260
|
+
* `editTransition` after-`let` seam) — the import's copy FLOATS the comment to
|
|
19261
|
+
* module-top, away from the decl. The inline oracle keeps the comment ONLY on the decl
|
|
19262
|
+
* (its import is authored far above, never adjacent), so the float is a partial-vs-inline
|
|
19263
|
+
* divergence on ALL six targets (svelte/vue double it at the wrong place, react/angular/
|
|
19264
|
+
* lit drop it, solid dedups). This pass restores the inline placement by STRIPPING the
|
|
19265
|
+
* floated comment from the import's `trailingComments`; the decl keeps it on its
|
|
19266
|
+
* `leadingComments` (object identity preserved), and the per-target emitters then handle
|
|
19267
|
+
* the decl-attached comment exactly as they do for the inline oracle (svelte/vue's
|
|
19268
|
+
* `mirrorSpliceBoundaryComments` restores the doubling at the decl seam).
|
|
19269
|
+
*
|
|
19270
|
+
* Runs BEFORE `normalizeSplicedEmitLines` so the corrected attachment is in place when
|
|
19271
|
+
* the emit-line shift runs. A comment is treated as FLOATED iff it is shared (object
|
|
19272
|
+
* identity) with some body node's `leadingComments` whose owner is NOT the import's
|
|
19273
|
+
* immediate body-successor; a genuine import-only trailing comment (owned by no decl's
|
|
19274
|
+
* leadingComments) and the adjacent-decl case (HostC) are both left untouched. Never
|
|
19275
|
+
* throws (D-04).
|
|
19276
|
+
*/
|
|
19277
|
+
function defloatHoistedImportComments(body, hoistImports) {
|
|
19278
|
+
if (hoistImports.length === 0) return;
|
|
19279
|
+
const hoistSet = new Set(hoistImports);
|
|
19280
|
+
const leadOwnerIndex = /* @__PURE__ */ new Map();
|
|
19281
|
+
for (let i = 0; i < body.length; i++) for (const c of body[i].leadingComments ?? []) if (!leadOwnerIndex.has(c)) leadOwnerIndex.set(c, i);
|
|
19282
|
+
for (let hi = 0; hi < body.length; hi++) {
|
|
19283
|
+
const node = body[hi];
|
|
19284
|
+
if (!hoistSet.has(node)) continue;
|
|
19285
|
+
const trailing = node.trailingComments;
|
|
19286
|
+
if (!trailing || trailing.length === 0) continue;
|
|
19287
|
+
const kept = trailing.filter((c) => {
|
|
19288
|
+
const owner = leadOwnerIndex.get(c);
|
|
19289
|
+
if (owner === void 0) return true;
|
|
19290
|
+
if (owner === hi + 1) return true;
|
|
19291
|
+
return false;
|
|
19292
|
+
});
|
|
19293
|
+
if (kept.length !== trailing.length) node.trailingComments = kept.length > 0 ? kept : null;
|
|
19294
|
+
}
|
|
19295
|
+
}
|
|
18780
19296
|
/** Build the named imported-name list for a (host or nested) partial import. */
|
|
18781
19297
|
function namedImports(imp) {
|
|
18782
19298
|
const out = [];
|
|
@@ -18839,6 +19355,7 @@ function inlineResolvedPartial(absPath, importedNames, importStmt, importerFile,
|
|
|
18839
19355
|
const nestedImports = [];
|
|
18840
19356
|
/** local name -> nested partial resolved path + the imported name. */
|
|
18841
19357
|
const nestedLocalMap = /* @__PURE__ */ new Map();
|
|
19358
|
+
const reExports = [];
|
|
18842
19359
|
let order = 0;
|
|
18843
19360
|
for (const stmt of partialBody) {
|
|
18844
19361
|
if (_babel_types.isImportDeclaration(stmt)) {
|
|
@@ -18864,9 +19381,47 @@ function inlineResolvedPartial(absPath, importedNames, importStmt, importerFile,
|
|
|
18864
19381
|
} else moduleImports.push(stmt);
|
|
18865
19382
|
continue;
|
|
18866
19383
|
}
|
|
19384
|
+
if (_babel_types.isExportNamedDeclaration(stmt) && !stmt.declaration && stmt.source) {
|
|
19385
|
+
const src = stmt.source;
|
|
19386
|
+
const declTypeOnly = stmt.exportKind === "type";
|
|
19387
|
+
for (const spec of stmt.specifiers) if (_babel_types.isExportSpecifier(spec)) {
|
|
19388
|
+
const exportedName = _babel_types.isIdentifier(spec.exported) ? spec.exported.name : spec.exported.value;
|
|
19389
|
+
const kind = declTypeOnly || spec.exportKind === "type" ? "type" : "value";
|
|
19390
|
+
const localId = spec.local;
|
|
19391
|
+
reExports.push({
|
|
19392
|
+
exportedName,
|
|
19393
|
+
source: src,
|
|
19394
|
+
kind,
|
|
19395
|
+
build: () => _babel_types.importSpecifier(_babel_types.identifier(exportedName), _babel_types.identifier(localId.name))
|
|
19396
|
+
});
|
|
19397
|
+
} else if (_babel_types.isExportNamespaceSpecifier(spec)) {
|
|
19398
|
+
const nsName = spec.exported.name;
|
|
19399
|
+
reExports.push({
|
|
19400
|
+
exportedName: nsName,
|
|
19401
|
+
source: src,
|
|
19402
|
+
kind: declTypeOnly ? "type" : "value",
|
|
19403
|
+
build: () => _babel_types.importNamespaceSpecifier(_babel_types.identifier(nsName))
|
|
19404
|
+
});
|
|
19405
|
+
}
|
|
19406
|
+
continue;
|
|
19407
|
+
}
|
|
19408
|
+
if (_babel_types.isExportAllDeclaration(stmt)) {
|
|
19409
|
+
ctx.diagnostics.push({
|
|
19410
|
+
code: RozieErrorCode.PARTIAL_UNSUPPORTED_IMPORT_FORM,
|
|
19411
|
+
severity: "error",
|
|
19412
|
+
message: `Script partial '${absPath}' uses \`export * from '${stmt.source.value}'\`. A star re-export has no statically-known named surface to inline — a partial is a compile-time inline, so each re-exported symbol must be named (e.g. \`export { foo } from '${stmt.source.value}'\`).`,
|
|
19413
|
+
loc: nodeLoc(stmt),
|
|
19414
|
+
...absPath ? { filename: absPath } : {},
|
|
19415
|
+
hint: `Replace the star re-export with explicit named re-exports: export { foo, bar } from '${stmt.source.value}'.`
|
|
19416
|
+
});
|
|
19417
|
+
continue;
|
|
19418
|
+
}
|
|
18867
19419
|
let bare = null;
|
|
18868
|
-
if (_babel_types.isExportNamedDeclaration(stmt) && stmt.declaration)
|
|
18869
|
-
|
|
19420
|
+
if (_babel_types.isExportNamedDeclaration(stmt) && stmt.declaration) {
|
|
19421
|
+
bare = stmt.declaration;
|
|
19422
|
+
const prevStmt = partialBody[partialBody.indexOf(stmt) - 1];
|
|
19423
|
+
if ((prevStmt && _babel_types.isImportDeclaration(prevStmt) && !PARTIAL_EXT.test(prevStmt.source.value) && prevStmt.trailingComments && stmt.leadingComments ? stmt.leadingComments.some((c) => prevStmt.trailingComments.includes(c)) : false) && stmt.leadingComments && stmt.leadingComments.length > 0 && (!bare.leadingComments || bare.leadingComments.length === 0)) bare.leadingComments = stmt.leadingComments;
|
|
19424
|
+
} else if (_babel_types.isVariableDeclaration(stmt) || _babel_types.isFunctionDeclaration(stmt) || _babel_types.isClassDeclaration(stmt) || _babel_types.isTSInterfaceDeclaration(stmt) || _babel_types.isTSTypeAliasDeclaration(stmt) || _babel_types.isTSEnumDeclaration(stmt) || _babel_types.isTSDeclareFunction(stmt)) bare = stmt;
|
|
18870
19425
|
if (!bare) continue;
|
|
18871
19426
|
const names = bindingNames(bare);
|
|
18872
19427
|
if (names.length === 0) continue;
|
|
@@ -18919,8 +19474,9 @@ function inlineResolvedPartial(absPath, importedNames, importStmt, importerFile,
|
|
|
18919
19474
|
}
|
|
18920
19475
|
for (const imp of moduleImports) {
|
|
18921
19476
|
const declKind = imp.importKind ?? "value";
|
|
18922
|
-
for (const spec of imp.specifiers) if (referencedAll.has(spec.local.name)) hoistSpecifier(ctx, imp.source, declKind, spec);
|
|
19477
|
+
for (const spec of imp.specifiers) if (referencedAll.has(spec.local.name)) hoistSpecifier(ctx, imp.source, declKind, spec, imp);
|
|
18923
19478
|
}
|
|
19479
|
+
for (const re of reExports) if (importedNames.includes(re.exportedName) || referencedAll.has(re.exportedName)) hoistSpecifier(ctx, re.source, re.kind, re.build());
|
|
18924
19480
|
const out = [];
|
|
18925
19481
|
for (const decl of includedSorted) {
|
|
18926
19482
|
const collidingNames = [];
|
|
@@ -19010,6 +19566,7 @@ function inlineScriptPartials(file, opts = {}) {
|
|
|
19010
19566
|
}
|
|
19011
19567
|
}
|
|
19012
19568
|
const splicedAbs = /* @__PURE__ */ new Set();
|
|
19569
|
+
const splicedBlocks = [];
|
|
19013
19570
|
const newBody = [];
|
|
19014
19571
|
for (const stmt of file.program.body) if (_babel_types.isImportDeclaration(stmt) && PARTIAL_EXT.test(stmt.source.value)) {
|
|
19015
19572
|
const absPath = hostPartialAbs.get(stmt) ?? null;
|
|
@@ -19038,9 +19595,38 @@ function inlineScriptPartials(file, opts = {}) {
|
|
|
19038
19595
|
if (splicedAbs.has(absPath)) continue;
|
|
19039
19596
|
splicedAbs.add(absPath);
|
|
19040
19597
|
const unionNames = hostPartialNames.get(absPath) ?? namedImports(stmt);
|
|
19041
|
-
|
|
19598
|
+
const hoistBefore = ctx.hoistImports.length;
|
|
19599
|
+
const spliced = inlineResolvedPartial(absPath, unionNames, stmt, fromFile, ctx);
|
|
19600
|
+
const newHoists = ctx.hoistImports.slice(hoistBefore);
|
|
19601
|
+
if (stmt.loc) {
|
|
19602
|
+
const anchorLine = stmt.loc.start.line;
|
|
19603
|
+
for (const hoist of newHoists) splicedBlocks.push({
|
|
19604
|
+
nodes: [hoist],
|
|
19605
|
+
anchorLine,
|
|
19606
|
+
originalGap: 1
|
|
19607
|
+
});
|
|
19608
|
+
let runStart = 0;
|
|
19609
|
+
let prevRunLastNode = null;
|
|
19610
|
+
while (runStart < spliced.length) {
|
|
19611
|
+
const fname = spliced[runStart].loc?.filename ?? null;
|
|
19612
|
+
let runEnd = runStart + 1;
|
|
19613
|
+
while (runEnd < spliced.length && (spliced[runEnd].loc?.filename ?? null) === fname) runEnd++;
|
|
19614
|
+
const nodes = spliced.slice(runStart, runEnd);
|
|
19615
|
+
const originalGap = measureOriginalGap(nodes.find((n) => n.loc) ?? nodes[0], newHoists, prevRunLastNode);
|
|
19616
|
+
splicedBlocks.push({
|
|
19617
|
+
nodes,
|
|
19618
|
+
anchorLine,
|
|
19619
|
+
originalGap
|
|
19620
|
+
});
|
|
19621
|
+
prevRunLastNode = nodes[nodes.length - 1] ?? prevRunLastNode;
|
|
19622
|
+
runStart = runEnd;
|
|
19623
|
+
}
|
|
19624
|
+
}
|
|
19625
|
+
newBody.push(...spliced);
|
|
19042
19626
|
} else newBody.push(stmt);
|
|
19043
19627
|
file.program.body = [...ctx.hoistImports, ...newBody];
|
|
19628
|
+
defloatHoistedImportComments(file.program.body, ctx.hoistImports);
|
|
19629
|
+
normalizeSplicedEmitLines(file.program.body, splicedBlocks);
|
|
19044
19630
|
return {
|
|
19045
19631
|
ast: file,
|
|
19046
19632
|
diagnostics
|
|
@@ -21347,6 +21933,27 @@ function rewriteRozieIdentifiers$4(program, ir, diagnostics) {
|
|
|
21347
21933
|
loc: ref.sourceLoc
|
|
21348
21934
|
});
|
|
21349
21935
|
normalizeModelAccessor$4(program);
|
|
21936
|
+
const vueProtected = new Set((ir.expose ?? []).map((e) => e.name));
|
|
21937
|
+
deconflictGeneratedSymbols(program, [
|
|
21938
|
+
{
|
|
21939
|
+
names: modelProps,
|
|
21940
|
+
trigger: {
|
|
21941
|
+
kind: "accessor",
|
|
21942
|
+
accessor: "$props"
|
|
21943
|
+
}
|
|
21944
|
+
},
|
|
21945
|
+
{
|
|
21946
|
+
names: dataNames,
|
|
21947
|
+
trigger: {
|
|
21948
|
+
kind: "accessor",
|
|
21949
|
+
accessor: "$data"
|
|
21950
|
+
}
|
|
21951
|
+
},
|
|
21952
|
+
{
|
|
21953
|
+
names: computedNames,
|
|
21954
|
+
trigger: { kind: "bare-read" }
|
|
21955
|
+
}
|
|
21956
|
+
], vueProtected);
|
|
21350
21957
|
traverse$17(program, {
|
|
21351
21958
|
MemberExpression(path) {
|
|
21352
21959
|
/* v8 ignore next -- defensive: MemberExpression nodes do not occur in TS type position */
|
|
@@ -21867,6 +22474,80 @@ function arrowBody$4(body) {
|
|
|
21867
22474
|
return genCode$9(_babel_types.arrowFunctionExpression([], body));
|
|
21868
22475
|
}
|
|
21869
22476
|
/**
|
|
22477
|
+
* Phase 55-04 (literal byte-identity) — reproduce the inline-authored comment
|
|
22478
|
+
* doubling at a script-partial splice boundary.
|
|
22479
|
+
*
|
|
22480
|
+
* In an inline-authored `<script>`, a comment block BETWEEN two statements is
|
|
22481
|
+
* attached by `@babel/parser` to BOTH neighbours (the earlier statement's
|
|
22482
|
+
* `trailingComments` AND the later statement's `leadingComments`). The `.rzts`
|
|
22483
|
+
* script-partial splice attaches the boundary banner ONLY to the spliced node's
|
|
22484
|
+
* `leadingComments` — the preceding statement lives in a different source file and
|
|
22485
|
+
* carries no matching trailing comment. Vue emits the residual body one statement
|
|
22486
|
+
* at a time (`stmts.map((s) => genCode(s)).join('\n')`), so each `genCode` call has
|
|
22487
|
+
* its own comment-dedup set: in the inline form the boundary banner therefore
|
|
22488
|
+
* prints TWICE (once as the previous statement's trailing, once as the next
|
|
22489
|
+
* statement's leading), with a blank line after the previous closing brace.
|
|
22490
|
+
* Re-mirroring the spliced node's leading comments back onto the preceding
|
|
22491
|
+
* statement's trailing comments restores that byte-for-byte.
|
|
22492
|
+
*
|
|
22493
|
+
* Fires at a genuine splice boundary in EITHER direction (Phase 56 R1 broadened
|
|
22494
|
+
* the trigger): the CURRENT statement is spliced (`cur.extra.__roziePartialOrigin`
|
|
22495
|
+
* — the Phase 55 leading seam) OR the PREVIOUS statement is spliced and CUR is an
|
|
22496
|
+
* inline host successor carrying the leading comment (the R1 TRAILING seam). In
|
|
22497
|
+
* both cases CUR's leading comments are mirrored onto PREV's trailing comments
|
|
22498
|
+
* UNLESS already shared (within-partial statement pairs share the same comment
|
|
22499
|
+
* objects; host-only pairs — neither node spliced — are left exactly as authored).
|
|
22500
|
+
* `normalizeSplicedEmitLines` (core) has already anchored the seam spacing, so the
|
|
22501
|
+
* mirrored trailing copy spaces correctly.
|
|
22502
|
+
*/
|
|
22503
|
+
function mirrorSpliceBoundaryComments$2(stmts) {
|
|
22504
|
+
for (let i = 1; i < stmts.length; i++) {
|
|
22505
|
+
const cur = stmts[i];
|
|
22506
|
+
const prev = stmts[i - 1];
|
|
22507
|
+
const curExtra = cur.extra;
|
|
22508
|
+
const prevExtra = prev.extra;
|
|
22509
|
+
const curSpliced = curExtra?.__roziePartialOrigin !== void 0;
|
|
22510
|
+
const prevSpliced = prevExtra?.__roziePartialOrigin !== void 0;
|
|
22511
|
+
if (!curSpliced && !prevSpliced) continue;
|
|
22512
|
+
const lead = cur.leadingComments;
|
|
22513
|
+
const prevTrail = prev.trailingComments;
|
|
22514
|
+
if (curSpliced && !prevSpliced && (!lead || lead.length === 0) && prevTrail && prevTrail.length > 0) {
|
|
22515
|
+
cur.leadingComments = [...prevTrail];
|
|
22516
|
+
continue;
|
|
22517
|
+
}
|
|
22518
|
+
if (!lead || lead.length === 0) continue;
|
|
22519
|
+
if (curSpliced && curExtra?.__rozieLeadingSeamPrevStripped === true) continue;
|
|
22520
|
+
const lastLead = lead[lead.length - 1];
|
|
22521
|
+
if (prevTrail && prevTrail.length > 0 && prevTrail[prevTrail.length - 1] === lastLead) continue;
|
|
22522
|
+
let toAppend = lead;
|
|
22523
|
+
if (prevSpliced && !curSpliced) {
|
|
22524
|
+
const afterGap = curExtra?.__rozieAfterGap;
|
|
22525
|
+
const anchorLine = (prev.loc?.end.line ?? 0) + (typeof afterGap === "number" ? afterGap : 1);
|
|
22526
|
+
const baseLine = lead[0]?.loc?.start.line;
|
|
22527
|
+
toAppend = lead.map((c) => {
|
|
22528
|
+
if (!c.loc) return { ...c };
|
|
22529
|
+
const startLine = baseLine === void 0 ? anchorLine : anchorLine + (c.loc.start.line - baseLine);
|
|
22530
|
+
const endLine = baseLine === void 0 ? anchorLine : anchorLine + (c.loc.end.line - baseLine);
|
|
22531
|
+
return {
|
|
22532
|
+
...c,
|
|
22533
|
+
loc: {
|
|
22534
|
+
...c.loc,
|
|
22535
|
+
start: {
|
|
22536
|
+
...c.loc.start,
|
|
22537
|
+
line: startLine
|
|
22538
|
+
},
|
|
22539
|
+
end: {
|
|
22540
|
+
...c.loc.end,
|
|
22541
|
+
line: endLine
|
|
22542
|
+
}
|
|
22543
|
+
}
|
|
22544
|
+
};
|
|
22545
|
+
});
|
|
22546
|
+
}
|
|
22547
|
+
prev.trailingComments = [...prevTrail ?? [], ...toAppend];
|
|
22548
|
+
}
|
|
22549
|
+
}
|
|
22550
|
+
/**
|
|
21870
22551
|
* Render a PropTypeAnnotation as a TypeScript type string.
|
|
21871
22552
|
*
|
|
21872
22553
|
* Reference examples produce these patterns:
|
|
@@ -22321,6 +23002,7 @@ function emitResidualScriptBody$1(clonedProgram, consumedLifecycleIndices) {
|
|
|
22321
23002
|
}
|
|
22322
23003
|
stmts.push(stmt);
|
|
22323
23004
|
}
|
|
23005
|
+
mirrorSpliceBoundaryComments$2(stmts);
|
|
22324
23006
|
return {
|
|
22325
23007
|
code: stmts.map((s) => genCode$9(s)).join("\n"),
|
|
22326
23008
|
stmts
|
|
@@ -24962,7 +25644,8 @@ function remapping$1(input, loader, options) {
|
|
|
24962
25644
|
* (the "parent" map) via @ampproject/remapping. Result: a single Source Map
|
|
24963
25645
|
* v3 that resolves emitted-output positions all the way back to .rozie.
|
|
24964
25646
|
*
|
|
24965
|
-
* Used by all
|
|
25647
|
+
* Used by all 6 target compose.ts files (react/vue/svelte/solid/lit/angular).
|
|
25648
|
+
* Replaces the per-target
|
|
24966
25649
|
* single-segment re-projection hack (Phase 3 WR-01 / Phase 4 Plan 04-05
|
|
24967
25650
|
* Task 1) removed in P2 (D-109).
|
|
24968
25651
|
*
|
|
@@ -24975,7 +25658,114 @@ function remapping$1(input, loader, options) {
|
|
|
24975
25658
|
* @experimental — shape may change before v1.0
|
|
24976
25659
|
*/
|
|
24977
25660
|
const remapping = typeof remapping$1 === "function" ? remapping$1 : remapping$1.default;
|
|
25661
|
+
/** Source-file extension test: a spliced script partial origin (Phase 54/55). */
|
|
25662
|
+
function isPartialSource(src) {
|
|
25663
|
+
return !!src && (src.endsWith(".rzts") || src.endsWith(".rzjs"));
|
|
25664
|
+
}
|
|
25665
|
+
/**
|
|
25666
|
+
* Recover a partial source's constant emit-line offset from the table. The table
|
|
25667
|
+
* is keyed by the absolute `loc.filename` stashed at splice time; a child map's
|
|
25668
|
+
* `sources` entry is the same absolute path, so an EXACT lookup is tried first.
|
|
25669
|
+
*
|
|
25670
|
+
* WR-03: the defensive fallback is restricted to a path-SEGMENT-BOUNDARY match
|
|
25671
|
+
* (`src.endsWith('/' + file) || file.endsWith('/' + src)`) so a partial whose path
|
|
25672
|
+
* is a bare substring of another's (e.g. `xa.rzts` vs `a.rzts`) never collides, and
|
|
25673
|
+
* — critically — if TWO OR MORE table entries match the boundary test (an ambiguous
|
|
25674
|
+
* bare basename shared across nested dirs) the lookup BAILS (returns `undefined`)
|
|
25675
|
+
* rather than mis-attributing one partial's offset to another. Returns `undefined`
|
|
25676
|
+
* when no unambiguous offset is known (mapping left as-is — D-04).
|
|
25677
|
+
*/
|
|
25678
|
+
function lookupPartialOffset(src, offsets) {
|
|
25679
|
+
if (!src || !offsets || offsets.size === 0) return void 0;
|
|
25680
|
+
const exact = offsets.get(src);
|
|
25681
|
+
if (exact !== void 0) return exact;
|
|
25682
|
+
let match;
|
|
25683
|
+
let matchCount = 0;
|
|
25684
|
+
for (const [file, off] of offsets) if (src.endsWith(`/${file}`) || file.endsWith(`/${src}`)) {
|
|
25685
|
+
match = off;
|
|
25686
|
+
matchCount++;
|
|
25687
|
+
}
|
|
25688
|
+
return matchCount === 1 ? match : void 0;
|
|
25689
|
+
}
|
|
25690
|
+
/**
|
|
25691
|
+
* Phase 55 Plan 03 (SC-2) — build the per-partial-file constant emit-line offset
|
|
25692
|
+
* table from the lowered script AST.
|
|
25693
|
+
*
|
|
25694
|
+
* Plan 02 shifted each spliced node's `loc.start.line` to a host-contiguous emit
|
|
25695
|
+
* value while stashing the true `.rzts` origin on `extra.__roziePartialOrigin`.
|
|
25696
|
+
* The per-partial offset is therefore the (constant) delta
|
|
25697
|
+
* `loc.start.line − __roziePartialOrigin.line`; subtracting it from a mapping's
|
|
25698
|
+
* original line restores the `.rzts`-local line. The offset is constant per
|
|
25699
|
+
* spliced block (Plan 02 anchored it), so one entry per partial `source` file
|
|
25700
|
+
* suffices — the first stashed node per file wins.
|
|
25701
|
+
*
|
|
25702
|
+
* Walks `scriptAst.program.body` (the spliced statements sit at top level) and
|
|
25703
|
+
* their attached leading/trailing/inner comments (comments carry the stash
|
|
25704
|
+
* directly). Never throws (D-04): a missing/zero stash is skipped, a null AST
|
|
25705
|
+
* yields an empty table.
|
|
25706
|
+
*
|
|
25707
|
+
* IN-02: the `innerComments` loop mirrors `shiftAttachedComments`
|
|
25708
|
+
* (inlineScriptPartials.ts) which walks leading/trailing/inner. In practice the
|
|
25709
|
+
* offset is per-file and first-stash-wins, so a leading/trailing comment or the
|
|
25710
|
+
* decl itself almost always supplies it — the inner loop is additive and harmless,
|
|
25711
|
+
* kept only so the stash-channel scan is symmetric with where stashes are written.
|
|
25712
|
+
*/
|
|
25713
|
+
function buildPartialLineOffsets(scriptAst) {
|
|
25714
|
+
const out = /* @__PURE__ */ new Map();
|
|
25715
|
+
const body = scriptAst?.program?.body;
|
|
25716
|
+
if (!body) return out;
|
|
25717
|
+
const record = (carrier, locLine) => {
|
|
25718
|
+
const origin = carrier?.__roziePartialOrigin;
|
|
25719
|
+
if (!origin || locLine === void 0) return;
|
|
25720
|
+
const key = origin.filename;
|
|
25721
|
+
if (!key || out.has(key)) return;
|
|
25722
|
+
out.set(key, locLine - origin.line);
|
|
25723
|
+
};
|
|
25724
|
+
for (const node of body) {
|
|
25725
|
+
const extra = node.extra;
|
|
25726
|
+
record(extra, node.loc?.start.line);
|
|
25727
|
+
for (const c of node.leadingComments ?? []) record(c, c.loc?.start.line);
|
|
25728
|
+
for (const c of node.trailingComments ?? []) record(c, c.loc?.start.line);
|
|
25729
|
+
for (const c of node.innerComments ?? []) record(c, c.loc?.start.line);
|
|
25730
|
+
}
|
|
25731
|
+
return out;
|
|
25732
|
+
}
|
|
24978
25733
|
/**
|
|
25734
|
+
* Phase 55 Plan 03 — per-target script-map flow survey (Task 1, Assumption A3).
|
|
25735
|
+
*
|
|
25736
|
+
* SURVEY RESULT (confirmed on disk 2026-06-20):
|
|
25737
|
+
*
|
|
25738
|
+
* 1. CONVERGENCE — all SIX per-target `sourcemap/compose.ts` wrappers
|
|
25739
|
+
* (react/vue/svelte/solid/lit/angular) import THIS `composeMaps` and route
|
|
25740
|
+
* their @babel/generator <script> child map through it as `children[0]`. No
|
|
25741
|
+
* target hand-rolls a second map merge; `composeMaps` is the single
|
|
25742
|
+
* convergence point, so the spliced-line restore arithmetic lives here ONCE
|
|
25743
|
+
* (D-03/D-05 uniformity) — never in a per-target wrapper or `emitScript.ts`.
|
|
25744
|
+
*
|
|
25745
|
+
* 2. ACTIVE MAP PATH — the five map-EMITTING targets (react/vue/svelte/solid/
|
|
25746
|
+
* angular) all pass a defined `userCodeLineOffset`, so each takes the
|
|
25747
|
+
* `userCodeLineOffset` branch below (step 3). Empirically, that branch
|
|
25748
|
+
* discarded the child map's per-node `sources` (it hardcoded `[opts.filename]`),
|
|
25749
|
+
* collapsing a spliced node's `.rzts` origin to the host `.rozie` — which is
|
|
25750
|
+
* exactly why the SC-2 line-fidelity smoke test was red/skipped. The restore
|
|
25751
|
+
* therefore lives in step 3. The step-4 remapping path is NOT exercised by
|
|
25752
|
+
* partials (every map-emitting target passes `userCodeLineOffset`), so it is
|
|
25753
|
+
* deliberately left untouched rather than carrying speculative dead code.
|
|
25754
|
+
*
|
|
25755
|
+
* 3. TABLE BUILD SITE — each of those five `emitXxx.ts` holds the lowered `ir`
|
|
25756
|
+
* (whose `ir.setupBody.scriptProgram` script AST carries the spliced nodes'
|
|
25757
|
+
* `extra.__roziePartialOrigin` stashes from Plan 02). Each builds the
|
|
25758
|
+
* `partialLineOffsets` table via {@link buildPartialLineOffsets} and threads
|
|
25759
|
+
* it into the `ComposeOpts` it already constructs. The table derives from the
|
|
25760
|
+
* IR, NOT from generator output — so NO `emitScript.ts` (the @babel/generator
|
|
25761
|
+
* caller) is touched (D-03).
|
|
25762
|
+
*
|
|
25763
|
+
* 4. LIT EXCEPTION — `packages/targets/lit/src/emitLit.ts` returns `map: null`
|
|
25764
|
+
* in v1 and does NOT call `composeSourceMap` (the wrapper is implemented but
|
|
25765
|
+
* dead until Phase 7 wires it). Lit therefore has no build+set site; its
|
|
25766
|
+
* wrapper still receives the `partialLineOffsets` field for forward-compat so
|
|
25767
|
+
* the restore flows automatically once Lit's map path is connected.
|
|
25768
|
+
*
|
|
24979
25769
|
* Merge the shell map + zero-or-more child maps into a single Source Map v3
|
|
24980
25770
|
* anchored to .rozie. Defensively re-asserts sources/sourcesContent per
|
|
24981
25771
|
* Pitfall 2 mitigation.
|
|
@@ -24994,6 +25784,27 @@ function composeMaps(opts) {
|
|
|
24994
25784
|
}
|
|
24995
25785
|
if (opts.userCodeLineOffset !== void 0) {
|
|
24996
25786
|
const childMap = opts.children[0].map;
|
|
25787
|
+
const childSources = childMap.sources ?? [];
|
|
25788
|
+
if (childSources.some((s) => isPartialSource(s)) && !!opts.partialLineOffsets && opts.partialLineOffsets.size > 0) {
|
|
25789
|
+
const decoded = decode(childMap.mappings);
|
|
25790
|
+
for (const line of decoded) for (const seg of line) if (seg.length >= 4) {
|
|
25791
|
+
const full = seg;
|
|
25792
|
+
const src = childSources[full[1]];
|
|
25793
|
+
const off = lookupPartialOffset(src, opts.partialLineOffsets);
|
|
25794
|
+
if (off !== void 0) full[2] = Math.max(0, full[2] - off);
|
|
25795
|
+
}
|
|
25796
|
+
const restoredMappings = encode(decoded);
|
|
25797
|
+
const sources = childSources.slice();
|
|
25798
|
+
const sourcesContent = sources.map((s, i) => s === opts.filename ? opts.source : childMap.sourcesContent?.[i] ?? null);
|
|
25799
|
+
return {
|
|
25800
|
+
version: 3,
|
|
25801
|
+
file: `${opts.filename}${opts.fileExt}`,
|
|
25802
|
+
sources,
|
|
25803
|
+
sourcesContent,
|
|
25804
|
+
names: childMap.names ?? [],
|
|
25805
|
+
mappings: ";".repeat(opts.userCodeLineOffset) + restoredMappings
|
|
25806
|
+
};
|
|
25807
|
+
}
|
|
24997
25808
|
return {
|
|
24998
25809
|
version: 3,
|
|
24999
25810
|
file: `${opts.filename}${opts.fileExt}`,
|
|
@@ -25027,7 +25838,8 @@ function composeSourceMap$4(ms, opts) {
|
|
|
25027
25838
|
outputOffset: opts.scriptOutputOffset
|
|
25028
25839
|
}] : [],
|
|
25029
25840
|
fileExt: ".vue",
|
|
25030
|
-
userCodeLineOffset: opts.userCodeLineOffset
|
|
25841
|
+
userCodeLineOffset: opts.userCodeLineOffset,
|
|
25842
|
+
partialLineOffsets: opts.partialLineOffsets
|
|
25031
25843
|
});
|
|
25032
25844
|
}
|
|
25033
25845
|
//#endregion
|
|
@@ -25212,7 +26024,8 @@ function emitVue(ir, opts = {}) {
|
|
|
25212
26024
|
source: opts.source,
|
|
25213
26025
|
scriptMap: shellScriptMap,
|
|
25214
26026
|
scriptOutputOffset,
|
|
25215
|
-
userCodeLineOffset
|
|
26027
|
+
userCodeLineOffset,
|
|
26028
|
+
partialLineOffsets: buildPartialLineOffsets(ir.setupBody.scriptProgram)
|
|
25216
26029
|
}) : null,
|
|
25217
26030
|
diagnostics: [
|
|
25218
26031
|
...scriptDiags,
|
|
@@ -29153,7 +29966,8 @@ function composeClassName(attrs, ctx) {
|
|
|
29153
29966
|
});
|
|
29154
29967
|
else segments.push({
|
|
29155
29968
|
kind: "plainBinding",
|
|
29156
|
-
expr: a.expression
|
|
29969
|
+
expr: a.expression,
|
|
29970
|
+
wrapForDisplay: a.wrapForDisplay
|
|
29157
29971
|
});
|
|
29158
29972
|
else if (a.kind === "spreadBinding") throw new Error(`React target: spreadBinding not valid in class array context (Phase 14).`);
|
|
29159
29973
|
else segments.push({
|
|
@@ -29175,6 +29989,10 @@ function composeClassName(attrs, ctx) {
|
|
|
29175
29989
|
const seg = segments[0];
|
|
29176
29990
|
const staticSegs = decomposeStaticClassExpr(seg.expr);
|
|
29177
29991
|
if (staticSegs) return renderInterpolatedClass(staticSegs, ctx);
|
|
29992
|
+
if (seg.wrapForDisplay) {
|
|
29993
|
+
ctx.collectors.runtime.add("clsx");
|
|
29994
|
+
return `clsx(${renderExpr$1(seg.expr, ir)})`;
|
|
29995
|
+
}
|
|
29178
29996
|
return renderExpr$1(seg.expr, ir);
|
|
29179
29997
|
}
|
|
29180
29998
|
if (segments.length === 1 && segments[0].kind === "interpolated") {
|
|
@@ -35009,7 +35827,8 @@ function composeSourceMap$3(ms, opts) {
|
|
|
35009
35827
|
outputOffset: opts.scriptOutputOffset
|
|
35010
35828
|
}] : [],
|
|
35011
35829
|
fileExt: ".tsx",
|
|
35012
|
-
userCodeLineOffset: opts.userCodeLineOffset
|
|
35830
|
+
userCodeLineOffset: opts.userCodeLineOffset,
|
|
35831
|
+
partialLineOffsets: opts.partialLineOffsets
|
|
35013
35832
|
});
|
|
35014
35833
|
}
|
|
35015
35834
|
//#endregion
|
|
@@ -35112,7 +35931,8 @@ function emitReact(ir, opts = {}) {
|
|
|
35112
35931
|
source: opts.source,
|
|
35113
35932
|
scriptMap: shellScriptMap,
|
|
35114
35933
|
scriptOutputOffset,
|
|
35115
|
-
userCodeLineOffset
|
|
35934
|
+
userCodeLineOffset,
|
|
35935
|
+
partialLineOffsets: buildPartialLineOffsets(ir.setupBody.scriptProgram)
|
|
35116
35936
|
}) : null,
|
|
35117
35937
|
diagnostics: [
|
|
35118
35938
|
...scriptDiags,
|
|
@@ -36106,6 +36926,80 @@ function arrowBody$2(body) {
|
|
|
36106
36926
|
return genCode$5(_babel_types.arrowFunctionExpression([], body));
|
|
36107
36927
|
}
|
|
36108
36928
|
/**
|
|
36929
|
+
* Phase 55-04 (literal byte-identity) — reproduce the inline-authored comment
|
|
36930
|
+
* doubling at a script-partial splice boundary.
|
|
36931
|
+
*
|
|
36932
|
+
* In an inline-authored `<script>`, a comment block BETWEEN two statements is
|
|
36933
|
+
* attached by `@babel/parser` to BOTH neighbours (the earlier statement's
|
|
36934
|
+
* `trailingComments` AND the later statement's `leadingComments`). The `.rzts`
|
|
36935
|
+
* script-partial splice attaches the boundary banner ONLY to the spliced node's
|
|
36936
|
+
* `leadingComments` — the preceding statement lives in a different source file and
|
|
36937
|
+
* carries no matching trailing comment. Svelte emits the residual body one
|
|
36938
|
+
* statement at a time (`stmts.map((s) => genCode(s)).join('\n')`), so each
|
|
36939
|
+
* `genCode` call has its own comment-dedup set: in the inline form the boundary
|
|
36940
|
+
* banner therefore prints TWICE (once as the previous statement's trailing, once
|
|
36941
|
+
* as the next statement's leading), with a blank line after the previous closing
|
|
36942
|
+
* brace. Re-mirroring the spliced node's leading comments back onto the preceding
|
|
36943
|
+
* statement's trailing comments restores that byte-for-byte.
|
|
36944
|
+
*
|
|
36945
|
+
* Fires at a genuine splice boundary in EITHER direction (Phase 56 R1 broadened
|
|
36946
|
+
* the trigger): the CURRENT statement is spliced (`cur.extra.__roziePartialOrigin`
|
|
36947
|
+
* — the Phase 55 leading seam) OR the PREVIOUS statement is spliced and CUR is an
|
|
36948
|
+
* inline host successor carrying the leading comment (the R1 TRAILING seam). In
|
|
36949
|
+
* both cases CUR's leading comments are mirrored onto PREV's trailing comments
|
|
36950
|
+
* UNLESS already shared (within-partial statement pairs share the same comment
|
|
36951
|
+
* objects; host-only pairs — neither node spliced — are left exactly as authored).
|
|
36952
|
+
* `normalizeSplicedEmitLines` (core) has already anchored the seam spacing, so the
|
|
36953
|
+
* mirrored trailing copy spaces correctly.
|
|
36954
|
+
*/
|
|
36955
|
+
function mirrorSpliceBoundaryComments$1(stmts) {
|
|
36956
|
+
for (let i = 1; i < stmts.length; i++) {
|
|
36957
|
+
const cur = stmts[i];
|
|
36958
|
+
const prev = stmts[i - 1];
|
|
36959
|
+
const curExtra = cur.extra;
|
|
36960
|
+
const prevExtra = prev.extra;
|
|
36961
|
+
const curSpliced = curExtra?.__roziePartialOrigin !== void 0;
|
|
36962
|
+
const prevSpliced = prevExtra?.__roziePartialOrigin !== void 0;
|
|
36963
|
+
if (!curSpliced && !prevSpliced) continue;
|
|
36964
|
+
const lead = cur.leadingComments;
|
|
36965
|
+
const prevTrail = prev.trailingComments;
|
|
36966
|
+
if (curSpliced && !prevSpliced && (!lead || lead.length === 0) && prevTrail && prevTrail.length > 0) {
|
|
36967
|
+
cur.leadingComments = [...prevTrail];
|
|
36968
|
+
continue;
|
|
36969
|
+
}
|
|
36970
|
+
if (!lead || lead.length === 0) continue;
|
|
36971
|
+
if (curSpliced && curExtra?.__rozieLeadingSeamPrevStripped === true) continue;
|
|
36972
|
+
const lastLead = lead[lead.length - 1];
|
|
36973
|
+
if (prevTrail && prevTrail.length > 0 && prevTrail[prevTrail.length - 1] === lastLead) continue;
|
|
36974
|
+
let toAppend = lead;
|
|
36975
|
+
if (prevSpliced && !curSpliced) {
|
|
36976
|
+
const afterGap = curExtra?.__rozieAfterGap;
|
|
36977
|
+
const anchorLine = (prev.loc?.end.line ?? 0) + (typeof afterGap === "number" ? afterGap : 1);
|
|
36978
|
+
const baseLine = lead[0]?.loc?.start.line;
|
|
36979
|
+
toAppend = lead.map((c) => {
|
|
36980
|
+
if (!c.loc) return { ...c };
|
|
36981
|
+
const startLine = baseLine === void 0 ? anchorLine : anchorLine + (c.loc.start.line - baseLine);
|
|
36982
|
+
const endLine = baseLine === void 0 ? anchorLine : anchorLine + (c.loc.end.line - baseLine);
|
|
36983
|
+
return {
|
|
36984
|
+
...c,
|
|
36985
|
+
loc: {
|
|
36986
|
+
...c.loc,
|
|
36987
|
+
start: {
|
|
36988
|
+
...c.loc.start,
|
|
36989
|
+
line: startLine
|
|
36990
|
+
},
|
|
36991
|
+
end: {
|
|
36992
|
+
...c.loc.end,
|
|
36993
|
+
line: endLine
|
|
36994
|
+
}
|
|
36995
|
+
}
|
|
36996
|
+
};
|
|
36997
|
+
});
|
|
36998
|
+
}
|
|
36999
|
+
prev.trailingComments = [...prevTrail ?? [], ...toAppend];
|
|
37000
|
+
}
|
|
37001
|
+
}
|
|
37002
|
+
/**
|
|
36109
37003
|
* Render a PropTypeAnnotation as a TypeScript type string. Mirrors the Vue
|
|
36110
37004
|
* target's renderType helper.
|
|
36111
37005
|
*/
|
|
@@ -36544,6 +37438,7 @@ function emitResidualScriptBody(clonedProgram, consumedLifecycleIndices, exposeN
|
|
|
36544
37438
|
}
|
|
36545
37439
|
stmts.push(stmt);
|
|
36546
37440
|
}
|
|
37441
|
+
mirrorSpliceBoundaryComments$1(stmts);
|
|
36547
37442
|
return {
|
|
36548
37443
|
code: stmts.map((s) => {
|
|
36549
37444
|
if (exposeNames.size > 0 && isExposedTopLevelDecl(s, exposeNames)) {
|
|
@@ -37207,6 +38102,14 @@ function emitSingleAttr$1(attr, ctx) {
|
|
|
37207
38102
|
if (styleObjectLowered !== null) return styleObjectLowered;
|
|
37208
38103
|
const expr = rewriteTemplateExpression$3(attr.expression, ir);
|
|
37209
38104
|
const outName = resolveAttrName(attr.name, ctx);
|
|
38105
|
+
if (attr.name === "style") {
|
|
38106
|
+
ctx.runtimeImports?.add("rozieStyle");
|
|
38107
|
+
return `${outName}={rozieStyle(${expr})}`;
|
|
38108
|
+
}
|
|
38109
|
+
if (attr.name === "class" && attr.wrapForDisplay && !_babel_types.isObjectExpression(attr.expression) && !_babel_types.isTemplateLiteral(attr.expression) && shouldWrapSvelteAttrBinding(attr.name, attr.expression, ctx)) {
|
|
38110
|
+
ctx.runtimeImports?.add("rozieClass");
|
|
38111
|
+
return `${outName}={rozieClass(${expr})}`;
|
|
38112
|
+
}
|
|
37210
38113
|
if (attr.wrapForDisplay && shouldWrapSvelteAttrBinding(attr.name, attr.expression, ctx)) {
|
|
37211
38114
|
ctx.runtimeImports?.add("rozieAttr");
|
|
37212
38115
|
return `${outName}={rozieAttr(${expr})}`;
|
|
@@ -37234,12 +38137,16 @@ function emitSingleAttr$1(attr, ctx) {
|
|
|
37234
38137
|
* Convert a single AttributeBinding into a JS expression string suitable for
|
|
37235
38138
|
* inclusion in an array (used by class/style merge below).
|
|
37236
38139
|
*/
|
|
37237
|
-
function attrToArraySegment$1(attr, ir, runtimeImports) {
|
|
38140
|
+
function attrToArraySegment$1(attr, ir, runtimeImports, isClass = false) {
|
|
37238
38141
|
if (attr.kind === "twoWayBinding") throw new Error(`Svelte target: twoWayBinding not valid in class/style array context (Phase 07.3 Wave 3 Plan 07.3-04).`);
|
|
37239
38142
|
if (attr.kind === "static") return JSON.stringify(attr.value);
|
|
37240
38143
|
if (attr.kind === "binding") {
|
|
37241
38144
|
const code = rewriteTemplateExpression$3(attr.expression, ir);
|
|
37242
38145
|
if (attr.wrapForDisplay && !_babel_types.isObjectExpression(attr.expression)) {
|
|
38146
|
+
if (isClass && !_babel_types.isTemplateLiteral(attr.expression)) {
|
|
38147
|
+
runtimeImports?.add("rozieClass");
|
|
38148
|
+
return `rozieClass(${code})`;
|
|
38149
|
+
}
|
|
37243
38150
|
runtimeImports?.add("rozieDisplay");
|
|
37244
38151
|
return `rozieDisplay(${code})`;
|
|
37245
38152
|
}
|
|
@@ -37330,7 +38237,7 @@ function emitAttributes$2(attrs, ctx) {
|
|
|
37330
38237
|
if (synthetic) merged.push(synthetic);
|
|
37331
38238
|
} else if (src.name === a.name && !isLiteralStyleObjectBinding(src)) merged.push(src);
|
|
37332
38239
|
for (const x of merged) consumed.add(x);
|
|
37333
|
-
const segments = merged.map((x) => attrToArraySegment$1(x, ctx.ir, ctx.runtimeImports));
|
|
38240
|
+
const segments = merged.map((x) => attrToArraySegment$1(x, ctx.ir, ctx.runtimeImports, a.name === "class"));
|
|
37334
38241
|
if (hasOpaqueMerge) for (const readExpr of opaqueSpreadClassReads) segments.push(readExpr);
|
|
37335
38242
|
if (hasOpaqueMerge) deferredMergedClassStyle.push(`${a.name}={[${segments.join(", ")}]}`);
|
|
37336
38243
|
else out.push(`${a.name}={[${segments.join(", ")}]}`);
|
|
@@ -38822,7 +39729,8 @@ function composeSourceMap$2(ms, opts) {
|
|
|
38822
39729
|
outputOffset: opts.scriptOutputOffset
|
|
38823
39730
|
}] : [],
|
|
38824
39731
|
fileExt: ".svelte",
|
|
38825
|
-
userCodeLineOffset: opts.userCodeLineOffset
|
|
39732
|
+
userCodeLineOffset: opts.userCodeLineOffset,
|
|
39733
|
+
partialLineOffsets: opts.partialLineOffsets
|
|
38826
39734
|
});
|
|
38827
39735
|
}
|
|
38828
39736
|
//#endregion
|
|
@@ -38926,7 +39834,8 @@ function emitSvelte(ir, opts = {}) {
|
|
|
38926
39834
|
source: opts.source,
|
|
38927
39835
|
scriptMap: shellScriptMap,
|
|
38928
39836
|
scriptOutputOffset,
|
|
38929
|
-
userCodeLineOffset
|
|
39837
|
+
userCodeLineOffset,
|
|
39838
|
+
partialLineOffsets: buildPartialLineOffsets(ir.setupBody.scriptProgram)
|
|
38930
39839
|
}) : null,
|
|
38931
39840
|
diagnostics: [
|
|
38932
39841
|
...scriptDiags,
|
|
@@ -40197,7 +41106,15 @@ function buildSlotCtx(slot) {
|
|
|
40197
41106
|
*/
|
|
40198
41107
|
function buildNgTemplateContextGuard(componentName, slots) {
|
|
40199
41108
|
if (slots.length === 0) return null;
|
|
40200
|
-
const
|
|
41109
|
+
const seenCtxNames = /* @__PURE__ */ new Set();
|
|
41110
|
+
const ctxNames = [];
|
|
41111
|
+
for (const s of slots) {
|
|
41112
|
+
const ctxName = slotCtxName(s.name);
|
|
41113
|
+
if (seenCtxNames.has(ctxName)) continue;
|
|
41114
|
+
seenCtxNames.add(ctxName);
|
|
41115
|
+
ctxNames.push(ctxName);
|
|
41116
|
+
}
|
|
41117
|
+
const unionType = ctxNames.join(" | ");
|
|
40201
41118
|
return [
|
|
40202
41119
|
`static ngTemplateContextGuard(`,
|
|
40203
41120
|
` _dir: ${componentName},`,
|
|
@@ -40989,7 +41906,10 @@ function emitScript$2(ir, opts = {}) {
|
|
|
40989
41906
|
const interfaceDecls = [];
|
|
40990
41907
|
for (const typeDecl of hoistedTypeDecls) interfaceDecls.push(genCode$3(typeDecl));
|
|
40991
41908
|
const slotFieldDecls = [];
|
|
41909
|
+
const seenSlotNames = /* @__PURE__ */ new Set();
|
|
40992
41910
|
for (const slot of ir.slots) {
|
|
41911
|
+
if (seenSlotNames.has(slot.name)) continue;
|
|
41912
|
+
seenSlotNames.add(slot.name);
|
|
40993
41913
|
const ctx = buildSlotCtx(slot);
|
|
40994
41914
|
interfaceDecls.push(ctx.interfaceDecl);
|
|
40995
41915
|
slotFieldDecls.push(ctx.fieldDecl);
|
|
@@ -41952,6 +42872,7 @@ function shouldWrapAttrBinding$1(name, expr, ctx, elementTagName) {
|
|
|
41952
42872
|
if (BOOLEAN_HTML_ATTRS$1.has(name.toLowerCase())) return false;
|
|
41953
42873
|
if ((name === "value" || name === "checked") && FORM_INPUT_TAGS$2.has(elementTagName.toLowerCase())) return false;
|
|
41954
42874
|
if (name === "style") return false;
|
|
42875
|
+
if (name === "class") return false;
|
|
41955
42876
|
if (_babel_types.isObjectExpression(expr)) return false;
|
|
41956
42877
|
return true;
|
|
41957
42878
|
}
|
|
@@ -44720,7 +45641,8 @@ function composeSourceMap$1(ms, opts) {
|
|
|
44720
45641
|
outputOffset: opts.scriptOutputOffset
|
|
44721
45642
|
}] : [],
|
|
44722
45643
|
fileExt: ".ts",
|
|
44723
|
-
userCodeLineOffset: opts.userCodeLineOffset
|
|
45644
|
+
userCodeLineOffset: opts.userCodeLineOffset,
|
|
45645
|
+
partialLineOffsets: opts.partialLineOffsets
|
|
44724
45646
|
});
|
|
44725
45647
|
}
|
|
44726
45648
|
//#endregion
|
|
@@ -45106,7 +46028,8 @@ function emitAngular(ir, opts = {}) {
|
|
|
45106
46028
|
source: opts.source,
|
|
45107
46029
|
scriptMap: shellScriptMap,
|
|
45108
46030
|
scriptOutputOffset,
|
|
45109
|
-
userCodeLineOffset
|
|
46031
|
+
userCodeLineOffset,
|
|
46032
|
+
partialLineOffsets: buildPartialLineOffsets(ir.setupBody.scriptProgram)
|
|
45110
46033
|
}) : null,
|
|
45111
46034
|
diagnostics: [
|
|
45112
46035
|
...scriptResult.diagnostics,
|
|
@@ -46050,6 +46973,56 @@ function tryHoistArrowToFunction(stmt) {
|
|
|
46050
46973
|
return _babel_types.inherits(fn, stmt);
|
|
46051
46974
|
}
|
|
46052
46975
|
/**
|
|
46976
|
+
* Phase 55-04 (literal byte-identity) — reproduce the inline-authored comment
|
|
46977
|
+
* doubling at a script-partial splice boundary.
|
|
46978
|
+
*
|
|
46979
|
+
* In an inline-authored `<script>`, a comment block BETWEEN two statements is
|
|
46980
|
+
* attached by `@babel/parser` to BOTH neighbours (the earlier statement's
|
|
46981
|
+
* `trailingComments` AND the later statement's `leadingComments`). The `.rzts`
|
|
46982
|
+
* script-partial splice instead attaches the boundary banner ONLY to the spliced
|
|
46983
|
+
* node's `leadingComments` — the preceding statement lives in a different source
|
|
46984
|
+
* file and so carries no matching trailing comment. Re-mirroring the spliced
|
|
46985
|
+
* node's leading comments back onto the preceding statement's trailing comments
|
|
46986
|
+
* restores the inline form byte-for-byte:
|
|
46987
|
+
* - whole-program generation (Solid here) prints the (deduped) banner once AND
|
|
46988
|
+
* gets the boundary blank line from `@babel/generator`'s `printJoin`
|
|
46989
|
+
* `_lastCommentLine` path — a trailing comment on the previous statement is
|
|
46990
|
+
* exactly what triggers the loc-delta blank-line insertion; and
|
|
46991
|
+
* - per-statement generation (Vue/Svelte) doubles the banner (one copy as the
|
|
46992
|
+
* previous statement's trailing, one as the next statement's leading).
|
|
46993
|
+
*
|
|
46994
|
+
* Fires ONLY at a genuine splice boundary: the current statement carries
|
|
46995
|
+
* `extra.__roziePartialOrigin` AND its leading comments are not ALREADY shared as
|
|
46996
|
+
* the previous statement's trailing comments (within-partial statement pairs
|
|
46997
|
+
* already share the same comment objects; host-only pairs are left exactly as
|
|
46998
|
+
* authored). MUST run before the arrow→function hoist — `t.inherits` does not
|
|
46999
|
+
* copy `extra`, so the spliced marker is only visible on the original nodes.
|
|
47000
|
+
*/
|
|
47001
|
+
function mirrorSpliceBoundaryComments(stmts) {
|
|
47002
|
+
for (let i = 1; i < stmts.length; i++) {
|
|
47003
|
+
const cur = stmts[i];
|
|
47004
|
+
const prev = stmts[i - 1];
|
|
47005
|
+
const lead = cur.leadingComments;
|
|
47006
|
+
if (!lead || lead.length === 0) continue;
|
|
47007
|
+
const extra = cur.extra;
|
|
47008
|
+
const curSpliced = extra?.__roziePartialOrigin !== void 0;
|
|
47009
|
+
const prevSpliced = prev.extra?.__roziePartialOrigin !== void 0;
|
|
47010
|
+
if (!curSpliced) {
|
|
47011
|
+
if (prevSpliced && extra?.__rozieAfterGap !== void 0) {
|
|
47012
|
+
const prevTrail = prev.trailingComments;
|
|
47013
|
+
const lastLead = lead[lead.length - 1];
|
|
47014
|
+
if (prevTrail && prevTrail.length > 0 && prevTrail[prevTrail.length - 1] === lastLead) continue;
|
|
47015
|
+
prev.trailingComments = [...prevTrail ?? [], ...lead];
|
|
47016
|
+
}
|
|
47017
|
+
continue;
|
|
47018
|
+
}
|
|
47019
|
+
const prevTrail = prev.trailingComments;
|
|
47020
|
+
const lastLead = lead[lead.length - 1];
|
|
47021
|
+
if (prevTrail && prevTrail.length > 0 && prevTrail[prevTrail.length - 1] === lastLead) continue;
|
|
47022
|
+
prev.trailingComments = [...prevTrail ?? [], ...lead];
|
|
47023
|
+
}
|
|
47024
|
+
}
|
|
47025
|
+
/**
|
|
46053
47026
|
* WR-01 ROOT CAUSE 2 — re-project an author function-type annotation written
|
|
46054
47027
|
* on a `VariableDeclarator` `id` (`const f: (e: E) => R = …`) onto a rebuilt
|
|
46055
47028
|
* `FunctionDeclaration` (which has no annotatable `id`). Each declarator-type
|
|
@@ -46175,7 +47148,7 @@ function emitScript$1(ir, collectors, _registry) {
|
|
|
46175
47148
|
}
|
|
46176
47149
|
}
|
|
46177
47150
|
for (const ref of ir.refs) hookLines.push(`let ${ref.name}Ref: HTMLElement | null = null;`);
|
|
46178
|
-
const
|
|
47151
|
+
const residualStmts = [];
|
|
46179
47152
|
for (const stmt of rewriteResult.rewrittenProgram.program.body) {
|
|
46180
47153
|
if (_babel_types.isVariableDeclaration(stmt)) {
|
|
46181
47154
|
if (stmt.declarations.every((d) => d.init && _babel_types.isCallExpression(d.init) && _babel_types.isIdentifier(d.init.callee) && d.init.callee.name === "$computed")) continue;
|
|
@@ -46185,8 +47158,10 @@ function emitScript$1(ir, collectors, _registry) {
|
|
|
46185
47158
|
const callee = stmt.expression.callee;
|
|
46186
47159
|
if (_babel_types.isIdentifier(callee) && (callee.name === "$onMount" || callee.name === "$onUnmount" || callee.name === "$onUpdate" || callee.name === "$watch" || callee.name === "$expose" || callee.name === "$provide")) continue;
|
|
46187
47160
|
}
|
|
46188
|
-
|
|
47161
|
+
residualStmts.push(stmt);
|
|
46189
47162
|
}
|
|
47163
|
+
mirrorSpliceBoundaryComments(residualStmts);
|
|
47164
|
+
const filteredStmts = residualStmts.map((stmt) => tryHoistArrowToFunction(stmt) ?? stmt);
|
|
46190
47165
|
let userArrowsSection = "";
|
|
46191
47166
|
let scriptMap = null;
|
|
46192
47167
|
if (filteredStmts.length > 0) {
|
|
@@ -46887,6 +47862,10 @@ function composeClassValue(attrs, ir, exprOpts, runtime) {
|
|
|
46887
47862
|
if (attrs.length === 1 && attrs[0].kind === "binding") {
|
|
46888
47863
|
const a = attrs[0];
|
|
46889
47864
|
if (_babel_types.isObjectExpression(a.expression)) return renderExpr(a.expression, ir, exprOpts);
|
|
47865
|
+
if (a.wrapForDisplay && !_babel_types.isTemplateLiteral(a.expression)) {
|
|
47866
|
+
runtime?.add("rozieClass");
|
|
47867
|
+
return `rozieClass(${renderExpr(a.expression, ir, exprOpts)})`;
|
|
47868
|
+
}
|
|
46890
47869
|
return renderExpr(a.expression, ir, exprOpts);
|
|
46891
47870
|
}
|
|
46892
47871
|
if (attrs.length === 1 && attrs[0].kind === "interpolated") {
|
|
@@ -46905,7 +47884,10 @@ function composeClassValue(attrs, ir, exprOpts, runtime) {
|
|
|
46905
47884
|
const parts = [];
|
|
46906
47885
|
for (const a of attrs) if (a.kind === "twoWayBinding") throw new Error(`Solid target: twoWayBinding not valid in class array context (Phase 07.3 Wave 3 Plan 07.3-07).`);
|
|
46907
47886
|
else if (a.kind === "static") parts.push(renderStaticClassValue(a.value));
|
|
46908
|
-
else if (a.kind === "binding")
|
|
47887
|
+
else if (a.kind === "binding") if (a.wrapForDisplay && !_babel_types.isTemplateLiteral(a.expression)) {
|
|
47888
|
+
runtime?.add("rozieClass");
|
|
47889
|
+
parts.push(`rozieClass(${renderExpr(a.expression, ir, exprOpts)})`);
|
|
47890
|
+
} else parts.push(`(${renderExpr(a.expression, ir, exprOpts)})`);
|
|
46909
47891
|
else if (a.kind === "spreadBinding") throw new Error(`Solid target: spreadBinding not valid in class array context (Phase 14).`);
|
|
46910
47892
|
else {
|
|
46911
47893
|
let lit = "";
|
|
@@ -49556,7 +50538,8 @@ function composeSourceMap(ms, opts) {
|
|
|
49556
50538
|
outputOffset: opts.scriptOutputOffset
|
|
49557
50539
|
}] : [],
|
|
49558
50540
|
fileExt: ".tsx",
|
|
49559
|
-
userCodeLineOffset: opts.userCodeLineOffset
|
|
50541
|
+
userCodeLineOffset: opts.userCodeLineOffset,
|
|
50542
|
+
partialLineOffsets: opts.partialLineOffsets
|
|
49560
50543
|
});
|
|
49561
50544
|
}
|
|
49562
50545
|
//#endregion
|
|
@@ -49662,7 +50645,8 @@ function emitSolid(ir, opts = {}) {
|
|
|
49662
50645
|
source: opts.source,
|
|
49663
50646
|
scriptMap: shell.scriptMap,
|
|
49664
50647
|
scriptOutputOffset: shell.scriptOutputOffset,
|
|
49665
|
-
userCodeLineOffset: shell.userCodeLineOffset
|
|
50648
|
+
userCodeLineOffset: shell.userCodeLineOffset,
|
|
50649
|
+
partialLineOffsets: buildPartialLineOffsets(ir.setupBody.scriptProgram)
|
|
49666
50650
|
}) : null;
|
|
49667
50651
|
const diagnostics = [
|
|
49668
50652
|
...scriptResult.diagnostics,
|
|
@@ -52534,6 +53518,10 @@ function emitAttribute(attr, ir, tagName, tagKind = "html", opts) {
|
|
|
52534
53518
|
return `style=\${styleMap(${expr})}`;
|
|
52535
53519
|
}
|
|
52536
53520
|
const expr = rewriteTemplateExpression(attr.expression, ir);
|
|
53521
|
+
if (attr.name === "style") {
|
|
53522
|
+
opts?.runtime.add("rozieStyle");
|
|
53523
|
+
return `style=\${rozieStyle(${expr})}`;
|
|
53524
|
+
}
|
|
52537
53525
|
if (tagKind === "component" || tagKind === "self") {
|
|
52538
53526
|
const propName = attr.name.includes("-") ? attr.name.replace(/-([a-z])/g, (_, ch) => ch.toUpperCase()) : attr.name;
|
|
52539
53527
|
if (opts?._state && (_babel_types.isArrayExpression(attr.expression) || _babel_types.isObjectExpression(attr.expression)) && isPureLiteral(attr.expression)) {
|
|
@@ -52953,9 +53941,12 @@ function emitElementOpenTag(node, ir, irName, opts) {
|
|
|
52953
53941
|
const expr = rewriteTemplateExpression(bindingClass.expression, ir);
|
|
52954
53942
|
const staticPart = staticClassValues.length > 0 ? `${staticClassValues.join(" ")} ` : "";
|
|
52955
53943
|
let classExpr = expr;
|
|
52956
|
-
if (bindingClass.wrapForDisplay) {
|
|
53944
|
+
if (bindingClass.wrapForDisplay) if (_babel_types.isTemplateLiteral(bindingClass.expression)) {
|
|
52957
53945
|
opts.runtime.add("rozieDisplay");
|
|
52958
53946
|
classExpr = `rozieDisplay(${expr})`;
|
|
53947
|
+
} else {
|
|
53948
|
+
opts.runtime.add("rozieClass");
|
|
53949
|
+
classExpr = `rozieClass(${expr})`;
|
|
52959
53950
|
}
|
|
52960
53951
|
parts.push(`class="${staticPart}\${(${classExpr})}"`);
|
|
52961
53952
|
} else if (bindingClass.kind === "interpolated") {
|