From c87a1916f435f36efa8873ddfc8e13a25d91c118 Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Wed, 24 May 2023 09:54:07 -0700 Subject: [PATCH] Infer property types for destructuring --- .../forget/src/TypeInference/InferTypes.ts | 32 ++++++++++++- ...destructuring-property-inference.expect.md | 48 +++++++++++++++++++ .../destructuring-property-inference.js | 7 +++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 compiler/forget/src/__tests__/fixtures/compiler/destructuring-property-inference.expect.md create mode 100644 compiler/forget/src/__tests__/fixtures/compiler/destructuring-property-inference.js diff --git a/compiler/forget/src/TypeInference/InferTypes.ts b/compiler/forget/src/TypeInference/InferTypes.ts index c804ec8735..a00cb5b5f6 100644 --- a/compiler/forget/src/TypeInference/InferTypes.ts +++ b/compiler/forget/src/TypeInference/InferTypes.ts @@ -201,9 +201,39 @@ function* generateInstructionTypes( break; } + case "Destructure": { + const pattern = value.lvalue.pattern; + if (pattern.kind === "ArrayPattern") { + for (let i = 0; i < pattern.items.length; i++) { + const item = pattern.items[i]; + if (item.kind === "Identifier") { + // To simulate tuples we use properties with `String()`, eg "0". + const propertyName = String(i); + yield equation(item.identifier.type, { + kind: "Property", + object: value.value.identifier.type, + propertyName, + }); + } else { + break; + } + } + } else { + for (const property of pattern.properties) { + if (property.kind === "ObjectProperty") { + yield equation(property.place.identifier.type, { + kind: "Property", + object: value.value.identifier.type, + propertyName: property.name, + }); + } + } + } + break; + } + case "DeclareLocal": case "DeclareContext": - case "Destructure": case "NewExpression": case "TypeCastExpression": case "JsxExpression": diff --git a/compiler/forget/src/__tests__/fixtures/compiler/destructuring-property-inference.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/destructuring-property-inference.expect.md new file mode 100644 index 0000000000..57536d03a9 --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/compiler/destructuring-property-inference.expect.md @@ -0,0 +1,48 @@ + +## Input + +```javascript +function Component(props) { + const x = []; + x.push(props.value); + const { length: y } = x; + foo(y); + return [x, y]; +} + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; +function Component(props) { + const $ = useMemoCache(5); + const c_0 = $[0] !== props.value; + let x; + if (c_0) { + x = []; + x.push(props.value); + $[0] = props.value; + $[1] = x; + } else { + x = $[1]; + } + const { length: y } = x; + foo(y); + const c_2 = $[2] !== x; + const c_3 = $[3] !== y; + let t0; + if (c_2 || c_3) { + t0 = [x, y]; + $[2] = x; + $[3] = y; + $[4] = t0; + } else { + t0 = $[4]; + } + return t0; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/compiler/destructuring-property-inference.js b/compiler/forget/src/__tests__/fixtures/compiler/destructuring-property-inference.js new file mode 100644 index 0000000000..47cba2aa68 --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/compiler/destructuring-property-inference.js @@ -0,0 +1,7 @@ +function Component(props) { + const x = []; + x.push(props.value); + const { length: y } = x; + foo(y); + return [x, y]; +}