mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[typer] Remove type inference of fields
Given that our type inference needs to be very conservative, there's not a lot of benefit to having such fine grained type inference. In the future, we can use type information from flow/ts for inference.
This commit is contained in:
@@ -451,15 +451,13 @@ export type Type =
|
||||
| PrimitiveType
|
||||
| FunctionType
|
||||
| ObjectType
|
||||
| PropType
|
||||
| PolyType
|
||||
| TypeVar;
|
||||
export type PrimitiveType = { kind: "Primitive" };
|
||||
export type FunctionType = {
|
||||
kind: "Function";
|
||||
};
|
||||
export type ObjectType = { kind: "Object"; properties: Map<string, Type> };
|
||||
export type PropType = { kind: "Prop"; objectType: Type; name: string };
|
||||
export type ObjectType = { kind: "Object" };
|
||||
export type TypeVar = {
|
||||
kind: "Type";
|
||||
id: TypeId;
|
||||
@@ -497,7 +495,6 @@ export function typeEquals(tA: Type, tB: Type): boolean {
|
||||
typeVarEquals(tA, tB) ||
|
||||
funcTypeEquals(tA, tB) ||
|
||||
objectTypeEquals(tA, tB) ||
|
||||
propTypeEquals(tA, tB) ||
|
||||
primitiveTypeEquals(tA, tB) ||
|
||||
polyTypeEquals(tA, tB)
|
||||
);
|
||||
@@ -519,32 +516,7 @@ function polyTypeEquals(tA: Type, tB: Type): boolean {
|
||||
}
|
||||
|
||||
function objectTypeEquals(tA: Type, tB: Type): boolean {
|
||||
if (tA.kind === "Object" && tB.kind === "Object") {
|
||||
if (tA.properties.size !== tB.properties.size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const key of tA.properties.keys()) {
|
||||
if (!typeEquals(tA.properties.get(key)!, tB.properties.get(key)!)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function propTypeEquals(tA: Type, tB: Type): boolean {
|
||||
if (tA.kind === "Prop" && tB.kind === "Prop") {
|
||||
if (tA.name !== tB.name) {
|
||||
return false;
|
||||
}
|
||||
return objectTypeEquals(tA.objectType, tB.objectType);
|
||||
}
|
||||
|
||||
return false;
|
||||
return tA.kind === "Object" && tB.kind === "Object";
|
||||
}
|
||||
|
||||
function funcTypeEquals(tA: Type, tB: Type): boolean {
|
||||
|
||||
@@ -3,10 +3,7 @@ import invariant from "invariant";
|
||||
import {
|
||||
HIRFunction,
|
||||
Instruction,
|
||||
LValue,
|
||||
makeType,
|
||||
Place,
|
||||
PropType,
|
||||
Type,
|
||||
typeEquals,
|
||||
TypeId,
|
||||
@@ -85,130 +82,60 @@ function generateTypeEquation(
|
||||
unifier: Unifier
|
||||
): Array<TypeEquation> {
|
||||
const equations: Array<TypeEquation> = [];
|
||||
|
||||
function add(left: Type | null, right: Type | null) {
|
||||
if (left === null || right === null) return;
|
||||
equations.push({
|
||||
left,
|
||||
right,
|
||||
});
|
||||
}
|
||||
|
||||
const { lvalue, value } = instr;
|
||||
const left: Type | null = assignTypeForLvalue(lvalue, equations, unifier);
|
||||
const left = assignType(lvalue?.place);
|
||||
|
||||
switch (value.kind) {
|
||||
case "Primitive": {
|
||||
if (left !== null) {
|
||||
equations.push({
|
||||
left,
|
||||
right: { kind: "Primitive" },
|
||||
});
|
||||
}
|
||||
add(left, { kind: "Primitive" });
|
||||
break;
|
||||
}
|
||||
|
||||
case "Identifier": {
|
||||
if (left !== null) {
|
||||
let right: Type = assignTypeForPlace(value, equations);
|
||||
equations.push({
|
||||
left,
|
||||
right,
|
||||
});
|
||||
}
|
||||
|
||||
add(left, assignType(value));
|
||||
break;
|
||||
}
|
||||
|
||||
case "BinaryExpression": {
|
||||
if (isPrimitiveBinaryOp(value.operator)) {
|
||||
equations.push({
|
||||
left: value.left.identifier.type,
|
||||
right: { kind: "Primitive" },
|
||||
});
|
||||
equations.push({
|
||||
left: value.right.identifier.type,
|
||||
right: { kind: "Primitive" },
|
||||
});
|
||||
add(assignType(value.left), { kind: "Primitive" });
|
||||
add(assignType(value.right), { kind: "Primitive" });
|
||||
}
|
||||
|
||||
if (left !== null) {
|
||||
equations.push({
|
||||
left,
|
||||
right: { kind: "Primitive" },
|
||||
});
|
||||
}
|
||||
|
||||
add(left, { kind: "Primitive" });
|
||||
break;
|
||||
}
|
||||
|
||||
case "CallExpression": {
|
||||
const argTypes = value.args.map((a) => a.identifier.type);
|
||||
|
||||
// TODO(gsn): Handle method calls separately
|
||||
if (value.callee.memberPath !== null) {
|
||||
break;
|
||||
}
|
||||
|
||||
equations.push({
|
||||
left: value.callee.identifier.type,
|
||||
right: { kind: "Function" },
|
||||
});
|
||||
|
||||
add(assignType(value.callee), { kind: "Function" });
|
||||
break;
|
||||
}
|
||||
|
||||
case "ObjectExpression": {
|
||||
invariant(left !== null, "invald object expression");
|
||||
const properties = new Map(
|
||||
[...(value.properties?.entries() ?? [])].map(([prop, place]) => [
|
||||
prop,
|
||||
place.identifier.type,
|
||||
])
|
||||
);
|
||||
|
||||
equations.push({
|
||||
left,
|
||||
right: {
|
||||
kind: "Object",
|
||||
properties,
|
||||
},
|
||||
});
|
||||
add(left, { kind: "Object" });
|
||||
break;
|
||||
}
|
||||
}
|
||||
return equations;
|
||||
}
|
||||
|
||||
function assignTypeForPlace(
|
||||
value: Place,
|
||||
equations: Array<TypeEquation>
|
||||
): Type {
|
||||
if (value.memberPath === null) {
|
||||
return value.identifier.type;
|
||||
function assignType(place: Place | undefined): Type | null {
|
||||
// We type only top level identifiers. Typing objects is not very useful
|
||||
// when we have to be so conservative.
|
||||
if (place?.memberPath !== null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (value.memberPath.length > 1) {
|
||||
// TODO(gsn): Lower nested memberPaths in HIR
|
||||
return makeType();
|
||||
}
|
||||
|
||||
const propName = value.memberPath[0];
|
||||
const propType = makeType();
|
||||
equations.push({
|
||||
left: propType,
|
||||
right: {
|
||||
kind: "Prop",
|
||||
objectType: value.identifier.type,
|
||||
name: propName,
|
||||
},
|
||||
});
|
||||
|
||||
return propType;
|
||||
}
|
||||
|
||||
function assignTypeForLvalue(
|
||||
lvalue: LValue | null,
|
||||
equations: Array<TypeEquation>,
|
||||
unifier: Unifier
|
||||
): Type | null {
|
||||
if (lvalue === null) return null;
|
||||
|
||||
return (
|
||||
unifier.generalize(lvalue.place.identifier.type, lvalue.place.memberPath) ??
|
||||
assignTypeForPlace(lvalue.place, equations)
|
||||
);
|
||||
return place.identifier.type;
|
||||
}
|
||||
|
||||
type Substitution = Map<TypeId, Type>;
|
||||
@@ -242,11 +169,6 @@ class Unifier {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type.kind === "Prop") {
|
||||
this.bindToProp(v, type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.occursCheck(v, type)) {
|
||||
throw new Error("cycle detected");
|
||||
}
|
||||
@@ -254,26 +176,6 @@ class Unifier {
|
||||
this.substitutions.set(v.id, type);
|
||||
}
|
||||
|
||||
bindToProp(type: TypeVar, prop: PropType) {
|
||||
let object = prop.objectType;
|
||||
|
||||
if (object.kind === "Type" && this.substitutions.has(object.id)) {
|
||||
object = this.substitutions.get(object.id)!;
|
||||
}
|
||||
|
||||
if (object.kind === "Object") {
|
||||
if (!object.properties.has(prop.name)) {
|
||||
object.properties.set(prop.name, type);
|
||||
return;
|
||||
}
|
||||
|
||||
this.unify(object.properties.get(prop.name)!, type);
|
||||
return;
|
||||
}
|
||||
|
||||
this.substitutions.set(type.id, prop);
|
||||
}
|
||||
|
||||
occursCheck(v: TypeVar, type: Type): boolean {
|
||||
if (typeEquals(v, type)) return true;
|
||||
|
||||
@@ -281,22 +183,10 @@ class Unifier {
|
||||
return this.occursCheck(v, this.substitutions.get(type.id)!);
|
||||
}
|
||||
|
||||
if (type.kind === "Object") {
|
||||
return [...type.properties.values()].some((p) => this.occursCheck(v, p));
|
||||
}
|
||||
|
||||
if (type.kind === "Prop") {
|
||||
return this.occursCheck(v, type.objectType);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
get(type: Type): Type {
|
||||
if (type.kind === "Primitive") {
|
||||
return type;
|
||||
}
|
||||
|
||||
if (type.kind === "Type") {
|
||||
if (this.substitutions.has(type.id)) {
|
||||
return this.get(this.substitutions.get(type.id)!);
|
||||
@@ -307,28 +197,4 @@ class Unifier {
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
generalize(objectType: Type, name: Array<string> | null): Type | null {
|
||||
if (objectType.kind === "Type" && this.substitutions.has(objectType.id)) {
|
||||
objectType = this.substitutions.get(objectType.id)!;
|
||||
}
|
||||
|
||||
if (
|
||||
name !== null &&
|
||||
objectType.kind === "Object" &&
|
||||
objectType.properties.has(name[0])
|
||||
) {
|
||||
let type = objectType.properties.get(name[0])!;
|
||||
if (type.kind === "Poly") {
|
||||
return type;
|
||||
}
|
||||
|
||||
type = { kind: "Poly" };
|
||||
|
||||
objectType.properties.set(name[0], type);
|
||||
return type;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,12 +35,12 @@ function Component(props) {
|
||||
|
||||
```
|
||||
bb0:
|
||||
[1] Const mutate items$30:TProp = read props$29.items
|
||||
[2] Const mutate maxItems$31:TProp = read props$29.maxItems
|
||||
[3] Const mutate renderedItems$32_@0:TPrimitive[3:33] = Array []
|
||||
[1] Const mutate items$30 = read props$29.items
|
||||
[2] Const mutate maxItems$31 = read props$29.maxItems
|
||||
[3] Const mutate renderedItems$32_@0[3:33] = Array []
|
||||
[4] Const mutate seen$33_@0[3:33] = New mutate Set$5()
|
||||
[5] Const mutate $34:TPrimitive = 0
|
||||
[6] Const mutate max$35_@2:TPrimitive = Call mutate Math$7.max(read $34:TPrimitive, read maxItems$31:TProp)
|
||||
[6] Const mutate max$35_@2:TPrimitive = Call mutate Math$7.max(read $34:TPrimitive, read maxItems$31)
|
||||
[7] For init=bb3 test=bb1 loop=bb5 update=bb4 fallthrough=bb2
|
||||
bb3:
|
||||
predecessor blocks: bb0
|
||||
@@ -92,15 +92,15 @@ bb4:
|
||||
[32] Goto bb1
|
||||
bb2:
|
||||
predecessor blocks: bb6 bb1
|
||||
[33] Const mutate count$66:TProp = read renderedItems$32_@0.length
|
||||
[33] Const mutate count$66 = read renderedItems$32_@0.length
|
||||
[34] Const mutate $67:TPrimitive = "div"
|
||||
[35] Const mutate $68 = "\n "
|
||||
[36] Const mutate $69:TPrimitive = "h1"
|
||||
[37] Const mutate $70 = " Items"
|
||||
[38] Const mutate t7$71_@5 = JSX <read $69:TPrimitive>{freeze count$66:TProp}{read $70}</read $69:TPrimitive>
|
||||
[38] Const mutate t7$71_@5 = JSX <read $69:TPrimitive>{freeze count$66}{read $70}</read $69:TPrimitive>
|
||||
[39] Const mutate $72 = "\n "
|
||||
[40] Const mutate $73 = "\n "
|
||||
[41] Const mutate t10$74_@6 = JSX <read $67:TPrimitive>{read $68}{read t7$71_@5}{read $72}{freeze renderedItems$32_@0:TPrimitive}{read $73}</read $67:TPrimitive>
|
||||
[41] Const mutate t10$74_@6 = JSX <read $67:TPrimitive>{read $68}{read t7$71_@5}{read $72}{freeze renderedItems$32_@0}{read $73}</read $67:TPrimitive>
|
||||
[42] Return read t10$74_@6
|
||||
```
|
||||
|
||||
@@ -110,14 +110,14 @@ bb2:
|
||||
function Component(
|
||||
props,
|
||||
) {
|
||||
[1] Const mutate items$30:TProp = read props$29.items
|
||||
[2] Const mutate maxItems$31:TProp = read props$29.maxItems
|
||||
scope @0 [3:33] deps=[read maxItems$31:TProp, read items$30.length, read items$30] out=[renderedItems$32_@0] {
|
||||
[3] Const mutate renderedItems$32_@0:TPrimitive[3:33] = Array []
|
||||
[1] Const mutate items$30 = read props$29.items
|
||||
[2] Const mutate maxItems$31 = read props$29.maxItems
|
||||
scope @0 [3:33] deps=[read maxItems$31, read items$30.length, read items$30] out=[renderedItems$32_@0] {
|
||||
[3] Const mutate renderedItems$32_@0[3:33] = Array []
|
||||
[4] Const mutate seen$33_@0[3:33] = New mutate Set$5()
|
||||
[5] Const mutate $34:TPrimitive = 0
|
||||
scope @2 [6:7] deps=[read maxItems$31:TProp] out=[max$35_@2] {
|
||||
[6] Const mutate max$35_@2:TPrimitive = Call mutate Math$7.max(read $34:TPrimitive, read maxItems$31:TProp)
|
||||
scope @2 [6:7] deps=[read maxItems$31] out=[max$35_@2] {
|
||||
[6] Const mutate max$35_@2:TPrimitive = Call mutate Math$7.max(read $34:TPrimitive, read maxItems$31)
|
||||
}
|
||||
for (
|
||||
[8] Let mutate i$36_@0:TPrimitive[3:33] = 0
|
||||
@@ -153,18 +153,18 @@ function Component(
|
||||
}
|
||||
}
|
||||
}
|
||||
[33] Const mutate count$66:TProp = read renderedItems$32_@0.length
|
||||
[33] Const mutate count$66 = read renderedItems$32_@0.length
|
||||
[34] Const mutate $67:TPrimitive = "div"
|
||||
[35] Const mutate $68 = "\n "
|
||||
[36] Const mutate $69:TPrimitive = "h1"
|
||||
[37] Const mutate $70 = " Items"
|
||||
scope @5 [38:39] deps=[freeze count$66:TProp] out=[$71_@5] {
|
||||
[38] Const mutate $71_@5 = JSX <read $69:TPrimitive>{freeze count$66:TProp}{read $70}</read $69:TPrimitive>
|
||||
scope @5 [38:39] deps=[freeze count$66] out=[$71_@5] {
|
||||
[38] Const mutate $71_@5 = JSX <read $69:TPrimitive>{freeze count$66}{read $70}</read $69:TPrimitive>
|
||||
}
|
||||
[39] Const mutate $72 = "\n "
|
||||
[40] Const mutate $73 = "\n "
|
||||
scope @6 [41:42] deps=[read $71_@5, freeze renderedItems$32_@0:TPrimitive] out=[$74_@6] {
|
||||
[41] Const mutate $74_@6 = JSX <read $67:TPrimitive>{read $68}{read $71_@5}{read $72}{freeze renderedItems$32_@0:TPrimitive}{read $73}</read $67:TPrimitive>
|
||||
scope @6 [41:42] deps=[read $71_@5, freeze renderedItems$32_@0] out=[$74_@6] {
|
||||
[41] Const mutate $74_@6 = JSX <read $67:TPrimitive>{read $68}{read $71_@5}{read $72}{freeze renderedItems$32_@0}{read $73}</read $67:TPrimitive>
|
||||
}
|
||||
return read $74_@6
|
||||
}
|
||||
|
||||
+11
-11
@@ -26,15 +26,15 @@ function call(x) {}
|
||||
|
||||
```
|
||||
bb0:
|
||||
[1] Const mutate cond$8:TProp = read props$7.cond
|
||||
[2] Const mutate x$9:TProp = read props$7.x
|
||||
[1] Const mutate cond$8 = read props$7.cond
|
||||
[2] Const mutate x$9 = read props$7.x
|
||||
[3] Const mutate a$10:TPrimitive = undefined
|
||||
[4] Let mutate a$14_@0[4:9] = undefined
|
||||
[4] If (read cond$8:TProp) then:bb2 else:bb3 fallthrough=bb1
|
||||
[4] If (read cond$8) then:bb2 else:bb3 fallthrough=bb1
|
||||
bb2:
|
||||
predecessor blocks: bb0
|
||||
[5] Const mutate a$11:TProp = read x$9:TProp
|
||||
[6] Reassign mutate a$14_@0[4:9] = read a$11:TProp
|
||||
[5] Const mutate a$11 = read x$9
|
||||
[6] Reassign mutate a$14_@0[4:9] = read a$11
|
||||
[6] Goto bb1
|
||||
bb3:
|
||||
predecessor blocks: bb0
|
||||
@@ -55,14 +55,14 @@ bb1:
|
||||
function Component(
|
||||
props,
|
||||
) {
|
||||
[1] Const mutate cond$8:TProp = read props$7.cond
|
||||
[2] Const mutate x$9:TProp = read props$7.x
|
||||
[1] Const mutate cond$8 = read props$7.cond
|
||||
[2] Const mutate x$9 = read props$7.x
|
||||
[3] Const mutate a$10:TPrimitive = undefined
|
||||
scope @0 [4:9] deps=[read cond$8:TProp, read x$9:TProp] out=[a$14_@0] {
|
||||
scope @0 [4:9] deps=[read cond$8, read x$9] out=[a$14_@0] {
|
||||
[4] Let mutate a$14_@0[4:9] = undefined
|
||||
if (read cond$8:TProp) {
|
||||
[5] Const mutate a$11:TProp = read x$9:TProp
|
||||
[6] Reassign mutate a$14_@0[4:9] = read a$11:TProp
|
||||
if (read cond$8) {
|
||||
[5] Const mutate a$11 = read x$9
|
||||
[6] Reassign mutate a$14_@0[4:9] = read a$11
|
||||
} else {
|
||||
scope @1 [7:8] deps=[] out=[a$12_@1] {
|
||||
[7] Const mutate a$12_@1 = Array []
|
||||
|
||||
@@ -52,31 +52,31 @@ bb2:
|
||||
Fallthrough: bb1
|
||||
bb8:
|
||||
predecessor blocks: bb2
|
||||
[7] Const mutate x$11:TProp = read props$6.v0
|
||||
[8] Reassign mutate x$16_@0[2:18] = read x$11:TProp
|
||||
[7] Const mutate x$11 = read props$6.v0
|
||||
[8] Reassign mutate x$16_@0[2:18] = read x$11
|
||||
[8] Goto bb1
|
||||
bb6:
|
||||
predecessor blocks: bb2
|
||||
[9] Const mutate x$12:TProp = read props$6.v1
|
||||
[10] Reassign mutate x$16_@0[2:18] = read x$12:TProp
|
||||
[9] Const mutate x$12 = read props$6.v1
|
||||
[10] Reassign mutate x$16_@0[2:18] = read x$12
|
||||
[10] Goto bb1
|
||||
bb4:
|
||||
predecessor blocks: bb2
|
||||
[11] Const mutate x$13:TProp = read props$6.v2
|
||||
[12] Reassign mutate x$16_@0[2:18] = read x$13:TProp
|
||||
[11] Const mutate x$13 = read props$6.v2
|
||||
[12] Reassign mutate x$16_@0[2:18] = read x$13
|
||||
[12] Goto bb1
|
||||
bb10:
|
||||
predecessor blocks: bb0
|
||||
[13] If (read props$6.cond2) then:bb12 else:bb13 fallthrough=bb1
|
||||
bb12:
|
||||
predecessor blocks: bb10
|
||||
[14] Const mutate x$14:TProp = read props$6.b
|
||||
[15] Reassign mutate x$16_@0[2:18] = read x$14:TProp
|
||||
[14] Const mutate x$14 = read props$6.b
|
||||
[15] Reassign mutate x$16_@0[2:18] = read x$14
|
||||
[15] Goto bb1
|
||||
bb13:
|
||||
predecessor blocks: bb10
|
||||
[16] Const mutate x$15:TProp = read props$6.c
|
||||
[17] Reassign mutate x$16_@0[2:18] = read x$15:TProp
|
||||
[16] Const mutate x$15 = read props$6.c
|
||||
[17] Reassign mutate x$16_@0[2:18] = read x$15
|
||||
[17] Goto bb1
|
||||
bb1:
|
||||
predecessor blocks: bb8 bb6 bb4 bb12 bb13
|
||||
@@ -99,29 +99,29 @@ function Component(
|
||||
[5] Const mutate $10:TPrimitive = 0
|
||||
switch (read props$6.test) {
|
||||
case read $10:TPrimitive: {
|
||||
[7] Const mutate x$11:TProp = read props$6.v0
|
||||
[8] Reassign mutate x$16_@0[2:18] = read x$11:TProp
|
||||
[7] Const mutate x$11 = read props$6.v0
|
||||
[8] Reassign mutate x$16_@0[2:18] = read x$11
|
||||
break bb1
|
||||
}
|
||||
case read $9:TPrimitive: {
|
||||
[9] Const mutate x$12:TProp = read props$6.v1
|
||||
[10] Reassign mutate x$16_@0[2:18] = read x$12:TProp
|
||||
[9] Const mutate x$12 = read props$6.v1
|
||||
[10] Reassign mutate x$16_@0[2:18] = read x$12
|
||||
break bb1
|
||||
}
|
||||
case read $8:TPrimitive: {
|
||||
}
|
||||
default: {
|
||||
[11] Const mutate x$13:TProp = read props$6.v2
|
||||
[12] Reassign mutate x$16_@0[2:18] = read x$13:TProp
|
||||
[11] Const mutate x$13 = read props$6.v2
|
||||
[12] Reassign mutate x$16_@0[2:18] = read x$13
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (read props$6.cond2) {
|
||||
[14] Const mutate x$14:TProp = read props$6.b
|
||||
[15] Reassign mutate x$16_@0[2:18] = read x$14:TProp
|
||||
[14] Const mutate x$14 = read props$6.b
|
||||
[15] Reassign mutate x$16_@0[2:18] = read x$14
|
||||
} else {
|
||||
[16] Const mutate x$15:TProp = read props$6.c
|
||||
[17] Reassign mutate x$16_@0[2:18] = read x$15:TProp
|
||||
[16] Const mutate x$15 = read props$6.c
|
||||
[17] Reassign mutate x$16_@0[2:18] = read x$15
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ function component() {
|
||||
bb0:
|
||||
[1] Const mutate $4:TPrimitive = 1
|
||||
[2] Const mutate x$5_@0:TObject = Object { t: read $4:TPrimitive }
|
||||
[3] Const mutate p$6:TPrimitive = read x$5_@0.t
|
||||
[3] Const mutate p$6 = read x$5_@0.t
|
||||
[4] Return
|
||||
```
|
||||
|
||||
@@ -28,7 +28,7 @@ function component(
|
||||
scope @0 [2:3] deps=[] out=[x$5_@0] {
|
||||
[2] Const mutate x$5_@0:TObject = Object { t: read $4:TPrimitive }
|
||||
}
|
||||
[3] Const mutate p$6:TPrimitive = read x$5_@0.t
|
||||
[3] Const mutate p$6 = read x$5_@0.t
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -19,17 +19,17 @@ function component() {
|
||||
|
||||
```
|
||||
bb0:
|
||||
[1] Const mutate t0$10_@0:TPrimitive = Call mutate makeSomePrimitive$1:TFunction()
|
||||
[2] Const mutate t1$11_@1:TPrimitive = Call mutate makeSomePrimitive$1:TFunction()
|
||||
[3] Const mutate x$12_@2:TObject = Object { u: read t0$10_@0:TPrimitive, v: read t1$11_@1:TPrimitive }
|
||||
[1] Const mutate t0$10_@0 = Call mutate makeSomePrimitive$1:TFunction()
|
||||
[2] Const mutate t1$11_@1 = Call mutate makeSomePrimitive$1:TFunction()
|
||||
[3] Const mutate x$12_@2:TObject = Object { u: read t0$10_@0, v: read t1$11_@1 }
|
||||
[4] Const mutate u$13:TPrimitive = read x$12_@2.u
|
||||
[5] Const mutate v$14:TPrimitive = read x$12_@2.v
|
||||
[6] Const mutate $15:TPrimitive = Binary read u$13:TPrimitive > read v$14:TPrimitive
|
||||
[7] If (read $15:TPrimitive) then:bb1 else:bb1 fallthrough=bb1
|
||||
bb1:
|
||||
predecessor blocks: bb0
|
||||
[8] Const mutate y$16:TPrimitive = read x$12_@2.u
|
||||
[9] Const mutate z$17:TPrimitive = read x$12_@2.v
|
||||
[8] Const mutate y$16 = read x$12_@2.u
|
||||
[9] Const mutate z$17 = read x$12_@2.v
|
||||
[10] Return
|
||||
```
|
||||
|
||||
@@ -39,21 +39,21 @@ bb1:
|
||||
function component(
|
||||
) {
|
||||
scope @0 [1:2] deps=[] out=[$10_@0] {
|
||||
[1] Const mutate $10_@0:TPrimitive = Call mutate makeSomePrimitive$1:TFunction()
|
||||
[1] Const mutate $10_@0 = Call mutate makeSomePrimitive$1:TFunction()
|
||||
}
|
||||
scope @1 [2:3] deps=[] out=[$11_@1] {
|
||||
[2] Const mutate $11_@1:TPrimitive = Call mutate makeSomePrimitive$1:TFunction()
|
||||
[2] Const mutate $11_@1 = Call mutate makeSomePrimitive$1:TFunction()
|
||||
}
|
||||
scope @2 [3:4] deps=[read $10_@0:TPrimitive, read $11_@1:TPrimitive] out=[x$12_@2] {
|
||||
[3] Const mutate x$12_@2:TObject = Object { u: read $10_@0:TPrimitive, v: read $11_@1:TPrimitive }
|
||||
scope @2 [3:4] deps=[read $10_@0, read $11_@1] out=[x$12_@2] {
|
||||
[3] Const mutate x$12_@2:TObject = Object { u: read $10_@0, v: read $11_@1 }
|
||||
}
|
||||
[4] Const mutate u$13:TPrimitive = read x$12_@2.u
|
||||
[5] Const mutate v$14:TPrimitive = read x$12_@2.v
|
||||
[6] Const mutate $15:TPrimitive = Binary read u$13:TPrimitive > read v$14:TPrimitive
|
||||
if (read $15:TPrimitive) {
|
||||
}
|
||||
[8] Const mutate y$16:TPrimitive = read x$12_@2.u
|
||||
[9] Const mutate z$17:TPrimitive = read x$12_@2.v
|
||||
[8] Const mutate y$16 = read x$12_@2.u
|
||||
[9] Const mutate z$17 = read x$12_@2.v
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ bb0:
|
||||
[1] Const mutate x$4_@0:TObject[1:4] = Object { }
|
||||
[2] Const mutate q$5_@1:TObject = Object { }
|
||||
[3] Reassign store x$4_@0.t[1:4] = read q$5_@1:TObject
|
||||
[4] Const mutate z$6:TObject = read x$4_@0.t
|
||||
[4] Const mutate z$6 = read x$4_@0.t
|
||||
[5] Return
|
||||
```
|
||||
|
||||
@@ -34,7 +34,7 @@ function component(
|
||||
}
|
||||
[3] Reassign store x$4_@0.t[1:4] = read q$5_@1:TObject
|
||||
}
|
||||
[4] Const mutate z$6:TObject = read x$4_@0.t
|
||||
[4] Const mutate z$6 = read x$4_@0.t
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@ bb0:
|
||||
[3] Const mutate o$8_@1:TObject = Object { }
|
||||
[4] Const mutate x$9_@2:TObject[4:8] = Object { }
|
||||
[5] Reassign store x$9_@2.t[4:8] = read p$7_@0:TPrimitive
|
||||
[6] Const mutate z$10_@2:TPrimitive[4:8] = read x$9_@2.t
|
||||
[6] Const mutate z$10_@2[4:8] = read x$9_@2.t
|
||||
[7] Reassign store x$9_@2.t[4:8] = read o$8_@1:TObject
|
||||
[8] Const mutate y$11:TPoly = read x$9_@2.t
|
||||
[8] Const mutate y$11 = read x$9_@2.t
|
||||
[9] Return
|
||||
```
|
||||
|
||||
@@ -48,10 +48,10 @@ function component(
|
||||
scope @2 [4:8] deps=[read p$7_@0:TPrimitive, read o$8_@1:TObject] out=[x$9_@2] {
|
||||
[4] Const mutate x$9_@2:TObject[4:8] = Object { }
|
||||
[5] Reassign store x$9_@2.t[4:8] = read p$7_@0:TPrimitive
|
||||
[6] Const mutate z$10_@2:TPrimitive[4:8] = read x$9_@2.t
|
||||
[6] Const mutate z$10_@2[4:8] = read x$9_@2.t
|
||||
[7] Reassign store x$9_@2.t[4:8] = read o$8_@1:TObject
|
||||
}
|
||||
[8] Const mutate y$11:TPoly = read x$9_@2.t
|
||||
[8] Const mutate y$11 = read x$9_@2.t
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user