diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts b/compiler/forget/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts index dfdd840a21..1295e640f1 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts +++ b/compiler/forget/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts @@ -17,6 +17,7 @@ import { Err, Ok, Result } from "../Utils/Result"; import { assertExhaustive } from "../Utils/utils"; import { Environment } from "./Environment"; import { + ArrayExpression, ArrayPattern, BlockId, BranchTerminal, @@ -1064,14 +1065,11 @@ function lowerExpression( } case "ArrayExpression": { const expr = exprPath as NodePath; - let elements: Array = []; + let elements: ArrayExpression["elements"] = []; for (const element of expr.get("elements")) { if (element.node == null) { - builder.errors.push({ - reason: `(BuildHIR::lowerExpression) Handle ${element.type} elements in ArrayExpression`, - severity: ErrorSeverity.Todo, - loc: null, - suggestions: null, + elements.push({ + kind: "Hole", }); continue; } else if (element.isExpression()) { @@ -2696,6 +2694,9 @@ function lowerAssignment( for (let i = 0; i < elements.length; i++) { const element = elements[i]; if (element.node == null) { + items.push({ + kind: "Hole", + }); continue; } if (element.isRestElement()) { diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/HIR/HIR.ts b/compiler/forget/packages/babel-plugin-react-forget/src/HIR/HIR.ts index 7f55f70b51..30290f231a 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/HIR/HIR.ts +++ b/compiler/forget/packages/babel-plugin-react-forget/src/HIR/HIR.ts @@ -472,8 +472,18 @@ export type LValuePattern = { kind: InstructionKind; }; +export type ArrayExpression = { + kind: "ArrayExpression"; + elements: Array; + loc: SourceLocation; +}; + export type Pattern = ArrayPattern | ObjectPattern; +export type Hole = { + kind: "Hole"; +}; + export type SpreadPattern = { kind: "Spread"; place: Place; @@ -481,7 +491,7 @@ export type SpreadPattern = { export type ArrayPattern = { kind: "ArrayPattern"; - items: Array; + items: Array; }; export type ObjectPattern = { @@ -648,11 +658,7 @@ export type InstructionValue = properties: Array; loc: SourceLocation; } - | { - kind: "ArrayExpression"; - elements: Array; - loc: SourceLocation; - } + | ArrayExpression | { kind: "JsxFragment"; children: Array; loc: SourceLocation } | { kind: "RegExpLiteral"; diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts b/compiler/forget/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts index 6a57bada74..05a87b1b10 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts +++ b/compiler/forget/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts @@ -239,6 +239,10 @@ export function printTerminal(terminal: Terminal): Array | string { return value; } +function printHole(): string { + return ""; +} + export function printInstructionValue(instrValue: ReactiveValue): string { let value = ""; switch (instrValue.kind) { @@ -247,6 +251,8 @@ export function printInstructionValue(instrValue: ReactiveValue): string { .map((element) => { if (element.kind === "Identifier") { return printPlace(element); + } else if (element.kind === "Hole") { + return printHole(); } else { return `...${printPlace(element.place)}`; } @@ -554,7 +560,16 @@ export function printPattern(pattern: Pattern | Place | SpreadPattern): string { switch (pattern.kind) { case "ArrayPattern": { return ( - "[ " + pattern.items.map((item) => printPattern(item)).join(", ") + " ]" + "[ " + + pattern.items + .map((item) => { + if (item.kind === "Hole") { + return ""; + } + return printPattern(item); + }) + .join(", ") + + " ]" ); } case "ObjectPattern": { diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/HIR/visitors.ts b/compiler/forget/packages/babel-plugin-react-forget/src/HIR/visitors.ts index 5b7862df43..321ca6799f 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/HIR/visitors.ts +++ b/compiler/forget/packages/babel-plugin-react-forget/src/HIR/visitors.ts @@ -158,7 +158,7 @@ export function* eachInstructionValueOperand( for (const element of instrValue.elements) { if (element.kind === "Identifier") { yield element; - } else { + } else if (element.kind === "Spread") { yield element.place; } } @@ -253,6 +253,8 @@ export function* eachPatternOperand(pattern: Pattern): Iterable { yield item; } else if (item.kind === "Spread") { yield item.place; + } else if (item.kind === "Hole") { + continue; } else { assertExhaustive( item, @@ -424,9 +426,11 @@ export function mapInstructionOperands( instrValue.elements = instrValue.elements.map((element) => { if (element.kind === "Identifier") { return fn(element); - } else { + } else if (element.kind === "Spread") { element.place = fn(element.place); return element; + } else { + return element; } }); break; @@ -496,9 +500,11 @@ export function mapPatternOperands( pattern.items = pattern.items.map((item) => { if (item.kind === "Identifier") { return fn(item); - } else { + } else if (item.kind === "Spread") { item.place = fn(item.place); return item; + } else { + return item; } }); break; diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/Optimization/DeadCodeElimination.ts b/compiler/forget/packages/babel-plugin-react-forget/src/Optimization/DeadCodeElimination.ts index 0d098231ca..e08582d414 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/Optimization/DeadCodeElimination.ts +++ b/compiler/forget/packages/babel-plugin-react-forget/src/Optimization/DeadCodeElimination.ts @@ -114,7 +114,7 @@ function visitInstruction(instr: Instruction, state: State): void { nextItems = originalItems.slice(0, i + 1); break; } - } else { + } else if (item.kind === "Spread") { if (state.used(item.place.identifier)) { nextItems = originalItems.slice(0, i + 1); break; diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts index 0e309809cb..494ed24f0d 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -716,8 +716,10 @@ function codegenInstructionValue( const elements = instrValue.elements.map((element) => { if (element.kind === "Identifier") { return codegenPlace(cx, element); - } else { + } else if (element.kind === "Spread") { return t.spreadElement(codegenPlace(cx, element.place)); + } else { + return null; } }); value = t.arrayExpression(elements); @@ -1245,7 +1247,14 @@ function codegenLValue( ): t.ArrayPattern | t.ObjectPattern | t.RestElement | t.Identifier { switch (pattern.kind) { case "ArrayPattern": { - return t.arrayPattern(pattern.items.map((item) => codegenLValue(item))); + return t.arrayPattern( + pattern.items.map((item) => { + if (item.kind === "Hole") { + return null; + } + return codegenLValue(item); + }) + ); } case "ObjectPattern": { return t.objectPattern( diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/PruneNonEscapingScopes.ts b/compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/PruneNonEscapingScopes.ts index 822c089fb8..c6dc25b89c 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/PruneNonEscapingScopes.ts +++ b/compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/PruneNonEscapingScopes.ts @@ -628,7 +628,7 @@ function computePatternLValues(pattern: Pattern): Array { for (const item of pattern.items) { if (item.kind === "Identifier") { lvalues.push({ place: item, level: MemoizationLevel.Conditional }); - } else { + } else if (item.kind === "Spread") { lvalues.push({ place: item.place, level: MemoizationLevel.Memoized }); } } diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-expr.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-expr.expect.md new file mode 100644 index 0000000000..9b03535e27 --- /dev/null +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-expr.expect.md @@ -0,0 +1,32 @@ + +## Input + +```javascript +function t(props) { + let x = [, foo, props]; + return x; +} + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; +function t(props) { + const $ = useMemoCache(2); + const c_0 = $[0] !== props; + let t0; + if (c_0) { + t0 = [, foo, props]; + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + return x; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-expr.js b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-expr.js new file mode 100644 index 0000000000..533b5553a1 --- /dev/null +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-expr.js @@ -0,0 +1,4 @@ +function t(props) { + let x = [, foo, props]; + return x; +} diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-pattern-dce-2.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-pattern-dce-2.expect.md new file mode 100644 index 0000000000..d8089b3cfa --- /dev/null +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-pattern-dce-2.expect.md @@ -0,0 +1,21 @@ + +## Input + +```javascript +function t(props) { + let [foo, bar, ,] = props; + return foo; +} + +``` + +## Code + +```javascript +function t(props) { + const [foo] = props; + return foo; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-pattern-dce-2.js b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-pattern-dce-2.js new file mode 100644 index 0000000000..3009a00812 --- /dev/null +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-pattern-dce-2.js @@ -0,0 +1,4 @@ +function t(props) { + let [foo, bar, ,] = props; + return foo; +} diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-pattern-dce.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-pattern-dce.expect.md new file mode 100644 index 0000000000..1778ec0203 --- /dev/null +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-pattern-dce.expect.md @@ -0,0 +1,21 @@ + +## Input + +```javascript +function t(props) { + let [, foo, bar] = props; + return foo; +} + +``` + +## Code + +```javascript +function t(props) { + const [, foo] = props; + return foo; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-pattern-dce.js b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-pattern-dce.js new file mode 100644 index 0000000000..2c070d4955 --- /dev/null +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array-pattern-dce.js @@ -0,0 +1,4 @@ +function t(props) { + let [, foo, bar] = props; + return foo; +} diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array.expect.md new file mode 100644 index 0000000000..5276adf724 --- /dev/null +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array.expect.md @@ -0,0 +1,23 @@ + +## Input + +```javascript +function t(props) { + let [, setstate] = useState(); + setstate(1); + return props.foo; +} + +``` + +## Code + +```javascript +function t(props) { + const [, setstate] = useState(); + setstate(1); + return props.foo; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array.js b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array.js new file mode 100644 index 0000000000..302672aa1c --- /dev/null +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/holey-array.js @@ -0,0 +1,5 @@ +function t(props) { + let [, setstate] = useState(); + setstate(1); + return props.foo; +}