@reckona/mreact-compiler 0.0.67 → 0.0.69
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/compiler-module-context.js.map +1 -1
- package/dist/diagnostics.js.map +1 -1
- package/dist/emit-client.js.map +1 -1
- package/dist/emit-compat.js.map +1 -1
- package/dist/emit-escape-helper.js.map +1 -1
- package/dist/emit-server-shared.js.map +1 -1
- package/dist/emit-server-stream.js.map +1 -1
- package/dist/emit-server.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal.js.map +1 -1
- package/dist/ir.js.map +1 -1
- package/dist/oxc-analysis-types.js.map +1 -1
- package/dist/oxc-await-analysis.js.map +1 -1
- package/dist/oxc-await-ids.js.map +1 -1
- package/dist/oxc-await-validation.js.map +1 -1
- package/dist/oxc-bindings.js.map +1 -1
- package/dist/oxc-body-lowering.js.map +1 -1
- package/dist/oxc-child-analysis.js.map +1 -1
- package/dist/oxc-code-utils.js.map +1 -1
- package/dist/oxc-component-detection.js.map +1 -1
- package/dist/oxc-component-props.js.map +1 -1
- package/dist/oxc-component-references.js.map +1 -1
- package/dist/oxc-dom-lowering.js.map +1 -1
- package/dist/oxc-expression-utils.js.map +1 -1
- package/dist/oxc-jsx-attributes.js.map +1 -1
- package/dist/oxc-jsx-text.js.map +1 -1
- package/dist/oxc-nested-lowering.js.map +1 -1
- package/dist/oxc-node-utils.js.map +1 -1
- package/dist/oxc-raw-jsx.js.map +1 -1
- package/dist/oxc-render-values.d.ts +2 -1
- package/dist/oxc-render-values.d.ts.map +1 -1
- package/dist/oxc-render-values.js +172 -3
- package/dist/oxc-render-values.js.map +1 -1
- package/dist/oxc-runtime-emit.js.map +1 -1
- package/dist/oxc-transform.js.map +1 -1
- package/dist/oxc.d.ts.map +1 -1
- package/dist/oxc.js +10 -9
- package/dist/oxc.js.map +1 -1
- package/dist/transform.js.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/src/oxc-render-values.ts +261 -8
- package/src/oxc.ts +14 -1
package/src/oxc-render-values.ts
CHANGED
|
@@ -51,6 +51,7 @@ export function collectOxcBodyJsxBindingNames(statements: readonly unknown[]): S
|
|
|
51
51
|
export function collectOxcReactiveReadAliases(
|
|
52
52
|
code: string,
|
|
53
53
|
statements: readonly unknown[],
|
|
54
|
+
reactiveDerivedFunctions: ReadonlySet<string> = new Set(),
|
|
54
55
|
): Map<string, string> {
|
|
55
56
|
const aliases = new Map<string, string>();
|
|
56
57
|
|
|
@@ -67,7 +68,12 @@ export function collectOxcReactiveReadAliases(
|
|
|
67
68
|
const initializer = unwrapOxcParentheses(readObject(declaration.init));
|
|
68
69
|
|
|
69
70
|
if (typeof id.name !== "string") continue;
|
|
70
|
-
if (
|
|
71
|
+
if (
|
|
72
|
+
!isOxcReactiveAliasExpression(initializer) &&
|
|
73
|
+
!isOxcReactiveDerivedAliasExpression(initializer, reactiveDerivedFunctions)
|
|
74
|
+
) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
71
77
|
|
|
72
78
|
aliases.set(id.name, readSource(code, initializer));
|
|
73
79
|
}
|
|
@@ -76,6 +82,45 @@ export function collectOxcReactiveReadAliases(
|
|
|
76
82
|
return aliases;
|
|
77
83
|
}
|
|
78
84
|
|
|
85
|
+
export function collectOxcReactiveDerivedFunctionNames(
|
|
86
|
+
statements: readonly unknown[],
|
|
87
|
+
): Set<string> {
|
|
88
|
+
const names = new Set<string>();
|
|
89
|
+
|
|
90
|
+
for (const statementValue of statements) {
|
|
91
|
+
const statement = readObject(statementValue);
|
|
92
|
+
|
|
93
|
+
if (statement.type === "FunctionDeclaration") {
|
|
94
|
+
const id = readObject(statement.id);
|
|
95
|
+
if (typeof id.name === "string" && isOxcReactiveDerivedFunction(statement)) {
|
|
96
|
+
names.add(id.name);
|
|
97
|
+
}
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (statement.type !== "VariableDeclaration" || statement.kind !== "const") {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
for (const declarationValue of readArray(statement.declarations)) {
|
|
106
|
+
const declaration = readObject(declarationValue);
|
|
107
|
+
const id = readObject(declaration.id);
|
|
108
|
+
const initializer = unwrapOxcParentheses(readObject(declaration.init));
|
|
109
|
+
|
|
110
|
+
if (
|
|
111
|
+
typeof id.name === "string" &&
|
|
112
|
+
(initializer.type === "FunctionExpression" ||
|
|
113
|
+
initializer.type === "ArrowFunctionExpression") &&
|
|
114
|
+
isOxcReactiveDerivedFunction(initializer)
|
|
115
|
+
) {
|
|
116
|
+
names.add(id.name);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return names;
|
|
122
|
+
}
|
|
123
|
+
|
|
79
124
|
export function rewriteOxcReactiveAliasExpressionCode(
|
|
80
125
|
code: string,
|
|
81
126
|
expression: Record<string, unknown>,
|
|
@@ -93,7 +138,14 @@ export function rewriteOxcReactiveAliasExpressionCode(
|
|
|
93
138
|
}
|
|
94
139
|
|
|
95
140
|
const replacements: ReactiveAliasReplacement[] = [];
|
|
96
|
-
collectOxcReactiveAliasReplacements(
|
|
141
|
+
collectOxcReactiveAliasReplacements(
|
|
142
|
+
expression,
|
|
143
|
+
undefined,
|
|
144
|
+
undefined,
|
|
145
|
+
aliases,
|
|
146
|
+
new Set(),
|
|
147
|
+
replacements,
|
|
148
|
+
);
|
|
97
149
|
|
|
98
150
|
if (replacements.length === 0) {
|
|
99
151
|
return undefined;
|
|
@@ -147,7 +199,9 @@ function collectOxcReactiveAliasReplacements(
|
|
|
147
199
|
replacements.push({
|
|
148
200
|
end,
|
|
149
201
|
start,
|
|
150
|
-
text: isOxcShorthandPropertyValue(object, parent)
|
|
202
|
+
text: isOxcShorthandPropertyValue(object, parent)
|
|
203
|
+
? `${object.name}: (${replacement})`
|
|
204
|
+
: `(${replacement})`,
|
|
151
205
|
});
|
|
152
206
|
}
|
|
153
207
|
return;
|
|
@@ -194,7 +248,14 @@ function collectOxcReactiveAliasReplacements(
|
|
|
194
248
|
|
|
195
249
|
if (Array.isArray(value)) {
|
|
196
250
|
for (const item of value) {
|
|
197
|
-
collectOxcReactiveAliasReplacements(
|
|
251
|
+
collectOxcReactiveAliasReplacements(
|
|
252
|
+
item,
|
|
253
|
+
object,
|
|
254
|
+
key,
|
|
255
|
+
aliases,
|
|
256
|
+
childShadowed,
|
|
257
|
+
replacements,
|
|
258
|
+
);
|
|
198
259
|
}
|
|
199
260
|
continue;
|
|
200
261
|
}
|
|
@@ -285,10 +346,7 @@ function isOxcFunctionNode(node: Record<string, unknown>): boolean {
|
|
|
285
346
|
);
|
|
286
347
|
}
|
|
287
348
|
|
|
288
|
-
function addOxcBlockBindingNames(
|
|
289
|
-
node: unknown,
|
|
290
|
-
shadowed: Set<string>,
|
|
291
|
-
): ReadonlySet<string> {
|
|
349
|
+
function addOxcBlockBindingNames(node: unknown, shadowed: Set<string>): ReadonlySet<string> {
|
|
292
350
|
const object = readObject(node);
|
|
293
351
|
const body = readArray(object.body);
|
|
294
352
|
|
|
@@ -350,6 +408,64 @@ function collectOxcBindingNames(node: unknown, names: Set<string>): void {
|
|
|
350
408
|
}
|
|
351
409
|
}
|
|
352
410
|
|
|
411
|
+
function collectOxcFunctionLocalBindings(
|
|
412
|
+
functionNode: Record<string, unknown>,
|
|
413
|
+
names: Set<string>,
|
|
414
|
+
): void {
|
|
415
|
+
collectOxcBindingNames(functionNode.id, names);
|
|
416
|
+
|
|
417
|
+
for (const parameter of readArray(functionNode.params)) {
|
|
418
|
+
collectOxcBindingNames(parameter, names);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
collectOxcLocalBindingsFromNode(readObject(functionNode.body), names);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function collectOxcLocalBindingsFromNode(node: unknown, names: Set<string>): void {
|
|
425
|
+
const object = readObject(node);
|
|
426
|
+
|
|
427
|
+
if (typeof object.type !== "string" || object.type.startsWith("TS")) {
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
if (object.type === "VariableDeclaration") {
|
|
432
|
+
for (const declaration of readArray(object.declarations)) {
|
|
433
|
+
collectOxcBindingNames(readObject(declaration).id, names);
|
|
434
|
+
}
|
|
435
|
+
} else if (object.type === "FunctionDeclaration" || object.type === "ClassDeclaration") {
|
|
436
|
+
collectOxcBindingNames(object.id, names);
|
|
437
|
+
return;
|
|
438
|
+
} else if (object.type === "ForOfStatement" || object.type === "ForInStatement") {
|
|
439
|
+
const left = readObject(object.left);
|
|
440
|
+
const declarations = readArray(left.declarations);
|
|
441
|
+
collectOxcBindingNames(
|
|
442
|
+
declarations.length > 0 ? readObject(declarations[0]).id : object.left,
|
|
443
|
+
names,
|
|
444
|
+
);
|
|
445
|
+
} else if (object.type === "ForStatement") {
|
|
446
|
+
collectOxcLocalBindingsFromNode(object.init, names);
|
|
447
|
+
} else if (isOxcFunctionNode(object)) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
for (const [key, value] of Object.entries(object)) {
|
|
452
|
+
if (key === "type" || key === "start" || key === "end" || key === "loc") {
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if (Array.isArray(value)) {
|
|
457
|
+
for (const item of value) {
|
|
458
|
+
collectOxcLocalBindingsFromNode(item, names);
|
|
459
|
+
}
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (typeof value === "object" && value !== null) {
|
|
464
|
+
collectOxcLocalBindingsFromNode(value, names);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
353
469
|
function readNumber(value: unknown): number | undefined {
|
|
354
470
|
return typeof value === "number" ? value : undefined;
|
|
355
471
|
}
|
|
@@ -479,6 +595,143 @@ function isOxcReactiveAliasExpression(expression: Record<string, unknown>): bool
|
|
|
479
595
|
return state.safe && state.reactive;
|
|
480
596
|
}
|
|
481
597
|
|
|
598
|
+
function isOxcReactiveDerivedAliasExpression(
|
|
599
|
+
expression: Record<string, unknown>,
|
|
600
|
+
reactiveDerivedFunctions: ReadonlySet<string>,
|
|
601
|
+
): boolean {
|
|
602
|
+
if (reactiveDerivedFunctions.size === 0) {
|
|
603
|
+
return false;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
const unwrappedExpression = unwrapOxcParentheses(expression);
|
|
607
|
+
|
|
608
|
+
if (unwrappedExpression.type !== "CallExpression") {
|
|
609
|
+
return false;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
if (readArray(unwrappedExpression.arguments).length !== 0) {
|
|
613
|
+
return false;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
const callee = readObject(unwrappedExpression.callee);
|
|
617
|
+
|
|
618
|
+
return (
|
|
619
|
+
callee.type === "Identifier" &&
|
|
620
|
+
typeof callee.name === "string" &&
|
|
621
|
+
reactiveDerivedFunctions.has(callee.name)
|
|
622
|
+
);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
function isOxcReactiveDerivedFunction(functionNode: Record<string, unknown>): boolean {
|
|
626
|
+
if (readArray(functionNode.params).length !== 0) {
|
|
627
|
+
return false;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
const localBindings = new Set<string>();
|
|
631
|
+
collectOxcFunctionLocalBindings(functionNode, localBindings);
|
|
632
|
+
const usage = analyzeOxcReactiveDerivedFunctionUsage(
|
|
633
|
+
readObject(functionNode.body),
|
|
634
|
+
localBindings,
|
|
635
|
+
);
|
|
636
|
+
|
|
637
|
+
return usage.reactive && usage.safe;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
function analyzeOxcReactiveDerivedFunctionUsage(
|
|
641
|
+
node: unknown,
|
|
642
|
+
localBindings: ReadonlySet<string>,
|
|
643
|
+
): ReactiveAliasExpressionState {
|
|
644
|
+
const object = readObject(node);
|
|
645
|
+
|
|
646
|
+
if (typeof object.type !== "string" || object.type.startsWith("TS")) {
|
|
647
|
+
return { reactive: false, safe: true };
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
if (isOxcFunctionNode(object)) {
|
|
651
|
+
return { reactive: false, safe: true };
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
if (object.type === "CallExpression") {
|
|
655
|
+
const callee = readObject(object.callee);
|
|
656
|
+
const member = callee.type === "MemberExpression" ? callee : undefined;
|
|
657
|
+
const property = readObject(member?.property);
|
|
658
|
+
const owner = readObject(member?.object);
|
|
659
|
+
const propertyName =
|
|
660
|
+
member?.computed === true
|
|
661
|
+
? undefined
|
|
662
|
+
: typeof property.name === "string"
|
|
663
|
+
? property.name
|
|
664
|
+
: undefined;
|
|
665
|
+
const ownerName = owner.type === "Identifier" ? owner.name : undefined;
|
|
666
|
+
|
|
667
|
+
if (propertyName === "get" && typeof ownerName === "string" && !localBindings.has(ownerName)) {
|
|
668
|
+
return mergeReactiveAliasStates([
|
|
669
|
+
{ reactive: true, safe: true },
|
|
670
|
+
...readArray(object.arguments).map((argument) =>
|
|
671
|
+
analyzeOxcReactiveDerivedFunctionUsage(argument, localBindings),
|
|
672
|
+
),
|
|
673
|
+
]);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
if (
|
|
677
|
+
propertyName !== undefined &&
|
|
678
|
+
typeof ownerName === "string" &&
|
|
679
|
+
!localBindings.has(ownerName) &&
|
|
680
|
+
isLikelyMutatingMethodName(propertyName)
|
|
681
|
+
) {
|
|
682
|
+
return { reactive: false, safe: false };
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
const states: ReactiveAliasExpressionState[] = [];
|
|
687
|
+
|
|
688
|
+
for (const [key, value] of Object.entries(object)) {
|
|
689
|
+
if (key === "type" || key === "start" || key === "end" || key === "loc") {
|
|
690
|
+
continue;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
if (Array.isArray(value)) {
|
|
694
|
+
states.push(
|
|
695
|
+
...value.map((item) => analyzeOxcReactiveDerivedFunctionUsage(item, localBindings)),
|
|
696
|
+
);
|
|
697
|
+
continue;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
if (typeof value === "object" && value !== null) {
|
|
701
|
+
states.push(analyzeOxcReactiveDerivedFunctionUsage(value, localBindings));
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
return mergeReactiveAliasStates(states);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
function mergeReactiveAliasStates(
|
|
709
|
+
states: readonly ReactiveAliasExpressionState[],
|
|
710
|
+
): ReactiveAliasExpressionState {
|
|
711
|
+
return states.reduce<ReactiveAliasExpressionState>(
|
|
712
|
+
(merged, state) => ({
|
|
713
|
+
reactive: merged.reactive || state.reactive,
|
|
714
|
+
safe: merged.safe && state.safe,
|
|
715
|
+
}),
|
|
716
|
+
{ reactive: false, safe: true },
|
|
717
|
+
);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
function isLikelyMutatingMethodName(name: string): boolean {
|
|
721
|
+
return (
|
|
722
|
+
name === "set" ||
|
|
723
|
+
name === "delete" ||
|
|
724
|
+
name === "clear" ||
|
|
725
|
+
name === "push" ||
|
|
726
|
+
name === "pop" ||
|
|
727
|
+
name === "shift" ||
|
|
728
|
+
name === "unshift" ||
|
|
729
|
+
name === "splice" ||
|
|
730
|
+
name === "sort" ||
|
|
731
|
+
name === "reverse"
|
|
732
|
+
);
|
|
733
|
+
}
|
|
734
|
+
|
|
482
735
|
function analyzeOxcReactiveAliasExpression(
|
|
483
736
|
expression: Record<string, unknown>,
|
|
484
737
|
): ReactiveAliasExpressionState {
|
package/src/oxc.ts
CHANGED
|
@@ -81,6 +81,7 @@ import {
|
|
|
81
81
|
} from "./oxc-expression-utils.js";
|
|
82
82
|
import {
|
|
83
83
|
collectOxcBodyJsxBindingNames,
|
|
84
|
+
collectOxcReactiveDerivedFunctionNames,
|
|
84
85
|
collectOxcReactiveReadAliases,
|
|
85
86
|
containsOxcJsxSyntax,
|
|
86
87
|
markOxcRenderValueExpressions,
|
|
@@ -237,6 +238,7 @@ function analyzeOxcToIr(
|
|
|
237
238
|
const compatRuntimeImports = collectOxcCompatRuntimeImportComponents(program);
|
|
238
239
|
const bodyLowerers = createOxcBodyLowerers(compatRuntimeImports);
|
|
239
240
|
const moduleRenderValueBindings = collectOxcBodyJsxBindingNames(body);
|
|
241
|
+
const reactiveDerivedFunctionNames = collectOxcReactiveDerivedFunctionNames(body);
|
|
240
242
|
|
|
241
243
|
for (const statement of body) {
|
|
242
244
|
const object = readObject(statement);
|
|
@@ -324,6 +326,7 @@ function analyzeOxcToIr(
|
|
|
324
326
|
options?.serverOutput,
|
|
325
327
|
componentCallNames,
|
|
326
328
|
bodyLowerers,
|
|
329
|
+
reactiveDerivedFunctionNames,
|
|
327
330
|
),
|
|
328
331
|
);
|
|
329
332
|
|
|
@@ -387,6 +390,7 @@ function analyzeOxcComponent(
|
|
|
387
390
|
serverOutput: AnalyzeModuleOptions["serverOutput"],
|
|
388
391
|
componentCallNames: Set<string> | undefined,
|
|
389
392
|
bodyLowerers: OxcBodyLowerers,
|
|
393
|
+
reactiveDerivedFunctionNames: ReadonlySet<string>,
|
|
390
394
|
): ComponentIr[] {
|
|
391
395
|
const object = readObject(statement);
|
|
392
396
|
|
|
@@ -414,6 +418,7 @@ function analyzeOxcComponent(
|
|
|
414
418
|
serverOutput,
|
|
415
419
|
componentCallNames,
|
|
416
420
|
bodyLowerers,
|
|
421
|
+
reactiveDerivedFunctionNames,
|
|
417
422
|
true,
|
|
418
423
|
),
|
|
419
424
|
];
|
|
@@ -442,6 +447,7 @@ function analyzeOxcComponent(
|
|
|
442
447
|
serverOutput,
|
|
443
448
|
componentCallNames,
|
|
444
449
|
bodyLowerers,
|
|
450
|
+
reactiveDerivedFunctionNames,
|
|
445
451
|
),
|
|
446
452
|
exported: false,
|
|
447
453
|
},
|
|
@@ -472,6 +478,7 @@ function analyzeOxcComponent(
|
|
|
472
478
|
serverOutput,
|
|
473
479
|
componentCallNames,
|
|
474
480
|
bodyLowerers,
|
|
481
|
+
reactiveDerivedFunctionNames,
|
|
475
482
|
),
|
|
476
483
|
];
|
|
477
484
|
}
|
|
@@ -504,6 +511,7 @@ function analyzeOxcComponent(
|
|
|
504
511
|
serverOutput,
|
|
505
512
|
componentCallNames,
|
|
506
513
|
bodyLowerers,
|
|
514
|
+
reactiveDerivedFunctionNames,
|
|
507
515
|
),
|
|
508
516
|
];
|
|
509
517
|
}
|
|
@@ -522,6 +530,7 @@ function analyzeOxcFunctionLikeComponent(
|
|
|
522
530
|
serverOutput: AnalyzeModuleOptions["serverOutput"],
|
|
523
531
|
componentCallNames: Set<string> | undefined,
|
|
524
532
|
bodyLowerers: OxcBodyLowerers,
|
|
533
|
+
reactiveDerivedFunctionNames: ReadonlySet<string>,
|
|
525
534
|
exportDefault = false,
|
|
526
535
|
): ComponentIr {
|
|
527
536
|
const functionBody = readObject(functionLike.body);
|
|
@@ -563,7 +572,11 @@ function analyzeOxcFunctionLikeComponent(
|
|
|
563
572
|
) ?? formatOxcBodyStatement(code, bodyStatement, bodyStatementJsx),
|
|
564
573
|
);
|
|
565
574
|
const componentBodyBindings = collectOxcVariableInitializers(body);
|
|
566
|
-
const reactiveAliasBindings = collectOxcReactiveReadAliases(
|
|
575
|
+
const reactiveAliasBindings = collectOxcReactiveReadAliases(
|
|
576
|
+
code,
|
|
577
|
+
body,
|
|
578
|
+
reactiveDerivedFunctionNames,
|
|
579
|
+
);
|
|
567
580
|
const childAnalysisContext = createOxcChildAnalysisContext(
|
|
568
581
|
componentNames,
|
|
569
582
|
target,
|