babel-plugin-react-compiler 19.0.0-beta-e552027-20250112 → 19.0.0-beta-27714ef-20250124
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/index.js +134 -17
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
@@ -121306,8 +121306,16 @@ addObject(BUILTIN_SHAPES, BuiltInMixedReadonlyId, [
|
|
121306
121306
|
[
|
121307
121307
|
"map",
|
121308
121308
|
addFunction(BUILTIN_SHAPES, [], {
|
121309
|
+
/**
|
121310
|
+
* Note `map`'s arguments are annotated as Effect.ConditionallyMutate as
|
121311
|
+
* calling `<array>.map(fn)` might invoke `fn`, which means replaying its
|
121312
|
+
* effects.
|
121313
|
+
*
|
121314
|
+
* (Note that Effect.Read / Effect.Capture on a function type means
|
121315
|
+
* potential data dependency or aliasing respectively.)
|
121316
|
+
*/
|
121309
121317
|
positionalParams: [],
|
121310
|
-
restParam: "
|
121318
|
+
restParam: "mutate?" /* ConditionallyMutate */,
|
121311
121319
|
returnType: { kind: "Object", shapeId: BuiltInArrayId },
|
121312
121320
|
calleeEffect: "mutate?" /* ConditionallyMutate */,
|
121313
121321
|
returnValueKind: "mutable" /* Mutable */,
|
@@ -121318,7 +121326,7 @@ addObject(BUILTIN_SHAPES, BuiltInMixedReadonlyId, [
|
|
121318
121326
|
"flatMap",
|
121319
121327
|
addFunction(BUILTIN_SHAPES, [], {
|
121320
121328
|
positionalParams: [],
|
121321
|
-
restParam: "
|
121329
|
+
restParam: "mutate?" /* ConditionallyMutate */,
|
121322
121330
|
returnType: { kind: "Object", shapeId: BuiltInArrayId },
|
121323
121331
|
calleeEffect: "mutate?" /* ConditionallyMutate */,
|
121324
121332
|
returnValueKind: "mutable" /* Mutable */,
|
@@ -121329,7 +121337,7 @@ addObject(BUILTIN_SHAPES, BuiltInMixedReadonlyId, [
|
|
121329
121337
|
"filter",
|
121330
121338
|
addFunction(BUILTIN_SHAPES, [], {
|
121331
121339
|
positionalParams: [],
|
121332
|
-
restParam: "
|
121340
|
+
restParam: "mutate?" /* ConditionallyMutate */,
|
121333
121341
|
returnType: { kind: "Object", shapeId: BuiltInArrayId },
|
121334
121342
|
calleeEffect: "mutate?" /* ConditionallyMutate */,
|
121335
121343
|
returnValueKind: "mutable" /* Mutable */,
|
@@ -125468,6 +125476,48 @@ var TYPED_GLOBALS = [
|
|
125468
125476
|
]
|
125469
125477
|
])
|
125470
125478
|
],
|
125479
|
+
[
|
125480
|
+
"performance",
|
125481
|
+
addObject(DEFAULT_SHAPES, "performance", [
|
125482
|
+
// Static methods (TODO)
|
125483
|
+
[
|
125484
|
+
"now",
|
125485
|
+
// Date.now()
|
125486
|
+
addFunction(DEFAULT_SHAPES, [], {
|
125487
|
+
positionalParams: [],
|
125488
|
+
restParam: "read" /* Read */,
|
125489
|
+
returnType: { kind: "Poly" },
|
125490
|
+
// TODO: could be Primitive, but that would change existing compilation
|
125491
|
+
calleeEffect: "read" /* Read */,
|
125492
|
+
returnValueKind: "mutable" /* Mutable */,
|
125493
|
+
// same here
|
125494
|
+
impure: true,
|
125495
|
+
canonicalName: "performance.now"
|
125496
|
+
})
|
125497
|
+
]
|
125498
|
+
])
|
125499
|
+
],
|
125500
|
+
[
|
125501
|
+
"Date",
|
125502
|
+
addObject(DEFAULT_SHAPES, "Date", [
|
125503
|
+
// Static methods (TODO)
|
125504
|
+
[
|
125505
|
+
"now",
|
125506
|
+
// Date.now()
|
125507
|
+
addFunction(DEFAULT_SHAPES, [], {
|
125508
|
+
positionalParams: [],
|
125509
|
+
restParam: "read" /* Read */,
|
125510
|
+
returnType: { kind: "Poly" },
|
125511
|
+
// TODO: could be Primitive, but that would change existing compilation
|
125512
|
+
calleeEffect: "read" /* Read */,
|
125513
|
+
returnValueKind: "mutable" /* Mutable */,
|
125514
|
+
// same here
|
125515
|
+
impure: true,
|
125516
|
+
canonicalName: "Date.now"
|
125517
|
+
})
|
125518
|
+
]
|
125519
|
+
])
|
125520
|
+
],
|
125471
125521
|
[
|
125472
125522
|
"Math",
|
125473
125523
|
addObject(DEFAULT_SHAPES, "Math", [
|
@@ -125535,6 +125585,20 @@ var TYPED_GLOBALS = [
|
|
125535
125585
|
calleeEffect: "read" /* Read */,
|
125536
125586
|
returnValueKind: "primitive" /* Primitive */
|
125537
125587
|
})
|
125588
|
+
],
|
125589
|
+
[
|
125590
|
+
"random",
|
125591
|
+
addFunction(DEFAULT_SHAPES, [], {
|
125592
|
+
positionalParams: [],
|
125593
|
+
restParam: "read" /* Read */,
|
125594
|
+
returnType: { kind: "Poly" },
|
125595
|
+
// TODO: could be Primitive, but that would change existing compilation
|
125596
|
+
calleeEffect: "read" /* Read */,
|
125597
|
+
returnValueKind: "mutable" /* Mutable */,
|
125598
|
+
// same here
|
125599
|
+
impure: true,
|
125600
|
+
canonicalName: "Math.random"
|
125601
|
+
})
|
125538
125602
|
]
|
125539
125603
|
])
|
125540
125604
|
],
|
@@ -126073,7 +126137,9 @@ var FunctionTypeSchema = z.object({
|
|
126073
126137
|
returnType: z.lazy(() => TypeSchema),
|
126074
126138
|
returnValueKind: ValueKindSchema,
|
126075
126139
|
noAlias: z.boolean().nullable().optional(),
|
126076
|
-
mutableOnlyIfOperandsAreMutable: z.boolean().nullable().optional()
|
126140
|
+
mutableOnlyIfOperandsAreMutable: z.boolean().nullable().optional(),
|
126141
|
+
impure: z.boolean().nullable().optional(),
|
126142
|
+
canonicalName: z.string().nullable().optional()
|
126077
126143
|
});
|
126078
126144
|
var HookTypeSchema = z.object({
|
126079
126145
|
kind: z.literal("hook"),
|
@@ -126346,6 +126412,10 @@ var EnvironmentConfigSchema = z.object({
|
|
126346
126412
|
*/
|
126347
126413
|
validateNoCapitalizedCalls: z.nullable(z.array(z.string())).default(null),
|
126348
126414
|
validateBlocklistedImports: z.nullable(z.array(z.string())).default(null),
|
126415
|
+
/**
|
126416
|
+
* Validate against impure functions called during render
|
126417
|
+
*/
|
126418
|
+
validateNoImpureFunctionsInRender: z.boolean().default(false),
|
126349
126419
|
/*
|
126350
126420
|
* When enabled, the compiler assumes that hooks follow the Rules of React:
|
126351
126421
|
* - Hooks may memoize computation based on any of their parameters, thus
|
@@ -133682,7 +133752,7 @@ function codegenInstructionValue(cx, instrValue) {
|
|
133682
133752
|
}
|
133683
133753
|
return value;
|
133684
133754
|
}
|
133685
|
-
var STRING_REQUIRES_EXPR_CONTAINER_PATTERN = /[\u{0000}-\u{001F}\u{007F}\u{0080}-\u{FFFF}]|"
|
133755
|
+
var STRING_REQUIRES_EXPR_CONTAINER_PATTERN = /[\u{0000}-\u{001F}\u{007F}\u{0080}-\u{FFFF}]|"|\\/u;
|
133686
133756
|
function codegenJsxAttribute(cx, attribute) {
|
133687
133757
|
switch (attribute.kind) {
|
133688
133758
|
case "JsxAttribute": {
|
@@ -133727,7 +133797,7 @@ function codegenJsxAttribute(cx, attribute) {
|
|
133727
133797
|
}
|
133728
133798
|
}
|
133729
133799
|
}
|
133730
|
-
var JSX_TEXT_CHILD_REQUIRES_EXPR_CONTAINER_PATTERN = /[<>&]/;
|
133800
|
+
var JSX_TEXT_CHILD_REQUIRES_EXPR_CONTAINER_PATTERN = /[<>&{}]/;
|
133731
133801
|
function codegenJsxElement(cx, place) {
|
133732
133802
|
const value = codegenPlace(cx, place);
|
133733
133803
|
switch (value.type) {
|
@@ -134923,11 +134993,15 @@ function inferOperandEffect(state, place) {
|
|
134923
134993
|
if (isRefOrRefValue(place.identifier)) {
|
134924
134994
|
break;
|
134925
134995
|
} else if (value.kind === "context" /* Context */) {
|
134996
|
+
CompilerError.invariant(value.context.size > 0, {
|
134997
|
+
reason: "[InferFunctionEffects] Expected Context-kind value's capture list to be non-empty.",
|
134998
|
+
loc: place.loc
|
134999
|
+
});
|
134926
135000
|
return {
|
134927
135001
|
kind: "ContextMutation",
|
134928
135002
|
loc: place.loc,
|
134929
135003
|
effect: place.effect,
|
134930
|
-
places: value.context
|
135004
|
+
places: value.context
|
134931
135005
|
};
|
134932
135006
|
} else if (value.kind !== "mutable" /* Mutable */ && // We ignore mutations of primitives since this is not a React-specific problem
|
134933
135007
|
value.kind !== "primitive" /* Primitive */) {
|
@@ -135682,10 +135756,11 @@ function inferBlock(env, state, block, functionEffects) {
|
|
135682
135756
|
break;
|
135683
135757
|
}
|
135684
135758
|
case "ArrayExpression": {
|
135685
|
-
const
|
135759
|
+
const contextRefOperands = getContextRefOperand(state, instrValue);
|
135760
|
+
const valueKind = contextRefOperands.length > 0 ? {
|
135686
135761
|
kind: "context" /* Context */,
|
135687
135762
|
reason: /* @__PURE__ */ new Set(["other" /* Other */]),
|
135688
|
-
context:
|
135763
|
+
context: new Set(contextRefOperands)
|
135689
135764
|
} : {
|
135690
135765
|
kind: "mutable" /* Mutable */,
|
135691
135766
|
reason: /* @__PURE__ */ new Set(["other" /* Other */]),
|
@@ -135726,10 +135801,11 @@ function inferBlock(env, state, block, functionEffects) {
|
|
135726
135801
|
break;
|
135727
135802
|
}
|
135728
135803
|
case "ObjectExpression": {
|
135729
|
-
const
|
135804
|
+
const contextRefOperands = getContextRefOperand(state, instrValue);
|
135805
|
+
const valueKind = contextRefOperands.length > 0 ? {
|
135730
135806
|
kind: "context" /* Context */,
|
135731
135807
|
reason: /* @__PURE__ */ new Set(["other" /* Other */]),
|
135732
|
-
context:
|
135808
|
+
context: new Set(contextRefOperands)
|
135733
135809
|
} : {
|
135734
135810
|
kind: "mutable" /* Mutable */,
|
135735
135811
|
reason: /* @__PURE__ */ new Set(["other" /* Other */]),
|
@@ -136319,11 +136395,17 @@ function inferBlock(env, state, block, functionEffects) {
|
|
136319
136395
|
}
|
136320
136396
|
case "LoadLocal": {
|
136321
136397
|
const lvalue = instr.lvalue;
|
136322
|
-
|
136398
|
+
CompilerError.invariant(
|
136399
|
+
!(state.isDefined(lvalue) && state.kind(lvalue).kind === "context" /* Context */),
|
136400
|
+
{
|
136401
|
+
reason: "[InferReferenceEffects] Unexpected LoadLocal with context kind",
|
136402
|
+
loc: lvalue.loc
|
136403
|
+
}
|
136404
|
+
);
|
136323
136405
|
state.referenceAndRecordEffects(
|
136324
136406
|
freezeActions,
|
136325
136407
|
instrValue.place,
|
136326
|
-
|
136408
|
+
"capture" /* Capture */,
|
136327
136409
|
"other" /* Other */
|
136328
136410
|
);
|
136329
136411
|
lvalue.effect = "mutate?" /* ConditionallyMutate */;
|
@@ -136577,13 +136659,14 @@ function inferBlock(env, state, block, functionEffects) {
|
|
136577
136659
|
({ values, reason }) => state.freezeValues(values, reason)
|
136578
136660
|
);
|
136579
136661
|
}
|
136580
|
-
function
|
136662
|
+
function getContextRefOperand(state, instrValue) {
|
136663
|
+
const result = [];
|
136581
136664
|
for (const place of eachInstructionValueOperand(instrValue)) {
|
136582
136665
|
if (state.isDefined(place) && state.kind(place).kind === "context" /* Context */) {
|
136583
|
-
|
136666
|
+
result.push(place);
|
136584
136667
|
}
|
136585
136668
|
}
|
136586
|
-
return
|
136669
|
+
return result;
|
136587
136670
|
}
|
136588
136671
|
function getFunctionCallSignature(env, type) {
|
136589
136672
|
if (type.kind !== "Function") {
|
@@ -144552,6 +144635,35 @@ function rewriteInstructions(rewriteInstrs, instructions) {
|
|
144552
144635
|
return instructions;
|
144553
144636
|
}
|
144554
144637
|
|
144638
|
+
// src/Validation/ValiateNoImpureFunctionsInRender.ts
|
144639
|
+
function validateNoImpureFunctionsInRender(fn) {
|
144640
|
+
const errors = new CompilerError();
|
144641
|
+
for (const [, block] of fn.body.blocks) {
|
144642
|
+
for (const instr of block.instructions) {
|
144643
|
+
const value = instr.value;
|
144644
|
+
if (value.kind === "MethodCall" || value.kind == "CallExpression") {
|
144645
|
+
const callee = value.kind === "MethodCall" ? value.property : value.callee;
|
144646
|
+
const signature = getFunctionCallSignature(
|
144647
|
+
fn.env,
|
144648
|
+
callee.identifier.type
|
144649
|
+
);
|
144650
|
+
if (signature != null && signature.impure === true) {
|
144651
|
+
errors.push({
|
144652
|
+
reason: "Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)",
|
144653
|
+
description: signature.canonicalName != null ? `\`${signature.canonicalName}\` is an impure function whose results may change on every call` : null,
|
144654
|
+
severity: "InvalidReact" /* InvalidReact */,
|
144655
|
+
loc: callee.loc,
|
144656
|
+
suggestions: null
|
144657
|
+
});
|
144658
|
+
}
|
144659
|
+
}
|
144660
|
+
}
|
144661
|
+
}
|
144662
|
+
if (errors.hasErrors()) {
|
144663
|
+
throw errors;
|
144664
|
+
}
|
144665
|
+
}
|
144666
|
+
|
144555
144667
|
// src/Entrypoint/Pipeline.ts
|
144556
144668
|
function run(func, config, fnType, useMemoCacheIdentifier, logger, filename, code) {
|
144557
144669
|
const contextIdentifiers = findContextIdentifiers(func);
|
@@ -144650,6 +144762,9 @@ function runWithEnvironment(func, env) {
|
|
144650
144762
|
if (env.config.validateNoJSXInTryStatements) {
|
144651
144763
|
validateNoJSXInTryStatement(hir);
|
144652
144764
|
}
|
144765
|
+
if (env.config.validateNoImpureFunctionsInRender) {
|
144766
|
+
validateNoImpureFunctionsInRender(hir);
|
144767
|
+
}
|
144653
144768
|
inferReactivePlaces(hir);
|
144654
144769
|
log2({ kind: "hir", name: "InferReactivePlaces", value: hir });
|
144655
144770
|
rewriteInstructionKindsBasedOnReassignment(hir);
|
@@ -145646,9 +145761,11 @@ function returnsNonNode(node) {
|
|
145646
145761
|
}
|
145647
145762
|
}
|
145648
145763
|
},
|
145764
|
+
// Skip traversing all nested functions and their return statements
|
145649
145765
|
ArrowFunctionExpression: skipNestedFunctions(node),
|
145650
145766
|
FunctionExpression: skipNestedFunctions(node),
|
145651
|
-
FunctionDeclaration: skipNestedFunctions(node)
|
145767
|
+
FunctionDeclaration: skipNestedFunctions(node),
|
145768
|
+
ObjectMethod: (node2) => node2.skip()
|
145652
145769
|
});
|
145653
145770
|
return !hasReturn || returnsNonNode2;
|
145654
145771
|
}
|