babel-plugin-react-compiler 0.0.0-experimental-dc8bd44-20241120 → 0.0.0-experimental-df7b47d-20241124
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 +233 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
@@ -136714,6 +136714,17 @@ const EnvironmentConfigSchema = z.object({
|
|
136714
136714
|
enableForest: z.boolean().default(false),
|
136715
136715
|
enableUseTypeAnnotations: z.boolean().default(false),
|
136716
136716
|
enableFunctionDependencyRewrite: z.boolean().default(true),
|
136717
|
+
enableOptionalDependencies: z.boolean().default(true),
|
136718
|
+
inferEffectDependencies: z
|
136719
|
+
.nullable(
|
136720
|
+
z.array(
|
136721
|
+
z.object({
|
136722
|
+
function: ExternalFunctionSchema,
|
136723
|
+
numRequiredArgs: z.number(),
|
136724
|
+
})
|
136725
|
+
)
|
136726
|
+
)
|
136727
|
+
.default(null),
|
136717
136728
|
inlineJsxTransform: ReactElementSymbolSchema.nullable().default(null),
|
136718
136729
|
validateHooksUsage: z.boolean().default(true),
|
136719
136730
|
validateRefAccessDuringRender: z.boolean().default(true),
|
@@ -136777,6 +136788,19 @@ const testComplexConfigDefaults = {
|
|
136777
136788
|
source: 'react-compiler-runtime',
|
136778
136789
|
importSpecifierName: 'useContext_withSelector',
|
136779
136790
|
},
|
136791
|
+
inferEffectDependencies: [
|
136792
|
+
{
|
136793
|
+
function: {source: 'react', importSpecifierName: 'useEffect'},
|
136794
|
+
numRequiredArgs: 1,
|
136795
|
+
},
|
136796
|
+
{
|
136797
|
+
function: {
|
136798
|
+
source: 'shared-runtime',
|
136799
|
+
importSpecifierName: 'useSpecialEffect',
|
136800
|
+
},
|
136801
|
+
numRequiredArgs: 2,
|
136802
|
+
},
|
136803
|
+
],
|
136780
136804
|
};
|
136781
136805
|
function parseConfigPragmaForTests(pragma) {
|
136782
136806
|
const maybeConfig = {};
|
@@ -141015,25 +141039,25 @@ function rewriteInstruction(instr, state) {
|
|
141015
141039
|
if (instr.value.kind === 'Destructure') {
|
141016
141040
|
switch (instr.value.lvalue.pattern.kind) {
|
141017
141041
|
case 'ArrayPattern': {
|
141018
|
-
let
|
141019
|
-
const
|
141020
|
-
for (let i =
|
141021
|
-
const item =
|
141042
|
+
let lastEntryIndex = 0;
|
141043
|
+
const items = instr.value.lvalue.pattern.items;
|
141044
|
+
for (let i = 0; i < items.length; i++) {
|
141045
|
+
const item = items[i];
|
141022
141046
|
if (item.kind === 'Identifier') {
|
141023
|
-
if (state.isIdOrNameUsed(item.identifier)) {
|
141024
|
-
|
141025
|
-
|
141047
|
+
if (!state.isIdOrNameUsed(item.identifier)) {
|
141048
|
+
items[i] = {kind: 'Hole'};
|
141049
|
+
} else {
|
141050
|
+
lastEntryIndex = i;
|
141026
141051
|
}
|
141027
141052
|
} else if (item.kind === 'Spread') {
|
141028
|
-
if (state.isIdOrNameUsed(item.place.identifier)) {
|
141029
|
-
|
141030
|
-
|
141053
|
+
if (!state.isIdOrNameUsed(item.place.identifier)) {
|
141054
|
+
items[i] = {kind: 'Hole'};
|
141055
|
+
} else {
|
141056
|
+
lastEntryIndex = i;
|
141031
141057
|
}
|
141032
141058
|
}
|
141033
141059
|
}
|
141034
|
-
|
141035
|
-
instr.value.lvalue.pattern.items = nextItems;
|
141036
|
-
}
|
141060
|
+
items.length = lastEntryIndex + 1;
|
141037
141061
|
break;
|
141038
141062
|
}
|
141039
141063
|
case 'ObjectPattern': {
|
@@ -151483,6 +151507,199 @@ function declareTemporary(env, block, result) {
|
|
151483
151507
|
},
|
151484
151508
|
});
|
151485
151509
|
}
|
151510
|
+
function inferEffectDependencies(fn) {
|
151511
|
+
let hasRewrite = false;
|
151512
|
+
const fnExpressions = new Map();
|
151513
|
+
const autodepFnConfigs = new Map();
|
151514
|
+
for (const effectTarget of fn.env.config.inferEffectDependencies) {
|
151515
|
+
const moduleTargets = getOrInsertWith(
|
151516
|
+
autodepFnConfigs,
|
151517
|
+
effectTarget.function.source,
|
151518
|
+
() => new Map()
|
151519
|
+
);
|
151520
|
+
moduleTargets.set(
|
151521
|
+
effectTarget.function.importSpecifierName,
|
151522
|
+
effectTarget.numRequiredArgs
|
151523
|
+
);
|
151524
|
+
}
|
151525
|
+
const autodepFnLoads = new Map();
|
151526
|
+
const scopeInfos = new Map();
|
151527
|
+
const reactiveIds = inferReactiveIdentifiers(fn);
|
151528
|
+
for (const [, block] of fn.body.blocks) {
|
151529
|
+
if (
|
151530
|
+
block.terminal.kind === 'scope' ||
|
151531
|
+
block.terminal.kind === 'pruned-scope'
|
151532
|
+
) {
|
151533
|
+
const scopeBlock = fn.body.blocks.get(block.terminal.block);
|
151534
|
+
scopeInfos.set(block.terminal.scope.id, {
|
151535
|
+
pruned: block.terminal.kind === 'pruned-scope',
|
151536
|
+
deps: block.terminal.scope.dependencies,
|
151537
|
+
hasSingleInstr:
|
151538
|
+
scopeBlock.instructions.length === 1 &&
|
151539
|
+
scopeBlock.terminal.kind === 'goto' &&
|
151540
|
+
scopeBlock.terminal.block === block.terminal.fallthrough,
|
151541
|
+
});
|
151542
|
+
}
|
151543
|
+
const rewriteInstrs = new Map();
|
151544
|
+
for (const instr of block.instructions) {
|
151545
|
+
const {value: value, lvalue: lvalue} = instr;
|
151546
|
+
if (value.kind === 'FunctionExpression') {
|
151547
|
+
fnExpressions.set(lvalue.identifier.id, instr);
|
151548
|
+
} else if (
|
151549
|
+
value.kind === 'LoadGlobal' &&
|
151550
|
+
value.binding.kind === 'ImportSpecifier'
|
151551
|
+
) {
|
151552
|
+
const moduleTargets = autodepFnConfigs.get(value.binding.module);
|
151553
|
+
if (moduleTargets != null) {
|
151554
|
+
const numRequiredArgs = moduleTargets.get(value.binding.imported);
|
151555
|
+
if (numRequiredArgs != null) {
|
151556
|
+
autodepFnLoads.set(lvalue.identifier.id, numRequiredArgs);
|
151557
|
+
}
|
151558
|
+
}
|
151559
|
+
} else if (
|
151560
|
+
value.kind === 'CallExpression' &&
|
151561
|
+
autodepFnLoads.get(value.callee.identifier.id) === value.args.length &&
|
151562
|
+
value.args[0].kind === 'Identifier'
|
151563
|
+
) {
|
151564
|
+
const fnExpr = fnExpressions.get(value.args[0].identifier.id);
|
151565
|
+
if (fnExpr != null) {
|
151566
|
+
const scopeInfo =
|
151567
|
+
fnExpr.lvalue.identifier.scope != null
|
151568
|
+
? scopeInfos.get(fnExpr.lvalue.identifier.scope.id)
|
151569
|
+
: null;
|
151570
|
+
CompilerError.invariant(scopeInfo != null, {
|
151571
|
+
reason: 'Expected function expression scope to exist',
|
151572
|
+
loc: value.loc,
|
151573
|
+
});
|
151574
|
+
if (scopeInfo.pruned || !scopeInfo.hasSingleInstr) {
|
151575
|
+
CompilerError.throwTodo({
|
151576
|
+
reason:
|
151577
|
+
'[InferEffectDependencies] Expected effect function to have non-pruned scope and its scope to have exactly one instruction',
|
151578
|
+
loc: fnExpr.loc,
|
151579
|
+
});
|
151580
|
+
}
|
151581
|
+
const effectDeps = [];
|
151582
|
+
const newInstructions = [];
|
151583
|
+
for (const dep of scopeInfo.deps) {
|
151584
|
+
const {place: place, instructions: instructions} =
|
151585
|
+
writeDependencyToInstructions(
|
151586
|
+
dep,
|
151587
|
+
reactiveIds.has(dep.identifier.id),
|
151588
|
+
fn.env,
|
151589
|
+
fnExpr.loc
|
151590
|
+
);
|
151591
|
+
newInstructions.push(...instructions);
|
151592
|
+
effectDeps.push(place);
|
151593
|
+
}
|
151594
|
+
const deps = {
|
151595
|
+
kind: 'ArrayExpression',
|
151596
|
+
elements: effectDeps,
|
151597
|
+
loc: GeneratedSource,
|
151598
|
+
};
|
151599
|
+
const depsPlace = createTemporaryPlace(fn.env, GeneratedSource);
|
151600
|
+
depsPlace.effect = exports.Effect.Read;
|
151601
|
+
newInstructions.push({
|
151602
|
+
id: makeInstructionId(0),
|
151603
|
+
loc: GeneratedSource,
|
151604
|
+
lvalue: Object.assign(Object.assign({}, depsPlace), {
|
151605
|
+
effect: exports.Effect.Mutate,
|
151606
|
+
}),
|
151607
|
+
value: deps,
|
151608
|
+
});
|
151609
|
+
value.args.push(
|
151610
|
+
Object.assign(Object.assign({}, depsPlace), {
|
151611
|
+
effect: exports.Effect.Freeze,
|
151612
|
+
})
|
151613
|
+
);
|
151614
|
+
rewriteInstrs.set(instr.id, newInstructions);
|
151615
|
+
}
|
151616
|
+
}
|
151617
|
+
}
|
151618
|
+
if (rewriteInstrs.size > 0) {
|
151619
|
+
hasRewrite = true;
|
151620
|
+
const newInstrs = [];
|
151621
|
+
for (const instr of block.instructions) {
|
151622
|
+
const newInstr = rewriteInstrs.get(instr.id);
|
151623
|
+
if (newInstr != null) {
|
151624
|
+
newInstrs.push(...newInstr, instr);
|
151625
|
+
} else {
|
151626
|
+
newInstrs.push(instr);
|
151627
|
+
}
|
151628
|
+
}
|
151629
|
+
block.instructions = newInstrs;
|
151630
|
+
}
|
151631
|
+
}
|
151632
|
+
if (hasRewrite) {
|
151633
|
+
markInstructionIds(fn.body);
|
151634
|
+
fixScopeAndIdentifierRanges(fn.body);
|
151635
|
+
}
|
151636
|
+
}
|
151637
|
+
function writeDependencyToInstructions(dep, reactive, env, loc) {
|
151638
|
+
const instructions = [];
|
151639
|
+
let currValue = createTemporaryPlace(env, GeneratedSource);
|
151640
|
+
currValue.reactive = reactive;
|
151641
|
+
instructions.push({
|
151642
|
+
id: makeInstructionId(0),
|
151643
|
+
loc: GeneratedSource,
|
151644
|
+
lvalue: Object.assign(Object.assign({}, currValue), {
|
151645
|
+
effect: exports.Effect.Mutate,
|
151646
|
+
}),
|
151647
|
+
value: {
|
151648
|
+
kind: 'LoadLocal',
|
151649
|
+
place: {
|
151650
|
+
kind: 'Identifier',
|
151651
|
+
identifier: dep.identifier,
|
151652
|
+
effect: exports.Effect.Capture,
|
151653
|
+
reactive: reactive,
|
151654
|
+
loc: loc,
|
151655
|
+
},
|
151656
|
+
loc: loc,
|
151657
|
+
},
|
151658
|
+
});
|
151659
|
+
for (const path of dep.path) {
|
151660
|
+
if (path.optional) {
|
151661
|
+
break;
|
151662
|
+
}
|
151663
|
+
const nextValue = createTemporaryPlace(env, GeneratedSource);
|
151664
|
+
nextValue.reactive = reactive;
|
151665
|
+
instructions.push({
|
151666
|
+
id: makeInstructionId(0),
|
151667
|
+
loc: GeneratedSource,
|
151668
|
+
lvalue: Object.assign(Object.assign({}, nextValue), {
|
151669
|
+
effect: exports.Effect.Mutate,
|
151670
|
+
}),
|
151671
|
+
value: {
|
151672
|
+
kind: 'PropertyLoad',
|
151673
|
+
object: Object.assign(Object.assign({}, currValue), {
|
151674
|
+
effect: exports.Effect.Capture,
|
151675
|
+
}),
|
151676
|
+
property: path.property,
|
151677
|
+
loc: loc,
|
151678
|
+
},
|
151679
|
+
});
|
151680
|
+
currValue = nextValue;
|
151681
|
+
}
|
151682
|
+
currValue.effect = exports.Effect.Freeze;
|
151683
|
+
return {place: currValue, instructions: instructions};
|
151684
|
+
}
|
151685
|
+
function inferReactiveIdentifiers(fn) {
|
151686
|
+
const reactiveIds = new Set();
|
151687
|
+
for (const [, block] of fn.body.blocks) {
|
151688
|
+
for (const instr of block.instructions) {
|
151689
|
+
for (const place of eachInstructionOperand(instr)) {
|
151690
|
+
if (place.reactive) {
|
151691
|
+
reactiveIds.add(place.identifier.id);
|
151692
|
+
}
|
151693
|
+
}
|
151694
|
+
}
|
151695
|
+
for (const place of eachTerminalOperand(block.terminal)) {
|
151696
|
+
if (place.reactive) {
|
151697
|
+
reactiveIds.add(place.identifier.id);
|
151698
|
+
}
|
151699
|
+
}
|
151700
|
+
}
|
151701
|
+
return reactiveIds;
|
151702
|
+
}
|
151486
151703
|
function instructionReordering(fn) {
|
151487
151704
|
var _a;
|
151488
151705
|
const shared = new Map();
|
@@ -157156,6 +157373,9 @@ function* runWithEnvironment(func, env) {
|
|
157156
157373
|
assertTerminalPredsExist(hir);
|
157157
157374
|
propagateScopeDependenciesHIR(hir);
|
157158
157375
|
yield log({kind: 'hir', name: 'PropagateScopeDependenciesHIR', value: hir});
|
157376
|
+
if (env.config.inferEffectDependencies) {
|
157377
|
+
inferEffectDependencies(hir);
|
157378
|
+
}
|
157159
157379
|
if (env.config.inlineJsxTransform) {
|
157160
157380
|
inlineJsxTransform(hir, env.config.inlineJsxTransform);
|
157161
157381
|
yield log({kind: 'hir', name: 'inlineJsxTransform', value: hir});
|
package/package.json
CHANGED