Tighten types of derived values (#2210)

Summary:
Release notes: None

If concrete, it can only be an object.
Pull Request resolved: https://github.com/facebook/prepack/pull/2210

Differential Revision: D8752067

Pulled By: NTillmann

fbshipit-source-id: 207c3a6e055924290029e770528dc24df1023ffe
This commit is contained in:
Nikolai Tillmann 2018-07-06 14:25:00 -07:00 committed by Facebook Github Bot
parent 36b322b250
commit e680248655
5 changed files with 25 additions and 29 deletions

View File

@ -13,7 +13,6 @@ import {
AbstractValue,
ArrayValue,
BoundFunctionValue,
ConcreteValue,
FunctionValue,
ObjectValue,
ProxyValue,
@ -164,7 +163,7 @@ export class Emitter {
endEmitting(
dependency: string | Generator | Value,
oldBody: SerializedBody,
valuesToProcess: void | Set<AbstractValue | ConcreteValue>,
valuesToProcess: void | Set<AbstractValue | ObjectValue>,
isChild: boolean = false
) {
invariant(!this._finalized);
@ -207,7 +206,7 @@ export class Emitter {
return lastBody;
}
processValues(valuesToProcess: Set<AbstractValue | ConcreteValue>) {
processValues(valuesToProcess: Set<AbstractValue | ObjectValue>) {
for (let value of valuesToProcess) this._processValue(value);
}
finalize() {
@ -468,10 +467,10 @@ export class Emitter {
emitNowOrAfterWaitingForDependencies(dependencies: Array<Value>, func: () => void, targetBody: SerializedBody) {
this.emitAfterWaiting(this.getReasonToWaitForDependencies(dependencies), dependencies, func, targetBody);
}
declare(value: AbstractValue | ConcreteValue) {
declare(value: AbstractValue | ObjectValue) {
invariant(!this._finalized);
invariant(!this._activeValues.has(value));
invariant(value instanceof ConcreteValue || value.hasIdentifier());
invariant(value instanceof ObjectValue || value.hasIdentifier());
invariant(this._isEmittingActiveGenerator());
invariant(!this.cannotDeclare());
invariant(!this._body.done);
@ -488,10 +487,10 @@ export class Emitter {
// Bodies of the following types will never contain any (temporal) abstract value declarations.
return this._body.type === "DelayInitializations" || this._body.type === "LazyObjectInitializer";
}
hasBeenDeclared(value: AbstractValue | ConcreteValue): boolean {
hasBeenDeclared(value: AbstractValue | ObjectValue): boolean {
return this.getDeclarationBody(value) !== undefined;
}
getDeclarationBody(value: AbstractValue | ConcreteValue): void | SerializedBody {
getDeclarationBody(value: AbstractValue | ObjectValue): void | SerializedBody {
for (let b = this._body; b !== undefined; b = b.parentBody) {
if (b.declaredValues !== undefined && b.declaredValues.has(value)) {
return b;

View File

@ -16,7 +16,6 @@ import {
AbstractValue,
BooleanValue,
BoundFunctionValue,
ConcreteValue,
ECMAScriptSourceFunctionValue,
EmptyValue,
FunctionValue,
@ -2083,7 +2082,7 @@ export class ResidualHeapSerializer {
_withGeneratorScope(
type: "Generator" | "AdditionalFunction",
generator: Generator,
valuesToProcess: void | Set<AbstractValue | ConcreteValue>,
valuesToProcess: void | Set<AbstractValue | ObjectValue>,
callback: SerializedBody => void,
isChildOverride?: boolean
): Array<BabelNodeStatement> {
@ -2110,7 +2109,7 @@ export class ResidualHeapSerializer {
serializeBinding: this.serializeBinding.bind(this),
serializeGenerator: (
generator: Generator,
valuesToProcess: Set<AbstractValue | ConcreteValue>
valuesToProcess: Set<AbstractValue | ObjectValue>
): Array<BabelNodeStatement> =>
this._withGeneratorScope("Generator", generator, valuesToProcess, () => generator.serialize(context)),
initGenerator: (generator: Generator) => {
@ -2127,7 +2126,7 @@ export class ResidualHeapSerializer {
emit: (statement: BabelNodeStatement) => {
this.emitter.emit(statement);
},
processValues: (valuesToProcess: Set<AbstractValue | ConcreteValue>) => {
processValues: (valuesToProcess: Set<AbstractValue | ObjectValue>) => {
this.emitter.processValues(valuesToProcess);
},
getPropertyAssignmentStatement: this._getPropertyAssignmentStatement.bind(this),
@ -2143,7 +2142,7 @@ export class ResidualHeapSerializer {
}
return canOmit;
},
declare: (value: AbstractValue | ConcreteValue) => {
declare: (value: AbstractValue | ObjectValue) => {
this.emitter.declare(value);
},
emitPropertyModification: (propertyBinding: PropertyBinding) => {

View File

@ -34,7 +34,7 @@ export type SerializedBody = {
type: SerializedBodyType,
entries: Array<BabelNodeStatement>,
done: boolean,
declaredValues?: Map<AbstractValue | ConcreteValue, SerializedBody>,
declaredValues?: Map<AbstractValue | ObjectValue, SerializedBody>,
parentBody?: SerializedBody,
nestingLevel?: number,
processing?: boolean,

View File

@ -66,14 +66,14 @@ export type SerializationContext = {|
mightHaveBeenDeleted: boolean,
deleteIfMightHaveBeenDeleted: boolean
) => BabelNodeStatement,
serializeGenerator: (Generator, Set<AbstractValue | ConcreteValue>) => Array<BabelNodeStatement>,
serializeGenerator: (Generator, Set<AbstractValue | ObjectValue>) => Array<BabelNodeStatement>,
initGenerator: Generator => void,
finalizeGenerator: Generator => void,
emitDefinePropertyBody: (ObjectValue, string | SymbolValue, Descriptor) => BabelNodeStatement,
emit: BabelNodeStatement => void,
processValues: (Set<AbstractValue | ConcreteValue>) => void,
processValues: (Set<AbstractValue | ObjectValue>) => void,
canOmit: Value => boolean,
declare: (AbstractValue | ConcreteValue) => void,
declare: (AbstractValue | ObjectValue) => void,
emitPropertyModification: PropertyBinding => void,
options: SerializerOptions,
|};
@ -82,7 +82,7 @@ export type VisitEntryCallbacks = {|
visitEquivalentValue: Value => Value,
visitGenerator: (Generator, Generator) => void,
canOmit: Value => boolean,
recordDeclaration: (AbstractValue | ConcreteValue) => void,
recordDeclaration: (AbstractValue | ObjectValue) => void,
recordDelayedEntry: (Generator, GeneratorEntry) => void,
visitModifiedObjectProperty: PropertyBinding => void,
visitModifiedBinding: Binding => [ResidualFunctionBinding, Value],
@ -92,13 +92,13 @@ export type VisitEntryCallbacks = {|
export type DerivedExpressionBuildNodeFunction = (
Array<BabelNodeExpression>,
SerializationContext,
Set<AbstractValue | ConcreteValue>
Set<AbstractValue | ObjectValue>
) => BabelNodeExpression;
export type GeneratorBuildNodeFunction = (
Array<BabelNodeExpression>,
SerializationContext,
Set<AbstractValue | ConcreteValue>
Set<AbstractValue | ObjectValue>
) => BabelNodeStatement;
export class GeneratorEntry {
@ -116,7 +116,7 @@ export class GeneratorEntry {
}
export type TemporalBuildNodeEntryArgs = {
declared?: AbstractValue | ConcreteValue,
declared?: AbstractValue | ObjectValue,
args: Array<Value>,
// If we're just trying to add roots for the serializer to notice, we don't need a buildNode.
buildNode?: GeneratorBuildNodeFunction,
@ -137,7 +137,7 @@ export class TemporalBuildNodeEntry extends GeneratorEntry {
}
}
declared: void | AbstractValue | ConcreteValue;
declared: void | AbstractValue | ObjectValue;
args: Array<Value>;
// If we're just trying to add roots for the serializer to notice, we don't need a buildNode.
buildNode: void | GeneratorBuildNodeFunction;
@ -411,7 +411,7 @@ class BindingAssignmentEntry extends GeneratorEntry {
function serializeBody(
generator: Generator,
context: SerializationContext,
valuesToProcess: Set<AbstractValue | ConcreteValue>
valuesToProcess: Set<AbstractValue | ObjectValue>
): BabelNodeBlockStatement {
let statements = context.serializeGenerator(generator, valuesToProcess);
if (statements.length === 1 && statements[0].type === "BlockStatement") return (statements[0]: any);
@ -918,8 +918,8 @@ export class Generator {
});
}
deriveConcrete(
buildValue: (intrinsicName: string) => ConcreteValue,
deriveConcreteObject(
buildValue: (intrinsicName: string) => ObjectValue,
args: Array<Value>,
buildNode_: DerivedExpressionBuildNodeFunction | BabelNodeExpression,
optionalArgs?: {| isPure?: boolean |}
@ -927,10 +927,8 @@ export class Generator {
invariant(buildNode_ instanceof Function || args.length === 0);
let id = t.identifier(this.preludeGenerator.nameGenerator.generate("derived"));
let value = buildValue(id.name);
if (value instanceof ObjectValue) {
value.intrinsicNameGenerated = true;
value._isScopedTemplate = true; // because this object doesn't exist ahead of time, and the visitor would otherwise declare it in the common scope
}
value.intrinsicNameGenerated = true;
value._isScopedTemplate = true; // because this object doesn't exist ahead of time, and the visitor would otherwise declare it in the common scope
this._addDerivedEntry(id.name, {
isPure: optionalArgs ? optionalArgs.isPure : undefined,
declared: value,

View File

@ -102,7 +102,7 @@ export default class ArrayValue extends ObjectValue {
): ArrayValue {
invariant(realm.generator !== undefined);
let value = realm.generator.deriveConcrete(
let value = realm.generator.deriveConcreteObject(
intrinsicName => new ArrayValue(realm, intrinsicName),
args,
buildFunction,