@fluixi/compiler 1.0.0-alpha.82 → 1.0.0-alpha.84
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/analyze/expr-shape.cjs +62 -1
- package/dist/analyze/expr-shape.d.cts +14 -0
- package/dist/analyze/expr-shape.mjs +41 -1
- package/dist/analyze/intrinsics.cjs +80 -1
- package/dist/analyze/intrinsics.d.cts +66 -0
- package/dist/analyze/intrinsics.mjs +59 -1
- package/dist/analyze/paren.cjs +134 -0
- package/dist/analyze/paren.d.cts +23 -0
- package/dist/analyze/paren.d.ts +24 -0
- package/dist/analyze/paren.d.ts.map +1 -0
- package/dist/analyze/paren.js +168 -0
- package/dist/analyze/paren.mjs +113 -0
- package/dist/analyze/props-destructure.cjs +226 -1
- package/dist/analyze/props-destructure.d.cts +83 -0
- package/dist/analyze/props-destructure.mjs +205 -1
- package/dist/analyze/reactive-bindings.cjs +190 -1
- package/dist/analyze/reactive-bindings.d.cts +42 -0
- package/dist/analyze/reactive-bindings.mjs +167 -1
- package/dist/analyze/reactive-expr.cjs +38 -1
- package/dist/analyze/reactive-expr.d.cts +38 -0
- package/dist/analyze/reactive-expr.mjs +17 -1
- package/dist/analyze/static-graph.cjs +811 -0
- package/dist/analyze/static-graph.d.cts +102 -0
- package/dist/analyze/static-graph.d.ts +103 -0
- package/dist/analyze/static-graph.d.ts.map +1 -0
- package/dist/analyze/static-graph.js +869 -0
- package/dist/analyze/static-graph.mjs +793 -0
- package/dist/babel-NRW4EFTG.mjs +636 -0
- package/dist/chunk-3YKZ4GNH.mjs +11 -0
- package/dist/chunk-EZR7NZOY.mjs +1718 -0
- package/dist/chunk-FSSWUXUR.mjs +16 -0
- package/dist/chunk-MJV3UXIL.mjs +158 -0
- package/dist/chunk-R2VHAZAX.mjs +1078 -0
- package/dist/codegen/backend.cjs +18 -1
- package/dist/codegen/backend.d.cts +35 -0
- package/dist/codegen/backends/imperative.cjs +542 -1
- package/dist/codegen/backends/imperative.d.cts +11 -0
- package/dist/codegen/backends/imperative.d.ts.map +1 -1
- package/dist/codegen/backends/imperative.js +68 -13
- package/dist/codegen/backends/imperative.mjs +519 -1
- package/dist/codegen/contract.cjs +52 -1
- package/dist/codegen/contract.d.cts +24 -0
- package/dist/codegen/contract.mjs +31 -1
- package/dist/codegen/partial-template.cjs +176 -1
- package/dist/codegen/partial-template.d.cts +61 -0
- package/dist/codegen/partial-template.mjs +153 -1
- package/dist/codegen/serialize-static.cjs +125 -1
- package/dist/codegen/serialize-static.d.cts +38 -0
- package/dist/codegen/serialize-static.d.ts +16 -0
- package/dist/codegen/serialize-static.d.ts.map +1 -1
- package/dist/codegen/serialize-static.js +25 -0
- package/dist/codegen/serialize-static.mjs +104 -1
- package/dist/frontend/babel/build-ir-lit.cjs +1509 -1
- package/dist/frontend/babel/build-ir-lit.d.cts +26 -0
- package/dist/frontend/babel/build-ir-lit.mjs +1478 -1
- package/dist/frontend/babel/build-ir.cjs +1524 -1
- package/dist/frontend/babel/build-ir.d.cts +35 -0
- package/dist/frontend/babel/build-ir.mjs +1495 -1
- package/dist/frontend/babel/index.cjs +2186 -1
- package/dist/frontend/babel/index.d.cts +33 -0
- package/dist/frontend/babel/index.mjs +2156 -1
- package/dist/frontend/babel/lower-template.cjs +1507 -1
- package/dist/frontend/babel/lower-template.d.cts +23 -0
- package/dist/frontend/babel/lower-template.mjs +1478 -1
- package/dist/frontend/babel/plugin.cjs +2132 -1
- package/dist/frontend/babel/plugin.d.cts +95 -0
- package/dist/frontend/babel/plugin.mjs +2103 -1
- package/dist/frontend/babel/server-functions.cjs +110 -1
- package/dist/frontend/babel/server-functions.d.cts +10 -0
- package/dist/frontend/babel/server-functions.mjs +89 -1
- package/dist/frontend/babel/types.cjs +18 -1
- package/dist/frontend/babel/types.d.cts +33 -0
- package/dist/frontend/types.cjs +18 -1
- package/dist/frontend/types.d.cts +25 -0
- package/dist/frontend/vocabulary.cjs +98 -0
- package/dist/frontend/vocabulary.d.cts +79 -0
- package/dist/frontend/vocabulary.d.ts +80 -0
- package/dist/frontend/vocabulary.d.ts.map +1 -0
- package/dist/frontend/vocabulary.js +124 -0
- package/dist/frontend/vocabulary.mjs +77 -0
- package/dist/index.cjs +1594 -13
- package/dist/index.d.cts +27 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.mjs +1574 -13
- package/dist/integrations.cjs +4307 -25
- package/dist/integrations.d.cts +215 -0
- package/dist/integrations.d.ts +16 -0
- package/dist/integrations.d.ts.map +1 -1
- package/dist/integrations.js +21 -2
- package/dist/integrations.mjs +531 -17
- package/dist/ir/nodes.cjs +18 -1
- package/dist/ir/nodes.d.cts +168 -0
- package/dist/ir/nodes.d.ts +46 -0
- package/dist/ir/nodes.d.ts.map +1 -1
- package/dist/lower/compile-template.cjs +1356 -1
- package/dist/lower/compile-template.d.cts +69 -0
- package/dist/lower/compile-template.d.ts +12 -0
- package/dist/lower/compile-template.d.ts.map +1 -1
- package/dist/lower/compile-template.js +5 -1
- package/dist/lower/compile-template.mjs +1336 -1
- package/dist/lower/jsx.cjs +529 -1
- package/dist/lower/jsx.d.cts +25 -0
- package/dist/lower/jsx.d.ts +2 -0
- package/dist/lower/jsx.d.ts.map +1 -1
- package/dist/lower/jsx.js +27 -4
- package/dist/lower/jsx.mjs +506 -1
- package/dist/lower/template.cjs +1061 -1
- package/dist/lower/template.d.cts +53 -0
- package/dist/lower/template.d.ts +14 -1
- package/dist/lower/template.d.ts.map +1 -1
- package/dist/lower/template.js +106 -19
- package/dist/lower/template.mjs +1042 -1
- package/dist/lower/text.cjs +42 -1
- package/dist/lower/text.d.cts +10 -0
- package/dist/lower/text.mjs +21 -1
- package/dist/optimize/analyze-static.cjs +112 -1
- package/dist/optimize/analyze-static.d.cts +39 -0
- package/dist/optimize/analyze-static.mjs +91 -1
- package/dist/optimize/collapse-strategies.cjs +90 -1
- package/dist/optimize/collapse-strategies.d.cts +30 -0
- package/dist/optimize/collapse-strategies.mjs +67 -1
- package/dist/options.cjs +33 -1
- package/dist/options.d.cts +39 -0
- package/dist/options.mjs +12 -1
- package/dist/resolve/builtins.cjs +73 -1
- package/dist/resolve/builtins.d.cts +68 -0
- package/dist/resolve/builtins.mjs +53 -1
- package/dist/resolve/component-globals.cjs +233 -13
- package/dist/resolve/component-globals.d.cts +80 -0
- package/dist/resolve/component-globals.mjs +210 -13
- package/dist/resolve/component-resolver.cjs +80 -1
- package/dist/resolve/component-resolver.d.cts +68 -0
- package/dist/resolve/component-resolver.mjs +59 -1
- package/dist/resolve/load-directive.cjs +93 -1
- package/dist/resolve/load-directive.d.cts +53 -0
- package/dist/resolve/load-directive.mjs +72 -1
- package/dist/resolve/resolve-ir.cjs +108 -1
- package/dist/resolve/resolve-ir.d.cts +53 -0
- package/dist/resolve/resolve-ir.mjs +85 -1
- package/dist/resolve/write-globals.cjs +318 -13
- package/dist/resolve/write-globals.d.cts +30 -0
- package/dist/resolve/write-globals.mjs +297 -13
- package/dist/server-fns-4ZXN6DYU.mjs +78 -0
- package/dist/server-functions-V6D6DRIA.mjs +82 -0
- package/dist/transform/bindings.cjs +71 -1
- package/dist/transform/bindings.d.cts +16 -0
- package/dist/transform/bindings.mjs +50 -1
- package/dist/transform/index.cjs +2732 -8
- package/dist/transform/index.d.cts +15 -0
- package/dist/transform/index.mjs +3773 -17
- package/dist/transform/intrinsics.cjs +216 -3
- package/dist/transform/intrinsics.d.cts +21 -0
- package/dist/transform/intrinsics.mjs +193 -3
- package/dist/transform/props.cjs +441 -3
- package/dist/transform/props.d.cts +45 -0
- package/dist/transform/props.mjs +1482 -12
- package/dist/transform/server-fn-id.cjs +35 -1
- package/dist/transform/server-fn-id.d.cts +9 -0
- package/dist/transform/server-fn-id.mjs +14 -1
- package/dist/transform/server-fns.cjs +114 -2
- package/dist/transform/server-fns.d.cts +12 -0
- package/dist/transform/server-fns.mjs +1155 -11
- package/dist/transform/source-locations.cjs +330 -0
- package/dist/transform/source-locations.d.cts +43 -0
- package/dist/transform/source-locations.d.ts +44 -0
- package/dist/transform/source-locations.d.ts.map +1 -0
- package/dist/transform/source-locations.js +238 -0
- package/dist/transform/source-locations.mjs +307 -0
- package/dist/transform/templates.cjs +2701 -7
- package/dist/transform/templates.d.cts +69 -0
- package/dist/transform/templates.d.ts +12 -4
- package/dist/transform/templates.d.ts.map +1 -1
- package/dist/transform/templates.js +72 -7
- package/dist/transform/templates.mjs +3743 -16
- package/dist/transform-BT4MMASR.mjs +893 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +6 -5
- package/dist/babel-4JUDAR2G.mjs +0 -1
- package/dist/chunk-3SAEGOMQ.mjs +0 -1
- package/dist/chunk-IBRM4W7I.mjs +0 -10
- package/dist/chunk-OHHZCYIQ.mjs +0 -1
- package/dist/chunk-PVR2SN3B.mjs +0 -1
- package/dist/chunk-QUIYULS2.mjs +0 -1
- package/dist/chunk-YR3SAEO7.mjs +0 -1
- package/dist/server-fns-6QM243HC.mjs +0 -2
- package/dist/server-functions-E3LKCZ4R.mjs +0 -1
- package/dist/transform-5WC4FWJE.mjs +0 -8
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import MagicString from 'magic-string';
|
|
2
|
+
import { type CompileTemplateOptions } from '../lower/compile-template.cjs';
|
|
3
|
+
import type { IRLoadStrategy } from '../ir/nodes.cjs';
|
|
4
|
+
import { type PropsDiagnostic } from './props.cjs';
|
|
5
|
+
import { type IntrinsicDiagnostic } from './intrinsics.cjs';
|
|
6
|
+
export interface TransformOptions extends CompileTemplateOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Which authoring syntaxes to compile. Both lower to the same IR, so this is
|
|
9
|
+
* about which source forms are touched, not about output.
|
|
10
|
+
* @default 'both'
|
|
11
|
+
*/
|
|
12
|
+
format?: 'jsx' | 'lit' | 'both';
|
|
13
|
+
/** Tag marking a template for compilation. @default 'html' */
|
|
14
|
+
litTag?: string;
|
|
15
|
+
/** Module the emitted runtime symbols are imported from. @default '@fluixi/dom' */
|
|
16
|
+
runtimeModule?: string;
|
|
17
|
+
/** Where reactive primitives come from. @default '@fluixi/reactive/signal' */
|
|
18
|
+
reactiveModule?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Rewrite a component's destructured props into property reads, so
|
|
21
|
+
* `function Card({ title })` keeps updating instead of reading `title` once.
|
|
22
|
+
* The edits go into the same string as the template edits, so the map still points
|
|
23
|
+
* at what the author wrote.
|
|
24
|
+
* @default true
|
|
25
|
+
*/
|
|
26
|
+
propsDestructure?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Record where each reactive primitive was created, so the devtools graph can say where a
|
|
29
|
+
* node comes from. Development tooling: leave it off for production, which then carries
|
|
30
|
+
* none of it.
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
33
|
+
sourceLocations?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Trim this prefix off the file name a source mark records, so a location reads
|
|
36
|
+
* `src/app.tsx:5:16` rather than an absolute path that means nothing to whoever opens it.
|
|
37
|
+
*/
|
|
38
|
+
sourceRoot?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Compile the `$` reactive intrinsics — `$signal`, `$memo`, `$effect`, `$store` — into
|
|
41
|
+
* the runtime calls they stand for, importing what they need.
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
intrinsics?: boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface UnresolvedDiagnostic {
|
|
47
|
+
/** The tag nothing supplies. */
|
|
48
|
+
name: string;
|
|
49
|
+
message: string;
|
|
50
|
+
}
|
|
51
|
+
export interface LoadDiagnostic {
|
|
52
|
+
/** The component the directive was written on. */
|
|
53
|
+
name: string;
|
|
54
|
+
strategy: IRLoadStrategy;
|
|
55
|
+
message: string;
|
|
56
|
+
}
|
|
57
|
+
export interface TransformResult {
|
|
58
|
+
code: string;
|
|
59
|
+
map: ReturnType<MagicString['generateMap']>;
|
|
60
|
+
/** Props patterns the rewrite refused, when `propsDestructure` is on. */
|
|
61
|
+
propsDiagnostics?: PropsDiagnostic[];
|
|
62
|
+
/** `$` names the module bound itself, so the intrinsic did not fire. */
|
|
63
|
+
intrinsicDiagnostics?: IntrinsicDiagnostic[];
|
|
64
|
+
/** `load:` directives that could not take effect, and why. */
|
|
65
|
+
loadDiagnostics?: LoadDiagnostic[];
|
|
66
|
+
/** Capitalised tags nothing supplies — they compile to an undefined reference. */
|
|
67
|
+
unresolvedDiagnostics?: UnresolvedDiagnostic[];
|
|
68
|
+
}
|
|
69
|
+
export declare function transformTemplates(code: string, id: string, options?: TransformOptions): TransformResult | null;
|
|
@@ -24,6 +24,18 @@ export interface TransformOptions extends CompileTemplateOptions {
|
|
|
24
24
|
* @default true
|
|
25
25
|
*/
|
|
26
26
|
propsDestructure?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Record where each reactive primitive was created, so the devtools graph can say where a
|
|
29
|
+
* node comes from. Development tooling: leave it off for production, which then carries
|
|
30
|
+
* none of it.
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
33
|
+
sourceLocations?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Trim this prefix off the file name a source mark records, so a location reads
|
|
36
|
+
* `src/app.tsx:5:16` rather than an absolute path that means nothing to whoever opens it.
|
|
37
|
+
*/
|
|
38
|
+
sourceRoot?: string;
|
|
27
39
|
/**
|
|
28
40
|
* Compile the `$` reactive intrinsics — `$signal`, `$memo`, `$effect`, `$store` — into
|
|
29
41
|
* the runtime calls they stand for, importing what they need.
|
|
@@ -54,9 +66,5 @@ export interface TransformResult {
|
|
|
54
66
|
/** Capitalised tags nothing supplies — they compile to an undefined reference. */
|
|
55
67
|
unresolvedDiagnostics?: UnresolvedDiagnostic[];
|
|
56
68
|
}
|
|
57
|
-
/**
|
|
58
|
-
* Compile every template in `code`. Returns null when the module has none, so a
|
|
59
|
-
* bundler can skip the file untouched.
|
|
60
|
-
*/
|
|
61
69
|
export declare function transformTemplates(code: string, id: string, options?: TransformOptions): TransformResult | null;
|
|
62
70
|
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/transform/templates.ts"],"names":[],"mappings":"AASA,OAAO,WAAW,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAiB,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAG1F,OAAO,KAAK,EAAqB,cAAc,EAAU,MAAM,gBAAgB,CAAC;AAWhF,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAA2C,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/transform/templates.ts"],"names":[],"mappings":"AASA,OAAO,WAAW,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAiB,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAG1F,OAAO,KAAK,EAAqB,cAAc,EAAU,MAAM,gBAAgB,CAAC;AAWhF,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAA2C,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAoBpG,MAAM,WAAW,gBAAiB,SAAQ,sBAAsB;IAC9D;;;;OAIG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAChC,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC;IAC5C,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,wEAAwE;IACxE,oBAAoB,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAC7C,8DAA8D;IAC9D,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,kFAAkF;IAClF,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;CAChD;AAwTD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,gBAAqB,GAC7B,eAAe,GAAG,IAAI,CAiNxB"}
|
|
@@ -21,6 +21,7 @@ import { imperativeBackend } from '../codegen/backends/imperative.js';
|
|
|
21
21
|
import { moduleBindings } from './bindings.js';
|
|
22
22
|
import { collectPropsEdits } from './props.js';
|
|
23
23
|
import { collectIntrinsicEdits, intrinsicImports } from './intrinsics.js';
|
|
24
|
+
import { collectSourceEdits, mayHaveReactiveCall } from './source-locations.js';
|
|
24
25
|
import { mayHaveIntrinsic } from '../analyze/intrinsics.js';
|
|
25
26
|
import { declaredNames } from '../analyze/reactive-bindings.js';
|
|
26
27
|
import { DOM_CONTROL_FLOW, CORE_CONTROL_FLOW, ROUTER_COMPONENTS } from '../resolve/builtins.js';
|
|
@@ -73,7 +74,15 @@ function isTemplateTag(node, litTag) {
|
|
|
73
74
|
}
|
|
74
75
|
/** The edits in `list` that no other edit in `list` contains. */
|
|
75
76
|
function outermost(list) {
|
|
76
|
-
return list.filter((e) => !list.some((o) => o !== e &&
|
|
77
|
+
return list.filter((e) => !list.some((o) => o !== e &&
|
|
78
|
+
o.start <= e.start &&
|
|
79
|
+
o.end >= e.end &&
|
|
80
|
+
o.end - o.start > e.end - e.start &&
|
|
81
|
+
// An insertion at either edge of the container sits beside it, not inside it, so
|
|
82
|
+
// it is not something the container's code already folded in. A statement can
|
|
83
|
+
// start where its callee starts (`$effect(…)`) and a declarator can end where its
|
|
84
|
+
// JSX ends (`const Row = () => <b/>`).
|
|
85
|
+
!(e.start === e.end && (e.start === o.start || e.start === o.end))));
|
|
77
86
|
}
|
|
78
87
|
/**
|
|
79
88
|
* Apply edits to a slice of the source.
|
|
@@ -91,10 +100,14 @@ function slice(code, start, end, edits) {
|
|
|
91
100
|
return out;
|
|
92
101
|
}
|
|
93
102
|
/** Describe one `${…}` for the lowering, substituting any template already compiled inside it. */
|
|
94
|
-
function bindHole(code, expr, edits) {
|
|
103
|
+
function bindHole(code, expr, edits, keepPosition = false) {
|
|
104
|
+
const at = keepPosition ? expr.loc?.start : undefined;
|
|
95
105
|
const hole = {
|
|
96
106
|
code: slice(code, expr.start, expr.end, edits),
|
|
97
107
|
reactive: isReactiveShape(shapeOf(expr)),
|
|
108
|
+
// Where the `${…}` is, so a binding made from it can say so. The source map cannot:
|
|
109
|
+
// the whole template is one overwrite. Only when source locations were asked for.
|
|
110
|
+
...(at ? { at: { line: at.line, column: at.column } } : {}),
|
|
98
111
|
};
|
|
99
112
|
if (expr.type === 'ArrowFunctionExpression' && expr.body?.type !== 'BlockStatement') {
|
|
100
113
|
hole.arrow = {
|
|
@@ -232,6 +245,30 @@ function strategyLiteral(s) {
|
|
|
232
245
|
parts.push(`query: ${JSON.stringify(s.query)}`);
|
|
233
246
|
return `{ ${parts.join(', ')} }`;
|
|
234
247
|
}
|
|
248
|
+
/**
|
|
249
|
+
* Offset → line and column, built once per module.
|
|
250
|
+
*
|
|
251
|
+
* The parser reports offsets into this file, since the pieces it is given carry the
|
|
252
|
+
* positions Babel recorded for the quasis.
|
|
253
|
+
*/
|
|
254
|
+
function positionsIn(code) {
|
|
255
|
+
const starts = [0];
|
|
256
|
+
for (let i = 0; i < code.length; i++)
|
|
257
|
+
if (code.charCodeAt(i) === 10)
|
|
258
|
+
starts.push(i + 1);
|
|
259
|
+
return (offset) => {
|
|
260
|
+
let low = 0;
|
|
261
|
+
let high = starts.length - 1;
|
|
262
|
+
while (low < high) {
|
|
263
|
+
const mid = (low + high + 1) >> 1;
|
|
264
|
+
if (starts[mid] <= offset)
|
|
265
|
+
low = mid;
|
|
266
|
+
else
|
|
267
|
+
high = mid - 1;
|
|
268
|
+
}
|
|
269
|
+
return { line: low + 1, column: offset - starts[low] };
|
|
270
|
+
};
|
|
271
|
+
}
|
|
235
272
|
/** Quasis and holes as position-carrying parser pieces. */
|
|
236
273
|
function toPieces(node) {
|
|
237
274
|
const pieces = [];
|
|
@@ -248,6 +285,13 @@ function toPieces(node) {
|
|
|
248
285
|
* Compile every template in `code`. Returns null when the module has none, so a
|
|
249
286
|
* bundler can skip the file untouched.
|
|
250
287
|
*/
|
|
288
|
+
/** No path module here: this runs in the browser as well as in a bundler. */
|
|
289
|
+
function relativeToRoot(id, root) {
|
|
290
|
+
if (!root)
|
|
291
|
+
return id;
|
|
292
|
+
const base = root.endsWith('/') ? root : `${root}/`;
|
|
293
|
+
return id.startsWith(base) ? id.slice(base.length) : id;
|
|
294
|
+
}
|
|
251
295
|
export function transformTemplates(code, id, options = {}) {
|
|
252
296
|
const litTag = options.litTag ?? 'html';
|
|
253
297
|
const format = options.format ?? 'both';
|
|
@@ -257,7 +301,13 @@ export function transformTemplates(code, id, options = {}) {
|
|
|
257
301
|
// A module can be nothing but `$signal` calls, so the skip check has to look for those
|
|
258
302
|
// too or the file is never parsed.
|
|
259
303
|
const wantsIntrinsics = options.intrinsics !== false && mayHaveIntrinsic(code);
|
|
260
|
-
|
|
304
|
+
// A module can be nothing but reactive calls and still need marking, so the skip check
|
|
305
|
+
// has to look for those too when source locations are wanted.
|
|
306
|
+
const wantsSources = options.sourceLocations === true && mayHaveReactiveCall(code);
|
|
307
|
+
// What a mark calls this file. The declaration marks and the usage marks are read back by
|
|
308
|
+
// name, so both passes have to spell it the same way.
|
|
309
|
+
const sourceName = relativeToRoot(id, options.sourceRoot);
|
|
310
|
+
if (!mayHaveTemplate && !(wantsJsx && code.includes('<')) && !wantsIntrinsics && !wantsSources)
|
|
261
311
|
return null;
|
|
262
312
|
const ast = parse(code, {
|
|
263
313
|
sourceType: 'module',
|
|
@@ -281,10 +331,18 @@ export function transformTemplates(code, id, options = {}) {
|
|
|
281
331
|
const intrinsics = options.intrinsics === false
|
|
282
332
|
? { edits: [], diagnostics: [], imports: new Map() }
|
|
283
333
|
: collectIntrinsicEdits(ast.program);
|
|
334
|
+
// Where each reactive primitive was created, for the devtools graph. Off unless asked
|
|
335
|
+
// for: it is development tooling, and production should carry none of it.
|
|
336
|
+
// `wantsSources` only decides whether a module with nothing else in it is worth parsing.
|
|
337
|
+
// Past that point the ast exists, and a component declaration is worth marking too.
|
|
338
|
+
const sources = options.sourceLocations === true
|
|
339
|
+
? collectSourceEdits(ast.program, sourceName)
|
|
340
|
+
: { edits: [], marked: 0 };
|
|
284
341
|
// Nothing to emit still returns a result when there's something to say — a shadowed
|
|
285
342
|
// intrinsic is a diagnostic even though the code comes back untouched.
|
|
286
343
|
const silent = found.length === 0 &&
|
|
287
344
|
props.edits.length === 0 &&
|
|
345
|
+
sources.edits.length === 0 &&
|
|
288
346
|
intrinsics.edits.length === 0 &&
|
|
289
347
|
intrinsics.diagnostics.length === 0 &&
|
|
290
348
|
props.diagnostics.length === 0;
|
|
@@ -302,20 +360,26 @@ export function transformTemplates(code, id, options = {}) {
|
|
|
302
360
|
declared: declaredNames(ast.program),
|
|
303
361
|
};
|
|
304
362
|
const hoisted = new Map();
|
|
305
|
-
const edits = [...props.edits, ...intrinsics.edits];
|
|
363
|
+
const edits = [...props.edits, ...intrinsics.edits, ...sources.edits];
|
|
306
364
|
for (const node of found) {
|
|
307
365
|
// A root inside another root's hole is emitted without partial templates,
|
|
308
366
|
// matching what the plugin does for nested emits. Marker layout has to agree
|
|
309
367
|
// between server and client, so this is not the place to change it.
|
|
310
368
|
const nested = found.some((o) => o !== node && o.start <= node.start && o.end >= node.end && o.end - o.start > node.end - node.start);
|
|
311
369
|
if (isJsx(node)) {
|
|
312
|
-
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, nested, used, needs, hoisted, options) });
|
|
370
|
+
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceName) });
|
|
313
371
|
continue;
|
|
314
372
|
}
|
|
315
|
-
const holes = node.quasi.expressions.map((e) => bindHole(code, e, edits));
|
|
373
|
+
const holes = node.quasi.expressions.map((e) => bindHole(code, e, edits, options.sourceLocations === true));
|
|
316
374
|
const result = compilePieces(toPieces(node), holes, {
|
|
317
375
|
...options,
|
|
318
376
|
hoistTemplates: true,
|
|
377
|
+
// A tag inside a template gets the same mark a JSX tag does. Without one, the nodes it
|
|
378
|
+
// makes are the only ones in the module carrying no mark, and they take whichever was
|
|
379
|
+
// left behind by the last declaration that did.
|
|
380
|
+
...(options.sourceLocations === true
|
|
381
|
+
? { sourceFile: sourceName, positionAt: positionsIn(code) }
|
|
382
|
+
: {}),
|
|
319
383
|
// Same defaults as the plugin, so moving a build over is not a rendering change.
|
|
320
384
|
templateClone: options.templateClone ?? true,
|
|
321
385
|
partialTemplates: nested ? false : options.partialTemplates ?? true,
|
|
@@ -417,10 +481,11 @@ export function transformTemplates(code, id, options = {}) {
|
|
|
417
481
|
* with anything already compiled inside them folded in, so nested JSX and nested
|
|
418
482
|
* `` html`` `` both come along for free.
|
|
419
483
|
*/
|
|
420
|
-
function compileJsx(code, node, edits, nested, used, needs, hoisted, options) {
|
|
484
|
+
function compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceFile) {
|
|
421
485
|
const ir = buildJsxIR(node, {
|
|
422
486
|
code: (n) => slice(code, n.start, n.end, edits),
|
|
423
487
|
used,
|
|
488
|
+
...(options.sourceLocations === true && sourceFile ? { sourceFile } : {}),
|
|
424
489
|
});
|
|
425
490
|
analyzeStatic(ir);
|
|
426
491
|
const report = resolveComponentSources(ir, {
|