From cbbfba27b4d88c3ada8118a8096a07350c2aa5ed Mon Sep 17 00:00:00 2001 From: Joseph Savona Date: Thu, 6 Oct 2022 08:56:20 -0700 Subject: [PATCH] [new-arch][easy] Handle declarations (let/const) through codegen Distinguishes between `LValue` and `Place`. For the most part this is the same data structure (LValue composes Place), but it's helpful to distinguish them since LValue has other properties such as the kind of declaration. The representations may diverge more in the future. This change lets us correctly emit code for variable declarations: previously we didn't emit `let` or `const`. --- compiler/forget/src/HIR/BuildDefUseGraph.ts | 16 +- compiler/forget/src/HIR/BuildHIR.ts | 35 +- compiler/forget/src/HIR/Codegen.ts | 59 ++- compiler/forget/src/HIR/HIR.ts | 13 +- compiler/forget/src/HIR/InferMutability.ts | 40 +- compiler/forget/src/HIR/PrintHIR.ts | 32 +- compiler/forget/src/HIR/ScopeAnalysis.ts | 235 --------- .../__tests__/fixtures/hir-svg/component.svg | 484 +++++++++--------- .../src/__tests__/fixtures/hir-svg/switch.svg | 198 +++---- .../src/__tests__/fixtures/hir/call.expect.md | 19 +- .../fixtures/hir/component.expect.md | 54 +- .../fixtures/hir/conditional-break.expect.md | 24 +- .../hir/conditional-on-mutable.expect.md | 22 +- .../fixtures/hir/constructor.expect.md | 19 +- .../fixtures/hir/hook-call.expect.md | 16 +- .../hir/independent-across-if.expect.md | 10 +- .../fixtures/hir/independent.expect.md | 10 +- .../hir/interdependent-across-if.expect.md | 10 +- .../fixtures/hir/interdependent.expect.md | 10 +- .../hir/property-assignment.expect.md | 16 +- .../hir/reassignment-conditional.expect.md | 17 +- .../fixtures/hir/reassignment.expect.md | 17 +- .../__tests__/fixtures/hir/simple.expect.md | 10 +- .../hir/switch-non-final-default.expect.md | 24 +- .../__tests__/fixtures/hir/switch.expect.md | 22 +- 25 files changed, 625 insertions(+), 787 deletions(-) diff --git a/compiler/forget/src/HIR/BuildDefUseGraph.ts b/compiler/forget/src/HIR/BuildDefUseGraph.ts index 366c324324..e31c4835ca 100644 --- a/compiler/forget/src/HIR/BuildDefUseGraph.ts +++ b/compiler/forget/src/HIR/BuildDefUseGraph.ts @@ -329,9 +329,9 @@ function buildInputsOutputsForBlock( case "Identifier": { builder.reference(instrValue, instrValue, Capability.Readonly); valueCapability = instrValue.capability; - if (instr.place !== null && instr.place.memberPath === null) { - builder.assign(instr.place, instr, instrValue); - instr.place.capability = valueCapability; + if (instr.lvalue !== null && instr.lvalue.place.memberPath === null) { + builder.assign(instr.lvalue.place, instr, instrValue); + instr.lvalue.place.capability = valueCapability; continue; } break; @@ -340,12 +340,12 @@ function buildInputsOutputsForBlock( assertExhaustive(instrValue, "Unexpected instruction kind"); } } - if (instr.place !== null) { - if (instr.place.memberPath == null) { - builder.init(instr.place, instr, true); - instr.place.capability = valueCapability; + if (instr.lvalue !== null) { + if (instr.lvalue.place.memberPath == null) { + builder.init(instr.lvalue.place, instr, true); + instr.lvalue.place.capability = valueCapability; } else { - builder.reference(instr.place, instr, valueCapability); + builder.reference(instr.lvalue.place, instr, valueCapability); } } } diff --git a/compiler/forget/src/HIR/BuildHIR.ts b/compiler/forget/src/HIR/BuildHIR.ts index 3ee33748de..641df8a6a6 100644 --- a/compiler/forget/src/HIR/BuildHIR.ts +++ b/compiler/forget/src/HIR/BuildHIR.ts @@ -14,6 +14,7 @@ import { HIRFunction, Identifier, IfTerminal, + InstructionKind, InstructionValue, Place, ReturnTerminal, @@ -546,11 +547,13 @@ function lowerStatement( } case "VariableDeclaration": { const stmt = stmtPath as NodePath; - const kind: string = stmt.node.kind; + const nodeKind: string = stmt.node.kind; invariant( - kind === "let" || kind === "const", + nodeKind === "let" || nodeKind === "const", "`var` declarations are not supported, use let or const" ); + const kind = + nodeKind === "let" ? InstructionKind.Let : InstructionKind.Const; for (const declaration of stmt.get("declarations")) { const id = lowerLVal(builder, declaration.get("id")); const init = declaration.get("init"); @@ -565,7 +568,7 @@ function lowerStatement( }; } builder.push({ - place: id, + lvalue: { place: id, kind }, value, path: stmt, }); @@ -581,7 +584,7 @@ function lowerStatement( return; } builder.push({ - place: null, + lvalue: null, value, path: stmt, }); @@ -620,7 +623,7 @@ function lowerStatement( case "WithStatement": { builder.push({ path: stmtPath, - place: null, + lvalue: null, value: { kind: "OtherStatement", path: stmtPath }, }); return; @@ -816,9 +819,9 @@ function lowerExpression( const operator = expr.node.operator; todoInvariant(operator === "=", "todo: support non-simple assignment"); builder.push({ + lvalue: { place: left, kind: InstructionKind.Reassign }, path: exprPath, value: right, - place: left, }); return left; } @@ -907,7 +910,11 @@ function lowerConditional( // Block for the consequent (if the test is truthy) const consequentBlock = builder.enter((blockId) => { let value = consequent(); - builder.push({ value, place: { ...place }, path: value.path }); + builder.push({ + value, + lvalue: { place: { ...place }, kind: InstructionKind.Const }, + path: value.path, + }); return { kind: "goto", block: continuationBlock.id, @@ -916,7 +923,11 @@ function lowerConditional( // Block for the alternate (if the test is not truthy) const alternateBlock = builder.enter((blockId) => { let value = alternate(); - builder.push({ value, place: { ...place }, path: value.path }); + builder.push({ + value, + lvalue: { place: { ...place }, kind: InstructionKind.Const }, + path: value.path, + }); return { kind: "goto", block: continuationBlock.id, @@ -969,7 +980,7 @@ function lowerJsxElementName( builder.push({ value: { kind: "Primitive", value: tag, path: exprPath }, path: exprPath, - place, + lvalue: { place, kind: InstructionKind.Const }, }); return { ...place }; } @@ -1002,7 +1013,7 @@ function lowerJsxElement( builder.push({ value: { kind: "JSXText", value: exprPath.node.value, path: exprPath }, path: exprPath, - place: { ...place }, + lvalue: { place: { ...place }, kind: InstructionKind.Const }, }); return place; } else { @@ -1016,7 +1027,7 @@ function lowerJsxElement( builder.push({ value: { kind: "OtherStatement", path: exprPath }, path: exprPath, - place: { ...place }, + lvalue: { place: { ...place }, kind: InstructionKind.Const }, }); return place; } @@ -1040,7 +1051,7 @@ function lowerExpressionToPlace( builder.push({ value: instr, path: exprPath, - place: { ...place }, + lvalue: { place: { ...place }, kind: InstructionKind.Const }, }); return place; } diff --git a/compiler/forget/src/HIR/Codegen.ts b/compiler/forget/src/HIR/Codegen.ts index cc3b407a5c..459a95c8fe 100644 --- a/compiler/forget/src/HIR/Codegen.ts +++ b/compiler/forget/src/HIR/Codegen.ts @@ -15,6 +15,8 @@ import { Identifier, IdentifierId, Instruction, + InstructionKind, + LValue, Place, } from "./HIR"; import { todoInvariant } from "./todo"; @@ -269,20 +271,46 @@ function writeInstr(cx: Context, instr: Instruction, body: Array) { assertExhaustive(instrValue, "Unexpected instruction kind"); } } - if (instr.place !== null) { + if (instr.lvalue !== null) { if ( - instr.place.kind === "Identifier" && - instr.place.value.name === null && - instr.place.memberPath === null + instr.lvalue.place.value.name === null && + instr.lvalue.place.memberPath === null ) { // Temporary value: don't immediately emit, instead save the value to refer to later - cx.temp.set(instr.place.value.id, value); + cx.temp.set(instr.lvalue.place.value.id, value); } else { - body.push( - t.expressionStatement( - t.assignmentExpression("=", codegenLVal(instr.place), value) - ) - ); + switch (instr.lvalue.kind) { + case InstructionKind.Const: { + body.push( + t.variableDeclaration("const", [ + t.variableDeclarator(codegenLVal(instr.lvalue), value), + ]) + ); + break; + } + case InstructionKind.Let: { + body.push( + t.variableDeclaration("let", [ + t.variableDeclarator(codegenLVal(instr.lvalue), value), + ]) + ); + break; + } + case InstructionKind.Reassign: { + body.push( + t.expressionStatement( + t.assignmentExpression("=", codegenLVal(instr.lvalue), value) + ) + ); + break; + } + default: { + assertExhaustive( + instr.lvalue.kind, + `Unexpected instruction kind '${instr.lvalue.kind}'` + ); + } + } } } else { body.push(t.expressionStatement(value)); @@ -309,15 +337,8 @@ function codegenJsxElement( } } -function codegenLVal(place: Place): t.LVal { - switch (place.kind) { - case "Identifier": { - return convertIdentifier(place.value); - } - default: { - throw new Error("todo other lval kinds"); - } - } +function codegenLVal(lval: LValue): t.LVal { + return convertIdentifier(lval.place.value); } function codegenValue( diff --git a/compiler/forget/src/HIR/HIR.ts b/compiler/forget/src/HIR/HIR.ts index 9e80a15cc3..d2432ab19d 100644 --- a/compiler/forget/src/HIR/HIR.ts +++ b/compiler/forget/src/HIR/HIR.ts @@ -128,11 +128,22 @@ export type SwitchTerminal = { * or may occur only for side-effects (many expression statements). */ export type Instruction = { - place: Place | null; + lvalue: LValue | null; value: InstructionValue; path: NodePath; }; +export type LValue = { + place: Place; + kind: InstructionKind; +}; + +export enum InstructionKind { + Const, // const declaration + Let, // let declaration + Reassign, // assing a new value to a let binding +} + /** * A value that may be assigned to a place. Similar to instructions, values * are not recursive: complex values such as objects or arrays are always diff --git a/compiler/forget/src/HIR/InferMutability.ts b/compiler/forget/src/HIR/InferMutability.ts index 2c9f892b32..dff3bd6dcc 100644 --- a/compiler/forget/src/HIR/InferMutability.ts +++ b/compiler/forget/src/HIR/InferMutability.ts @@ -220,11 +220,11 @@ function flowMutabilityBackwards(vertex: Vertex, epoch: number) { function inferBlock(graph: UseGraph, block: BasicBlock) { for (const instr of block.instructions) { - if (instr.place !== null) { - if (instr.place.memberPath == null) { - graph.init(instr.place, instr); + if (instr.lvalue !== null) { + if (instr.lvalue.place.memberPath == null) { + graph.init(instr.lvalue.place, instr); } else { - graph.reference(instr.place, instr, Capability.Mutable); + graph.reference(instr.lvalue.place, instr, Capability.Mutable); } } const instrValue = instr.value; @@ -239,8 +239,8 @@ function inferBlock(graph: UseGraph, block: BasicBlock) { case "ArrayExpression": { for (const element of instrValue.elements) { graph.reference(element, instrValue, Capability.Readonly); - if (instr.place !== null) { - graph.capture(instr.place, instr, element); + if (instr.lvalue !== null) { + graph.capture(instr.lvalue.place, instr, element); } } break; @@ -250,8 +250,8 @@ function inferBlock(graph: UseGraph, block: BasicBlock) { let prevArg: Place | null = null; for (const arg of instrValue.args) { graph.reference(arg, instrValue, Capability.Mutable); - if (instr.place !== null) { - graph.capture(instr.place, instr, arg); + if (instr.lvalue !== null) { + graph.capture(instr.lvalue.place, instr, arg); } if (prevArg !== null) { graph.capture(prevArg, instr, arg); @@ -271,8 +271,8 @@ function inferBlock(graph: UseGraph, block: BasicBlock) { let prevArg: Place | null = null; for (const arg of instrValue.args) { graph.reference(arg, instrValue, capability); - if (instr.place !== null) { - graph.capture(instr.place, instr, arg); + if (instr.lvalue !== null) { + graph.capture(instr.lvalue.place, instr, arg); } if (prevArg !== null) { graph.capture(prevArg, instr, arg); @@ -286,8 +286,8 @@ function inferBlock(graph: UseGraph, block: BasicBlock) { if (instrValue.properties !== null) { for (const [_key, value] of Object.entries(instrValue.properties)) { graph.reference(value, instrValue, Capability.Readonly); - if (instr.place !== null) { - graph.capture(instr.place, instr, value); + if (instr.lvalue !== null) { + graph.capture(instr.lvalue.place, instr, value); } } } @@ -306,15 +306,15 @@ function inferBlock(graph: UseGraph, block: BasicBlock) { graph.reference(instrValue.tag, instrValue, Capability.Readonly); for (const [_prop, value] of Object.entries(instrValue.props)) { graph.reference(value, instrValue, Capability.Readonly); - if (instr.place !== null) { - graph.capture(instr.place, instr, value); + if (instr.lvalue !== null) { + graph.capture(instr.lvalue.place, instr, value); } } if (instrValue.children !== null) { for (const child of instrValue.children) { graph.reference(child, instrValue, Capability.Readonly); - if (instr.place !== null) { - graph.capture(instr.place, instr, child); + if (instr.lvalue !== null) { + graph.capture(instr.lvalue.place, instr, child); } } } @@ -327,8 +327,8 @@ function inferBlock(graph: UseGraph, block: BasicBlock) { } case "Identifier": { graph.reference(instrValue, instrValue, Capability.Readonly); - if (instr.place !== null) { - graph.assign(instr.place, instr, instrValue); + if (instr.lvalue !== null) { + graph.assign(instr.lvalue.place, instr, instrValue); } valueCapability = instrValue.capability; break; @@ -337,8 +337,8 @@ function inferBlock(graph: UseGraph, block: BasicBlock) { assertExhaustive(instrValue, "Unexpected instruction kind"); } } - if (instr.place !== null) { - instr.place.capability = valueCapability; + if (instr.lvalue !== null) { + instr.lvalue.place.capability = valueCapability; } } } diff --git a/compiler/forget/src/HIR/PrintHIR.ts b/compiler/forget/src/HIR/PrintHIR.ts index 448205bb49..08d6265429 100644 --- a/compiler/forget/src/HIR/PrintHIR.ts +++ b/compiler/forget/src/HIR/PrintHIR.ts @@ -6,7 +6,15 @@ */ import { assertExhaustive } from "../Common/utils"; -import { HIR, Instruction, InstructionValue, Place, Terminal } from "./HIR"; +import { + HIR, + Instruction, + InstructionKind, + InstructionValue, + LValue, + Place, + Terminal, +} from "./HIR"; export type Options = { indent: number; @@ -63,8 +71,8 @@ export function printMixedHIR( function printInstruction(instr: Instruction): string { const value = printInstructionValue(instr.value); - if (instr.place !== null) { - return `${printPlace(instr.place)} = ${value}`; + if (instr.lvalue !== null) { + return `${printLValue(instr.lvalue)} = ${value}`; } else { return value; } @@ -204,6 +212,24 @@ function printInstructionValue(instrValue: InstructionValue): string { return value; } +export function printLValue(lval: LValue): string { + const place = printPlace(lval.place); + switch (lval.kind) { + case InstructionKind.Let: { + return `Let ${place}`; + } + case InstructionKind.Const: { + return `Const ${place}`; + } + case InstructionKind.Reassign: { + return `Reassign ${place}`; + } + default: { + assertExhaustive(lval.kind, `Unexpected lvalue kind '${lval.kind}'`); + } + } +} + export function printPlace(place: Place): string { const items = [place.capability, " ", place.value.name, "$", place.value.id]; if (place.memberPath != null) { diff --git a/compiler/forget/src/HIR/ScopeAnalysis.ts b/compiler/forget/src/HIR/ScopeAnalysis.ts index a0cda1f2bb..07c4493203 100644 --- a/compiler/forget/src/HIR/ScopeAnalysis.ts +++ b/compiler/forget/src/HIR/ScopeAnalysis.ts @@ -5,26 +5,14 @@ * LICENSE file in the root directory of this source tree. */ -import { assertExhaustive } from "../Common/utils"; -import { invariant } from "../CompilerError"; -import DisjointSet from "./DisjointSet"; import { - BasicBlock, - BlockId, Capability, - HIR, HIRFunction, - IdentifierId, - Instruction, - InstructionValue, makeScopeId, - Place, ReactFunction, ReactiveScope, ScopeId, - Terminal, } from "./HIR"; -import todo from "./todo"; // import * as t from "@babel/types"; @@ -197,11 +185,6 @@ function analyze(fn: HIRFunction): ReactFunction { const returnScopeId = makeScopeId(0); const scopes: Map = new Map(); - const block = fn.body.blocks.get(fn.body.entry)!; - const context = new Context(fn.body); - analyzeBlock(context, fn.body.entry, block); - context.analyzeControls(); - return { path: fn.path, id: fn.id, @@ -210,221 +193,3 @@ function analyze(fn: HIRFunction): ReactFunction { scopes, }; } - -class Context { - #blocks: Map> = new Map(); - #groups: DisjointSet = - new DisjointSet(); - body: HIR; - - constructor(body: HIR) { - this.body = body; - } - - union(items: Array, block: BasicBlock) { - this.#groups.union(items); - for (const item of items) { - if (typeof item === "number") { - // IdentifierId - let set = this.#blocks.get(item); - if (set == null) { - set = new Set(); - this.#blocks.set(item, set); - } - set.add(block); - } - } - } - - /** - * Find items that participate in control flow together - */ - analyzeControls() { - const mergeSets: Array> = []; - const blocks: Map = new Map(); - this.#groups.forEach((prevItem, prevGroup) => { - this.#groups.forEach((nextItem, nextGroup) => { - if ( - prevGroup === nextGroup || - typeof prevItem !== "number" || - typeof nextItem !== "number" - ) { - // Already part of the same group, by definition this includes item === nextItem - return; - } - const prevBlocks = this.#blocks.get(prevItem)!; - const nextBlocks = this.#blocks.get(nextItem)!; - - const overlap = []; - for (const block of prevBlocks) { - if (nextBlocks.has(block)) { - overlap.push(block); - } - } - if (overlap.length > 1) { - mergeSets.push(overlap); - } - }); - }); - for (const set of mergeSets) { - this.#groups.union(set); - } - } -} - -function analyzeBlock(cx: Context, id: BlockId, block: BasicBlock) { - for (const instr of block.instructions) { - const instrValue = instr.value; - let mutables: Array = []; - switch (instrValue.kind) { - case "JSXText": - case "Primitive": { - // no mutable values - break; - } - case "Identifier": { - const value = getMutable(instrValue); - if (value !== null) { - mutables.push(value); - } - break; - } - case "UnaryExpression": { - const value = getMutable(instrValue.value); - if (value !== null) { - mutables.push(value); - } - break; - } - case "BinaryExpression": { - const left = getMutable(instrValue.left); - const right = getMutable(instrValue.right); - if (left !== null) { - mutables.push(left); - } - if (right !== null) { - mutables.push(right); - } - break; - } - case "ArrayExpression": { - for (const _element of instrValue.elements) { - const element = getMutable(_element); - if (element !== null) { - mutables.push(element); - } - } - break; - } - case "ObjectExpression": { - if (instrValue.properties !== null) { - for (const _value of Object.values(instrValue.properties)) { - const value = getMutable(_value); - if (value !== null) { - mutables.push(value); - } - } - } - break; - } - case "JsxExpression": { - const tag = getMutable(instrValue.tag); - if (tag !== null) { - mutables.push(tag); - } - for (const _prop of Object.values(instrValue.props)) { - const prop = getMutable(_prop); - if (prop !== null) { - mutables.push(prop); - } - } - if (instrValue.children !== null) { - for (const _child of instrValue.children) { - const child = getMutable(_child); - if (child !== null) { - mutables.push(child); - } - } - } - break; - } - case "NewExpression": - case "CallExpression": { - const callee = getMutable(instrValue.callee); - if (callee !== null) { - mutables.push(callee); - } - for (const _arg of instrValue.args) { - const arg = getMutable(_arg); - if (arg !== null) { - mutables.push(arg); - } - } - break; - } - case "OtherStatement": { - // no-op for the value itself - break; - } - default: { - assertExhaustive( - instrValue, - `Unexpected instruction kind '${ - (instrValue as any as InstructionValue).kind - }'` - ); - } - } - const place = instr.place !== null ? getMutable(instr.place) : null; - invariant( - instr.place === null || - instr.place.kind !== "Identifier" || - place !== null, - "Expected instruction assignment target to be inferred as mutable if present." - ); - if (place !== null) { - mutables.push(place); - } - if (mutables.length !== 0) { - mutables.push(instr); - cx.union(mutables, block); - } - } - switch (block.terminal.kind) { - case "if": { - const consequent = cx.body.blocks.get(block.terminal.consequent)!; - analyzeBlock(cx, block.terminal.consequent, consequent); - const alternate = cx.body.blocks.get(block.terminal.alternate)!; - analyzeBlock(cx, block.terminal.alternate, alternate); - if ( - block.terminal.fallthrough !== null && - block.terminal.fallthrough !== block.terminal.alternate - ) { - const fallthrough = cx.body.blocks.get(block.terminal.fallthrough)!; - analyzeBlock(cx, block.terminal.fallthrough, fallthrough); - } - break; - } - case "switch": { - todo("implement scope analysis for switch statements"); - } - case "throw": - case "return": - case "goto": { - // no-op - break; - } - default: { - assertExhaustive( - block.terminal, - `Unexpected terminal kind '${(block.terminal as any as Terminal).kind}'` - ); - } - } -} - -function getMutable(place: Place): IdentifierId | null { - return place.kind === "Identifier" && place.capability === Capability.Mutable - ? place.value.id - : null; -} diff --git a/compiler/forget/src/__tests__/fixtures/hir-svg/component.svg b/compiler/forget/src/__tests__/fixtures/hir-svg/component.svg index e3317f4d2e..14371d0713 100644 --- a/compiler/forget/src/__tests__/fixtures/hir-svg/component.svg +++ b/compiler/forget/src/__tests__/fixtures/hir-svg/component.svg @@ -4,721 +4,721 @@ - + BuildDefUseGraph - + v0 - -v0 (frozen props$1.items @ frozen props$1.items) <update> + +v0 (frozen props$1.items @ frozen props$1.items) <update> v1 - -v1 (frozen items$2 @ frozen items$2 = frozen props$1.items) <assign> + +v1 (frozen items$2 @ Const frozen items$2 = frozen props$1.items) <assign> v0->v1 - - + + v2 - -v2 (frozen props$1.maxItems @ frozen props$1.maxItems) <update> + +v2 (frozen props$1.maxItems @ frozen props$1.maxItems) <update> v0->v2 - - + + v12 - -v12 (frozen items$2 @ If (frozen items$2) then:bb3 else:bb2) <update> + +v12 (frozen items$2 @ If (frozen items$2) then:bb3 else:bb2) <update> v1->v12 - - + + v3 - -v3 (frozen maxItems$3 @ frozen maxItems$3 = frozen props$1.maxItems) <assign> + +v3 (frozen maxItems$3 @ Const frozen maxItems$3 = frozen props$1.maxItems) <assign> v2->v3 - - + + v10 - -v10 (frozen maxItems$3 @ Call mutable Math$8.max(mutable $9, frozen maxItems$3)) <update> + +v10 (frozen maxItems$3 @ Call mutable Math$8.max(mutable $9, frozen maxItems$3)) <update> v3->v10 - - + + v4 - -v4 (readonly renderedItems$4 @ readonly renderedItems$4 = Array []) <assign> + +v4 (readonly renderedItems$4 @ Const readonly renderedItems$4 = Array []) <assign> v18 - -v18 (readonly renderedItems$4.length @ readonly renderedItems$4.length) <update> + +v18 (readonly renderedItems$4.length @ readonly renderedItems$4.length) <update> v4->v18 - - + + v49 - -v49 (mutable renderedItems$4.push @ Call mutable renderedItems$4.push(mutable $15)) <update> + +v49 (mutable renderedItems$4.push @ Call mutable renderedItems$4.push(mutable $15)) <update> v4->v49 - - + + v62 - -v62 (<join> @ <no-instr>) <update> + +v62 (<join> @ <no-instr>) <update> v4->v62 - - + + v71 - -v71 (<join> @ <no-instr>) <update> + +v71 (<join> @ <no-instr>) <update> v4->v71 - - + + v19 - -v19 (readonly count$17 @ readonly count$17 = readonly renderedItems$4.length) <assign> + +v19 (readonly count$17 @ Const readonly count$17 = readonly renderedItems$4.length) <assign> v18->v19 - - + + v34 - -v34 (frozen renderedItems$4 @ JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <update> + +v34 (frozen renderedItems$4 @ JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <update> v18->v34 - - + + v51 - -v51 (readonly renderedItems$4.length @ Binary readonly renderedItems$4.length >= readonly max$7) <update> + +v51 (readonly renderedItems$4.length @ Binary readonly renderedItems$4.length >= readonly max$7) <update> v49->v51 - - + + v62->v18 - - + + v71->v49 - - + + v5 - -v5 (mutable Set$6 @ New mutable Set$6()) <update> + +v5 (mutable Set$6 @ New mutable Set$6()) <update> v6 - -v6 (readonly seen$5 @ readonly seen$5 = New mutable Set$6()) <assign> + +v6 (readonly seen$5 @ Const readonly seen$5 = New mutable Set$6()) <assign> v39 - -v39 (mutable seen$5.has @ Call mutable seen$5.has(frozen item$10)) <update> + +v39 (mutable seen$5.has @ Call mutable seen$5.has(frozen item$10)) <update> v6->v39 - - + + v56 - -v56 (<join> @ <no-instr>) <update> + +v56 (<join> @ <no-instr>) <update> v6->v56 - - + + v59 - -v59 (<join> @ <no-instr>) <update> + +v59 (<join> @ <no-instr>) <update> v6->v59 - - + + v39->v56 - - + + v39->v59 - - + + v43 - -v43 (mutable seen$5.add @ Call mutable seen$5.add(frozen item$10)) <update> + +v43 (mutable seen$5.add @ Call mutable seen$5.add(frozen item$10)) <update> v56->v43 - - + + v59->v39 - - + + v7 - -v7 (readonly $9 @ readonly $9 = 0) <assign> + +v7 (readonly $9 @ Const readonly $9 = 0) <assign> v9 - -v9 (mutable $9 @ Call mutable Math$8.max(mutable $9, frozen maxItems$3)) <update> + +v9 (mutable $9 @ Call mutable Math$8.max(mutable $9, frozen maxItems$3)) <update> v7->v9 - - + + v8 - -v8 (mutable Math$8.max @ Call mutable Math$8.max(mutable $9, frozen maxItems$3)) <update> + +v8 (mutable Math$8.max @ Call mutable Math$8.max(mutable $9, frozen maxItems$3)) <update> v11 - -v11 (readonly max$7 @ readonly max$7 = Call mutable Math$8.max(mutable $9, frozen maxItems$3)) <assign> + +v11 (readonly max$7 @ Const readonly max$7 = Call mutable Math$8.max(mutable $9, frozen maxItems$3)) <assign> v52 - -v52 (readonly max$7 @ Binary readonly renderedItems$4.length >= readonly max$7) <update> + +v52 (readonly max$7 @ Binary readonly renderedItems$4.length >= readonly max$7) <update> v11->v52 - - + + v72 - -v72 (<join> @ <no-instr>) <update> + +v72 (<join> @ <no-instr>) <update> v11->v72 - - + + v52->v72 - - + + v72->v52 - - + + v13 - -v13 (readonly $11 @ readonly $11 = null) <assign> + +v13 (readonly $11 @ Const readonly $11 = null) <assign> v15 - -v15 (readonly $11 @ Binary frozen item$10 == readonly $11) <update> + +v15 (readonly $11 @ Binary frozen item$10 == readonly $11) <update> v13->v15 - - + + v14 - -v14 (frozen item$10 @ Binary frozen item$10 == readonly $11) <update> + +v14 (frozen item$10 @ Binary frozen item$10 == readonly $11) <update> v40 - -v40 (frozen item$10 @ Call mutable seen$5.has(frozen item$10)) <update> + +v40 (frozen item$10 @ Call mutable seen$5.has(frozen item$10)) <update> v14->v40 - - + + v57 - -v57 (<join> @ <no-instr>) <update> + +v57 (<join> @ <no-instr>) <update> v14->v57 - - + + v40->v57 - - + + v57->v14 - - + + v44 - -v44 (frozen item$10 @ Call mutable seen$5.add(frozen item$10)) <update> + +v44 (frozen item$10 @ Call mutable seen$5.add(frozen item$10)) <update> v57->v44 - - + + v16 - -v16 (frozen $12 @ frozen $12 = Binary frozen item$10 == readonly $11) <assign> + +v16 (frozen $12 @ Const frozen $12 = Binary frozen item$10 == readonly $11) <assign> v17 - -v17 (frozen $12 @ If (frozen $12) then:bb8 else:bb9) <update> + +v17 (frozen $12 @ If (frozen $12) then:bb8 else:bb9) <update> v16->v17 - - + + v38 - -v38 (frozen $13 @ frozen $13 = frozen $12) <assign> + +v38 (frozen $13 @ Const frozen $13 = frozen $12) <assign> v17->v38 - - + + v42 - -v42 (frozen $13 @ If (frozen $13) then:bb1 else:bb4) <update> + +v42 (frozen $13 @ If (frozen $13) then:bb1 else:bb4) <update> v38->v42 - - + + v25 - -v25 (frozen count$17 @ JSX <frozen $20>{frozen count$17}{frozen $21}</frozen $20>) <update> + +v25 (frozen count$17 @ JSX <frozen $20>{frozen count$17}{frozen $21}</frozen $20>) <update> v19->v25 - - + + v20 - -v20 (readonly $18 @ readonly $18 = "div") <assign> + +v20 (readonly $18 @ Const readonly $18 = "div") <assign> v30 - -v30 (frozen $18 @ JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <update> + +v30 (frozen $18 @ JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <update> v20->v30 - - + + v21 - -v21 (readonly $19 @ readonly $19 = " -      ") <assign> + +v21 (readonly $19 @ Const readonly $19 = " +      ") <assign> v31 - -v31 (frozen $19 @ JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <update> + +v31 (frozen $19 @ JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <update> v21->v31 - - + + v22 - -v22 (readonly $20 @ readonly $20 = "h1") <assign> + +v22 (readonly $20 @ Const readonly $20 = "h1") <assign> v24 - -v24 (frozen $20 @ JSX <frozen $20>{frozen count$17}{frozen $21}</frozen $20>) <update> + +v24 (frozen $20 @ JSX <frozen $20>{frozen count$17}{frozen $21}</frozen $20>) <update> v22->v24 - - + + v23 - -v23 (readonly $21 @ readonly $21 = " Items") <assign> + +v23 (readonly $21 @ Const readonly $21 = " Items") <assign> v26 - -v26 (frozen $21 @ JSX <frozen $20>{frozen count$17}{frozen $21}</frozen $20>) <update> + +v26 (frozen $21 @ JSX <frozen $20>{frozen count$17}{frozen $21}</frozen $20>) <update> v23->v26 - - + + v27 - -v27 (readonly $22 @ readonly $22 = JSX <frozen $20>{frozen count$17}{frozen $21}</frozen $20>) <assign> + +v27 (readonly $22 @ Const readonly $22 = JSX <frozen $20>{frozen count$17}{frozen $21}</frozen $20>) <assign> v32 - -v32 (frozen $22 @ JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <update> + +v32 (frozen $22 @ JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <update> v27->v32 - - + + v28 - -v28 (readonly $23 @ readonly $23 = " -      ") <assign> + +v28 (readonly $23 @ Const readonly $23 = " +      ") <assign> v33 - -v33 (frozen $23 @ JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <update> + +v33 (frozen $23 @ JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <update> v28->v33 - - + + v29 - -v29 (readonly $24 @ readonly $24 = " -    ") <assign> + +v29 (readonly $24 @ Const readonly $24 = " +    ") <assign> v35 - -v35 (frozen $24 @ JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <update> + +v35 (frozen $24 @ JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <update> v29->v35 - - + + v36 - -v36 (readonly $25 @ readonly $25 = JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <assign> + +v36 (readonly $25 @ Const readonly $25 = JSX <frozen $18>{frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24}</frozen $18>) <assign> v37 - -v37 (frozen $25 @ Return frozen $25) <update> + +v37 (frozen $25 @ Return frozen $25) <update> v36->v37 - - + + v41 - -v41 (readonly $13 @ readonly $13 = Call mutable seen$5.has(frozen item$10)) <assign> + +v41 (readonly $13 @ Const readonly $13 = Call mutable seen$5.has(frozen item$10)) <assign> v41->v42 - - + + v43->v56 - - + + v43->v59 - - + + v47 - -v47 (frozen item$10 @ JSX <frozen $14>{frozen item$10}</frozen $14>) <update> + +v47 (frozen item$10 @ JSX <frozen $14>{frozen item$10}</frozen $14>) <update> v44->v47 - - + + v47->v57 - - + + v45 - -v45 (readonly $14 @ readonly $14 = "div") <assign> + +v45 (readonly $14 @ Const readonly $14 = "div") <assign> v46 - -v46 (frozen $14 @ JSX <frozen $14>{frozen item$10}</frozen $14>) <update> + +v46 (frozen $14 @ JSX <frozen $14>{frozen item$10}</frozen $14>) <update> v45->v46 - - + + v48 - -v48 (readonly $15 @ readonly $15 = JSX <frozen $14>{frozen item$10}</frozen $14>) <assign> + +v48 (readonly $15 @ Const readonly $15 = JSX <frozen $14>{frozen item$10}</frozen $14>) <assign> v50 - -v50 (mutable $15 @ Call mutable renderedItems$4.push(mutable $15)) <update> + +v50 (mutable $15 @ Call mutable renderedItems$4.push(mutable $15)) <update> v48->v50 - - + + v51->v18 - - + + v51->v62 - - + + v51->v71 - - + + v53 - -v53 (frozen $16 @ frozen $16 = Binary readonly renderedItems$4.length >= readonly max$7) <assign> + +v53 (frozen $16 @ Const frozen $16 = Binary readonly renderedItems$4.length >= readonly max$7) <assign> v54 - -v54 (frozen $16 @ If (frozen $16) then:bb2 else:bb1) <update> + +v54 (frozen $16 @ If (frozen $16) then:bb2 else:bb1) <update> v53->v54 - - + + v55 - -v55 (frozen props$1 @ <no-instr>) <assign> + +v55 (frozen props$1 @ <no-instr>) <assign> v55->v0 - - + + diff --git a/compiler/forget/src/__tests__/fixtures/hir-svg/switch.svg b/compiler/forget/src/__tests__/fixtures/hir-svg/switch.svg index 242aa2410b..9c213d390c 100644 --- a/compiler/forget/src/__tests__/fixtures/hir-svg/switch.svg +++ b/compiler/forget/src/__tests__/fixtures/hir-svg/switch.svg @@ -4,298 +4,298 @@ - + BuildDefUseGraph - + v0 - -v0 (readonly x$2 @ readonly x$2 = Array []) <assign> + +v0 (readonly x$2 @ Let readonly x$2 = Array []) <assign> v7 - -v7 (mutable x$2.push @ Call mutable x$2.push(frozen props$1.p2)) <update> + +v7 (mutable x$2.push @ Call mutable x$2.push(frozen props$1.p2)) <update> v0->v7 - - + + v12 - -v12 (readonly x$2 @ readonly x$2) <update> + +v12 (readonly x$2 @ readonly x$2) <update> v0->v12 - - + + v15 - -v15 (frozen x$2 @ JSX <frozen Component$0 data={frozen x$2} ></frozen Component$0>) <update> + +v15 (frozen x$2 @ JSX <frozen Component$0 data={frozen x$2} ></frozen Component$0>) <update> v0->v15 - - + + v9 - -v9 (mutable x$2.push @ Call mutable x$2.push(frozen props$1.p3)) <update> + +v9 (mutable x$2.push @ Call mutable x$2.push(frozen props$1.p3)) <update> v7->v9 - - + + v12->v15 - - + + v13 - -v13 (readonly y$3 @ readonly y$3 = readonly x$2) <assign> + +v13 (readonly y$3 @ Reassign readonly y$3 = readonly x$2) <assign> v12->v13 - - + + v1 - -v1 (readonly y$3 @ readonly y$3 = undefined) <assign> + +v1 (readonly y$3 @ Let readonly y$3 = undefined) <assign> v17 - -v17 (mutable y$3.push @ Call mutable y$3.push(frozen props$1.p4)) <update> + +v17 (mutable y$3.push @ Call mutable y$3.push(frozen props$1.p4)) <update> v1->v17 - - + + v20 - -v20 (frozen y$3 @ JSX <frozen Component$0 data={frozen y$3} >{frozen child$6}</frozen Component$0>) <update> + +v20 (frozen y$3 @ JSX <frozen Component$0 data={frozen y$3} >{frozen child$6}</frozen Component$0>) <update> v17->v20 - - + + v2 - -v2 (readonly $4 @ readonly $4 = false) <assign> + +v2 (readonly $4 @ Const readonly $4 = false) <assign> v6 - -v6 (readonly $4 @ Switch (frozen props$1.p0);   Case readonly $5: bb4;   Case readonly $4: bb2;   Default: bb1) <update> + +v6 (readonly $4 @ Switch (frozen props$1.p0);   Case readonly $5: bb4;   Case readonly $4: bb2;   Default: bb1) <update> v2->v6 - - + + v3 - -v3 (readonly $5 @ readonly $5 = true) <assign> + +v3 (readonly $5 @ Const readonly $5 = true) <assign> v5 - -v5 (readonly $5 @ Switch (frozen props$1.p0);   Case readonly $5: bb4;   Case readonly $4: bb2;   Default: bb1) <update> + +v5 (readonly $5 @ Switch (frozen props$1.p0);   Case readonly $5: bb4;   Case readonly $4: bb2;   Default: bb1) <update> v3->v5 - - + + v4 - -v4 (frozen props$1.p0 @ Switch (frozen props$1.p0);   Case readonly $5: bb4;   Case readonly $4: bb2;   Default: bb1) <update> + +v4 (frozen props$1.p0 @ Switch (frozen props$1.p0);   Case readonly $5: bb4;   Case readonly $4: bb2;   Default: bb1) <update> v8 - -v8 (frozen props$1.p2 @ Call mutable x$2.push(frozen props$1.p2)) <update> + +v8 (frozen props$1.p2 @ Call mutable x$2.push(frozen props$1.p2)) <update> v4->v8 - - + + v18 - -v18 (frozen props$1.p4 @ Call mutable y$3.push(frozen props$1.p4)) <update> + +v18 (frozen props$1.p4 @ Call mutable y$3.push(frozen props$1.p4)) <update> v4->v18 - - + + v25 - -v25 (<join> @ <no-instr>) <update> + +v25 (<join> @ <no-instr>) <update> v4->v25 - - + + v10 - -v10 (frozen props$1.p3 @ Call mutable x$2.push(frozen props$1.p3)) <update> + +v10 (frozen props$1.p3 @ Call mutable x$2.push(frozen props$1.p3)) <update> v8->v10 - - + + v25->v18 - - + + v9->v12 - - + + v10->v25 - - + + v11 - -v11 (readonly y$3 @ readonly y$3 = Array []) <assign> + +v11 (readonly y$3 @ Reassign readonly y$3 = Array []) <assign> v13->v17 - - + + v14 - -v14 (frozen Component$0 @ JSX <frozen Component$0 data={frozen x$2} ></frozen Component$0>) <update> + +v14 (frozen Component$0 @ JSX <frozen Component$0 data={frozen x$2} ></frozen Component$0>) <update> v19 - -v19 (frozen Component$0 @ JSX <frozen Component$0 data={frozen y$3} >{frozen child$6}</frozen Component$0>) <update> + +v19 (frozen Component$0 @ JSX <frozen Component$0 data={frozen y$3} >{frozen child$6}</frozen Component$0>) <update> v14->v19 - - + + v16 - -v16 (readonly child$6 @ readonly child$6 = JSX <frozen Component$0 data={frozen x$2} ></frozen Component$0>) <assign> + +v16 (readonly child$6 @ Const readonly child$6 = JSX <frozen Component$0 data={frozen x$2} ></frozen Component$0>) <assign> v21 - -v21 (frozen child$6 @ JSX <frozen Component$0 data={frozen y$3} >{frozen child$6}</frozen Component$0>) <update> + +v21 (frozen child$6 @ JSX <frozen Component$0 data={frozen y$3} >{frozen child$6}</frozen Component$0>) <update> v16->v21 - - + + v22 - -v22 (readonly $7 @ readonly $7 = JSX <frozen Component$0 data={frozen y$3} >{frozen child$6}</frozen Component$0>) <assign> + +v22 (readonly $7 @ Const readonly $7 = JSX <frozen Component$0 data={frozen y$3} >{frozen child$6}</frozen Component$0>) <assign> v23 - -v23 (frozen $7 @ Return frozen $7) <update> + +v23 (frozen $7 @ Return frozen $7) <update> v22->v23 - - + + v24 - -v24 (frozen props$1 @ <no-instr>) <assign> + +v24 (frozen props$1 @ <no-instr>) <assign> v24->v4 - - + + diff --git a/compiler/forget/src/__tests__/fixtures/hir/call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/call.expect.md index 81d11d66e4..7c236f2afe 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/call.expect.md @@ -34,14 +34,14 @@ function foo$0() { ``` bb0: - readonly a$2 = Array [] - readonly b$3 = Object { } + Const readonly a$2 = Array [] + Const readonly b$3 = Object { } Call mutable foo$4(mutable a$2, mutable b$3) - readonly $6 = "div" - readonly _$5 = JSX + Const readonly $6 = "div" + Let readonly _$5 = JSX Call mutable foo$4(mutable b$3) - readonly $7 = "div" - readonly $8 = JSX + Const readonly $7 = "div" + Const readonly $8 = JSX Return frozen $8 ``` @@ -49,10 +49,11 @@ bb0: ```javascript function Component$0(props$1) { - a$2 = []; - b$3 = {}; + const a$2 = []; + const b$3 = {}; foo$4(a$2, b$3); - _$5 =
; + let _$5 =
; + foo$4(b$3); return
; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md index 299ded6e10..279301828d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md @@ -35,44 +35,44 @@ function Component(props) { ``` bb0: - frozen items$2 = frozen props$1.items - frozen maxItems$3 = frozen props$1.maxItems - readonly renderedItems$4 = Array [] - readonly seen$5 = New mutable Set$6() - readonly $9 = 0 - readonly max$7 = Call mutable Math$8.max(mutable $9, frozen maxItems$3) + Const frozen items$2 = frozen props$1.items + Const frozen maxItems$3 = frozen props$1.maxItems + Const readonly renderedItems$4 = Array [] + Const readonly seen$5 = New mutable Set$6() + Const readonly $9 = 0 + Const readonly max$7 = Call mutable Math$8.max(mutable $9, frozen maxItems$3) Goto bb1 bb1: If (frozen items$2) then:bb3 else:bb2 bb3: - readonly $11 = null - frozen $12 = Binary frozen item$10 == readonly $11 + Const readonly $11 = null + Const frozen $12 = Binary frozen item$10 == readonly $11 If (frozen $12) then:bb8 else:bb9 bb2: - readonly count$17 = readonly renderedItems$4.length - readonly $18 = "div" - readonly $19 = "\n " - readonly $20 = "h1" - readonly $21 = " Items" - readonly $22 = JSX {frozen count$17}{frozen $21} - readonly $23 = "\n " - readonly $24 = "\n " - readonly $25 = JSX {frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24} + Const readonly count$17 = readonly renderedItems$4.length + Const readonly $18 = "div" + Const readonly $19 = "\n " + Const readonly $20 = "h1" + Const readonly $21 = " Items" + Const readonly $22 = JSX {frozen count$17}{frozen $21} + Const readonly $23 = "\n " + Const readonly $24 = "\n " + Const readonly $25 = JSX {frozen $19}{frozen $22}{frozen $23}{frozen renderedItems$4}{frozen $24} Return frozen $25 bb8: - frozen $13 = frozen $12 + Const frozen $13 = frozen $12 Goto bb7 bb9: - readonly $13 = Call mutable seen$5.has(frozen item$10) + Const readonly $13 = Call mutable seen$5.has(frozen item$10) Goto bb7 bb7: If (frozen $13) then:bb1 else:bb4 bb4: Call mutable seen$5.add(frozen item$10) - readonly $14 = "div" - readonly $15 = JSX {frozen item$10} + Const readonly $14 = "div" + Const readonly $15 = JSX {frozen item$10} Call mutable renderedItems$4.push(mutable $15) - frozen $16 = Binary readonly renderedItems$4.length >= readonly max$7 + Const frozen $16 = Binary readonly renderedItems$4.length >= readonly max$7 If (frozen $16) then:bb2 else:bb1 ``` @@ -80,11 +80,11 @@ bb4: ```javascript function Component$0(props$1) { - items$2 = props$1.items; - maxItems$3 = props$1.maxItems; - renderedItems$4 = []; - seen$5 = new Set$6(); - max$7 = Math$8.max(0, maxItems$3); + const items$2 = props$1.items; + const maxItems$3 = props$1.maxItems; + const renderedItems$4 = []; + const seen$5 = new Set$6(); + const max$7 = Math$8.max(0, maxItems$3); ("<>"); } diff --git a/compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md b/compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md index 3ba5256d42..6c27c54b52 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md @@ -78,11 +78,11 @@ function Component(props) { ``` bb0: - readonly a_DEBUG$2 = Array [] + Const readonly a_DEBUG$2 = Array [] Call mutable a_DEBUG$2.push(frozen props$1.a) If (frozen props$1.b) then:bb2 else:bb1 bb2: - readonly $3 = null + Const readonly $3 = null Return frozen $3 bb1: Call mutable a_DEBUG$2.push(frozen props$1.d) @@ -93,7 +93,7 @@ bb1: ```javascript function Component$0(props$1) { - a_DEBUG$2 = []; + const a_DEBUG$2 = []; a_DEBUG$2.push(props$1.a); if (props$1.b) { return null; @@ -108,7 +108,7 @@ function Component$0(props$1) { ``` bb0: - readonly a$2 = Array [] + Const readonly a$2 = Array [] Call mutable a$2.push(frozen props$1.a) If (frozen props$1.b) then:bb2 else:bb1 bb2: @@ -123,7 +123,7 @@ bb1: ```javascript function Component$0(props$1) { - a$2 = []; + const a$2 = []; a$2.push(props$1.a); if (props$1.b) { a$2.push(props$1.c); @@ -139,12 +139,12 @@ function Component$0(props$1) { ``` bb0: - readonly a$2 = Array [] + Const readonly a$2 = Array [] Call mutable a$2.push(frozen props$1.a) If (frozen props$1.b) then:bb2 else:bb1 bb2: Call mutable a$2.push(frozen props$1.c) - readonly $3 = null + Const readonly $3 = null Return frozen $3 bb1: Call mutable a$2.push(frozen props$1.d) @@ -155,7 +155,7 @@ bb1: ```javascript function Component$0(props$1) { - a$2 = []; + const a$2 = []; a$2.push(props$1.a); if (props$1.b) { a$2.push(props$1.c); @@ -171,7 +171,7 @@ function Component$0(props$1) { ``` bb0: - readonly a$2 = Array [] + Const readonly a$2 = Array [] Call mutable a$2.push(frozen props$1.a) If (frozen props$1.b) then:bb2 else:bb1 bb2: @@ -186,7 +186,7 @@ bb1: ```javascript function Component$0(props$1) { - a$2 = []; + const a$2 = []; a$2.push(props$1.a); if (props$1.b) { a$2.push(props$1.c); @@ -202,7 +202,7 @@ function Component$0(props$1) { ``` bb0: - readonly a$2 = Array [] + Const readonly a$2 = Array [] Call mutable a$2.push(frozen props$1.a) If (frozen props$1.b) then:bb1 else:bb2 bb1: @@ -217,7 +217,7 @@ bb2: ```javascript function Component$0(props$1) { - a$2 = []; + const a$2 = []; a$2.push(props$1.a); if (props$1.b) { a$2.push(props$1.d); diff --git a/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md b/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md index 273ea3e3e6..7d95dfd50c 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md @@ -67,8 +67,8 @@ function mayMutate() {} ``` bb0: - readonly a$2 = Array [] - readonly b$3 = Array [] + Const readonly a$2 = Array [] + Const readonly b$3 = Array [] If (readonly b$3) then:bb2 else:bb1 bb2: Call mutable a$2.push(frozen props$1.p0) @@ -79,7 +79,7 @@ bb4: Call mutable b$3.push(frozen props$1.p2) Goto bb3 bb3: - readonly $5 = JSX + Const readonly $5 = JSX Return frozen $5 ``` @@ -87,8 +87,8 @@ bb3: ```javascript function Component$0(props$1) { - a$2 = []; - b$3 = []; + const a$2 = []; + const b$3 = []; if (b$3) { a$2.push(props$1.p0); ("<>"); @@ -107,9 +107,9 @@ function Component$0(props$1) { ``` bb0: - readonly a$2 = Array [] - readonly b$3 = Array [] - readonly $5 = Call mutable mayMutate$4(mutable b$3) + Const readonly a$2 = Array [] + Const readonly b$3 = Array [] + Const readonly $5 = Call mutable mayMutate$4(mutable b$3) If (readonly $5) then:bb2 else:bb1 bb2: Call mutable a$2.push(frozen props$1.p0) @@ -120,7 +120,7 @@ bb4: Call mutable b$3.push(frozen props$1.p2) Goto bb3 bb3: - readonly $7 = JSX + Const readonly $7 = JSX Return frozen $7 ``` @@ -128,8 +128,8 @@ bb3: ```javascript function Component$0(props$1) { - a$2 = []; - b$3 = []; + const a$2 = []; + const b$3 = []; if (mayMutate$4(b$3)) { a$2.push(props$1.p0); ("<>"); diff --git a/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md b/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md index 479fde7fba..0aa2ea7015 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md @@ -34,14 +34,14 @@ function Foo$0() { ``` bb0: - readonly a$2 = Array [] - readonly b$3 = Object { } + Const readonly a$2 = Array [] + Const readonly b$3 = Object { } New mutable Foo$4(mutable a$2, mutable b$3) - readonly $6 = "div" - readonly _$5 = JSX + Const readonly $6 = "div" + Let readonly _$5 = JSX New mutable Foo$4(mutable b$3) - readonly $7 = "div" - readonly $8 = JSX + Const readonly $7 = "div" + Const readonly $8 = JSX Return frozen $8 ``` @@ -49,10 +49,11 @@ bb0: ```javascript function Component$0(props$1) { - a$2 = []; - b$3 = {}; + const a$2 = []; + const b$3 = {}; new Foo$4(a$2, b$3); - _$5 =
; + let _$5 =
; + new Foo$4(b$3); return
; } 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 5c38bfc370..7ac2ad574c 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md @@ -53,13 +53,13 @@ function foo$0() { ``` bb0: - readonly x$2 = Array [] - frozen y$3 = Call frozen useFreeze$4(frozen x$2) + Const readonly x$2 = Array [] + Const frozen y$3 = Call frozen useFreeze$4(frozen x$2) Call mutable foo$5(frozen y$3, frozen x$2) - readonly $6 = "\n " - readonly $7 = "\n " - readonly $8 = "\n " - readonly $9 = JSX {frozen $6}{frozen x$2}{frozen $7}{frozen y$3}{frozen $8} + Const readonly $6 = "\n " + Const readonly $7 = "\n " + Const readonly $8 = "\n " + Const readonly $9 = JSX {frozen $6}{frozen x$2}{frozen $7}{frozen y$3}{frozen $8} Return frozen $9 ``` @@ -67,8 +67,8 @@ bb0: ```javascript function Component$0(props$1) { - x$2 = []; - y$3 = useFreeze$4(x$2); + const x$2 = []; + const y$3 = useFreeze$4(x$2); foo$5(y$3, x$2); return ( diff --git a/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md index 3ed3be514d..a0828e3d84 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md @@ -97,15 +97,15 @@ function Foo$0() { ``` bb0: - readonly a$2 = Call mutable compute$3(frozen props$1.a) - readonly b$4 = Call mutable compute$3(frozen props$1.b) + Const readonly a$2 = Call mutable compute$3(frozen props$1.a) + Const readonly b$4 = Call mutable compute$3(frozen props$1.b) If (frozen props$1.c) then:bb2 else:bb1 bb2: Call mutable mutate$5(mutable a$2) Call mutable mutate$5(mutable b$4) Goto bb1 bb1: - readonly $7 = JSX + Const readonly $7 = JSX Return frozen $7 ``` @@ -113,8 +113,8 @@ bb1: ```javascript function Component$0(props$1) { - a$2 = compute$3(props$1.a); - b$4 = compute$3(props$1.b); + const a$2 = compute$3(props$1.a); + const b$4 = compute$3(props$1.b); if (props$1.c) { mutate$5(a$2); mutate$5(b$4); diff --git a/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md b/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md index ba4d6536fa..19ee176fee 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md @@ -28,9 +28,9 @@ function Foo() {} ``` bb0: - readonly a$2 = Call mutable compute$3(frozen props$1.a) - readonly b$4 = Call mutable compute$3(frozen props$1.b) - readonly $6 = JSX + Const readonly a$2 = Call mutable compute$3(frozen props$1.a) + Const readonly b$4 = Call mutable compute$3(frozen props$1.b) + Const readonly $6 = JSX Return frozen $6 ``` @@ -38,8 +38,8 @@ bb0: ```javascript function Component$0(props$1) { - a$2 = compute$3(props$1.a); - b$4 = compute$3(props$1.b); + const a$2 = compute$3(props$1.a); + const b$4 = compute$3(props$1.b); return ; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md index 8cef61b7e3..4528ebedc8 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md @@ -76,14 +76,14 @@ function Foo$0() { ``` bb0: - readonly a$2 = Call mutable compute$3(frozen props$1.a) - readonly b$4 = Call mutable compute$3(frozen props$1.b) + Const readonly a$2 = Call mutable compute$3(frozen props$1.a) + Const readonly b$4 = Call mutable compute$3(frozen props$1.b) If (frozen props$1.c) then:bb2 else:bb1 bb2: Call mutable foo$5(mutable a$2, mutable b$4) Goto bb1 bb1: - readonly $7 = JSX + Const readonly $7 = JSX Return frozen $7 ``` @@ -91,8 +91,8 @@ bb1: ```javascript function Component$0(props$1) { - a$2 = compute$3(props$1.a); - b$4 = compute$3(props$1.b); + const a$2 = compute$3(props$1.a); + const b$4 = compute$3(props$1.b); if (props$1.c) { foo$5(a$2, b$4); ("<>"); diff --git a/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md b/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md index 287a7cdedf..43ac1bc3d8 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md @@ -28,10 +28,10 @@ function Foo() {} ``` bb0: - readonly a$2 = Call mutable compute$3(frozen props$1.a) - readonly b$4 = Call mutable compute$3(frozen props$1.b) + Const readonly a$2 = Call mutable compute$3(frozen props$1.a) + Const readonly b$4 = Call mutable compute$3(frozen props$1.b) Call mutable foo$5(mutable a$2, mutable b$4) - readonly $7 = JSX + Const readonly $7 = JSX Return frozen $7 ``` @@ -39,8 +39,8 @@ bb0: ```javascript function Component$0(props$1) { - a$2 = compute$3(props$1.a); - b$4 = compute$3(props$1.b); + const a$2 = compute$3(props$1.a); + const b$4 = compute$3(props$1.b); foo$5(a$2, b$4); return ; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md index f7e53da58e..a7cb076b9e 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md @@ -17,12 +17,12 @@ function Component(props) { ``` bb0: - readonly x$2 = Object { } - readonly y$3 = Array [] - readonly x$2.y = readonly y$3 - readonly child$4 = JSX + Const readonly x$2 = Object { } + Const readonly y$3 = Array [] + Reassign readonly x$2.y = readonly y$3 + Const readonly child$4 = JSX Call mutable x$2.y.push(frozen props$1.p0) - readonly $5 = JSX {frozen child$4} + Const readonly $5 = JSX {frozen child$4} Return frozen $5 ``` @@ -30,10 +30,10 @@ bb0: ```javascript function Component$0(props$1) { - x$2 = {}; - y$3 = []; + const x$2 = {}; + const y$3 = []; x$2 = y$3; - child$4 = ; + const child$4 = ; x$2.y.push(props$1.p0); return {child$4}; } 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 9a6e79240a..1d15cafa2d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md @@ -23,17 +23,17 @@ function Component(props) { ``` bb0: - readonly x$2 = Array [] + Let readonly x$2 = Array [] Call mutable x$2.push(frozen props$1.p0) - readonly y$3 = readonly x$2 + Let readonly y$3 = readonly x$2 If (frozen props$1.p1) then:bb2 else:bb1 bb2: - readonly x$2 = Array [] + Reassign readonly x$2 = Array [] Goto bb1 bb1: - readonly _$4 = JSX + Let readonly _$4 = JSX Call mutable y$3.push(frozen props$1.p2) - readonly $5 = JSX + Const readonly $5 = JSX Return frozen $5 ``` @@ -41,15 +41,16 @@ bb1: ```javascript function Component$0(props$1) { - x$2 = []; + let x$2 = []; x$2.push(props$1.p0); - y$3 = x$2; + let y$3 = x$2; if (props$1.p1) { x$2 = []; ("<>"); } - _$4 = ; + let _$4 = ; + y$3.push(props$1.p2); return ; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md index 69ff4aefbd..044f294372 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md @@ -21,13 +21,13 @@ function Component(props) { ``` bb0: - readonly x$2 = Array [] + Let readonly x$2 = Array [] Call mutable x$2.push(frozen props$1.p0) - readonly y$3 = readonly x$2 - readonly x$2 = Array [] - readonly _$4 = JSX + Let readonly y$3 = readonly x$2 + Reassign readonly x$2 = Array [] + Let readonly _$4 = JSX Call mutable y$3.push(frozen props$1.p1) - readonly $5 = JSX + Const readonly $5 = JSX Return frozen $5 ``` @@ -35,11 +35,12 @@ bb0: ```javascript function Component$0(props$1) { - x$2 = []; + let x$2 = []; x$2.push(props$1.p0); - y$3 = x$2; + let y$3 = x$2; x$2 = []; - _$4 = ; + let _$4 = ; + y$3.push(props$1.p1); return ; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md b/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md index c9052b24e1..e1fb624c18 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md @@ -17,13 +17,13 @@ function foo(x, y) { bb0: If (frozen x$1) then:bb2 else:bb1 bb2: - readonly $3 = false - readonly $4 = Call mutable foo$0(mutable $3, frozen y$2) + Const readonly $3 = false + Const readonly $4 = Call mutable foo$0(mutable $3, frozen y$2) Return frozen $4 bb1: - readonly $5 = 10 - frozen $6 = Binary frozen y$2 * readonly $5 - readonly $7 = Array [frozen $6] + Const readonly $5 = 10 + Const frozen $6 = Binary frozen y$2 * readonly $5 + Const readonly $7 = Array [frozen $6] Return frozen $7 ``` 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 409f1dec2e..a301daf79e 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 @@ -32,27 +32,27 @@ function Component(props) { ``` bb0: - readonly x$2 = Array [] - readonly y$3 = undefined - readonly $4 = false - readonly $5 = true - readonly $6 = 1 + Let readonly x$2 = Array [] + Let readonly y$3 = undefined + Const readonly $4 = false + Const readonly $5 = true + Const readonly $6 = 1 Switch (frozen props$1.p0) Case readonly $6: bb1 Case readonly $5: bb6 Default: bb1 Case readonly $4: bb2 bb1: - readonly child$7 = JSX + Const readonly child$7 = JSX Call mutable y$3.push(frozen props$1.p4) - readonly $8 = JSX {frozen child$7} + Const readonly $8 = JSX {frozen child$7} Return frozen $8 bb6: Call mutable x$2.push(frozen props$1.p2) - readonly y$3 = Array [] + Reassign readonly y$3 = Array [] Goto bb1 bb2: - readonly y$3 = readonly x$2 + Reassign readonly y$3 = readonly x$2 Goto bb1 ``` @@ -60,8 +60,8 @@ bb2: ```javascript function Component$0(props$1) { - x$2 = []; - y$3 = undefined; + let x$2 = []; + let y$3 = undefined; switch (props$1.p0) { case 1: break; @@ -81,7 +81,7 @@ function Component$0(props$1) { } } - child$7 = ; + const child$7 = ; y$3.push(props$1.p4); return {child$7}; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md index 9c29e63b5f..e10639f01a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md @@ -28,10 +28,10 @@ function Component(props) { ``` bb0: - readonly x$2 = Array [] - readonly y$3 = undefined - readonly $4 = false - readonly $5 = true + Let readonly x$2 = Array [] + Let readonly y$3 = undefined + Const readonly $4 = false + Const readonly $5 = true Switch (frozen props$1.p0) Case readonly $5: bb4 Case readonly $4: bb2 @@ -39,15 +39,15 @@ bb0: bb4: Call mutable x$2.push(frozen props$1.p2) Call mutable x$2.push(frozen props$1.p3) - readonly y$3 = Array [] + Reassign readonly y$3 = Array [] Goto bb2 bb2: - readonly y$3 = readonly x$2 + Reassign readonly y$3 = readonly x$2 Goto bb1 bb1: - readonly child$6 = JSX + Const readonly child$6 = JSX Call mutable y$3.push(frozen props$1.p4) - readonly $7 = JSX {frozen child$6} + Const readonly $7 = JSX {frozen child$6} Return frozen $7 ``` @@ -55,8 +55,8 @@ bb1: ```javascript function Component$0(props$1) { - x$2 = []; - y$3 = undefined; + let x$2 = []; + let y$3 = undefined; switch (props$1.p0) { case true: { x$2.push(props$1.p2); @@ -71,7 +71,7 @@ function Component$0(props$1) { } } - child$6 = ; + const child$6 = ; y$3.push(props$1.p4); return {child$6}; }