diff --git a/compiler/forget/src/CompilerPipeline.ts b/compiler/forget/src/CompilerPipeline.ts index 8865b82c59..50ed36278f 100644 --- a/compiler/forget/src/CompilerPipeline.ts +++ b/compiler/forget/src/CompilerPipeline.ts @@ -13,6 +13,7 @@ import { ReactiveFunction, } from "./HIR"; import { EnvironmentOptions, mergeOptions } from "./HIR/Environment"; +import { validateConsistentIdentifiers } from "./HIR/ValidateConsistentIdentifiers"; import { analyseFunctions, dropMemoCalls, @@ -60,6 +61,8 @@ export function* run( enterSSA(hir); yield log({ kind: "hir", name: "SSA", value: hir }); + validateConsistentIdentifiers(hir); + eliminateRedundantPhi(hir); yield log({ kind: "hir", name: "EliminateRedundantPhi", value: hir }); diff --git a/compiler/forget/src/HIR/BuildHIR.ts b/compiler/forget/src/HIR/BuildHIR.ts index 66f202d6a6..025974703d 100644 --- a/compiler/forget/src/HIR/BuildHIR.ts +++ b/compiler/forget/src/HIR/BuildHIR.ts @@ -110,7 +110,7 @@ export function lower( param.node.loc ?? GeneratedSource, InstructionKind.Let, param, - { kind: "LoadLocal", place, loc: place.loc } + place ); } else { builder.errors.push({ @@ -590,7 +590,7 @@ function lowerStatement( } case "VariableDeclaration": { const stmt = stmtPath as NodePath; - const nodeKind: string = stmt.node.kind; + const nodeKind: t.VariableDeclaration["kind"] = stmt.node.kind; if (nodeKind === "var") { builder.errors.push({ reason: `(BuildHIR::lowerStatement) Handle ${nodeKind} kinds in VariableDeclaration`, @@ -604,15 +604,24 @@ function lowerStatement( for (const declaration of stmt.get("declarations")) { const id = declaration.get("id"); const init = declaration.get("init"); - let value: InstructionValue; + let value: Place; if (init.node != null) { - value = lowerExpression(builder, init as NodePath); + value = lowerExpressionToTemporary( + builder, + init as NodePath + ); } else { - value = { - kind: "Primitive", - value: undefined, - loc: id.node.loc ?? GeneratedSource, - }; + value = buildTemporaryPlace(builder, id.node.loc ?? GeneratedSource); + builder.push({ + id: makeInstructionId(0), + lvalue: { place: { ...value }, kind: InstructionKind.Const }, + value: { + kind: "Primitive", + value: undefined, + loc: id.node.loc ?? GeneratedSource, + }, + loc: value.loc, + }); } lowerAssignment( builder, @@ -1177,7 +1186,7 @@ function lowerExpression( left.node.loc ?? GeneratedSource, InstructionKind.Reassign, left, - lowerExpression(builder, expr.get("right")) + lowerExpressionToTemporary(builder, expr.get("right")) ); } @@ -1209,21 +1218,41 @@ function lowerExpression( switch (leftNode.type) { case "Identifier": { const leftExpr = left as NodePath; - const place = lowerIdentifier(builder, leftExpr); + const identifier = lowerIdentifier(builder, leftExpr); + const leftPlace = lowerExpressionToTemporary(builder, leftExpr); const right = lowerExpressionToTemporary(builder, expr.get("right")); + const binaryPlace = buildTemporaryPlace(builder, exprLoc); builder.push({ id: makeInstructionId(0), - lvalue: { place: { ...place }, kind: InstructionKind.Reassign }, + lvalue: { + place: { ...binaryPlace }, + kind: InstructionKind.Const, + }, value: { kind: "BinaryExpression", operator: binaryOperator, - left: { ...place }, + left: leftPlace, right, loc: exprLoc, }, loc: exprLoc, }); - return { kind: "LoadLocal", place, loc: exprLoc }; + const result = buildTemporaryPlace(builder, exprLoc); + builder.push({ + id: makeInstructionId(0), + lvalue: { place: { ...result }, kind: InstructionKind.Const }, + value: { + kind: "StoreLocal", + lvalue: { + place: { ...identifier }, + kind: InstructionKind.Reassign, + }, + value: { ...binaryPlace }, + loc: exprLoc, + }, + loc: exprLoc, + }); + return { kind: "LoadLocal", place: identifier, loc: exprLoc }; } case "MemberExpression": { // a.b.c += @@ -1546,13 +1575,13 @@ function lowerExpression( }); return { kind: "UnsupportedNode", node: exprNode, loc: exprLoc }; } - const temp = buildTemporaryPlace( + const primitiveTemp = buildTemporaryPlace( builder, expr.node.loc ?? GeneratedSource ); builder.push({ id: makeInstructionId(0), - lvalue: { place: { ...temp }, kind: InstructionKind.Const }, + lvalue: { place: { ...primitiveTemp }, kind: InstructionKind.Const }, value: { kind: "Primitive", value: 1, @@ -1560,18 +1589,39 @@ function lowerExpression( }, loc: expr.node.loc ?? GeneratedSource, }); + const temp = buildTemporaryPlace( + builder, + expr.node.loc ?? GeneratedSource + ); const identifier = lowerIdentifier( builder, argument as NodePath ); builder.push({ id: makeInstructionId(0), - lvalue: { place: { ...identifier }, kind: InstructionKind.Reassign }, + lvalue: { place: { ...temp }, kind: InstructionKind.Const }, value: { kind: "BinaryExpression", operator: expr.node.operator === "++" ? "+" : "-", left: { ...identifier }, - right: { ...temp }, + right: { ...primitiveTemp }, + loc: exprLoc, + }, + loc: exprLoc, + }); + builder.push({ + id: makeInstructionId(0), + lvalue: { + place: buildTemporaryPlace(builder, exprLoc), + kind: InstructionKind.Const, + }, + value: { + kind: "StoreLocal", + lvalue: { + place: { ...identifier }, + kind: InstructionKind.Reassign, + }, + value: { ...temp }, loc: exprLoc, }, loc: exprLoc, @@ -1883,7 +1933,7 @@ function lowerAssignment( loc: SourceLocation, kind: InstructionKind, lvaluePath: NodePath, - value: InstructionValue + value: Place ): InstructionValue { const lvalueNode = lvaluePath.node; switch (lvalueNode.type) { @@ -1913,6 +1963,7 @@ function lowerAssignment( }; } + const temporary = buildTemporaryPlace(builder, loc); const place: Place = { kind: "Identifier", identifier: identifier, @@ -1921,28 +1972,24 @@ function lowerAssignment( }; builder.push({ id: makeInstructionId(0), - lvalue: { place: { ...place }, kind }, - value, + lvalue: { place: { ...temporary }, kind }, + value: { + kind: "StoreLocal", + lvalue: { + place: { ...place }, + kind, + }, + value, + loc, + }, loc, }); - return { kind: "LoadLocal", place, loc: place.loc }; + return { kind: "LoadLocal", place, loc: temporary.loc }; } case "MemberExpression": { const lvalue = lvaluePath as NodePath; const property = lvalue.get("property"); const object = lowerExpressionToTemporary(builder, lvalue.get("object")); - let valuePlace: Place; - if (value.kind === "LoadLocal") { - valuePlace = value.place; - } else { - valuePlace = buildTemporaryPlace(builder, loc); - builder.push({ - id: makeInstructionId(0), - lvalue: { place: { ...valuePlace }, kind: InstructionKind.Const }, - value, - loc, - }); - } if (!lvalue.node.computed) { if (!property.isIdentifier()) { builder.errors.push({ @@ -1956,7 +2003,7 @@ function lowerAssignment( kind: "PropertyStore", object, property: property.node.name, - value: valuePlace, + value, loc, }; } else { @@ -1974,20 +2021,13 @@ function lowerAssignment( kind: "ComputedStore", object, property: propertyPlace, - value: valuePlace, + value, loc, }; } } case "ArrayPattern": { const lvalue = lvaluePath as NodePath; - const arrayPlace = buildTemporaryPlace(builder, loc); - builder.push({ - id: makeInstructionId(0), - lvalue: { place: { ...arrayPlace }, kind: InstructionKind.Const }, - value, - loc, - }); const elements = lvalue.get("elements"); let hasError = false; for (let i = 0; i < elements.length; i++) { @@ -2018,27 +2058,32 @@ function lowerAssignment( }, loc: element.node.loc ?? GeneratedSource, }); - const value: InstructionValue = { - kind: "ComputedLoad", + const propertyPlace = buildTemporaryPlace(builder, property.loc); + builder.push({ + id: makeInstructionId(0), + lvalue: { place: { ...propertyPlace }, kind: InstructionKind.Const }, + value: { + kind: "ComputedLoad", + loc, + object: { ...value }, + property, + }, loc, - object: { ...arrayPlace }, - property, - }; - lowerAssignment(builder, loc, kind, element as NodePath, value); + }); + lowerAssignment( + builder, + loc, + kind, + element as NodePath, + propertyPlace + ); } return hasError ? { kind: "UnsupportedNode", node: lvalueNode, loc } - : { kind: "LoadLocal", place: arrayPlace, loc: arrayPlace.loc }; + : { kind: "LoadLocal", place: value, loc: value.loc }; } case "ObjectPattern": { const lvalue = lvaluePath as NodePath; - const objectPlace = buildTemporaryPlace(builder, loc); - builder.push({ - id: makeInstructionId(0), - lvalue: { place: { ...objectPlace }, kind }, - value, - loc, - }); const properties = lvalue.get("properties"); let hasError = false; for (let i = 0; i < properties.length; i++) { @@ -2072,18 +2117,27 @@ function lowerAssignment( hasError = true; continue; } - const value: InstructionValue = { - kind: "PropertyLoad", + const propertyPlace = buildTemporaryPlace( + builder, + property.node.loc ?? GeneratedSource + ); + builder.push({ + id: makeInstructionId(0), + lvalue: { place: { ...propertyPlace }, kind: InstructionKind.Const }, + value: { + kind: "PropertyLoad", + loc, + object: { ...value }, + property: key.node.name, + optional: false, // Key of ObjectPattern (evaluation of LVal) cannot be optional. + }, loc, - object: { ...objectPlace }, - property: key.node.name, - optional: false, // Key of ObjectPattern (evaluation of LVal) cannot be optional. - }; - lowerAssignment(builder, loc, kind, element, value); + }); + lowerAssignment(builder, loc, kind, element, propertyPlace); } return hasError ? { kind: "UnsupportedNode", node: lvalueNode, loc } - : { kind: "LoadLocal", place: objectPlace, loc: objectPlace.loc }; + : { kind: "LoadLocal", place: value, loc: value.loc }; } default: { builder.errors.push({ diff --git a/compiler/forget/src/HIR/HIR.ts b/compiler/forget/src/HIR/HIR.ts index 0db41d1b74..767fda771b 100644 --- a/compiler/forget/src/HIR/HIR.ts +++ b/compiler/forget/src/HIR/HIR.ts @@ -418,6 +418,12 @@ export type InstructionValue = place: Place; loc: SourceLocation; } + | { + kind: "StoreLocal"; + lvalue: LValue; + value: Place; + loc: SourceLocation; + } | { kind: "Primitive"; value: number | boolean | string | null | undefined; diff --git a/compiler/forget/src/HIR/PrintHIR.ts b/compiler/forget/src/HIR/PrintHIR.ts index 1168dc5e22..8efb151920 100644 --- a/compiler/forget/src/HIR/PrintHIR.ts +++ b/compiler/forget/src/HIR/PrintHIR.ts @@ -315,6 +315,12 @@ export function printInstructionValue(instrValue: ReactiveValue): string { value = `LoadLocal ${printPlace(instrValue.place)}`; break; } + case "StoreLocal": { + value = `StoreLocal ${instrValue.lvalue.kind} ${printPlace( + instrValue.lvalue.place + )} = ${printPlace(instrValue.value)}`; + break; + } case "PropertyLoad": { value = `PropertyLoad ${printPlace(instrValue.object)}.${ instrValue.property @@ -412,6 +418,20 @@ function isMutable(range: MutableRange): boolean { } function printMutableRange(identifier: Identifier): string { + invariant( + (identifier.mutableRange.start === 0 && + identifier.mutableRange.end === 0) || + identifier.mutableRange.end > identifier.mutableRange.start, + "Identifier mutableRange was invalid: [%s:%s]", + identifier.mutableRange.start, + identifier.mutableRange.end + ); + if (identifier.scope !== null) { + invariant( + identifier.scope.range.end > identifier.scope.range.start, + "Identifier scope mutableRange was invalid" + ); + } const range = identifier.scope !== null ? identifier.scope.range diff --git a/compiler/forget/src/HIR/ValidateConsistentIdentifiers.ts b/compiler/forget/src/HIR/ValidateConsistentIdentifiers.ts new file mode 100644 index 0000000000..0ad9988a51 --- /dev/null +++ b/compiler/forget/src/HIR/ValidateConsistentIdentifiers.ts @@ -0,0 +1,69 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { CompilerError } from "../CompilerError"; +import { + GeneratedSource, + HIRFunction, + Identifier, + IdentifierId, + SourceLocation, +} from "./HIR"; +import { eachInstructionValueOperand, eachTerminalOperand } from "./visitors"; + +/** + * Validation pass to check that there is a 1:1 mapping between Identifier objects and IdentifierIds, + * ie there can only be one Identifier instance per IdentifierId. + */ +export function validateConsistentIdentifiers(fn: HIRFunction): void { + const identifiers: Identifiers = new Map(); + for (const [, block] of fn.body.blocks) { + for (const phi of block.phis) { + validate(identifiers, phi.id); + for (const [, operand] of phi.operands) { + validate(identifiers, operand); + } + } + for (const instr of block.instructions) { + if (instr.lvalue.place.identifier.name !== null) { + CompilerError.invariant( + `Expected all lvalues to be temporaries, found '${instr.lvalue.place.identifier.name}'`, + instr.lvalue.place.loc + ); + } + validate( + identifiers, + instr.lvalue.place.identifier, + instr.lvalue.place.loc + ); + for (const operand of eachInstructionValueOperand(instr.value)) { + validate(identifiers, operand.identifier, operand.loc); + } + } + for (const operand of eachTerminalOperand(block.terminal)) { + validate(identifiers, operand.identifier, operand.loc); + } + } +} + +type Identifiers = Map; + +function validate( + identifiers: Identifiers, + identifier: Identifier, + loc: SourceLocation | null = null +): void { + const previous = identifiers.get(identifier.id); + if (previous === undefined) { + identifiers.set(identifier.id, identifier); + } else if (identifier !== previous) { + CompilerError.invariant( + `Duplicate identifier for id ${identifier.id}`, + loc ?? GeneratedSource + ); + } +} diff --git a/compiler/forget/src/HIR/visitors.ts b/compiler/forget/src/HIR/visitors.ts index 2da106e5e3..85285b60d5 100644 --- a/compiler/forget/src/HIR/visitors.ts +++ b/compiler/forget/src/HIR/visitors.ts @@ -52,6 +52,11 @@ export function* eachInstructionValueOperand( yield instrValue.place; break; } + case "StoreLocal": { + yield instrValue.lvalue.place; + yield instrValue.value; + break; + } case "PropertyLoad": { yield instrValue.object; break; @@ -181,6 +186,11 @@ export function mapInstructionOperands( instrValue.place = fn(instrValue.place); break; } + case "StoreLocal": { + instrValue.lvalue.place = fn(instrValue.lvalue.place); + instrValue.value = fn(instrValue.value); + break; + } case "NewExpression": case "CallExpression": { instrValue.callee = fn(instrValue.callee); diff --git a/compiler/forget/src/Inference/InferAlias.ts b/compiler/forget/src/Inference/InferAlias.ts index 1bd5df17a6..e4f057fca5 100644 --- a/compiler/forget/src/Inference/InferAlias.ts +++ b/compiler/forget/src/Inference/InferAlias.ts @@ -3,33 +3,24 @@ import { Identifier, Instruction, isPrimitiveType, - LValue, Place, } from "../HIR/HIR"; import DisjointSet from "../Utils/DisjointSet"; export type AliasSet = Set; -class AliasAnalyser { - aliases = new DisjointSet(); - - alias(lvalue: LValue, alias: Place) { - this.aliases.union([lvalue.place.identifier, alias.identifier]); - } -} - export function inferAliases(func: HIRFunction): DisjointSet { - const analyser = new AliasAnalyser(); + const aliases = new DisjointSet(); for (const [_, block] of func.body.blocks) { for (const instr of block.instructions) { - inferInstr(instr, analyser); + inferInstr(instr, aliases); } } - return analyser.aliases; + return aliases; } -function inferInstr(instr: Instruction, state: AliasAnalyser) { +function inferInstr(instr: Instruction, aliases: DisjointSet) { const { lvalue, value: instrValue } = instr; let alias: Place | null = null; switch (instrValue.kind) { @@ -40,6 +31,11 @@ function inferInstr(instr: Instruction, state: AliasAnalyser) { alias = instrValue.place; break; } + case "StoreLocal": { + // aliases.union([instrValue.place.identifier, instrValue.value.identifier]); + alias = instrValue.value; + break; + } case "ComputedLoad": case "PropertyLoad": { alias = instrValue.object; @@ -53,5 +49,5 @@ function inferInstr(instr: Instruction, state: AliasAnalyser) { return; } - state.alias(lvalue, alias); + aliases.union([lvalue.place.identifier, alias.identifier]); } diff --git a/compiler/forget/src/Inference/InferAliasForStores.ts b/compiler/forget/src/Inference/InferAliasForStores.ts index c36b11ee58..79c40bcb73 100644 --- a/compiler/forget/src/Inference/InferAliasForStores.ts +++ b/compiler/forget/src/Inference/InferAliasForStores.ts @@ -24,6 +24,9 @@ export function inferAliasForStores( if (lvalue.place.effect !== Effect.Store) { continue; } + if (value.kind === "StoreLocal") { + maybeAlias(aliases, value.lvalue.place, value.value, instr.id); + } for (const operand of eachInstructionValueOperand(value)) { if ( operand.effect === Effect.Capture || diff --git a/compiler/forget/src/Inference/InferMutableLifetimes.ts b/compiler/forget/src/Inference/InferMutableLifetimes.ts index 52a6dacc95..f7373a51e6 100644 --- a/compiler/forget/src/Inference/InferMutableLifetimes.ts +++ b/compiler/forget/src/Inference/InferMutableLifetimes.ts @@ -118,8 +118,15 @@ export function inferMutableLifetimes( } for (const instr of block.instructions) { - for (const input of eachInstructionOperand(instr)) { - inferPlace(input, instr, inferMutableRangeForStores); + if (instr.value.kind === "StoreLocal") { + inferPlace(instr.value.value, instr, inferMutableRangeForStores); + instr.value.lvalue.place.identifier.mutableRange.start = instr.id; + instr.value.lvalue.place.identifier.mutableRange.end = + makeInstructionId(instr.id + 1); + } else { + for (const input of eachInstructionOperand(instr)) { + inferPlace(input, instr, inferMutableRangeForStores); + } } const lvalueId = instr.lvalue.place.identifier; diff --git a/compiler/forget/src/Inference/InferReferenceEffects.ts b/compiler/forget/src/Inference/InferReferenceEffects.ts index f886ba318b..785883e99d 100644 --- a/compiler/forget/src/Inference/InferReferenceEffects.ts +++ b/compiler/forget/src/Inference/InferReferenceEffects.ts @@ -307,9 +307,9 @@ class InferenceState { } case Effect.Capture: { if ( + valueKind === ValueKind.Immutable || valueKind === ValueKind.Frozen || - valueKind === ValueKind.MaybeFrozen || - valueKind === ValueKind.Immutable + valueKind === ValueKind.MaybeFrozen ) { effect = Effect.Read; } else { @@ -790,6 +790,21 @@ function inferBlock( state.alias(lvalue.place, instrValue.place); continue; } + case "StoreLocal": { + const effect = + state.isDefined(instrValue.lvalue.place) && + state.kind(instrValue.lvalue.place) === ValueKind.Context + ? Effect.Mutate + : Effect.Capture; + state.reference(instrValue.value, effect); + + const lvalue = instr.lvalue; + state.alias(lvalue.place, instrValue.value); + lvalue.place.effect = Effect.Store; + state.alias(instrValue.lvalue.place, instrValue.value); + instrValue.lvalue.place.effect = Effect.Store; + continue; + } default: { assertExhaustive(instrValue, "Unexpected instruction kind"); } diff --git a/compiler/forget/src/Optimization/ConstantPropagation.ts b/compiler/forget/src/Optimization/ConstantPropagation.ts index 77a5504c5d..6a7ca792f0 100644 --- a/compiler/forget/src/Optimization/ConstantPropagation.ts +++ b/compiler/forget/src/Optimization/ConstantPropagation.ts @@ -313,6 +313,14 @@ function evaluateInstruction( case "LoadLocal": { return read(constants, value.place); } + case "StoreLocal": { + const placeValue = read(constants, value.value); + if (placeValue !== null) { + constants.set(value.lvalue.place.identifier.id, placeValue); + } + // NOTE: always return null to avoid replacing the StoreLocal with its value + return null; + } default: { // TODO: handle more cases return null; diff --git a/compiler/forget/src/Optimization/DeadCodeElimination.ts b/compiler/forget/src/Optimization/DeadCodeElimination.ts index 42ddc812a8..4036a6c1cc 100644 --- a/compiler/forget/src/Optimization/DeadCodeElimination.ts +++ b/compiler/forget/src/Optimization/DeadCodeElimination.ts @@ -40,7 +40,7 @@ export function deadCodeElimination(fn: HIRFunction): void { const instr = block.instructions[i]!; if ( !used.has(instr.lvalue.place.identifier) && - pruneableValue(instr.value) && + pruneableValue(instr.value, used) && // Can't prune the last value of a value block, that's its value! !(block.kind !== "block" && i === block.instructions.length - 1) ) { @@ -76,8 +76,15 @@ export function deadCodeElimination(fn: HIRFunction): void { * Returns true if it is safe to prune an instruction with the given value. * Functions which may have side- */ -function pruneableValue(value: InstructionValue): boolean { +function pruneableValue( + value: InstructionValue, + used: Set +): boolean { switch (value.kind) { + case "StoreLocal": { + // Stores are pruneable only if the identifier being stored to is never read later + return !used.has(value.lvalue.place.identifier); + } case "CallExpression": case "ComputedCall": case "ComputedStore": diff --git a/compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts index bbb2a72867..daae03b26b 100644 --- a/compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -99,11 +99,7 @@ function codegenBlock(cx: Context, block: ReactiveBlock): t.BlockStatement { for (const item of block) { switch (item.kind) { case "instruction": { - const statement = codegenInstructionNullable( - cx, - item.instruction, - codegenInstructionValue(cx, item.instruction.value) - ); + const statement = codegenInstructionNullable(cx, item.instruction); if (statement !== null) { statements.push(statement); } @@ -359,23 +355,47 @@ function codegenTerminal( function codegenInstructionNullable( cx: Context, - instr: ReactiveInstruction, - value: t.Expression + instr: ReactiveInstruction ): t.Statement | null { let statement; - if (instr.lvalue !== null && cx.hasDeclared(instr.lvalue.place.identifier)) { - statement = codegenInstruction( - cx, - { - ...instr, - lvalue: { - ...instr.lvalue, - kind: InstructionKind.Reassign, - }, - }, - value - ); + if (instr.value.kind === "StoreLocal") { + const kind = cx.hasDeclared(instr.value.lvalue.place.identifier) + ? InstructionKind.Reassign + : instr.value.lvalue.kind; + const value = codegenPlace(cx, instr.value.value); + switch (kind) { + case InstructionKind.Const: { + return createVariableDeclaration(instr.loc, "const", [ + t.variableDeclarator( + convertIdentifier(instr.value.lvalue.place.identifier), + value + ), + ]); + } + case InstructionKind.Let: { + return createVariableDeclaration(instr.loc, "let", [ + t.variableDeclarator( + convertIdentifier(instr.value.lvalue.place.identifier), + value + ), + ]); + } + case InstructionKind.Reassign: { + return createExpressionStatement( + instr.loc, + t.assignmentExpression( + "=", + convertIdentifier(instr.value.lvalue.place.identifier), + value + ) + ); + } + default: { + assertExhaustive(kind, `Unexpected instruction kind '${kind}'`); + } + } } else { + const value = codegenInstructionValue(cx, instr.value); statement = codegenInstruction(cx, instr, value); } if (statement.type === "EmptyStatement") { @@ -473,7 +493,10 @@ function codegenInstruction( cx.temp.set(instr.lvalue.place.identifier.id, value); return t.emptyStatement(); } else { - switch (instr.lvalue.kind) { + const kind = cx.hasDeclared(instr.lvalue.place.identifier) + ? InstructionKind.Reassign + : instr.lvalue.kind; + switch (kind) { case InstructionKind.Const: { return createVariableDeclaration(instr.loc, "const", [ t.variableDeclarator(codegenLVal(instr.lvalue), value), @@ -492,7 +515,7 @@ function codegenInstruction( } default: { assertExhaustive( - instr.lvalue.kind, + kind, `Unexpected instruction kind '${instr.lvalue.kind}'` ); } @@ -704,6 +727,12 @@ function codegenInstructionValue( value = codegenPlace(cx, instrValue.place); break; } + case "StoreLocal": { + CompilerError.invariant( + `Unexpected StoreLocal in codegenInstructionValue`, + instrValue.loc + ); + } case "FunctionExpression": { value = instrValue.expr; break; diff --git a/compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts b/compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts index b51e11a1f8..f886032234 100644 --- a/compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts +++ b/compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts @@ -21,27 +21,34 @@ import { } from "./visitors"; type IdentifierReactivity = Map; -class Visitor extends ReactiveFunctionVisitor { - override visitInstruction( - instr: ReactiveInstruction, - reactivityMap: IdentifierReactivity - ) { - this.traverseInstruction(instr, reactivityMap); + +class State { + reactivityMap: IdentifierReactivity = new Map(); + temporaries: Map = new Map(); +} + +class Visitor extends ReactiveFunctionVisitor { + override visitInstruction(instr: ReactiveInstruction, state: State) { + this.traverseInstruction(instr, state); const lval = instr.lvalue; if (lval == null) { return; } const { value } = instr; - let hasReactiveInput = reactivityMap.get(lval.place.identifier.id) === true; - if (!hasReactiveInput && value.kind !== "LoadGlobal") { - for (const operand of eachReactiveValueOperand(value)) { - // We currently treat free variables (from module or global scope) as - // non-reactive. We may later want type information about specific - // free variables, or a toggle `treatFreeVarsAsReactive`. - if (reactivityMap.get(operand.identifier.id)) { - hasReactiveInput = true; - break; - } + let hasReactiveInput = false; + // Globals are currently treated as non-reactive this happens implicitly because LoadGlobal + // has no operands which can be registered as reactive. + // Consider adding an option to declare whether a given global can be reactive or not, or + // a more general "treat all globals as reactive" flag. + for (const operand of eachReactiveValueOperand(value)) { + if (operand.effect === Effect.Store) { + continue; + } + const resolvedId: IdentifierId = + state.temporaries.get(operand.identifier.id) ?? operand.identifier.id; + if (state.reactivityMap.get(resolvedId)) { + hasReactiveInput = true; + break; } } if ( @@ -56,7 +63,7 @@ class Visitor extends ReactiveFunctionVisitor { // allow treating safe hooks as non-reactive. hasReactiveInput = true; } - reactivityMap.set(lval.place.identifier.id, hasReactiveInput); + state.reactivityMap.set(lval.place.identifier.id, hasReactiveInput); if (hasReactiveInput) { // all mutating effects must also be marked as reactive @@ -65,12 +72,10 @@ class Visitor extends ReactiveFunctionVisitor { case Effect.Capture: case Effect.Store: case Effect.Mutate: { - // Explicitly compare to `false` here, since absence from the - // map indicates a free variable - // todo [@mofeiZ] add knowledge about free variables - if (reactivityMap.get(operand.identifier.id) === false) { - reactivityMap.set(operand.identifier.id, true); - } + const resolvedId: IdentifierId = + state.temporaries.get(operand.identifier.id) ?? + operand.identifier.id; + state.reactivityMap.set(resolvedId, true); break; } case Effect.Freeze: @@ -90,6 +95,14 @@ class Visitor extends ReactiveFunctionVisitor { } } } + if (instr.lvalue !== null) { + if (instr.value.kind === "LoadLocal") { + state.temporaries.set( + instr.lvalue.place.identifier.id, + instr.value.place.identifier.id + ); + } + } } } /** @@ -134,18 +147,14 @@ export function inferReactiveIdentifiers( fn: ReactiveFunction ): Set { const visitor = new Visitor(); - const reactivityMap: IdentifierReactivity = new Map(); + const state = new State(); for (const param of fn.params) { - reactivityMap.set(param.identifier.id, true); + state.reactivityMap.set(param.identifier.id, true); } - let size: number; - do { - size = reactivityMap.size; - visitReactiveFunction(fn, visitor, reactivityMap); - } while (reactivityMap.size > size); + visitReactiveFunction(fn, visitor, state); const result = new Set(); - reactivityMap.forEach((isReactive, id) => { + state.reactivityMap.forEach((isReactive, id) => { if (isReactive) result.add(id); }); return result; diff --git a/compiler/forget/src/ReactiveScopes/InferReactiveScopeVariables.ts b/compiler/forget/src/ReactiveScopes/InferReactiveScopeVariables.ts index 5f686ad438..bbee09a376 100644 --- a/compiler/forget/src/ReactiveScopes/InferReactiveScopeVariables.ts +++ b/compiler/forget/src/ReactiveScopes/InferReactiveScopeVariables.ts @@ -102,14 +102,29 @@ export function inferReactiveScopeVariables(fn: HIRFunction): void { if (range.end > range.start + 1 || mayAllocate(instr.value)) { operands.push(instr.lvalue!.place.identifier); } - for (const operand of eachInstructionOperand(instr)) { + if (instr.value.kind === "StoreLocal") { if ( - isMutable(instr, operand) && - // exclude global variables from being added to scopes, we can't recreate them! - // TODO: improve handling of module-scoped variables and globals - operand.identifier.mutableRange.start > 0 + instr.value.lvalue.place.identifier.mutableRange.end > + instr.value.lvalue.place.identifier.mutableRange.start + 1 ) { - operands.push(operand.identifier); + operands.push(instr.value.lvalue.place.identifier); + } + if ( + isMutable(instr, instr.value.value) && + instr.value.value.identifier.mutableRange.start > 0 + ) { + operands.push(instr.value.value.identifier); + } + } else { + for (const operand of eachInstructionOperand(instr)) { + if ( + isMutable(instr, operand) && + // exclude global variables from being added to scopes, we can't recreate them! + // TODO: improve handling of module-scoped variables and globals + operand.identifier.mutableRange.start > 0 + ) { + operands.push(operand.identifier); + } } } if (operands.length !== 0) { @@ -168,6 +183,7 @@ function isMutable({ id }: Instruction, place: Place): boolean { function mayAllocate(value: InstructionValue): boolean { switch (value.kind) { + case "StoreLocal": case "LoadGlobal": case "TypeCastExpression": case "BinaryExpression": diff --git a/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts b/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts index 0c81b7fdff..813b65c7d2 100644 --- a/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts +++ b/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts @@ -522,18 +522,15 @@ class Context { * Record a variable that is declared in some other scope and that is being reassigned in the * current one as a {@link ReactiveScope.reassignments} */ - visitReassignment(lvalue: LValue): void { - if (lvalue.kind !== InstructionKind.Reassign) { - return; - } - const declaration = this.#declarations.get(lvalue.place.identifier.id); + visitReassignment(place: Place): void { + const declaration = this.#declarations.get(place.identifier.id); if ( this.currentScope != null && - lvalue.place.identifier.scope != null && + place.identifier.scope != null && declaration !== undefined && - declaration.scope !== lvalue.place.identifier.scope + declaration.scope !== place.identifier.scope ) { - this.currentScope.reassignments.add(lvalue.place.identifier); + this.currentScope.reassignments.add(place.identifier); } } } @@ -570,21 +567,21 @@ function visit(context: Context, block: ReactiveBlock): void { break; } case "for": { - visitReactiveValue(context, terminal.init); - visitReactiveValue(context, terminal.test); + visitReactiveValue(context, terminal.id, terminal.init); + visitReactiveValue(context, terminal.id, terminal.test); context.enterConditional(() => { - visitReactiveValue(context, terminal.update); + visitReactiveValue(context, terminal.id, terminal.update); visit(context, terminal.loop); }); break; } case "do-while": { visit(context, terminal.loop); - visitReactiveValue(context, terminal.test); + visitReactiveValue(context, terminal.id, terminal.test); break; } case "while": { - visitReactiveValue(context, terminal.test); + visitReactiveValue(context, terminal.id, terminal.test); context.enterConditional(() => { visit(context, terminal.loop); }); @@ -642,22 +639,25 @@ function visit(context: Context, block: ReactiveBlock): void { } } -function visitReactiveValue(context: Context, value: ReactiveValue): void { +function visitReactiveValue( + context: Context, + id: InstructionId, + value: ReactiveValue +): void { switch (value.kind) { case "LogicalExpression": { - visitReactiveValue(context, value.left); - + visitReactiveValue(context, id, value.left); context.enterConditional(() => { - visitReactiveValue(context, value.right); + visitReactiveValue(context, id, value.right); }); break; } case "ConditionalExpression": { - visitReactiveValue(context, value.test); + visitReactiveValue(context, id, value.test); context.enterConditional(() => { - visitReactiveValue(context, value.consequent); - visitReactiveValue(context, value.alternate); + visitReactiveValue(context, id, value.consequent); + visitReactiveValue(context, id, value.alternate); }); break; } @@ -665,7 +665,7 @@ function visitReactiveValue(context: Context, value: ReactiveValue): void { for (const instr of value.instructions) { visitInstruction(context, instr); } - visitInstructionValue(context, value.value, null); + visitInstructionValue(context, id, value.value, null); break; } default: { @@ -678,6 +678,7 @@ function visitReactiveValue(context: Context, value: ReactiveValue): void { function visitInstructionValue( context: Context, + id: InstructionId, value: ReactiveValue, lvalue: LValue | null ): void { @@ -696,20 +697,26 @@ function visitInstructionValue( } else { context.visitProperty(value.object, value.property); } + } else if (value.kind === "StoreLocal") { + context.visitOperand(value.value); + if (value.lvalue.kind === InstructionKind.Reassign) { + context.visitReassignment(value.lvalue.place); + } + context.declare(value.lvalue.place.identifier, { + id, + scope: context.currentScope, + }); } else { - visitReactiveValue(context, value); + visitReactiveValue(context, id, value); } } function visitInstruction(context: Context, instr: ReactiveInstruction): void { const { lvalue } = instr; - visitInstructionValue(context, instr.value, lvalue); + visitInstructionValue(context, instr.id, instr.value, lvalue); if (lvalue == null) { return; } - if (lvalue.kind === InstructionKind.Reassign) { - context.visitReassignment(lvalue); - } context.declare(lvalue.place.identifier, { id: instr.id, scope: context.currentScope, diff --git a/compiler/forget/src/SSA/EnterSSA.ts b/compiler/forget/src/SSA/EnterSSA.ts index 89a2ce8b67..02a16508af 100644 --- a/compiler/forget/src/SSA/EnterSSA.ts +++ b/compiler/forget/src/SSA/EnterSSA.ts @@ -212,7 +212,16 @@ export default function enterSSA(func: HIRFunction): void { } for (const instr of block.instructions) { - mapInstructionOperands(instr, (place) => builder.getPlace(place)); + if (instr.value.kind === "StoreLocal") { + const oldPlace = instr.value.lvalue.place; + const newPlace = builder.definePlace(oldPlace); + instr.lvalue.kind = InstructionKind.Const; + instr.value.lvalue.place = newPlace; + + instr.value.value = builder.getPlace(instr.value.value); + } else { + mapInstructionOperands(instr, (place) => builder.getPlace(place)); + } const oldPlace = instr.lvalue.place; const newPlace = builder.definePlace(oldPlace); diff --git a/compiler/forget/src/SSA/LeaveSSA.ts b/compiler/forget/src/SSA/LeaveSSA.ts index 1104ca6007..223c60664b 100644 --- a/compiler/forget/src/SSA/LeaveSSA.ts +++ b/compiler/forget/src/SSA/LeaveSSA.ts @@ -110,7 +110,7 @@ export function leaveSSA(fn: HIRFunction): void { for (const instr of block.instructions) { // Iterate the instructions and perform any rewrites as well as promoting SSA variables to // `let` or `reassign` where possible. - const { lvalue } = instr; + const { lvalue, value } = instr; if ( lvalue.kind === InstructionKind.Const && rewrites.has(lvalue.place.identifier) @@ -122,16 +122,30 @@ export function leaveSSA(fn: HIRFunction): void { rewrites.get(lvalue.place.identifier) === lvalue.place.identifier ? InstructionKind.Let : InstructionKind.Reassign; - } else if (lvalue.place.identifier.name != null) { - const originalLVal = declarations.get(lvalue.place.identifier.name); + } else if ( + value.kind === "StoreLocal" && + value.lvalue.place.identifier.name != null + ) { + const originalLVal = declarations.get( + value.lvalue.place.identifier.name + ); if (originalLVal === undefined) { - declarations.set(lvalue.place.identifier.name, lvalue); + declarations.set(value.lvalue.place.identifier.name, value.lvalue); + value.lvalue.kind = InstructionKind.Const; } else { // This is an instance of the original id, so we need to promote the original declaration // to a `let` and the current lval to a `reassign` originalLVal.kind = InstructionKind.Let; - lvalue.kind = InstructionKind.Reassign; } + } else if ( + value.kind === "StoreLocal" && + rewrites.has(value.lvalue.place.identifier) + ) { + value.lvalue.kind = + rewrites.get(value.lvalue.place.identifier) === + value.lvalue.place.identifier + ? InstructionKind.Let + : InstructionKind.Reassign; } rewritePlace(lvalue.place, rewrites, declarations); for (const operand of eachInstructionValueOperand(instr.value)) { @@ -223,6 +237,58 @@ export function leaveSSA(fn: HIRFunction): void { ); const declaration = declarations.get(phi.id.name); if (declaration === undefined) { + let initValue: Place; + if (initOperand === null) { + initValue = { + effect: Effect.Read, + kind: "Identifier", + loc: GeneratedSource, + identifier: { + id: fn.env.nextIdentifierId, + name: null, + mutableRange: { + // TODO: this is technically the wrong start range; we do this because the instruction to create the + // undefined and the instruction to store it to the identifier share an InstructionId, which makes + // this value otherwise appear mutable when stored. All that matters is that the range end prior + // to the StoreLocal's instruction id, so we decrement by one. + start: makeInstructionId(block.terminal.id - 1), + end: makeInstructionId(block.terminal.id), + }, + scope: null, + type: { kind: "Primitive" }, + }, + }; + block.instructions.push({ + id: block.terminal.id, + lvalue: { + place: { ...initValue, effect: Effect.Mutate }, + kind: InstructionKind.Const, + }, + value: { + kind: "Primitive", + // TODO: consider leaving the variable uninitialized rather than explicitly undefined. + value: undefined, + loc: GeneratedSource, + }, + loc: GeneratedSource, + }); + } else { + initValue = { + kind: "Identifier", + identifier: initOperand, + effect: Effect.Capture, + loc: GeneratedSource, + }; + } + const lvalue: LValue = { + place: { + kind: "Identifier", + identifier: phi.id, + effect: Effect.Mutate, + loc: GeneratedSource, + }, + kind: InstructionKind.Let, + }; const instr: Instruction = { // NOTE: reuse the terminal id since these lets must be scoped with the terminal anyway. // the mutable range of this canonical id must by definition span from the binding (before @@ -231,34 +297,31 @@ export function leaveSSA(fn: HIRFunction): void { lvalue: { place: { kind: "Identifier", - identifier: phi.id, + identifier: { + id: fn.env.nextIdentifierId, + mutableRange: { + start: block.terminal.id, + end: makeInstructionId(block.terminal.id + 1), + }, + name: null, + scope: null, + type: phi.id.type, + }, effect: Effect.Mutate, loc: GeneratedSource, }, - kind: InstructionKind.Let, + kind: InstructionKind.Const, + }, + value: { + kind: "StoreLocal", + lvalue, + value: initValue, + loc: GeneratedSource, }, - value: - initOperand !== null - ? { - kind: "LoadLocal", - place: { - kind: "Identifier", - identifier: initOperand, - effect: Effect.Read, - loc: GeneratedSource, - }, - loc: GeneratedSource, - } - : { - kind: "Primitive", - // TODO: consider leaving the variable uninitialized rather than explicitly undefined. - value: undefined, - loc: GeneratedSource, - }, loc: GeneratedSource, }; block.instructions.push(instr); - declarations.set(phi.id.name, instr.lvalue); + declarations.set(phi.id.name, lvalue); phi.id.mutableRange.start = terminal.id; if (!isPhiMutatedAfterCreation) { phi.id.mutableRange.end = makeInstructionId(terminal.id + 1); diff --git a/compiler/forget/src/TypeInference/InferTypes.ts b/compiler/forget/src/TypeInference/InferTypes.ts index d7670911dc..1d52f7e21a 100644 --- a/compiler/forget/src/TypeInference/InferTypes.ts +++ b/compiler/forget/src/TypeInference/InferTypes.ts @@ -112,6 +112,15 @@ function* generateInstructionTypes( break; } + case "StoreLocal": { + yield equation(left, value.value.identifier.type); + yield equation( + value.lvalue.place.identifier.type, + value.value.identifier.type + ); + break; + } + case "BinaryExpression": { if (isPrimitiveBinaryOp(value.operator)) { yield equation(value.left.identifier.type, { kind: "Primitive" }); diff --git a/compiler/forget/src/__tests__/fixtures/hir/_bug.capturing-func-simple-alias.expect.md b/compiler/forget/src/__tests__/fixtures/hir/_bug.capturing-func-simple-alias.expect.md index 8de657bb48..5ff013bf3d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/_bug.capturing-func-simple-alias.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/_bug.capturing-func-simple-alias.expect.md @@ -20,14 +20,15 @@ function component(a) { function component(a) { const $ = React.unstable_useMemoCache(2); const c_0 = $[0] !== a; - let x; + let t0; if (c_0) { - x = { a: a }; + t0 = { a: a }; $[0] = a; - $[1] = x; + $[1] = t0; } else { - x = $[1]; + t0 = $[1]; } + const x = t0; (function () { y = x; diff --git a/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md b/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md index 63f754b2c9..88c854c57f 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md @@ -18,13 +18,14 @@ function component() { ```javascript function component() { const $ = React.unstable_useMemoCache(3); - let z; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - z = []; - $[0] = z; + t0 = []; + $[0] = t0; } else { - z = $[0]; + t0 = $[0]; } + const z = t0; let y; if ($[1] === Symbol.for("react.memo_cache_sentinel")) { y = {}; diff --git a/compiler/forget/src/__tests__/fixtures/hir/allocating-primitive-as-dep.expect.md b/compiler/forget/src/__tests__/fixtures/hir/allocating-primitive-as-dep.expect.md index e6031161e4..4d64b373f8 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/allocating-primitive-as-dep.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/allocating-primitive-as-dep.expect.md @@ -41,63 +41,68 @@ function AllocatingPrimitiveAsDep(props) { } const t1 = t0.b + 1; const c_2 = $[2] !== t1; - let y; + let t2; if (c_2) { - y = foo(t1); + t2 = foo(t1); $[2] = t1; - $[3] = y; + $[3] = t2; } else { - y = $[3]; + t2 = $[3]; } + const y = t2; return y; } function PrimitiveAsDepNested(props) { - const $ = React.unstable_useMemoCache(10); + const $ = React.unstable_useMemoCache(11); const c_0 = $[0] !== props.b; const c_1 = $[1] !== props.a; let x; + let y; if (c_0 || c_1) { x = {}; mutate(x); - const c_3 = $[3] !== props.b; + const c_4 = $[4] !== props.b; let t0; - if (c_3) { + if (c_4) { t0 = bar(props.b); - $[3] = props.b; - $[4] = t0; + $[4] = props.b; + $[5] = t0; } else { - t0 = $[4]; + t0 = $[5]; } const t1 = t0 + 1; - const c_5 = $[5] !== t1; - let y; - if (c_5) { - y = foo(t1); - $[5] = t1; - $[6] = y; + const c_6 = $[6] !== t1; + let t2; + if (c_6) { + t2 = foo(t1); + $[6] = t1; + $[7] = t2; } else { - y = $[6]; + t2 = $[7]; } + y = t2; mutate(x, props.a); $[0] = props.b; $[1] = props.a; $[2] = x; + $[3] = y; } else { x = $[2]; + y = $[3]; } - const c_7 = $[7] !== x; - const c_8 = $[8] !== y; - let t2; - if (c_7 || c_8) { - t2 = [x, y]; - $[7] = x; - $[8] = y; - $[9] = t2; + const c_8 = $[8] !== x; + const c_9 = $[9] !== y; + let t3; + if (c_8 || c_9) { + t3 = [x, y]; + $[8] = x; + $[9] = y; + $[10] = t3; } else { - t2 = $[9]; + t3 = $[10]; } - return t2; + return t3; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/array-access-assignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/array-access-assignment.expect.md index ceac7b26cb..1e0cd1f8ef 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/array-access-assignment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/array-access-assignment.expect.md @@ -26,14 +26,15 @@ function foo(a, b, c) { if (c_0 || c_1 || c_2) { x = [a]; const c_5 = $[5] !== b; - let y; + let t0; if (c_5) { - y = [null, b]; + t0 = [null, b]; $[5] = b; - $[6] = y; + $[6] = t0; } else { - y = $[6]; + t0 = $[6]; } + const y = t0; z = [[], [], [c]]; x[0] = y[1]; z[0][0] = x[0]; @@ -48,16 +49,16 @@ function foo(a, b, c) { } const c_7 = $[7] !== x; const c_8 = $[8] !== z; - let t0; + let t1; if (c_7 || c_8) { - t0 = [x, z]; + t1 = [x, z]; $[7] = x; $[8] = z; - $[9] = t0; + $[9] = t1; } else { - t0 = $[9]; + t1 = $[9]; } - return t0; + return t1; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/assignment-in-nested-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/assignment-in-nested-if.expect.md index 4f1f37ae5c..5ee3cdac92 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/assignment-in-nested-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/assignment-in-nested-if.expect.md @@ -24,12 +24,14 @@ function useBar(props) { let z = undefined; if (props.a) { if (props.b) { + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - z = baz(); - $[0] = z; + t0 = baz(); + $[0] = t0; } else { - z = $[0]; + t0 = $[0]; } + z = t0; } } return z; diff --git a/compiler/forget/src/__tests__/fixtures/hir/assignment-variations.expect.md b/compiler/forget/src/__tests__/fixtures/hir/assignment-variations.expect.md index 1d31fd3a44..466df3ea3b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/assignment-variations.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/assignment-variations.expect.md @@ -16,8 +16,7 @@ function f() { ```javascript function f() { - let x = 3; - x = x >>> 1; + const x = 3 >>> 1; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/bug_object-pattern.expect.md b/compiler/forget/src/__tests__/fixtures/hir/bug_object-pattern.expect.md index 1573ca3811..649298ccc0 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/bug_object-pattern.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/bug_object-pattern.expect.md @@ -17,14 +17,15 @@ function component(t) { const $ = React.unstable_useMemoCache(2); const a = t.a; const c_0 = $[0] !== a; - let y; + let t0; if (c_0) { - y = { a: a }; + t0 = { a: a }; $[0] = a; - $[1] = y; + $[1] = t0; } else { - y = $[1]; + t0 = $[1]; } + const y = t0; return y; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/capture-func-passed-to-jsx.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capture-func-passed-to-jsx.expect.md index 16570e78f8..deb506ce66 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capture-func-passed-to-jsx.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capture-func-passed-to-jsx.expect.md @@ -22,46 +22,50 @@ function component(a, b) { function component(a, b) { const $ = React.unstable_useMemoCache(9); const c_0 = $[0] !== b; - let y; + let t0; if (c_0) { - y = { b: b }; + t0 = { b: b }; $[0] = b; - $[1] = y; + $[1] = t0; } else { - y = $[1]; + t0 = $[1]; } + const y = t0; const c_2 = $[2] !== a; - let z; + let t1; if (c_2) { - z = { a: a }; + t1 = { a: a }; $[2] = a; - $[3] = z; + $[3] = t1; } else { - z = $[3]; + t1 = $[3]; } + const z = t1; const c_4 = $[4] !== z.a; const c_5 = $[5] !== y.b; - let x; + let t2; if (c_4 || c_5) { - x = function () { + t2 = function () { z.a = 2; y.b; }; $[4] = z.a; $[5] = y.b; - $[6] = x; + $[6] = t2; } else { - x = $[6]; + t2 = $[6]; } + const x = t2; const c_7 = $[7] !== x; - let t; + let t3; if (c_7) { - t = ; + t3 = ; $[7] = x; - $[8] = t; + $[8] = t3; } else { - t = $[8]; + t3 = $[8]; } + const t = t3; mutate(x); return t; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-arrow-function-1.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-arrow-function-1.expect.md index 13ad4c6c84..c11c944dbf 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-arrow-function-1.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-arrow-function-1.expect.md @@ -18,25 +18,27 @@ function component(a) { function component(a) { const $ = React.unstable_useMemoCache(4); const c_0 = $[0] !== a; - let z; + let t0; if (c_0) { - z = { a: a }; + t0 = { a: a }; $[0] = a; - $[1] = z; + $[1] = t0; } else { - z = $[1]; + t0 = $[1]; } + const z = t0; const c_2 = $[2] !== z; - let x; + let t1; if (c_2) { - x = () => { + t1 = () => { z; }; $[2] = z; - $[3] = x; + $[3] = t1; } else { - x = $[3]; + t1 = $[3]; } + const x = t1; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-func-mutate-2.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-func-mutate-2.expect.md index f9b87ad5f7..55339e98d2 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-func-mutate-2.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-func-mutate-2.expect.md @@ -21,14 +21,15 @@ function component(a, b) { function component(a, b) { const $ = React.unstable_useMemoCache(5); const c_0 = $[0] !== b; - let y; + let t0; if (c_0) { - y = { b: b }; + t0 = { b: b }; $[0] = b; - $[1] = y; + $[1] = t0; } else { - y = $[1]; + t0 = $[1]; } + const y = t0; const c_2 = $[2] !== a; const c_3 = $[3] !== y.b; let x; diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-func-mutate-3.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-func-mutate-3.expect.md index 3f31743d4d..1fdf0b7eb0 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-func-mutate-3.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-func-mutate-3.expect.md @@ -20,37 +20,40 @@ function component(a, b) { function component(a, b) { const $ = React.unstable_useMemoCache(7); const c_0 = $[0] !== b; - let y; + let t0; if (c_0) { - y = { b: b }; + t0 = { b: b }; $[0] = b; - $[1] = y; + $[1] = t0; } else { - y = $[1]; + t0 = $[1]; } + const y = t0; const c_2 = $[2] !== a; - let z; + let t1; if (c_2) { - z = { a: a }; + t1 = { a: a }; $[2] = a; - $[3] = z; + $[3] = t1; } else { - z = $[3]; + t1 = $[3]; } + const z = t1; const c_4 = $[4] !== z.a; const c_5 = $[5] !== y.b; - let x; + let t2; if (c_4 || c_5) { - x = function () { + t2 = function () { z.a = 2; y.b; }; $[4] = z.a; $[5] = y.b; - $[6] = x; + $[6] = t2; } else { - x = $[6]; + t2 = $[6]; } + const x = t2; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-func-mutate.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-func-mutate.expect.md index 665bd61a88..555b7635c1 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-func-mutate.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-func-mutate.expect.md @@ -26,14 +26,15 @@ function component(a, b) { if (c_0 || c_1) { const z = { a: a }; const c_3 = $[3] !== b; - let y; + let t0; if (c_3) { - y = { b: b }; + t0 = { b: b }; $[3] = b; - $[4] = y; + $[4] = t0; } else { - y = $[4]; + t0 = $[4]; } + const y = t0; x = function () { z.a = 2; y.b; diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-function-1.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-function-1.expect.md index 640f1805d7..1ba76cd11a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-function-1.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-function-1.expect.md @@ -18,25 +18,27 @@ function component(a) { function component(a) { const $ = React.unstable_useMemoCache(4); const c_0 = $[0] !== a; - let z; + let t0; if (c_0) { - z = { a: a }; + t0 = { a: a }; $[0] = a; - $[1] = z; + $[1] = t0; } else { - z = $[1]; + t0 = $[1]; } + const z = t0; const c_2 = $[2] !== z; - let x; + let t1; if (c_2) { - x = function () { + t1 = function () { z; }; $[2] = z; - $[3] = x; + $[3] = t1; } else { - x = $[3]; + t1 = $[3]; } + const x = t1; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-function-member-expr-call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-function-member-expr-call.expect.md index 73a1740d14..cd11bc3c6e 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-function-member-expr-call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-function-member-expr-call.expect.md @@ -19,44 +19,45 @@ function component({ mutator }) { ## Code ```javascript -function component(t23) { +function component(t28) { const $ = React.unstable_useMemoCache(7); - const t0 = t23; - const mutator = t0.mutator; + const mutator = t28.mutator; const c_0 = $[0] !== mutator; - let poke; + let t0; if (c_0) { - poke = () => { + t0 = () => { mutator.poke(); }; $[0] = mutator; - $[1] = poke; + $[1] = t0; } else { - poke = $[1]; + t0 = $[1]; } - const c_2 = $[2] !== t0.mutator.user; - let hide; + const poke = t0; + const c_2 = $[2] !== mutator.user; + let t1; if (c_2) { - hide = () => { + t1 = () => { mutator.user.hide(); }; - $[2] = t0.mutator.user; - $[3] = hide; + $[2] = mutator.user; + $[3] = t1; } else { - hide = $[3]; + t1 = $[3]; } + const hide = t1; const c_4 = $[4] !== poke; const c_5 = $[5] !== hide; - let t1; + let t2; if (c_4 || c_5) { - t1 = ; + t2 = ; $[4] = poke; $[5] = hide; - $[6] = t1; + $[6] = t2; } else { - t1 = $[6]; + t2 = $[6]; } - return t1; + return t2; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-function-within-block.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-function-within-block.expect.md index ebdfd83a0e..b6ecc41614 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-function-within-block.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-function-within-block.expect.md @@ -21,25 +21,27 @@ function component(a) { function component(a) { const $ = React.unstable_useMemoCache(4); const c_0 = $[0] !== a; - let z; + let t0; if (c_0) { - z = { a: a }; + t0 = { a: a }; $[0] = a; - $[1] = z; + $[1] = t0; } else { - z = $[1]; + t0 = $[1]; } + const z = t0; const c_2 = $[2] !== z; - let x; + let t1; if (c_2) { - x = function () { + t1 = function () { z; }; $[2] = z; - $[3] = x; + $[3] = t1; } else { - x = $[3]; + t1 = $[3]; } + const x = t1; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-member-expr.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-member-expr.expect.md index 7ec2f87fd4..9eb8a5cc1c 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-member-expr.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-member-expr.expect.md @@ -18,25 +18,27 @@ function component(a) { function component(a) { const $ = React.unstable_useMemoCache(4); const c_0 = $[0] !== a; - let z; + let t0; if (c_0) { - z = { a: a }; + t0 = { a: a }; $[0] = a; - $[1] = z; + $[1] = t0; } else { - z = $[1]; + t0 = $[1]; } + const z = t0; const c_2 = $[2] !== z.a; - let x; + let t1; if (c_2) { - x = function () { + t1 = function () { z.a; }; $[2] = z.a; - $[3] = x; + $[3] = t1; } else { - x = $[3]; + t1 = $[3]; } + const x = t1; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-call.expect.md index 9e1667151f..16583f4ac3 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-call.expect.md @@ -27,25 +27,27 @@ function component(a) { t0 = $[1]; } const c_2 = $[2] !== t0; - let z; + let t1; if (c_2) { - z = { a: t0 }; + t1 = { a: t0 }; $[2] = t0; - $[3] = z; + $[3] = t1; } else { - z = $[3]; + t1 = $[3]; } + const z = t1; const c_4 = $[4] !== z.a; - let x; + let t2; if (c_4) { - x = function () { + t2 = function () { z.a.a(); }; $[4] = z.a; - $[5] = x; + $[5] = t2; } else { - x = $[5]; + t2 = $[5]; } + const x = t2; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr-in-nested-func.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr-in-nested-func.expect.md index 33ac90a195..74a8575667 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr-in-nested-func.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr-in-nested-func.expect.md @@ -29,27 +29,29 @@ function component(a) { t0 = $[1]; } const c_2 = $[2] !== t0; - let z; + let t1; if (c_2) { - z = { a: t0 }; + t1 = { a: t0 }; $[2] = t0; - $[3] = z; + $[3] = t1; } else { - z = $[3]; + t1 = $[3]; } + const z = t1; const c_4 = $[4] !== z.a.a; - let x; + let t2; if (c_4) { - x = function () { + t2 = function () { (function () { z.a.a; })(); }; $[4] = z.a.a; - $[5] = x; + $[5] = t2; } else { - x = $[5]; + t2 = $[5]; } + const x = t2; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr.expect.md index 8895ecd944..0ff028550d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr.expect.md @@ -27,25 +27,27 @@ function component(a) { t0 = $[1]; } const c_2 = $[2] !== t0; - let z; + let t1; if (c_2) { - z = { a: t0 }; + t1 = { a: t0 }; $[2] = t0; - $[3] = z; + $[3] = t1; } else { - z = $[3]; + t1 = $[3]; } + const z = t1; const c_4 = $[4] !== z.a.a; - let x; + let t2; if (c_4) { - x = function () { + t2 = function () { z.a.a; }; $[4] = z.a.a; - $[5] = x; + $[5] = t2; } else { - x = $[5]; + t2 = $[5]; } + const x = t2; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-variable-in-nested-block.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-variable-in-nested-block.expect.md index fcbd205f5c..a49d9ace8b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-variable-in-nested-block.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-variable-in-nested-block.expect.md @@ -20,27 +20,29 @@ function component(a) { function component(a) { const $ = React.unstable_useMemoCache(4); const c_0 = $[0] !== a; - let z; + let t0; if (c_0) { - z = { a: a }; + t0 = { a: a }; $[0] = a; - $[1] = z; + $[1] = t0; } else { - z = $[1]; + t0 = $[1]; } + const z = t0; const c_2 = $[2] !== z; - let x; + let t1; if (c_2) { - x = function () { + t1 = function () { { z; } }; $[2] = z; - $[3] = x; + $[3] = t1; } else { - x = $[3]; + t1 = $[3]; } + const x = t1; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-variable-in-nested-function.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-variable-in-nested-function.expect.md index dde6984aed..fdee9711a3 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-variable-in-nested-function.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-variable-in-nested-function.expect.md @@ -20,27 +20,29 @@ function component(a) { function component(a) { const $ = React.unstable_useMemoCache(4); const c_0 = $[0] !== a; - let z; + let t0; if (c_0) { - z = { a: a }; + t0 = { a: a }; $[0] = a; - $[1] = z; + $[1] = t0; } else { - z = $[1]; + t0 = $[1]; } + const z = t0; const c_2 = $[2] !== z; - let x; + let t1; if (c_2) { - x = function () { + t1 = function () { (function () { z; })(); }; $[2] = z; - $[3] = x; + $[3] = t1; } else { - x = $[3]; + t1 = $[3]; } + const x = t1; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md index e1f3544fc4..0acc2fedb3 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md @@ -45,14 +45,15 @@ function Component(props) { renderedItems = []; const seen = new Set(); const c_3 = $[3] !== maxItems; - let max; + let t0; if (c_3) { - max = Math.max(0, maxItems); + t0 = Math.max(0, maxItems); $[3] = maxItems; - $[4] = max; + $[4] = t0; } else { - max = $[4]; + t0 = $[4]; } + const max = t0; for (let i = 0; i < items.length; i = i + 1, i) { const item = items.at(i); if (item == null || seen.has(item)) { @@ -74,31 +75,31 @@ function Component(props) { const count = renderedItems.length; const c_5 = $[5] !== count; - let t0; - if (c_5) { - t0 =

{count} Items

; - $[5] = count; - $[6] = t0; - } else { - t0 = $[6]; - } - const c_7 = $[7] !== t0; - const c_8 = $[8] !== renderedItems; let t1; + if (c_5) { + t1 =

{count} Items

; + $[5] = count; + $[6] = t1; + } else { + t1 = $[6]; + } + const c_7 = $[7] !== t1; + const c_8 = $[8] !== renderedItems; + let t2; if (c_7 || c_8) { - t1 = ( + t2 = (
- {t0} + {t1} {renderedItems}
); - $[7] = t0; + $[7] = t1; $[8] = renderedItems; - $[9] = t1; + $[9] = t2; } else { - t1 = $[9]; + t2 = $[9]; } - return t1; + return t2; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/concise-arrow-expr.expect.md b/compiler/forget/src/__tests__/fixtures/hir/concise-arrow-expr.expect.md index b0e1da977a..e43709ed22 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/concise-arrow-expr.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/concise-arrow-expr.expect.md @@ -17,24 +17,25 @@ function component() { const $ = React.unstable_useMemoCache(4); const setX = useState(0)[1]; const c_0 = $[0] !== setX; - let handler; - if (c_0) { - handler = (v) => setX(v); - $[0] = setX; - $[1] = handler; - } else { - handler = $[1]; - } - const c_2 = $[2] !== handler; let t0; - if (c_2) { - t0 = ; - $[2] = handler; - $[3] = t0; + if (c_0) { + t0 = (v) => setX(v); + $[0] = setX; + $[1] = t0; } else { - t0 = $[3]; + t0 = $[1]; } - return t0; + const handler = t0; + const c_2 = $[2] !== handler; + let t1; + if (c_2) { + t1 = ; + $[2] = handler; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/controlled-input.expect.md b/compiler/forget/src/__tests__/fixtures/hir/controlled-input.expect.md index 614f9b65d4..1e18384a2c 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/controlled-input.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/controlled-input.expect.md @@ -15,30 +15,31 @@ function component() { ```javascript function component() { const $ = React.unstable_useMemoCache(5); - const t1 = useState(0); - const x = t1[0]; - const setX = t1[1]; + const t2 = useState(0); + const x = t2[0]; + const setX = t2[1]; const c_0 = $[0] !== setX; - let handler; + let t0; if (c_0) { - handler = (event) => setX(event.target.value); + t0 = (event) => setX(event.target.value); $[0] = setX; - $[1] = handler; + $[1] = t0; } else { - handler = $[1]; + t0 = $[1]; } + const handler = t0; const c_2 = $[2] !== handler; const c_3 = $[3] !== x; - let t0; + let t1; if (c_2 || c_3) { - t0 = ; + t1 = ; $[2] = handler; $[3] = x; - $[4] = t0; + $[4] = t1; } else { - t0 = $[4]; + t1 = $[4]; } - return t0; + return t1; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/destructure-capture-global.expect.md b/compiler/forget/src/__tests__/fixtures/hir/destructure-capture-global.expect.md index 9f0d022a43..94d5c7c989 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/destructure-capture-global.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/destructure-capture-global.expect.md @@ -17,14 +17,15 @@ let someGlobal = {}; function component(a) { const $ = React.unstable_useMemoCache(2); const c_0 = $[0] !== a; - let x; + let t0; if (c_0) { - x = { a: a, someGlobal: someGlobal }; + t0 = { a: a, someGlobal: someGlobal }; $[0] = a; - $[1] = x; + $[1] = t0; } else { - x = $[1]; + t0 = $[1]; } + const x = t0; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/for-logical.expect.md b/compiler/forget/src/__tests__/fixtures/hir/for-logical.expect.md index fa80e50243..8a47de3f23 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/for-logical.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/for-logical.expect.md @@ -32,9 +32,9 @@ function foo(props) { for ( let x = 0; x > props.min && x < props.max; - x = x$0 + (props.cond ? props.increment : 2), x + x = x + (props.cond ? props.increment : 2), x ) { - const x$0 = x * 2; + x = x * 2; } return y; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/frozen-after-alias.expect.md b/compiler/forget/src/__tests__/fixtures/hir/frozen-after-alias.expect.md index fc8e3c68fd..e3716fd0d4 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/frozen-after-alias.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/frozen-after-alias.expect.md @@ -20,13 +20,14 @@ function foo(x) {} ```javascript function Component() { const $ = React.unstable_useMemoCache(1); - let a; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - a = []; - $[0] = a; + t0 = []; + $[0] = t0; } else { - a = $[0]; + t0 = $[0]; } + const a = t0; const b = a; useFreeze(a); foo(b); diff --git a/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md index 58beec82e3..4ecc4cc7fa 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md @@ -27,30 +27,31 @@ function foo() {} function Component(props) { const $ = React.unstable_useMemoCache(3); - let x; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - x = []; - $[0] = x; + t0 = []; + $[0] = t0; } else { - x = $[0]; + t0 = $[0]; } + const x = t0; const y = useFreeze(x); foo(y, x); const c_1 = $[1] !== y; - let t0; + let t1; if (c_1) { - t0 = ( + t1 = ( {x} {y} ); $[1] = y; - $[2] = t0; + $[2] = t1; } else { - t0 = $[2]; + t1 = $[2]; } - return t0; + return t1; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-arguments.expect.md b/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-arguments.expect.md index 5309f9b52d..041d0e374f 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-arguments.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-arguments.expect.md @@ -20,13 +20,14 @@ function call(x) {} ```javascript function Component() { const $ = React.unstable_useMemoCache(1); - let a; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - a = []; - $[0] = a; + t0 = []; + $[0] = t0; } else { - a = $[0]; + t0 = $[0]; } + const a = t0; useFreeze(a); useFreeze(a); call(a); diff --git a/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md b/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md index feec1ee910..77dbdb1337 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md @@ -33,12 +33,14 @@ function Component(props) { if (cond) { a = x; } else { + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - a = []; - $[0] = a; + t0 = []; + $[0] = t0; } else { - a = $[0]; + t0 = $[0]; } + a = t0; } useFreeze(a); diff --git a/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md b/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md index 48cbfb3ba1..9a344bd0d9 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md @@ -40,35 +40,37 @@ function Foo() {} function Component(props) { const $ = React.unstable_useMemoCache(7); const c_0 = $[0] !== props.a; - let a; + let t0; if (c_0) { - a = compute(props.a); + t0 = compute(props.a); $[0] = props.a; - $[1] = a; + $[1] = t0; } else { - a = $[1]; + t0 = $[1]; } + const a = t0; const c_2 = $[2] !== props.b; - let b; + let t1; if (c_2) { - b = compute(props.b); + t1 = compute(props.b); $[2] = props.b; - $[3] = b; + $[3] = t1; } else { - b = $[3]; + t1 = $[3]; } + const b = t1; const c_4 = $[4] !== a; const c_5 = $[5] !== b; - let t0; + let t2; if (c_4 || c_5) { - t0 = ; + t2 = ; $[4] = a; $[5] = b; - $[6] = t0; + $[6] = t2; } else { - t0 = $[6]; + t2 = $[6]; } - return t0; + return t2; } function compute() {} diff --git a/compiler/forget/src/__tests__/fixtures/hir/method-call-computed.expect.md b/compiler/forget/src/__tests__/fixtures/hir/method-call-computed.expect.md index a051c52c9a..1350a34241 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/method-call-computed.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/method-call-computed.expect.md @@ -24,36 +24,39 @@ function foo(a, b, c) { function foo(a, b, c) { const $ = React.unstable_useMemoCache(8); const c_0 = $[0] !== a; - let x; + let t0; if (c_0) { - x = makeObject(a); + t0 = makeObject(a); $[0] = a; - $[1] = x; + $[1] = t0; } else { - x = $[1]; + t0 = $[1]; } + const x = t0; const c_2 = $[2] !== a; - let y; + let t1; if (c_2) { - y = makeObject(a); + t1 = makeObject(a); $[2] = a; - $[3] = y; + $[3] = t1; } else { - y = $[3]; + t1 = $[3]; } + const y = t1; const c_4 = $[4] !== x; const c_5 = $[5] !== y.method; const c_6 = $[6] !== b; - let z; + let t2; if (c_4 || c_5 || c_6) { - z = x[y.method](b); + t2 = x[y.method](b); $[4] = x; $[5] = y.method; $[6] = b; - $[7] = z; + $[7] = t2; } else { - z = $[7]; + t2 = $[7]; } + const z = t2; return z; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/method-call-fn-call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/method-call-fn-call.expect.md index 50758f51f9..110ced0ca0 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/method-call-fn-call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/method-call-fn-call.expect.md @@ -21,29 +21,31 @@ function foo(a, b, c) { function foo(a, b, c) { const $ = React.unstable_useMemoCache(6); const c_0 = $[0] !== a; - let x; + let t0; if (c_0) { - x = makeObject(a); + t0 = makeObject(a); $[0] = a; - $[1] = x; + $[1] = t0; } else { - x = $[1]; + t0 = $[1]; } + const x = t0; const method = x.method; const c_2 = $[2] !== method; const c_3 = $[3] !== x; const c_4 = $[4] !== b; - let y; + let t1; if (c_2 || c_3 || c_4) { - y = method.call(x, b); + t1 = method.call(x, b); $[2] = method; $[3] = x; $[4] = b; - $[5] = y; + $[5] = t1; } else { - y = $[5]; + t1 = $[5]; } + const y = t1; return y; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/method-call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/method-call.expect.md index ec2c29a0fc..ea898b3969 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/method-call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/method-call.expect.md @@ -20,25 +20,27 @@ function foo(a, b, c) { function foo(a, b, c) { const $ = React.unstable_useMemoCache(5); const c_0 = $[0] !== a; - let x; + let t0; if (c_0) { - x = makeObject(a); + t0 = makeObject(a); $[0] = a; - $[1] = x; + $[1] = t0; } else { - x = $[1]; + t0 = $[1]; } + const x = t0; const c_2 = $[2] !== x; const c_3 = $[3] !== b; - let y; + let t1; if (c_2 || c_3) { - y = x.foo(b); + t1 = x.foo(b); $[2] = x; $[3] = b; - $[4] = y; + $[4] = t1; } else { - y = $[4]; + t1 = $[4]; } + const y = t1; return y; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md b/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md index 844e1391e7..465e44b685 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md @@ -44,13 +44,14 @@ function Component(props) { const $ = React.unstable_useMemoCache(1); const a = {}; const b = {}; - let c; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - c = {}; - $[0] = c; + t0 = {}; + $[0] = t0; } else { - c = $[0]; + t0 = $[0]; } + const c = t0; const d = {}; while (true) { mutate(a, b); diff --git a/compiler/forget/src/__tests__/fixtures/hir/obj-literal-cached-in-if-else.expect.md b/compiler/forget/src/__tests__/fixtures/hir/obj-literal-cached-in-if-else.expect.md index c552f392d3..9a1877dcd6 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/obj-literal-cached-in-if-else.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/obj-literal-cached-in-if-else.expect.md @@ -23,22 +23,26 @@ function foo(a, b, c, d) { let x = undefined; if (someVal) { const c_0 = $[0] !== b; + let t0; if (c_0) { - x = { b: b }; + t0 = { b: b }; $[0] = b; - $[1] = x; + $[1] = t0; } else { - x = $[1]; + t0 = $[1]; } + x = t0; } else { const c_2 = $[2] !== c; + let t1; if (c_2) { - x = { c: c }; + t1 = { c: c }; $[2] = c; - $[3] = x; + $[3] = t1; } else { - x = $[3]; + t1 = $[3]; } + x = t1; } return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/obj-mutated-after-if-else-with-alias.expect.md b/compiler/forget/src/__tests__/fixtures/hir/obj-mutated-after-if-else-with-alias.expect.md index 2a43eb71fb..e14877c15d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/obj-mutated-after-if-else-with-alias.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/obj-mutated-after-if-else-with-alias.expect.md @@ -23,10 +23,11 @@ function foo(a, b, c, d) { ```javascript function foo(a, b, c, d) { const $ = React.unstable_useMemoCache(2); + someObj(); const c_0 = $[0] !== a; let x; if (c_0) { - x = someObj(); + x = undefined; if (a) { const y = someObj(); const z = y; diff --git a/compiler/forget/src/__tests__/fixtures/hir/obj-mutated-after-if-else.expect.md b/compiler/forget/src/__tests__/fixtures/hir/obj-mutated-after-if-else.expect.md index 161b3b01ea..f9e81d1ba9 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/obj-mutated-after-if-else.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/obj-mutated-after-if-else.expect.md @@ -21,10 +21,11 @@ function foo(a, b, c, d) { ```javascript function foo(a, b, c, d) { const $ = React.unstable_useMemoCache(2); + someObj(); const c_0 = $[0] !== a; let x; if (c_0) { - x = someObj(); + x = undefined; if (a) { x = someObj(); } else { diff --git a/compiler/forget/src/__tests__/fixtures/hir/obj-mutated-after-nested-if-else-with-alias.expect.md b/compiler/forget/src/__tests__/fixtures/hir/obj-mutated-after-nested-if-else-with-alias.expect.md index 504a45b0b6..9dd095f521 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/obj-mutated-after-nested-if-else-with-alias.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/obj-mutated-after-nested-if-else-with-alias.expect.md @@ -29,11 +29,12 @@ function foo(a, b, c, d) { ```javascript function foo(a, b, c, d) { const $ = React.unstable_useMemoCache(3); + someObj(); const c_0 = $[0] !== a; const c_1 = $[1] !== b; let x; if (c_0 || c_1) { - x = someObj(); + x = undefined; if (a) { let z = undefined; if (b) { diff --git a/compiler/forget/src/__tests__/fixtures/hir/object-pattern-params.expect.md b/compiler/forget/src/__tests__/fixtures/hir/object-pattern-params.expect.md index c0a8ec7d70..09d63d71ff 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/object-pattern-params.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/object-pattern-params.expect.md @@ -13,40 +13,42 @@ function component({ a, b }) { ## Code ```javascript -function component(t12) { +function component(t19) { const $ = React.unstable_useMemoCache(7); - const a = t12.a; - const b = t12.b; + const a = t19.a; + const b = t19.b; const c_0 = $[0] !== a; - let y; + let t0; if (c_0) { - y = { a: a }; + t0 = { a: a }; $[0] = a; - $[1] = y; + $[1] = t0; } else { - y = $[1]; + t0 = $[1]; } + const y = t0; const c_2 = $[2] !== b; - let z; + let t1; if (c_2) { - z = { b: b }; + t1 = { b: b }; $[2] = b; - $[3] = z; + $[3] = t1; } else { - z = $[3]; + t1 = $[3]; } + const z = t1; const c_4 = $[4] !== y; const c_5 = $[5] !== z; - let t0; + let t2; if (c_4 || c_5) { - t0 = { y: y, z: z }; + t2 = { y: y, z: z }; $[4] = y; $[5] = z; - $[6] = t0; + $[6] = t2; } else { - t0 = $[6]; + t2 = $[6]; } - return t0; + return t2; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/primitive-as-dep.expect.md b/compiler/forget/src/__tests__/fixtures/hir/primitive-as-dep.expect.md index d7066d71a9..7db41c5a0f 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/primitive-as-dep.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/primitive-as-dep.expect.md @@ -34,54 +34,59 @@ function PrimitiveAsDep(props) { const $ = React.unstable_useMemoCache(2); const t0 = props.b + 1; const c_0 = $[0] !== t0; - let y; + let t1; if (c_0) { - y = foo(t0); + t1 = foo(t0); $[0] = t0; - $[1] = y; + $[1] = t1; } else { - y = $[1]; + t1 = $[1]; } + const y = t1; return y; } function PrimitiveAsDepNested(props) { - const $ = React.unstable_useMemoCache(8); + const $ = React.unstable_useMemoCache(9); const c_0 = $[0] !== props.b; const c_1 = $[1] !== props.a; let x; + let y; if (c_0 || c_1) { x = {}; mutate(x); const t0 = props.b + 1; - const c_3 = $[3] !== t0; - let y; - if (c_3) { - y = foo(t0); - $[3] = t0; - $[4] = y; + const c_4 = $[4] !== t0; + let t1; + if (c_4) { + t1 = foo(t0); + $[4] = t0; + $[5] = t1; } else { - y = $[4]; + t1 = $[5]; } + y = t1; mutate(x, props.a); $[0] = props.b; $[1] = props.a; $[2] = x; + $[3] = y; } else { x = $[2]; + y = $[3]; } - const c_5 = $[5] !== x; - const c_6 = $[6] !== y; - let t1; - if (c_5 || c_6) { - t1 = [x, y]; - $[5] = x; - $[6] = y; - $[7] = t1; + const c_6 = $[6] !== x; + const c_7 = $[7] !== y; + let t2; + if (c_6 || c_7) { + t2 = [x, y]; + $[6] = x; + $[7] = y; + $[8] = t2; } else { - t1 = $[7]; + t2 = $[8]; } - return t1; + return t2; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/prop-capturing-function-1.expect.md b/compiler/forget/src/__tests__/fixtures/hir/prop-capturing-function-1.expect.md index b1280d73f9..7dcbede9de 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/prop-capturing-function-1.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/prop-capturing-function-1.expect.md @@ -19,26 +19,28 @@ function component(a, b) { const $ = React.unstable_useMemoCache(5); const c_0 = $[0] !== a; const c_1 = $[1] !== b; - let z; + let t0; if (c_0 || c_1) { - z = { a: a, b: b }; + t0 = { a: a, b: b }; $[0] = a; $[1] = b; - $[2] = z; + $[2] = t0; } else { - z = $[2]; + t0 = $[2]; } + const z = t0; const c_3 = $[3] !== z; - let x; + let t1; if (c_3) { - x = function () { + t1 = function () { z; }; $[3] = z; - $[4] = x; + $[4] = t1; } else { - x = $[4]; + t1 = $[4]; } + const x = t1; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md index e9514dd4a5..c7552085ba 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md @@ -36,27 +36,29 @@ function Component(props) { } const y = x; if (props.p1) { + let t0; if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - x = []; - $[2] = x; + t0 = []; + $[2] = t0; } else { - x = $[2]; + t0 = $[2]; } + x = t0; } y.push(props.p2); const c_3 = $[3] !== x; const c_4 = $[4] !== y; - let t0; + let t1; if (c_3 || c_4) { - t0 = ; + t1 = ; $[3] = x; $[4] = y; - $[5] = t0; + $[5] = t1; } else { - t0 = $[5]; + t1 = $[5]; } - return t0; + return t1; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md index 0e4381c6f9..79d36dd99e 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md @@ -48,14 +48,15 @@ function foo(a, b, c) { x = $[1]; } const c_2 = $[2] !== x; - let y; + let t0; if (c_2) { - y =
{x}
; + t0 =
{x}
; $[2] = x; - $[3] = y; + $[3] = t0; } else { - y = $[3]; + t0 = $[3]; } + const y = t0; bb3: switch (b) { case 0: { const c_4 = $[4] !== b; @@ -83,9 +84,9 @@ function foo(a, b, c) { } const c_8 = $[8] !== y; const c_9 = $[9] !== x; - let t0; + let t1; if (c_8 || c_9) { - t0 = ( + t1 = (
{y} {x} @@ -93,11 +94,11 @@ function foo(a, b, c) { ); $[8] = y; $[9] = x; - $[10] = t0; + $[10] = t1; } else { - t0 = $[10]; + t1 = $[10]; } - return t0; + return t1; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md index f3d722749e..0b3212b74d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md @@ -30,12 +30,14 @@ function Component(props) { x = []; x.push(props.p0); y = x; + let t0; if ($[4] === Symbol.for("react.memo_cache_sentinel")) { - x = []; - $[4] = x; + t0 = []; + $[4] = t0; } else { - x = $[4]; + t0 = $[4]; } + x = t0; y.push(props.p1); $[0] = props.p0; @@ -48,16 +50,16 @@ function Component(props) { } const c_5 = $[5] !== x; const c_6 = $[6] !== y; - let t0; + let t1; if (c_5 || c_6) { - t0 = ; + t1 = ; $[5] = x; $[6] = y; - $[7] = t0; + $[7] = t1; } else { - t0 = $[7]; + t1 = $[7]; } - return t0; + return t1; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/reduce-reactive-deps-cond-scope.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reduce-reactive-deps-cond-scope.expect.md index 8cea94f8b8..bbeca80f3a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reduce-reactive-deps-cond-scope.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reduce-reactive-deps-cond-scope.expect.md @@ -60,14 +60,15 @@ function TestReactiveDepsInCondScope(props) { x = {}; if (foo) { const c_2 = $[2] !== props.a.b; - let tmp; + let t0; if (c_2) { - tmp = bar(props.a.b); + t0 = bar(props.a.b); $[2] = props.a.b; - $[3] = tmp; + $[3] = t0; } else { - tmp = $[3]; + t0 = $[3]; } + const tmp = t0; x.a = tmp; } $[0] = props; diff --git a/compiler/forget/src/__tests__/fixtures/hir/same-variable-as-dep-and-redeclare-maybe-frozen.expect.md b/compiler/forget/src/__tests__/fixtures/hir/same-variable-as-dep-and-redeclare-maybe-frozen.expect.md index 4ba3d1f238..c4f6052007 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/same-variable-as-dep-and-redeclare-maybe-frozen.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/same-variable-as-dep-and-redeclare-maybe-frozen.expect.md @@ -89,9 +89,9 @@ function foo(props) { } const c_10 = $[10] !== x; const c_11 = $[11] !== y; - let content; + let t1; if (c_10 || c_11) { - content = ( + t1 = (
{x} {y} @@ -99,15 +99,16 @@ function foo(props) { ); $[10] = x; $[11] = y; - $[12] = content; + $[12] = t1; } else { - content = $[12]; + t1 = $[12]; } + const content = t1; const c_13 = $[13] !== header; const c_14 = $[14] !== content; - let t1; + let t2; if (c_13 || c_14) { - t1 = ( + t2 = ( <> {header} {content} @@ -115,11 +116,11 @@ function foo(props) { ); $[13] = header; $[14] = content; - $[15] = t1; + $[15] = t2; } else { - t1 = $[15]; + t2 = $[15]; } - return t1; + return t2; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/same-variable-as-dep-and-redeclare.expect.md b/compiler/forget/src/__tests__/fixtures/hir/same-variable-as-dep-and-redeclare.expect.md index 35f80c5340..dc4c090b37 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/same-variable-as-dep-and-redeclare.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/same-variable-as-dep-and-redeclare.expect.md @@ -58,14 +58,15 @@ function foo(props) { x = $[1]; } const c_2 = $[2] !== x; - let header; + let t0; if (c_2) { - header =
{x}
; + t0 =
{x}
; $[2] = x; - $[3] = header; + $[3] = t0; } else { - header = $[3]; + t0 = $[3]; } + const header = t0; const c_4 = $[4] !== x; const c_5 = $[5] !== props.b; const c_6 = $[6] !== props.c; @@ -86,9 +87,9 @@ function foo(props) { } const c_9 = $[9] !== x; const c_10 = $[10] !== y; - let content; + let t1; if (c_9 || c_10) { - content = ( + t1 = (
{x} {y} @@ -96,15 +97,16 @@ function foo(props) { ); $[9] = x; $[10] = y; - $[11] = content; + $[11] = t1; } else { - content = $[11]; + t1 = $[11]; } + const content = t1; const c_12 = $[12] !== header; const c_13 = $[13] !== content; - let t0; + let t2; if (c_12 || c_13) { - t0 = ( + t2 = ( <> {header} {content} @@ -112,11 +114,11 @@ function foo(props) { ); $[12] = header; $[13] = content; - $[14] = t0; + $[14] = t2; } else { - t0 = $[14]; + t2 = $[14]; } - return t0; + return t2; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/simple-function-1.expect.md b/compiler/forget/src/__tests__/fixtures/hir/simple-function-1.expect.md index 2711e32bce..e7be6f7969 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/simple-function-1.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/simple-function-1.expect.md @@ -16,15 +16,16 @@ function component() { ```javascript function component() { const $ = React.unstable_useMemoCache(1); - let x; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - x = function (a) { + t0 = function (a) { a.foo(); }; - $[0] = x; + $[0] = t0; } else { - x = $[0]; + t0 = $[0]; } + const x = t0; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/simple-scope.expect.md b/compiler/forget/src/__tests__/fixtures/hir/simple-scope.expect.md index 63e9e6427a..b934e57fd9 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/simple-scope.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/simple-scope.expect.md @@ -15,14 +15,15 @@ function foo(a) { function foo(a) { const $ = React.unstable_useMemoCache(2); const c_0 = $[0] !== a.b; - let x; + let t0; if (c_0) { - x = [a.b]; + t0 = [a.b]; $[0] = a.b; - $[1] = x; + $[1] = t0; } else { - x = $[1]; + t0 = $[1]; } + const x = t0; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md index fc50027b02..770afae39d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md @@ -16,13 +16,14 @@ function Component(props) { ```javascript function Component(props) { const $ = React.unstable_useMemoCache(1); - let x; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - x = [1, 2]; - $[0] = x; + t0 = [1, 2]; + $[0] = t0; } else { - x = $[0]; + t0 = $[0]; } + const x = t0; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-newexpression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-newexpression.expect.md index 71ee1c3284..91a2f48e2d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-newexpression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-newexpression.expect.md @@ -20,15 +20,16 @@ function Foo() {} function Component(props) { const $ = React.unstable_useMemoCache(1); - let c; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const a = []; const b = {}; - c = new Foo(a, b); - $[0] = c; + t0 = new Foo(a, b); + $[0] = t0; } else { - c = $[0]; + t0 = $[0]; } + const c = t0; return c; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-non-empty-initializer.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-non-empty-initializer.expect.md index 26de88456a..4c98edcb97 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-non-empty-initializer.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-non-empty-initializer.expect.md @@ -19,13 +19,14 @@ function foo(a, b) { ```javascript function foo(a, b) { const $ = React.unstable_useMemoCache(1); - let x; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - x = []; - $[0] = x; + t0 = []; + $[0] = t0; } else { - x = $[0]; + t0 = $[0]; } + let x = t0; if (a) { x = 1; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md index 1168b7d192..9ac9eb5a89 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md @@ -26,13 +26,14 @@ function foo() { const x = 1; const y = 3; - let t; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t = { x: x, y: y }; - $[0] = t; + t0 = { x: x, y: y }; + $[0] = t0; } else { - t = $[0]; + t0 = $[0]; } + const t = t0; return t; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md index 7d3b670978..ac74ec2403 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md @@ -16,13 +16,14 @@ function Component(props) { ```javascript function Component(props) { const $ = React.unstable_useMemoCache(1); - let x; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - x = { a: 1, b: 2 }; - $[0] = x; + t0 = { a: 1, b: 2 }; + $[0] = t0; } else { - x = $[0]; + t0 = $[0]; } + const x = t0; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-if.expect.md index be7c9291e6..c022fa68dc 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-if.expect.md @@ -26,22 +26,24 @@ function foo(a) { if (c_0) { x = {}; if (a) { - let y; + let t0; if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - y = {}; - $[2] = y; + t0 = {}; + $[2] = t0; } else { - y = $[2]; + t0 = $[2]; } + const y = t0; x.y = y; } else { - let z; + let t1; if ($[3] === Symbol.for("react.memo_cache_sentinel")) { - z = {}; - $[3] = z; + t1 = {}; + $[3] = t1; } else { - z = $[3]; + t1 = $[3]; } + const z = t1; x.z = z; } $[0] = a; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-inside-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-inside-if.expect.md index bf4d8496b3..536dccae86 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-inside-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-inside-if.expect.md @@ -32,13 +32,14 @@ function foo(a) { mutate(y); } else { - let z; + let t0; if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - z = {}; - $[2] = z; + t0 = {}; + $[2] = t0; } else { - z = $[2]; + t0 = $[2]; } + const z = t0; x.z = z; } $[0] = a; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md index 7ce4f48830..38e4ce493b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md @@ -16,13 +16,14 @@ function foo() { ```javascript function foo() { const $ = React.unstable_useMemoCache(2); - let x; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - x = []; - $[0] = x; + t0 = []; + $[0] = t0; } else { - x = $[0]; + t0 = $[0]; } + const x = t0; let y; if ($[1] === Symbol.for("react.memo_cache_sentinel")) { y = {}; diff --git a/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md b/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md index edc2f43429..617fbc88fb 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md @@ -45,12 +45,14 @@ function Component(props) { } case true: { x.push(props.p2); + let t0; if ($[3] === Symbol.for("react.memo_cache_sentinel")) { - y = []; - $[3] = y; + t0 = []; + $[3] = t0; } else { - y = $[3]; + t0 = $[3]; } + y = t0; break bb1; } default: { @@ -68,27 +70,28 @@ function Component(props) { y = $[2]; } const c_4 = $[4] !== x; - let child; + let t1; if (c_4) { - child = ; + t1 = ; $[4] = x; - $[5] = child; + $[5] = t1; } else { - child = $[5]; + t1 = $[5]; } + const child = t1; y.push(props.p4); const c_6 = $[6] !== y; const c_7 = $[7] !== child; - let t0; + let t2; if (c_6 || c_7) { - t0 = {child}; + t2 = {child}; $[6] = y; $[7] = child; - $[8] = t0; + $[8] = t2; } else { - t0 = $[8]; + t2 = $[8]; } - return t0; + return t2; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md index 7f1b6fd659..1ab3f13f01 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md @@ -51,27 +51,28 @@ function Component(props) { y = $[2]; } const c_3 = $[3] !== x; - let child; + let t0; if (c_3) { - child = ; + t0 = ; $[3] = x; - $[4] = child; + $[4] = t0; } else { - child = $[4]; + t0 = $[4]; } + const child = t0; y.push(props.p4); const c_5 = $[5] !== y; const c_6 = $[6] !== child; - let t0; + let t1; if (c_5 || c_6) { - t0 = {child}; + t1 = {child}; $[5] = y; $[6] = child; - $[7] = t0; + $[7] = t1; } else { - t0 = $[7]; + t1 = $[7]; } - return t0; + return t1; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/tagged-template-literal.expect.md b/compiler/forget/src/__tests__/fixtures/hir/tagged-template-literal.expect.md index 34b5d25fbb..6a58dca5dc 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/tagged-template-literal.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/tagged-template-literal.expect.md @@ -26,9 +26,9 @@ function component() { ```javascript function component() { const $ = React.unstable_useMemoCache(1); - let t; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t = graphql` + t0 = graphql` fragment List_viewer on Viewer @argumentDefinitions( count: { @@ -40,10 +40,11 @@ function component() { ) `; - $[0] = t; + $[0] = t0; } else { - t = $[0]; + t0 = $[0]; } + const t = t0; return t; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/timers.expect.md b/compiler/forget/src/__tests__/fixtures/hir/timers.expect.md index fcaa487b20..414007af95 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/timers.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/timers.expect.md @@ -20,40 +20,42 @@ function Component(props) { ```javascript function Component(props) { const $ = React.unstable_useMemoCache(4); - let start; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - start = performance.now(); - $[0] = start; - } else { - start = $[0]; - } - let now; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - now = Date.now(); - $[1] = now; - } else { - now = $[1]; - } let t0; - if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { t0 = performance.now(); - $[2] = t0; + $[0] = t0; } else { - t0 = $[2]; + t0 = $[0]; } - const time = t0 - start; + const start = t0; let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = Date.now(); + $[1] = t1; + } else { + t1 = $[1]; + } + const now = t1; + let t2; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t2 = performance.now(); + $[2] = t2; + } else { + t2 = $[2]; + } + const time = t2 - start; + let t3; if ($[3] === Symbol.for("react.memo_cache_sentinel")) { - t1 = ( + t3 = (
rendering took {time} at {now}
); - $[3] = t1; + $[3] = t3; } else { - t1 = $[3]; + t3 = $[3]; } - return t1; + return t3; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-binary-operator.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-binary-operator.expect.md index ee6bbd378d..087ff35c9a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-binary-operator.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-binary-operator.expect.md @@ -17,20 +17,22 @@ function component() { ```javascript function component() { const $ = React.unstable_useMemoCache(2); - let a; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - a = some(); - $[0] = a; + t0 = some(); + $[0] = t0; } else { - a = $[0]; + t0 = $[0]; } - let b; + const a = t0; + let t1; if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - b = someOther(); - $[1] = b; + t1 = someOther(); + $[1] = t1; } else { - b = $[1]; + t1 = $[1]; } + const b = t1; if (a > b) { } } diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-field-load.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-field-load.expect.md index 5283cf0d4d..42357dd2b2 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-field-load.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-field-load.expect.md @@ -15,13 +15,14 @@ function component() { ```javascript function component() { const $ = React.unstable_useMemoCache(1); - let x; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - x = { t: 1 }; - $[0] = x; + t0 = { t: 1 }; + $[0] = t0; } else { - x = $[0]; + t0 = $[0]; } + const x = t0; const p = x.t; return p; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-test-field-load-binary-op.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-test-field-load-binary-op.expect.md index 746b9035b5..bd346cd04f 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-test-field-load-binary-op.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-test-field-load-binary-op.expect.md @@ -35,13 +35,14 @@ function component() { } else { t1 = $[1]; } - let x; + let t2; if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - x = { u: t0, v: t1 }; - $[2] = x; + t2 = { u: t0, v: t1 }; + $[2] = t2; } else { - x = $[2]; + t2 = $[2]; } + const x = t2; const u = x.u; const v = x.v; if (u > v) { diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-test-field-store.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-test-field-store.expect.md index 542effbdf7..62636834cf 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-test-field-store.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-test-field-store.expect.md @@ -20,13 +20,14 @@ function component() { let x; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { x = {}; - let q; + let t0; if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - q = {}; - $[1] = q; + t0 = {}; + $[1] = t0; } else { - q = $[1]; + t0 = $[1]; } + const q = t0; x.t = q; $[0] = x; } else { diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-test-polymorphic.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-test-polymorphic.expect.md index 7673f82d17..dabcaf399a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-test-polymorphic.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-test-polymorphic.expect.md @@ -24,20 +24,22 @@ function component() { ```javascript function component() { const $ = React.unstable_useMemoCache(3); - let p; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - p = makePrimitive(); - $[0] = p; + t0 = makePrimitive(); + $[0] = t0; } else { - p = $[0]; + t0 = $[0]; } - let o; + const p = t0; + let t1; if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - o = {}; - $[1] = o; + t1 = {}; + $[1] = t1; } else { - o = $[1]; + t1 = $[1]; } + const o = t1; let x; if ($[2] === Symbol.for("react.memo_cache_sentinel")) { x = {}; diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-test-return-type-inference.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-test-return-type-inference.expect.md index 024902953f..0a4b769a0f 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-test-return-type-inference.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-test-return-type-inference.expect.md @@ -20,29 +20,32 @@ function component() { ```javascript function component() { const $ = React.unstable_useMemoCache(3); - let x; + let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - x = foo(); - $[0] = x; + t0 = foo(); + $[0] = t0; } else { - x = $[0]; + t0 = $[0]; } - let y; + const x = t0; + let t1; if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - y = foo(); - $[1] = y; + t1 = foo(); + $[1] = t1; } else { - y = $[1]; + t1 = $[1]; } + const y = t1; if (x > y) { } - let z_0; + let t2; if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - z_0 = foo(); - $[2] = z_0; + t2 = foo(); + $[2] = t2; } else { - z_0 = $[2]; + t2 = $[2]; } + const z_0 = t2; return z_0; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/unary-expr.expect.md b/compiler/forget/src/__tests__/fixtures/hir/unary-expr.expect.md index 47beec00f0..d67398abb8 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/unary-expr.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/unary-expr.expect.md @@ -22,14 +22,15 @@ function component(a) { function component(a) { const $ = React.unstable_useMemoCache(10); const c_0 = $[0] !== a; - let t; + let t0; if (c_0) { - t = { t: a }; + t0 = { t: a }; $[0] = a; - $[1] = t; + $[1] = t0; } else { - t = $[1]; + t0 = $[1]; } + const t = t0; const z = +t.t; const q = -t.t; const p = void t.t; @@ -44,9 +45,9 @@ function component(a) { const c_6 = $[6] !== m; const c_7 = $[7] !== e; const c_8 = $[8] !== f; - let t0; + let t1; if (c_2 || c_3 || c_4 || c_5 || c_6 || c_7 || c_8) { - t0 = { z: z, p: p, q: q, n: n, m: m, e: e, f: f }; + t1 = { z: z, p: p, q: q, n: n, m: m, e: e, f: f }; $[2] = z; $[3] = p; $[4] = q; @@ -54,11 +55,11 @@ function component(a) { $[6] = m; $[7] = e; $[8] = f; - $[9] = t0; + $[9] = t1; } else { - t0 = $[9]; + t1 = $[9]; } - return t0; + return t1; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/useMemo-simple.expect.md b/compiler/forget/src/__tests__/fixtures/hir/useMemo-simple.expect.md index bcf90184da..ef1baed8c5 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/useMemo-simple.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/useMemo-simple.expect.md @@ -15,24 +15,25 @@ function component(a) { function component(a) { const $ = React.unstable_useMemoCache(4); const c_0 = $[0] !== a; - let x; - if (c_0) { - x = (() => [a])(); - $[0] = a; - $[1] = x; - } else { - x = $[1]; - } - const c_2 = $[2] !== x; let t0; - if (c_2) { - t0 = ; - $[2] = x; - $[3] = t0; + if (c_0) { + t0 = (() => [a])(); + $[0] = a; + $[1] = t0; } else { - t0 = $[3]; + t0 = $[1]; } - return t0; + const x = t0; + const c_2 = $[2] !== x; + let t1; + if (c_2) { + t1 = ; + $[2] = x; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; } ``` diff --git a/compiler/forget/yarn.lock b/compiler/forget/yarn.lock index afa3019a65..62d377b5f2 100644 --- a/compiler/forget/yarn.lock +++ b/compiler/forget/yarn.lock @@ -83,13 +83,14 @@ "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" -"@babel/generator@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.7.tgz#f8ef57c8242665c5929fe2e8d82ba75460187b4a" - integrity sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw== +"@babel/generator@^7.21.1": + version "7.21.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.1.tgz#951cc626057bc0af2c35cd23e9c64d384dea83dd" + integrity sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA== dependencies: - "@babel/types" "^7.20.7" + "@babel/types" "^7.21.0" "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" "@babel/helper-annotate-as-pure@^7.18.6": @@ -135,6 +136,14 @@ "@babel/template" "^7.18.10" "@babel/types" "^7.19.0" +"@babel/helper-function-name@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" + integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== + dependencies: + "@babel/template" "^7.20.7" + "@babel/types" "^7.21.0" + "@babel/helper-hoist-variables@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" @@ -260,10 +269,10 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.3.tgz#8dd36d17c53ff347f9e55c328710321b49479a9a" integrity sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ== -"@babel/parser@^7.20.13": - version "7.20.13" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.13.tgz#ddf1eb5a813588d2fb1692b70c6fce75b945c088" - integrity sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw== +"@babel/parser@^7.20.7", "@babel/parser@^7.21.2": + version "7.21.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.2.tgz#dacafadfc6d7654c3051a66d6fe55b6cb2f2a0b3" + integrity sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -459,6 +468,15 @@ "@babel/parser" "^7.18.10" "@babel/types" "^7.18.10" +"@babel/template@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" + integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@babel/template@^7.3.3": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31" @@ -484,18 +502,18 @@ lodash "^4.17.10" "@babel/traverse@^7.19.1": - version "7.20.13" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.13.tgz#817c1ba13d11accca89478bd5481b2d168d07473" - integrity sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ== + version "7.21.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.2.tgz#ac7e1f27658750892e815e60ae90f382a46d8e75" + integrity sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw== dependencies: "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.7" + "@babel/generator" "^7.21.1" "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" + "@babel/helper-function-name" "^7.21.0" "@babel/helper-hoist-variables" "^7.18.6" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.20.13" - "@babel/types" "^7.20.7" + "@babel/parser" "^7.21.2" + "@babel/types" "^7.21.2" debug "^4.1.0" globals "^11.1.0" @@ -543,6 +561,15 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" +"@babel/types@^7.21.0", "@babel/types@^7.21.2": + version "7.21.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.2.tgz#92246f6e00f91755893c2876ad653db70c8310d1" + integrity sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -831,7 +858,7 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@^3.0.3": +"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== @@ -841,7 +868,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== @@ -862,6 +889,14 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.17": + version "0.3.17" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"