Infer more primitive types

Handles three more cases: 

* Template literals 

* deletion (property/computed) 

* type casts 

Only the latter has an observable impact, though i added tests for deletion just 
in case and found a bug. For type casts, they're reasonably common internally 
for fixmes, so this PR will help to ensure we don't drop type information just 
because of a cast.
This commit is contained in:
Joe Savona
2023-06-04 20:27:24 -04:00
parent 084edadaa1
commit e410815aeb
8 changed files with 108 additions and 5 deletions
@@ -837,7 +837,8 @@ function inferBlock(
state.reference(instrValue.object, Effect.Mutate);
state.reference(instrValue.property, Effect.Read);
state.initialize(instrValue, ValueKind.Immutable);
state.reference(instr.lvalue, Effect.Mutate);
state.define(instr.lvalue, instrValue);
instr.lvalue.effect = Effect.Mutate;
continue;
}
case "ComputedLoad": {
@@ -108,6 +108,7 @@ function* generateInstructionTypes(
const left = lvalue.identifier.type;
switch (value.kind) {
case "TemplateLiteral":
case "JSXText":
case "Primitive": {
yield equation(left, { kind: "Primitive" });
@@ -232,21 +233,28 @@ function* generateInstructionTypes(
break;
}
case "TypeCastExpression": {
yield equation(left, value.value.identifier.type);
break;
}
case "PropertyDelete":
case "ComputedDelete": {
yield equation(left, { kind: "Primitive" });
break;
}
case "DeclareLocal":
case "DeclareContext":
case "NewExpression":
case "TypeCastExpression":
case "JsxExpression":
case "JsxFragment":
case "RegExpLiteral":
case "PropertyStore":
case "PropertyDelete":
case "ComputedStore":
case "ComputedLoad":
case "ComputedDelete":
case "FunctionExpression":
case "TaggedTemplateExpression":
case "TemplateLiteral":
case "Await":
case "NextIterableOf":
case "ExpressionStatement":
@@ -0,0 +1,25 @@
## Input
```javascript
// @debug
function Component(props) {
const x = makeObject();
const y = delete x[props.value];
return y;
}
```
## Code
```javascript
// @debug
function Component(props) {
const x = makeObject();
const y = delete x[props.value];
return y;
}
```
@@ -0,0 +1,6 @@
// @debug
function Component(props) {
const x = makeObject();
const y = delete x[props.value];
return y;
}
@@ -0,0 +1,23 @@
## Input
```javascript
function Component(props) {
const x = makeObject();
const y = delete x.value;
return y;
}
```
## Code
```javascript
function Component(props) {
const x = makeObject();
const y = delete x.value;
return y;
}
```
@@ -0,0 +1,5 @@
function Component(props) {
const x = makeObject();
const y = delete x.value;
return y;
}
@@ -0,0 +1,26 @@
## Input
```javascript
// @flow
function Component(props) {
// We can infer that `x` is a primitive bc it is aliased to `y`,
// which is used in a binary expression
const x = foo();
const y = (x: any);
y + 1;
return x;
}
```
## Code
```javascript
// @flow
function Component(props) {
const x = foo();
return x;
}
```
@@ -0,0 +1,9 @@
// @flow
function Component(props) {
// We can infer that `x` is a primitive bc it is aliased to `y`,
// which is used in a binary expression
const x = foo();
const y = (x: any);
y + 1;
return x;
}