diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts index 6fd7c0a459..a45f00889f 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts @@ -41,10 +41,12 @@ import { SourceLocation, SpreadPattern, ThrowTerminal, + Type, makeInstructionId, makeType, } from "./HIR"; import HIRBuilder, { Bindings } from "./HIRBuilder"; +import { BuiltInArrayId } from "./ObjectShape"; /* * ******************************************************************************************* @@ -2148,21 +2150,23 @@ function lowerExpression( } case "TypeCastExpression": { let expr = exprPath as NodePath; + const typeAnnotation = expr.get("typeAnnotation").get("typeAnnotation"); return { kind: "TypeCastExpression", value: lowerExpressionToTemporary(builder, expr.get("expression")), - typeAnnotation: expr.get("typeAnnotation").get("typeAnnotation").node, - type: makeType(), + typeAnnotation: typeAnnotation.node, + type: lowerType(builder, typeAnnotation), loc: exprLoc, }; } case "TSAsExpression": { let expr = exprPath as NodePath; + const typeAnnotation = expr.get("typeAnnotation"); return { kind: "TypeCastExpression", value: lowerExpressionToTemporary(builder, expr.get("expression")), - typeAnnotation: expr.get("typeAnnotation").node, - type: makeType(), + typeAnnotation: typeAnnotation.node, + type: lowerType(builder, typeAnnotation), loc: exprLoc, }; } @@ -3791,3 +3795,52 @@ function gatherCapturedDeps( function notNull(value: T | null): value is T { return value !== null; } + +function lowerType( + _builder: HIRBuilder, + path: NodePath +): Type { + const node = path.node; + switch (node.type) { + case "GenericTypeAnnotation": { + const typeAnnotation = path as NodePath; + const id = typeAnnotation.get("id"); + if (id.node.type === "Identifier" && id.node.name === "Array") { + return { kind: "Object", shapeId: BuiltInArrayId }; + } + return makeType(); + } + case "TSTypeReference": { + const typeReference = path as NodePath; + const typeName = typeReference.get("typeName").node; + if (typeName.type === "Identifier" && typeName.name === "Array") { + return { kind: "Object", shapeId: BuiltInArrayId }; + } + return makeType(); + } + case "ArrayTypeAnnotation": + case "TSArrayType": { + return { kind: "Object", shapeId: BuiltInArrayId }; + } + case "BooleanLiteralTypeAnnotation": + case "BooleanTypeAnnotation": + case "NullLiteralTypeAnnotation": + case "NumberLiteralTypeAnnotation": + case "NumberTypeAnnotation": + case "StringLiteralTypeAnnotation": + case "StringTypeAnnotation": + case "TSBooleanKeyword": + case "TSNullKeyword": + case "TSNumberKeyword": + case "TSStringKeyword": + case "TSSymbolKeyword": + case "TSUndefinedKeyword": + case "TSVoidKeyword": + case "VoidTypeAnnotation": { + return { kind: "Primitive" }; + } + default: { + return makeType(); + } + } +} diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts index c58727f5e1..20c4ccfd93 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts @@ -373,7 +373,9 @@ export function printInstructionValue(instrValue: ReactiveValue): string { break; } case "TypeCastExpression": { - value = `TypeCast ${printPlace(instrValue.value)}`; + value = `TypeCast ${printPlace(instrValue.value)}: ${printType( + instrValue.type + )}`; break; } case "JsxExpression": { diff --git a/compiler/packages/babel-plugin-react-forget/src/TypeInference/InferTypes.ts b/compiler/packages/babel-plugin-react-forget/src/TypeInference/InferTypes.ts index 6938f575b8..0d41f2504c 100644 --- a/compiler/packages/babel-plugin-react-forget/src/TypeInference/InferTypes.ts +++ b/compiler/packages/babel-plugin-react-forget/src/TypeInference/InferTypes.ts @@ -262,7 +262,8 @@ function* generateInstructionTypes( } case "TypeCastExpression": { - yield equation(left, value.value.identifier.type); + yield equation(value.type, value.value.identifier.type); + yield equation(left, value.type); break; } diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array.expect.md index 89cf3bbb76..d871aa4856 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array.expect.md @@ -2,14 +2,16 @@ ## Input ```javascript -import { identity } from "shared-runtime"; - function Component(props: { id: number }) { - const x = [props.id] as number[]; - const y = identity(x[0]); + const x = makeArray(props.id) as number[]; + const y = x.at(0); return y; } +function makeArray(x: T): Array { + return [x]; +} + export const FIXTURE_ENTRYPOINT = { fn: Component, params: [{ id: 42 }], @@ -21,23 +23,42 @@ export const FIXTURE_ENTRYPOINT = { ```javascript import { unstable_useMemoCache as useMemoCache } from "react"; -import { identity } from "shared-runtime"; - function Component(props) { - const $ = useMemoCache(2); + const $ = useMemoCache(4); let t0; if ($[0] !== props.id) { - const x = [props.id] as number[]; - t0 = identity(x[0]); + t0 = makeArray(props.id); $[0] = props.id; $[1] = t0; } else { t0 = $[1]; } - const y = t0; + const x = t0 as number[]; + let t1; + if ($[2] !== x) { + t1 = x.at(0); + $[2] = x; + $[3] = t1; + } else { + t1 = $[3]; + } + const y = t1; return y; } +function makeArray(x) { + const $ = useMemoCache(2); + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; +} + export const FIXTURE_ENTRYPOINT = { fn: Component, params: [{ id: 42 }], diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array.ts b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array.ts index b022243746..ec4b6f7904 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array.ts +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array.ts @@ -1,11 +1,13 @@ -import { identity } from "shared-runtime"; - function Component(props: { id: number }) { - const x = [props.id] as number[]; - const y = identity(x[0]); + const x = makeArray(props.id) as number[]; + const y = x.at(0); return y; } +function makeArray(x: T): Array { + return [x]; +} + export const FIXTURE_ENTRYPOINT = { fn: Component, params: [{ id: 42 }], diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array_.flow.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array_.flow.expect.md index f2efea98d2..3175f6d8d7 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array_.flow.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array_.flow.expect.md @@ -3,11 +3,11 @@ ```javascript // @flow -import { identity } from "shared-runtime"; +import { identity, makeArray } from "shared-runtime"; function Component(props: { id: number }) { - const x = ([props.id]: Array); - const y = identity(x[0]); + const x = (makeArray(props.id): Array); + const y = x.at(0); return y; } @@ -22,20 +22,28 @@ export const FIXTURE_ENTRYPOINT = { ```javascript import { unstable_useMemoCache as useMemoCache } from "react"; -import { identity } from "shared-runtime"; +import { identity, makeArray } from "shared-runtime"; function Component(props) { - const $ = useMemoCache(2); + const $ = useMemoCache(4); let t0; if ($[0] !== props.id) { - const x = ([props.id]: Array); - t0 = identity(x[0]); + t0 = makeArray(props.id); $[0] = props.id; $[1] = t0; } else { t0 = $[1]; } - const y = t0; + const x = (t0: Array); + let t1; + if ($[2] !== x) { + t1 = x.at(0); + $[2] = x; + $[3] = t1; + } else { + t1 = $[3]; + } + const y = t1; return y; } diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array_.flow.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array_.flow.js index f5eea1216b..1efc8b7bbe 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array_.flow.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array_.flow.js @@ -1,9 +1,9 @@ // @flow -import { identity } from "shared-runtime"; +import { identity, makeArray } from "shared-runtime"; function Component(props: { id: number }) { - const x = ([props.id]: Array); - const y = identity(x[0]); + const x = (makeArray(props.id): Array); + const y = x.at(0); return y; } diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-number.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-number.expect.md index 96479eeb6b..f4e07ae4f1 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-number.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-number.expect.md @@ -20,20 +20,10 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { unstable_useMemoCache as useMemoCache } from "react"; import { identity } from "shared-runtime"; function Component(props) { - const $ = useMemoCache(2); - let t0; - if ($[0] !== props.id) { - t0 = identity(props.id); - $[0] = props.id; - $[1] = t0; - } else { - t0 = $[1]; - } - const x = t0; + const x = identity(props.id); const y = x as number; return y; } diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-number_.flow.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-number_.flow.expect.md index d164f45da0..7b5a821764 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-number_.flow.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-number_.flow.expect.md @@ -21,20 +21,10 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { unstable_useMemoCache as useMemoCache } from "react"; import { identity } from "shared-runtime"; function Component(props) { - const $ = useMemoCache(2); - let t0; - if ($[0] !== props.id) { - t0 = identity(props.id); - $[0] = props.id; - $[1] = t0; - } else { - t0 = $[1]; - } - const x = t0; + const x = identity(props.id); const y = (x: number); return y; } diff --git a/compiler/packages/sprout/src/shared-runtime.ts b/compiler/packages/sprout/src/shared-runtime.ts index 0695809aa8..c61a30819d 100644 --- a/compiler/packages/sprout/src/shared-runtime.ts +++ b/compiler/packages/sprout/src/shared-runtime.ts @@ -127,6 +127,10 @@ export function makeObject_Primitives(): StringKeyedObject { return { a: 0, b: "value1", c: true }; } +export function makeArray(value: T): Array { + return [value]; +} + export function addOne(value: number): number { return value + 1; }