Support TS type annotations in TypeCastExpression instr
Adds support for TSAsExpression in BuildHIR, which lowers to a TypeCastExpression, and to Codegen to reproduce the `as` expression.
Joe Savona committed
Dec 11, 2023 at 11:34 UTC
d163c0b7c3900db9f595c3dd95cee68517b4704a
11 files changed
+274
-6
compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts
+13
-1
@@ -42,6 +42,7 @@ import {
42
SpreadPattern,
43
ThrowTerminal,
44
makeInstructionId,
45
+ makeType,
46
} from "./HIR";
47
import HIRBuilder, { Bindings } from "./HIRBuilder";
48
@@ -2150,7 +2151,18 @@ function lowerExpression(
2151
return {
2152
kind: "TypeCastExpression",
2153
value: lowerExpressionToTemporary(builder, expr.get("expression")),
2153
- type: expr.get("typeAnnotation").node,
2154
+ typeAnnotation: expr.get("typeAnnotation").get("typeAnnotation").node,
2155
+ type: makeType(),
2156
+ loc: exprLoc,
2157
+ };
2158
+ }
2159
+ case "TSAsExpression": {
2160
+ let expr = exprPath as NodePath<t.TSAsExpression>;
2161
+ return {
2162
+ kind: "TypeCastExpression",
2163
+ value: lowerExpressionToTemporary(builder, expr.get("expression")),
2164
+ typeAnnotation: expr.get("typeAnnotation").node,
2165
+ type: makeType(),
2166
loc: exprLoc,
2167
};
2168
}
compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts
+2
-1
@@ -718,7 +718,8 @@ export type InstructionValue =
718
| {
719
kind: "TypeCastExpression";
720
value: Place;
721
- type: t.TypeAnnotation;
721
+ typeAnnotation: t.FlowType | t.TSType;
722
+ type: Type;
723
loc: SourceLocation;
724
}
725
| {
compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+11
-4
@@ -1508,10 +1508,17 @@ function codegenInstructionValue(
1508
break;
1509
}
1510
case "TypeCastExpression": {
1511
- value = t.typeCastExpression(
1512
- codegenPlaceToExpression(cx, instrValue.value),
1513
- instrValue.type
1514
- );
1511
+ if (t.isTSType(instrValue.typeAnnotation)) {
1512
+ value = t.tsAsExpression(
1513
+ codegenPlaceToExpression(cx, instrValue.value),
1514
+ instrValue.typeAnnotation
1515
+ );
1516
+ } else {
1517
+ value = t.typeCastExpression(
1518
+ codegenPlaceToExpression(cx, instrValue.value),
1519
+ t.typeAnnotation(instrValue.typeAnnotation)
1520
+ );
1521
+ }
1522
break;
1523
}
1524
case "LogicalExpression": {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array.expect.md
new
+49
@@ -0,0 +1,49 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+import { identity } from "shared-runtime";
6
+
7
+function Component(props: { id: number }) {
8
+ const x = [props.id] as number[];
9
+ const y = identity(x[0]);
10
+ return y;
11
+}
12
+
13
+export const FIXTURE_ENTRYPOINT = {
14
+ fn: Component,
15
+ params: [{ id: 42 }],
16
+};
17
+
18
+```
19
+
20
+## Code
21
+
22
+```javascript
23
+import { unstable_useMemoCache as useMemoCache } from "react";
24
+import { identity } from "shared-runtime";
25
+
26
+function Component(props) {
27
+ const $ = useMemoCache(2);
28
+ let t0;
29
+ if ($[0] !== props.id) {
30
+ const x = [props.id] as number[];
31
+ t0 = identity(x[0]);
32
+ $[0] = props.id;
33
+ $[1] = t0;
34
+ } else {
35
+ t0 = $[1];
36
+ }
37
+ const y = t0;
38
+ return y;
39
+}
40
+
41
+export const FIXTURE_ENTRYPOINT = {
42
+ fn: Component,
43
+ params: [{ id: 42 }],
44
+};
45
+
46
+```
47
+
48
+### Eval output
49
+(kind: ok) 42
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array.ts
new
+12
@@ -0,0 +1,12 @@
1
+import { identity } from "shared-runtime";
2
+
3
+function Component(props: { id: number }) {
4
+ const x = [props.id] as number[];
5
+ const y = identity(x[0]);
6
+ return y;
7
+}
8
+
9
+export const FIXTURE_ENTRYPOINT = {
10
+ fn: Component,
11
+ params: [{ id: 42 }],
12
+};
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array_.flow.expect.md
new
+50
@@ -0,0 +1,50 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @flow
6
+import { identity } from "shared-runtime";
7
+
8
+function Component(props: { id: number }) {
9
+ const x = ([props.id]: Array<number>);
10
+ const y = identity(x[0]);
11
+ return y;
12
+}
13
+
14
+export const FIXTURE_ENTRYPOINT = {
15
+ fn: Component,
16
+ params: [{ id: 42 }],
17
+};
18
+
19
+```
20
+
21
+## Code
22
+
23
+```javascript
24
+import { unstable_useMemoCache as useMemoCache } from "react";
25
+import { identity } from "shared-runtime";
26
+
27
+function Component(props) {
28
+ const $ = useMemoCache(2);
29
+ let t0;
30
+ if ($[0] !== props.id) {
31
+ const x = ([props.id]: Array<number>);
32
+ t0 = identity(x[0]);
33
+ $[0] = props.id;
34
+ $[1] = t0;
35
+ } else {
36
+ t0 = $[1];
37
+ }
38
+ const y = t0;
39
+ return y;
40
+}
41
+
42
+export const FIXTURE_ENTRYPOINT = {
43
+ fn: Component,
44
+ params: [{ id: 42 }],
45
+};
46
+
47
+```
48
+
49
+### Eval output
50
+(kind: ok) 42
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-array_.flow.js
new
+13
@@ -0,0 +1,13 @@
1
+// @flow
2
+import { identity } from "shared-runtime";
3
+
4
+function Component(props: { id: number }) {
5
+ const x = ([props.id]: Array<number>);
6
+ const y = identity(x[0]);
7
+ return y;
8
+}
9
+
10
+export const FIXTURE_ENTRYPOINT = {
11
+ fn: Component,
12
+ params: [{ id: 42 }],
13
+};
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-number.expect.md
new
+49
@@ -0,0 +1,49 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+import { identity } from "shared-runtime";
6
+
7
+function Component(props: { id: number }) {
8
+ const x = identity(props.id);
9
+ const y = x as number;
10
+ return y;
11
+}
12
+
13
+export const FIXTURE_ENTRYPOINT = {
14
+ fn: Component,
15
+ params: [{ id: 42 }],
16
+};
17
+
18
+```
19
+
20
+## Code
21
+
22
+```javascript
23
+import { unstable_useMemoCache as useMemoCache } from "react";
24
+import { identity } from "shared-runtime";
25
+
26
+function Component(props) {
27
+ const $ = useMemoCache(2);
28
+ let t0;
29
+ if ($[0] !== props.id) {
30
+ t0 = identity(props.id);
31
+ $[0] = props.id;
32
+ $[1] = t0;
33
+ } else {
34
+ t0 = $[1];
35
+ }
36
+ const x = t0;
37
+ const y = x as number;
38
+ return y;
39
+}
40
+
41
+export const FIXTURE_ENTRYPOINT = {
42
+ fn: Component,
43
+ params: [{ id: 42 }],
44
+};
45
+
46
+```
47
+
48
+### Eval output
49
+(kind: ok) 42
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-number.ts
new
+12
@@ -0,0 +1,12 @@
1
+import { identity } from "shared-runtime";
2
+
3
+function Component(props: { id: number }) {
4
+ const x = identity(props.id);
5
+ const y = x as number;
6
+ return y;
7
+}
8
+
9
+export const FIXTURE_ENTRYPOINT = {
10
+ fn: Component,
11
+ params: [{ id: 42 }],
12
+};
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-number_.flow.expect.md
new
+50
@@ -0,0 +1,50 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @flow
6
+import { identity } from "shared-runtime";
7
+
8
+function Component(props: {id: number}) {
9
+ const x = identity(props.id);
10
+ const y = (x: number);
11
+ return y;
12
+}
13
+
14
+export const FIXTURE_ENTRYPOINT = {
15
+ fn: Component,
16
+ params: [{id: 42}],
17
+};
18
+
19
+```
20
+
21
+## Code
22
+
23
+```javascript
24
+import { unstable_useMemoCache as useMemoCache } from "react";
25
+import { identity } from "shared-runtime";
26
+
27
+function Component(props) {
28
+ const $ = useMemoCache(2);
29
+ let t0;
30
+ if ($[0] !== props.id) {
31
+ t0 = identity(props.id);
32
+ $[0] = props.id;
33
+ $[1] = t0;
34
+ } else {
35
+ t0 = $[1];
36
+ }
37
+ const x = t0;
38
+ const y = (x: number);
39
+ return y;
40
+}
41
+
42
+export const FIXTURE_ENTRYPOINT = {
43
+ fn: Component,
44
+ params: [{ id: 42 }],
45
+};
46
+
47
+```
48
+
49
+### Eval output
50
+(kind: ok) 42
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/type-annotations/type-annotation-as-number_.flow.js
new
+13
@@ -0,0 +1,13 @@
1
+// @flow
2
+import { identity } from "shared-runtime";
3
+
4
+function Component(props: {id: number}) {
5
+ const x = identity(props.id);
6
+ const y = (x: number);
7
+ return y;
8
+}
9
+
10
+export const FIXTURE_ENTRYPOINT = {
11
+ fn: Component,
12
+ params: [{id: 42}],
13
+};