Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1701)

Unified Diff: pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart

Issue 2616103002: Flatten inferrer implementation (Closed)
Patch Set: Updated cf. comment. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/inferrer/node_tracer.dart ('k') | pkg/compiler/lib/src/inferrer/type_graph_dump.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
index 2f7abd5c93f2cbe82540243f9fb94d946cbeab62..e6bf0871d90f130cc220cc78761d5e3839adf2d9 100644
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
@@ -8,353 +8,871 @@ import '../closure.dart' show ClosureClassMap;
import '../common.dart';
import '../common/names.dart' show Identifiers, Selectors;
import '../compiler.dart' show Compiler;
+import '../constants/constant_system.dart';
+import '../constants/expressions.dart';
import '../constants/values.dart' show ConstantValue, IntConstantValue;
-import '../core_types.dart' show CommonElements;
import '../elements/resolution_types.dart' show ResolutionDartType;
import '../elements/elements.dart';
import '../js_backend/backend_helpers.dart';
import '../js_backend/js_backend.dart' as js;
import '../native/native.dart' as native;
import '../resolution/operators.dart' as op;
+import '../resolution/semantic_visitor.dart';
+import '../resolution/tree_elements.dart' show TreeElements;
import '../tree/tree.dart' as ast;
+import '../types/constants.dart' show computeTypeMask;
import '../types/types.dart' show TypeMask, GlobalTypeInferenceElementData;
import '../universe/call_structure.dart' show CallStructure;
import '../universe/selector.dart' show Selector;
import '../universe/side_effects.dart' show SideEffects;
import '../util/util.dart' show Link, Setlet;
-import '../world.dart' show ClosedWorld, ClosedWorldRefiner;
+import '../world.dart' show ClosedWorld;
+import 'inferrer_engine.dart';
import 'inferrer_visitor.dart';
+import 'type_graph_nodes.dart';
+import 'type_system.dart';
-/**
- * Common super class used by [SimpleTypeInferrerVisitor] to propagate
- * type information about visited nodes, as well as to request type
- * information of elements.
- */
-abstract class InferrerEngine<T, V extends TypeSystem>
- implements MinimalInferrerEngine<T> {
+/// [SimpleTypeInferrerVisitor] can be thought of as a type-inference graph
+/// builder for a single element.
+///
+/// Calling [run] will start the work of visiting the body of the code to
+/// construct a set of infernece-nodes that abstractly represent what the code
+/// is doing.
+///
+/// This visitor is parameterized by an [InferenceEngine], which internally
+/// decides how to represent inference nodes.
+class SimpleTypeInferrerVisitor extends ast.Visitor<TypeInformation>
+ with
+ SemanticSendResolvedMixin<TypeInformation, dynamic>,
+ CompoundBulkMixin<TypeInformation, dynamic>,
+ SetIfNullBulkMixin<TypeInformation, dynamic>,
+ PrefixBulkMixin<TypeInformation, dynamic>,
+ PostfixBulkMixin<TypeInformation, dynamic>,
+ ErrorBulkMixin<TypeInformation, dynamic>,
+ NewBulkMixin<TypeInformation, dynamic>,
+ SetBulkMixin<TypeInformation, dynamic>
+ implements SemanticSendVisitor<TypeInformation, dynamic> {
final Compiler compiler;
- final ClosedWorld closedWorld;
- final ClosedWorldRefiner closedWorldRefiner;
- final V types;
- final Map<ast.Node, T> concreteTypes = new Map<ast.Node, T>();
- final Set<Element> generativeConstructorsExposingThis = new Set<Element>();
-
- /// Data computed internally within elements, like the type-mask of a send a
- /// list allocation, or a for-in loop.
- final Map<Element, GlobalTypeInferenceElementData> inTreeData =
- new Map<Element, GlobalTypeInferenceElementData>();
-
- InferrerEngine(
- this.compiler, this.closedWorld, this.closedWorldRefiner, this.types);
-
- CommonElements get commonElements => closedWorld.commonElements;
-
- /**
- * Records the default type of parameter [parameter].
- */
- void setDefaultTypeOfParameter(ParameterElement parameter, T type);
-
- /**
- * This helper breaks abstractions but is currently required to work around
- * the wrong modelling of default values of optional parameters of
- * synthetic constructors.
- *
- * TODO(johnniwinther): Remove once default values of synthetic parameters
- * are fixed.
- */
- bool hasAlreadyComputedTypeOfParameterDefault(ParameterElement paramemter);
-
- /**
- * Returns the type of [element].
- */
- T typeOfElement(Element element);
-
- /**
- * Returns the return type of [element].
- */
- T returnTypeOfElement(Element element);
-
- /**
- * Records that [node] sets final field [element] to be of type [type].
- *
- * [nodeHolder] is the element holder of [node].
- */
- void recordTypeOfFinalField(
- ast.Node node, Element nodeHolder, Element field, T type);
-
- /**
- * Records that [node] sets non-final field [element] to be of type
- * [type].
- */
- void recordTypeOfNonFinalField(Spannable node, Element field, T type);
-
- /**
- * Records that [element] is of type [type].
- */
- void recordType(Element element, T type);
-
- /**
- * Records that the return type [element] is of type [type].
- */
- void recordReturnType(Element element, T type);
-
- /**
- * Registers that [caller] calls [callee] at location [node], with
- * [selector], and [arguments]. Note that [selector] is null for
- * forwarding constructors.
- *
- * [sideEffects] will be updated to incorporate [callee]'s side
- * effects.
- *
- * [inLoop] tells whether the call happens in a loop.
- */
- T registerCalledElement(
- Spannable node,
- Selector selector,
- TypeMask mask,
- Element caller,
- Element callee,
- ArgumentsTypes<T> arguments,
- SideEffects sideEffects,
- bool inLoop);
-
- /**
- * Registers that [caller] calls [selector] with [receiverType] as
- * receiver, and [arguments].
- *
- * [sideEffects] will be updated to incorporate the potential
- * callees' side effects.
- *
- * [inLoop] tells whether the call happens in a loop.
- */
- T registerCalledSelector(
- ast.Node node,
- Selector selector,
- TypeMask mask,
- T receiverType,
- Element caller,
- ArgumentsTypes<T> arguments,
- SideEffects sideEffects,
- bool inLoop);
-
- /**
- * Registers that [caller] calls [closure] with [arguments].
- *
- * [sideEffects] will be updated to incorporate the potential
- * callees' side effects.
- *
- * [inLoop] tells whether the call happens in a loop.
- */
- T registerCalledClosure(
- ast.Node node,
- Selector selector,
- TypeMask mask,
- T closure,
- Element caller,
- ArgumentsTypes<T> arguments,
- SideEffects sideEffects,
- bool inLoop);
-
- /**
- * Registers a call to await with an expression of type [argumentType] as
- * argument.
- */
- T registerAwait(ast.Node node, T argumentType);
-
- /**
- * Notifies to the inferrer that [analyzedElement] can have return
- * type [newType]. [currentType] is the type the [InferrerVisitor]
- * currently found.
- *
- * Returns the new type for [analyzedElement].
- */
- T addReturnTypeFor(Element analyzedElement, T currentType, T newType);
-
- /**
- * Applies [f] to all elements in the universe that match
- * [selector] and [mask]. If [f] returns false, aborts the iteration.
- */
- void forEachElementMatching(
- Selector selector, TypeMask mask, bool f(Element element)) {
- Iterable<Element> elements =
- closedWorld.allFunctions.filter(selector, mask);
- for (Element e in elements) {
- if (!f(e.implementation)) return;
+ final AstElement analyzedElement;
+ final ResolvedAst resolvedAst;
+ final TypeSystem types;
+ final Map<JumpTarget, List<LocalsHandler>> breaksFor =
+ new Map<JumpTarget, List<LocalsHandler>>();
+ final Map<JumpTarget, List<LocalsHandler>> continuesFor =
+ new Map<JumpTarget, List<LocalsHandler>>();
+ LocalsHandler locals;
+ final List<TypeInformation> cascadeReceiverStack =
+ new List<TypeInformation>();
+
+ TypeInformation returnType;
+ bool visitingInitializers = false;
+ bool isConstructorRedirect = false;
+ bool seenSuperConstructorCall = false;
+ SideEffects sideEffects = new SideEffects.empty();
+ final Element outermostElement;
+ final InferrerEngine inferrer;
+ final Setlet<Entity> capturedVariables = new Setlet<Entity>();
+ final GlobalTypeInferenceElementData inTreeData;
+
+ SimpleTypeInferrerVisitor.internal(
+ AstElement analyzedElement,
+ this.resolvedAst,
+ this.outermostElement,
+ InferrerEngine inferrer,
+ this.compiler,
+ this.locals)
+ : this.analyzedElement = analyzedElement,
+ this.inferrer = inferrer,
+ this.types = inferrer.types,
+ this.inTreeData = inferrer.dataOf(analyzedElement) {
+ assert(outermostElement != null);
+ if (locals != null) return;
+ ast.Node node;
+ if (resolvedAst.kind == ResolvedAstKind.PARSED) {
+ node = resolvedAst.node;
+ }
+ FieldInitializationScope fieldScope =
+ analyzedElement.isGenerativeConstructor
+ ? new FieldInitializationScope(types)
+ : null;
+ locals =
+ new LocalsHandler(inferrer, types, compiler.options, node, fieldScope);
+ }
+
+ SimpleTypeInferrerVisitor(Element element, ResolvedAst resolvedAst,
+ Compiler compiler, InferrerEngine inferrer, [LocalsHandler handler])
+ : this.internal(
+ element,
+ resolvedAst,
+ element.outermostEnclosingMemberOrTopLevel.implementation,
+ inferrer,
+ compiler,
+ handler);
+
+ TreeElements get elements => resolvedAst.elements;
+
+ bool accumulateIsChecks = false;
+ bool conditionIsSimple = false;
+ List<ast.Send> isChecks;
+ int loopLevel = 0;
+
+ bool get inLoop => loopLevel > 0;
+ bool get isThisExposed {
+ return analyzedElement.isGenerativeConstructor
+ ? locals.fieldScope.isThisExposed
+ : true;
+ }
+
+ void set isThisExposed(value) {
+ if (analyzedElement.isGenerativeConstructor) {
+ locals.fieldScope.isThisExposed = value;
+ }
+ }
+
+ DiagnosticReporter get reporter => compiler.reporter;
+
+ ClosedWorld get closedWorld => inferrer.closedWorld;
+
+ @override
+ SemanticSendVisitor get sendVisitor => this;
+
+ @override
+ TypeInformation apply(ast.Node node, _) => visit(node);
+
+ TypeInformation visitAssert(ast.Assert node) {
+ // Avoid pollution from assert statement unless enabled.
+ if (!compiler.options.enableUserAssertions) {
+ return null;
+ }
+ List<ast.Send> tests = <ast.Send>[];
+ bool simpleCondition = handleCondition(node.condition, tests);
+ LocalsHandler saved = locals;
+ locals = new LocalsHandler.from(locals, node);
+ updateIsChecks(tests, usePositive: true);
+
+ LocalsHandler thenLocals = locals;
+ locals = new LocalsHandler.from(saved, node);
+ if (simpleCondition) updateIsChecks(tests, usePositive: false);
+ visit(node.message);
+ locals.seenReturnOrThrow = true;
+ saved.mergeDiamondFlow(thenLocals, locals);
+ locals = saved;
+ return null;
+ }
+
+ @override
+ TypeInformation bulkHandleSet(ast.SendSet node, _) {
+ return handleSendSet(node);
+ }
+
+ @override
+ TypeInformation bulkHandleCompound(ast.SendSet node, _) {
+ return handleSendSet(node);
+ }
+
+ @override
+ TypeInformation bulkHandleSetIfNull(ast.SendSet node, _) {
+ return handleSendSet(node);
+ }
+
+ @override
+ TypeInformation bulkHandlePrefix(ast.SendSet node, _) {
+ return handleSendSet(node);
+ }
+
+ @override
+ TypeInformation bulkHandlePostfix(ast.SendSet node, _) {
+ return handleSendSet(node);
+ }
+
+ @override
+ TypeInformation bulkHandleError(ast.Node node, ErroneousElement error, _) {
+ return types.dynamicType;
+ }
+
+ TypeInformation visitNode(ast.Node node) {
+ return node.visitChildren(this);
+ }
+
+ TypeInformation visit(ast.Node node) {
+ return node == null ? null : node.accept(this);
+ }
+
+ TypeInformation visitLiteralString(ast.LiteralString node) {
+ return types.stringLiteralType(node.dartString);
+ }
+
+ TypeInformation visitStringJuxtaposition(ast.StringJuxtaposition node) {
+ node.visitChildren(this);
+ return types.stringType;
+ }
+
+ TypeInformation visitLiteralBool(ast.LiteralBool node) {
+ return types.boolLiteralType(node);
+ }
+
+ TypeInformation visitLiteralDouble(ast.LiteralDouble node) {
+ ConstantSystem constantSystem = compiler.backend.constantSystem;
+ // The JavaScript backend may turn this literal into an integer at
+ // runtime.
+ return types.getConcreteTypeFor(
+ computeTypeMask(closedWorld, constantSystem.createDouble(node.value)));
+ }
+
+ TypeInformation visitLiteralInt(ast.LiteralInt node) {
+ ConstantSystem constantSystem = compiler.backend.constantSystem;
+ // The JavaScript backend may turn this literal into a double at
+ // runtime.
+ return types.getConcreteTypeFor(
+ computeTypeMask(closedWorld, constantSystem.createInt(node.value)));
+ }
+
+ TypeInformation visitLiteralNull(ast.LiteralNull node) {
+ return types.nullType;
+ }
+
+ TypeInformation visitLiteralSymbol(ast.LiteralSymbol node) {
+ // TODO(kasperl): We should be able to tell that the type of a literal
+ // symbol is always a non-null exact symbol implementation -- not just
+ // any non-null subtype of the symbol interface.
+ return types.nonNullSubtype(closedWorld.commonElements.symbolClass);
+ }
+
+ @override
+ void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) {
+ // Deferred access does not affect inference.
+ }
+
+ TypeInformation handleTypeLiteralGet() {
+ return types.typeType;
+ }
+
+ @override
+ TypeInformation bulkHandleNode(ast.Node node, String message, _) {
+ return internalError(node, message.replaceAll('#', '$node'));
+ }
+
+ @override
+ TypeInformation visitConstantGet(
+ ast.Send node, ConstantExpression constant, _) {
+ return bulkHandleNode(node, "Constant read `#` unhandled.", _);
+ }
+
+ @override
+ TypeInformation visitConstantInvoke(
+ ast.Send node,
+ ConstantExpression constant,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
+ return bulkHandleNode(node, "Constant invoke `#` unhandled.", _);
+ }
+
+ TypeInformation visitClassTypeLiteralGet(
+ ast.Send node, ConstantExpression constant, _) {
+ return handleTypeLiteralGet();
+ }
+
+ TypeInformation visitClassTypeLiteralInvoke(
+ ast.Send node,
+ ConstantExpression constant,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
+ return handleTypeLiteralInvoke(arguments);
+ }
+
+ TypeInformation visitTypedefTypeLiteralGet(
+ ast.Send node, ConstantExpression constant, _) {
+ return handleTypeLiteralGet();
+ }
+
+ TypeInformation visitTypedefTypeLiteralInvoke(
+ ast.Send node,
+ ConstantExpression constant,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
+ return handleTypeLiteralInvoke(arguments);
+ }
+
+ TypeInformation visitTypeVariableTypeLiteralGet(
+ ast.Send node, TypeVariableElement element, _) {
+ return handleTypeLiteralGet();
+ }
+
+ TypeInformation visitTypeVariableTypeLiteralInvoke(
+ ast.Send node,
+ TypeVariableElement element,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
+ return handleTypeLiteralInvoke(arguments);
+ }
+
+ TypeInformation visitDynamicTypeLiteralGet(
+ ast.Send node, ConstantExpression constant, _) {
+ return handleTypeLiteralGet();
+ }
+
+ TypeInformation visitDynamicTypeLiteralInvoke(
+ ast.Send node,
+ ConstantExpression constant,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
+ return handleTypeLiteralInvoke(arguments);
+ }
+
+ TypeInformation _thisType;
+ TypeInformation get thisType {
+ if (_thisType != null) return _thisType;
+ ClassElement cls = outermostElement.enclosingClass;
+ if (closedWorld.isUsedAsMixin(cls)) {
+ return _thisType = types.nonNullSubtype(cls);
+ } else {
+ return _thisType = types.nonNullSubclass(cls);
+ }
+ }
+
+ @override
+ TypeInformation visitThisGet(ast.Identifier node, _) {
+ return thisType;
+ }
+
+ TypeInformation visitIdentifier(ast.Identifier node) {
+ if (node.isThis()) {
+ return thisType;
+ } else if (node.isSuper()) {
+ return internalError(node, 'Unexpected expression $node.');
+ } else {
+ Element element = elements[node];
+ if (Elements.isLocal(element)) {
+ LocalElement local = element;
+ return locals.use(local);
+ }
+ return null;
}
}
- GlobalTypeInferenceElementData _dataOf(AstElement element) => inTreeData
- .putIfAbsent(element, () => new GlobalTypeInferenceElementData());
-
- /**
- * Update [sideEffects] with the side effects of [callee] being
- * called with [selector].
- */
- void updateSideEffects(
- SideEffects sideEffects, Selector selector, Element callee) {
- if (callee.isField) {
- if (callee.isInstanceMember) {
- if (selector.isSetter) {
- sideEffects.setChangesInstanceProperty();
- } else if (selector.isGetter) {
- sideEffects.setDependsOnInstancePropertyStore();
+ void potentiallyAddIsCheck(ast.Send node) {
+ if (!accumulateIsChecks) return;
+ if (!Elements.isLocal(elements[node.receiver])) return;
+ isChecks.add(node);
+ }
+
+ void potentiallyAddNullCheck(ast.Send node, ast.Node receiver) {
+ if (!accumulateIsChecks) return;
+ if (!Elements.isLocal(elements[receiver])) return;
+ isChecks.add(node);
+ }
+
+ void updateIsChecks(List<ast.Node> tests, {bool usePositive}) {
+ void narrow(Element element, ResolutionDartType type, ast.Node node) {
+ if (element is LocalElement) {
+ TypeInformation existing = locals.use(element);
+ TypeInformation newType =
+ types.narrowType(existing, type, isNullable: false);
+ locals.update(element, newType, node);
+ }
+ }
+
+ if (tests == null) return;
+ for (ast.Send node in tests) {
+ if (node.isTypeTest) {
+ if (node.isIsNotCheck) {
+ if (usePositive) continue;
} else {
- sideEffects.setAllSideEffects();
- sideEffects.setDependsOnSomething();
+ if (!usePositive) continue;
}
+ ResolutionDartType type =
+ elements.getType(node.typeAnnotationFromIsCheckOrCast);
+ narrow(elements[node.receiver], type, node);
} else {
- if (selector.isSetter) {
- sideEffects.setChangesStaticProperty();
- } else if (selector.isGetter) {
- sideEffects.setDependsOnStaticPropertyStore();
+ Element receiverElement = elements[node.receiver];
+ Element argumentElement = elements[node.arguments.first];
+ String operator = node.selector.asOperator().source;
+ if ((operator == '==' && usePositive) ||
+ (operator == '!=' && !usePositive)) {
+ // Type the elements as null.
+ if (Elements.isLocal(receiverElement)) {
+ locals.update(receiverElement, types.nullType, node);
+ }
+ if (Elements.isLocal(argumentElement)) {
+ locals.update(argumentElement, types.nullType, node);
+ }
} else {
- sideEffects.setAllSideEffects();
- sideEffects.setDependsOnSomething();
+ // Narrow the elements to a non-null type.
+ ResolutionDartType objectType = closedWorld.commonElements.objectType;
+ if (Elements.isLocal(receiverElement)) {
+ narrow(receiverElement, objectType, node);
+ }
+ if (Elements.isLocal(argumentElement)) {
+ narrow(argumentElement, objectType, node);
+ }
}
}
- } else if (callee.isGetter && !selector.isGetter) {
- sideEffects.setAllSideEffects();
- sideEffects.setDependsOnSomething();
+ }
+ }
+
+ @override
+ TypeInformation visitIndex(
+ ast.Send node, ast.Node receiver, ast.Node index, _) {
+ return handleDynamicInvoke(node);
+ }
+
+ @override
+ TypeInformation visitDynamicPropertyInvoke(ast.Send node, ast.Node receiver,
+ ast.NodeList arguments, Selector selector, _) {
+ return handleDynamicInvoke(node);
+ }
+
+ @override
+ TypeInformation visitIfNotNullDynamicPropertyInvoke(ast.Send node,
+ ast.Node receiver, ast.NodeList arguments, Selector selector, _) {
+ return handleDynamicInvoke(node);
+ }
+
+ @override
+ TypeInformation visitThisPropertyInvoke(
+ ast.Send node, ast.NodeList arguments, Selector selector, _) {
+ return handleDynamicInvoke(node);
+ }
+
+ @override
+ TypeInformation visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) {
+ TypeInformation firstType = visit(left);
+ TypeInformation secondType = visit(right);
+ return types.allocateDiamondPhi(types.narrowNotNull(firstType), secondType);
+ }
+
+ @override
+ TypeInformation visitLogicalAnd(
+ ast.Send node, ast.Node left, ast.Node right, _) {
+ conditionIsSimple = false;
+ bool oldAccumulateIsChecks = accumulateIsChecks;
+ List<ast.Send> oldIsChecks = isChecks;
+ if (!accumulateIsChecks) {
+ accumulateIsChecks = true;
+ isChecks = <ast.Send>[];
+ }
+ visit(left);
+ LocalsHandler saved = locals;
+ locals = new LocalsHandler.from(locals, node);
+ updateIsChecks(isChecks, usePositive: true);
+ LocalsHandler narrowed;
+ if (oldAccumulateIsChecks) {
+ narrowed = new LocalsHandler.topLevelCopyOf(locals);
} else {
- sideEffects.add(closedWorldRefiner.getCurrentlyKnownSideEffects(callee));
+ accumulateIsChecks = false;
+ isChecks = oldIsChecks;
}
+ visit(right);
+ if (oldAccumulateIsChecks) {
+ bool invalidatedInRightHandSide(ast.Send test) {
+ Element receiver = elements[test.receiver];
+ if (receiver is LocalElement) {
+ return narrowed.locals[receiver] != locals.locals[receiver];
+ }
+ return false;
+ }
+
+ isChecks.removeWhere(invalidatedInRightHandSide);
+ }
+ saved.mergeDiamondFlow(locals, null);
+ locals = saved;
+ return types.boolType;
+ }
+
+ @override
+ TypeInformation visitLogicalOr(
+ ast.Send node, ast.Node left, ast.Node right, _) {
+ conditionIsSimple = false;
+ List<ast.Send> tests = <ast.Send>[];
+ bool isSimple = handleCondition(left, tests);
+ LocalsHandler saved = locals;
+ locals = new LocalsHandler.from(locals, node);
+ if (isSimple) updateIsChecks(tests, usePositive: false);
+ bool oldAccumulateIsChecks = accumulateIsChecks;
+ accumulateIsChecks = false;
+ visit(right);
+ accumulateIsChecks = oldAccumulateIsChecks;
+ saved.mergeDiamondFlow(locals, null);
+ locals = saved;
+ return types.boolType;
}
- /**
- * Returns the type for [nativeBehavior]. See documentation on
- * [native.NativeBehavior].
- */
- T typeOfNativeBehavior(native.NativeBehavior nativeBehavior) {
- if (nativeBehavior == null) return types.dynamicType;
- List typesReturned = nativeBehavior.typesReturned;
- if (typesReturned.isEmpty) return types.dynamicType;
- T returnType;
- for (var type in typesReturned) {
- T mappedType;
- if (type == native.SpecialType.JsObject) {
- mappedType = types.nonNullExact(commonElements.objectClass);
- } else if (type == commonElements.stringType) {
- mappedType = types.stringType;
- } else if (type == commonElements.intType) {
- mappedType = types.intType;
- } else if (type == commonElements.numType ||
- type == commonElements.doubleType) {
- // Note: the backend double class is specifically for non-integer
- // doubles, and a native behavior returning 'double' does not guarantee
- // a non-integer return type, so we return the number type for those.
- mappedType = types.numType;
- } else if (type == commonElements.boolType) {
- mappedType = types.boolType;
- } else if (type == commonElements.nullType) {
- mappedType = types.nullType;
- } else if (type.isVoid) {
- mappedType = types.nullType;
- } else if (type.isDynamic) {
- return types.dynamicType;
+ @override
+ TypeInformation visitNot(ast.Send node, ast.Node expression, _) {
+ bool oldAccumulateIsChecks = accumulateIsChecks;
+ accumulateIsChecks = false;
+ visit(expression);
+ accumulateIsChecks = oldAccumulateIsChecks;
+ return types.boolType;
+ }
+
+ @override
+ TypeInformation visitIs(
+ ast.Send node, ast.Node expression, ResolutionDartType type, _) {
+ potentiallyAddIsCheck(node);
+ visit(expression);
+ return types.boolType;
+ }
+
+ @override
+ TypeInformation visitIsNot(
+ ast.Send node, ast.Node expression, ResolutionDartType type, _) {
+ potentiallyAddIsCheck(node);
+ visit(expression);
+ return types.boolType;
+ }
+
+ @override
+ TypeInformation visitAs(
+ ast.Send node, ast.Node expression, ResolutionDartType type, _) {
+ TypeInformation receiverType = visit(expression);
+ return types.narrowType(receiverType, type);
+ }
+
+ @override
+ TypeInformation visitUnary(
+ ast.Send node, op.UnaryOperator operator, ast.Node expression, _) {
+ return handleDynamicInvoke(node);
+ }
+
+ @override
+ TypeInformation visitNotEquals(
+ ast.Send node, ast.Node left, ast.Node right, _) {
+ handleDynamicInvoke(node);
+ return types.boolType;
+ }
+
+ @override
+ TypeInformation visitEquals(ast.Send node, ast.Node left, ast.Node right, _) {
+ return handleDynamicInvoke(node);
+ }
+
+ @override
+ TypeInformation visitBinary(ast.Send node, ast.Node left,
+ op.BinaryOperator operator, ast.Node right, _) {
+ return handleDynamicInvoke(node);
+ }
+
+ // Because some nodes just visit their children, we may end up
+ // visiting a type annotation, that may contain a send in case of a
+ // prefixed type. Therefore we explicitly visit the type annotation
+ // to avoid confusing the [ResolvedVisitor].
+ visitTypeAnnotation(ast.TypeAnnotation node) {}
+
+ TypeInformation visitConditional(ast.Conditional node) {
+ List<ast.Send> tests = <ast.Send>[];
+ bool simpleCondition = handleCondition(node.condition, tests);
+ LocalsHandler saved = locals;
+ locals = new LocalsHandler.from(locals, node);
+ updateIsChecks(tests, usePositive: true);
+ TypeInformation firstType = visit(node.thenExpression);
+ LocalsHandler thenLocals = locals;
+ locals = new LocalsHandler.from(saved, node);
+ if (simpleCondition) updateIsChecks(tests, usePositive: false);
+ TypeInformation secondType = visit(node.elseExpression);
+ saved.mergeDiamondFlow(thenLocals, locals);
+ locals = saved;
+ TypeInformation type = types.allocateDiamondPhi(firstType, secondType);
+ return type;
+ }
+
+ TypeInformation visitVariableDefinitions(ast.VariableDefinitions node) {
+ for (Link<ast.Node> link = node.definitions.nodes;
+ !link.isEmpty;
+ link = link.tail) {
+ ast.Node definition = link.head;
+ if (definition is ast.Identifier) {
+ locals.update(elements[definition], types.nullType, node);
} else {
- mappedType = types.nonNullSubtype(type.element);
- }
- returnType = types.computeLUB(returnType, mappedType);
- if (returnType == types.dynamicType) {
- break;
+ assert(definition.asSendSet() != null);
+ handleSendSet(definition);
}
}
- return returnType;
+ return null;
}
- // TODO(johnniwinther): Pass the [ResolvedAst] instead of [owner].
- void updateSelectorInTree(
- AstElement owner, Spannable node, Selector selector, TypeMask mask) {
- ast.Node astNode = node;
- GlobalTypeInferenceElementData data = _dataOf(owner);
- if (astNode.asSendSet() != null) {
- if (selector.isSetter || selector.isIndexSet) {
- data.setTypeMask(node, mask);
- } else if (selector.isGetter || selector.isIndex) {
- data.setGetterTypeMaskInComplexSendSet(node, mask);
- } else {
- assert(selector.isOperator);
- data.setOperatorTypeMaskInComplexSendSet(node, mask);
+ bool handleCondition(ast.Node node, List<ast.Send> tests) {
+ bool oldConditionIsSimple = conditionIsSimple;
+ bool oldAccumulateIsChecks = accumulateIsChecks;
+ List<ast.Send> oldIsChecks = isChecks;
+ accumulateIsChecks = true;
+ conditionIsSimple = true;
+ isChecks = tests;
+ visit(node);
+ bool simpleCondition = conditionIsSimple;
+ accumulateIsChecks = oldAccumulateIsChecks;
+ isChecks = oldIsChecks;
+ conditionIsSimple = oldConditionIsSimple;
+ return simpleCondition;
+ }
+
+ TypeInformation visitIf(ast.If node) {
+ List<ast.Send> tests = <ast.Send>[];
+ bool simpleCondition = handleCondition(node.condition, tests);
+ LocalsHandler saved = locals;
+ locals = new LocalsHandler.from(locals, node);
+ updateIsChecks(tests, usePositive: true);
+ visit(node.thenPart);
+ LocalsHandler thenLocals = locals;
+ locals = new LocalsHandler.from(saved, node);
+ if (simpleCondition) updateIsChecks(tests, usePositive: false);
+ visit(node.elsePart);
+ saved.mergeDiamondFlow(thenLocals, locals);
+ locals = saved;
+ return null;
+ }
+
+ void setupBreaksAndContinues(JumpTarget element) {
+ if (element == null) return;
+ if (element.isContinueTarget) continuesFor[element] = <LocalsHandler>[];
+ if (element.isBreakTarget) breaksFor[element] = <LocalsHandler>[];
+ }
+
+ void clearBreaksAndContinues(JumpTarget element) {
+ continuesFor.remove(element);
+ breaksFor.remove(element);
+ }
+
+ List<LocalsHandler> getBreaks(JumpTarget element) {
+ List<LocalsHandler> list = <LocalsHandler>[locals];
+ if (element == null) return list;
+ if (!element.isBreakTarget) return list;
+ return list..addAll(breaksFor[element]);
+ }
+
+ List<LocalsHandler> getLoopBackEdges(JumpTarget element) {
+ List<LocalsHandler> list = <LocalsHandler>[locals];
+ if (element == null) return list;
+ if (!element.isContinueTarget) return list;
+ return list..addAll(continuesFor[element]);
+ }
+
+ TypeInformation handleLoop(ast.Node node, void logic()) {
+ loopLevel++;
+ bool changed = false;
+ JumpTarget target = elements.getTargetDefinition(node);
+ LocalsHandler saved = locals;
+ saved.startLoop(node);
+ do {
+ // Setup (and clear in case of multiple iterations of the loop)
+ // the lists of breaks and continues seen in the loop.
+ setupBreaksAndContinues(target);
+ locals = new LocalsHandler.from(saved, node);
+ logic();
+ changed = saved.mergeAll(getLoopBackEdges(target));
+ } while (changed);
+ loopLevel--;
+ saved.endLoop(node);
+ bool keepOwnLocals = node.asDoWhile() == null;
+ saved.mergeAfterBreaks(getBreaks(target), keepOwnLocals: keepOwnLocals);
+ locals = saved;
+ clearBreaksAndContinues(target);
+ return null;
+ }
+
+ TypeInformation visitWhile(ast.While node) {
+ return handleLoop(node, () {
+ List<ast.Send> tests = <ast.Send>[];
+ handleCondition(node.condition, tests);
+ updateIsChecks(tests, usePositive: true);
+ visit(node.body);
+ });
+ }
+
+ TypeInformation visitDoWhile(ast.DoWhile node) {
+ return handleLoop(node, () {
+ visit(node.body);
+ List<ast.Send> tests = <ast.Send>[];
+ handleCondition(node.condition, tests);
+ updateIsChecks(tests, usePositive: true);
+ });
+ }
+
+ TypeInformation visitFor(ast.For node) {
+ visit(node.initializer);
+ return handleLoop(node, () {
+ List<ast.Send> tests = <ast.Send>[];
+ handleCondition(node.condition, tests);
+ updateIsChecks(tests, usePositive: true);
+ visit(node.body);
+ visit(node.update);
+ });
+ }
+
+ TypeInformation visitTryStatement(ast.TryStatement node) {
+ LocalsHandler saved = locals;
+ locals = new LocalsHandler.from(locals, node, useOtherTryBlock: false);
+ visit(node.tryBlock);
+ saved.mergeDiamondFlow(locals, null);
+ locals = saved;
+ for (ast.Node catchBlock in node.catchBlocks) {
+ saved = locals;
+ locals = new LocalsHandler.from(locals, catchBlock);
+ visit(catchBlock);
+ saved.mergeDiamondFlow(locals, null);
+ locals = saved;
+ }
+ visit(node.finallyBlock);
+ return null;
+ }
+
+ TypeInformation visitThrow(ast.Throw node) {
+ node.visitChildren(this);
+ locals.seenReturnOrThrow = true;
+ return types.nonNullEmpty();
+ }
+
+ TypeInformation visitCatchBlock(ast.CatchBlock node) {
+ ast.Node exception = node.exception;
+ if (exception != null) {
+ ResolutionDartType type = elements.getType(node.type);
+ TypeInformation mask =
+ type == null || type.treatAsDynamic || type.isTypeVariable
+ ? types.dynamicType
+ : types.nonNullSubtype(type.element);
+ locals.update(elements[exception], mask, node);
+ }
+ ast.Node trace = node.trace;
+ if (trace != null) {
+ locals.update(elements[trace], types.dynamicType, node);
+ }
+ visit(node.block);
+ return null;
+ }
+
+ TypeInformation visitParenthesizedExpression(
+ ast.ParenthesizedExpression node) {
+ return visit(node.expression);
+ }
+
+ TypeInformation visitBlock(ast.Block node) {
+ if (node.statements != null) {
+ for (ast.Node statement in node.statements) {
+ visit(statement);
+ if (locals.aborts) break;
}
- } else if (astNode.asSend() != null) {
- data.setTypeMask(node, mask);
+ }
+ return null;
+ }
+
+ TypeInformation visitLabeledStatement(ast.LabeledStatement node) {
+ ast.Statement body = node.statement;
+ if (body is ast.Loop ||
+ body is ast.SwitchStatement ||
+ Elements.isUnusedLabel(node, elements)) {
+ // Loops and switches handle their own labels.
+ visit(body);
} else {
- assert(astNode.asForIn() != null);
- if (selector == Selectors.iterator) {
- data.setIteratorTypeMask(node, mask);
- } else if (selector == Selectors.current) {
- data.setCurrentTypeMask(node, mask);
- } else {
- assert(selector == Selectors.moveNext);
- data.setMoveNextTypeMask(node, mask);
- }
+ JumpTarget targetElement = elements.getTargetDefinition(body);
+ setupBreaksAndContinues(targetElement);
+ visit(body);
+ locals.mergeAfterBreaks(getBreaks(targetElement));
+ clearBreaksAndContinues(targetElement);
}
+ return null;
}
- bool isNativeElement(Element element) {
- return compiler.backend.isNative(element);
+ TypeInformation visitBreakStatement(ast.BreakStatement node) {
+ JumpTarget target = elements.getTargetOf(node);
+ locals.seenBreakOrContinue = true;
+ // Do a deep-copy of the locals, because the code following the
+ // break will change them.
+ breaksFor[target].add(new LocalsHandler.deepCopyOf(locals));
+ return null;
}
- void analyze(ResolvedAst resolvedAst, ArgumentsTypes arguments);
+ TypeInformation visitContinueStatement(ast.ContinueStatement node) {
+ JumpTarget target = elements.getTargetOf(node);
+ locals.seenBreakOrContinue = true;
+ // Do a deep-copy of the locals, because the code following the
+ // continue will change them.
+ continuesFor[target].add(new LocalsHandler.deepCopyOf(locals));
+ return null;
+ }
- bool checkIfExposesThis(Element element) {
- element = element.implementation;
- return generativeConstructorsExposingThis.contains(element);
+ internalError(Spannable node, String reason) {
+ reporter.internalError(node, reason);
}
- void recordExposesThis(Element element, bool exposesThis) {
- element = element.implementation;
- if (exposesThis) {
- generativeConstructorsExposingThis.add(element);
+ TypeInformation visitSwitchStatement(ast.SwitchStatement node) {
+ visit(node.parenthesizedExpression);
+
+ setupBreaksAndContinues(elements.getTargetDefinition(node));
+ if (Elements.switchStatementHasContinue(node, elements)) {
+ void forEachLabeledCase(void action(JumpTarget target)) {
+ for (ast.SwitchCase switchCase in node.cases) {
+ for (ast.Node labelOrCase in switchCase.labelsAndCases) {
+ if (labelOrCase.asLabel() == null) continue;
+ LabelDefinition labelElement =
+ elements.getLabelDefinition(labelOrCase);
+ if (labelElement != null) {
+ action(labelElement.target);
+ }
+ }
+ }
+ }
+
+ forEachLabeledCase((JumpTarget target) {
+ setupBreaksAndContinues(target);
+ });
+
+ // If the switch statement has a continue, we conservatively
+ // visit all cases and update [locals] until we have reached a
+ // fixed point.
+ bool changed;
+ locals.startLoop(node);
+ do {
+ changed = false;
+ for (ast.Node switchCase in node.cases) {
+ LocalsHandler saved = locals;
+ locals = new LocalsHandler.from(locals, switchCase);
+ visit(switchCase);
+ changed = saved.mergeAll([locals]) || changed;
+ locals = saved;
+ }
+ } while (changed);
+ locals.endLoop(node);
+
+ forEachLabeledCase((JumpTarget target) {
+ clearBreaksAndContinues(target);
+ });
+ } else {
+ LocalsHandler saved = locals;
+ List<LocalsHandler> localsToMerge = <LocalsHandler>[];
+ bool hasDefaultCase = false;
+
+ for (ast.SwitchCase switchCase in node.cases) {
+ if (switchCase.isDefaultCase) {
+ hasDefaultCase = true;
+ }
+ locals = new LocalsHandler.from(saved, switchCase);
+ visit(switchCase);
+ localsToMerge.add(locals);
+ }
+ saved.mergeAfterBreaks(localsToMerge, keepOwnLocals: !hasDefaultCase);
+ locals = saved;
}
+ clearBreaksAndContinues(elements.getTargetDefinition(node));
+ return null;
}
-}
-/// [SimpleTypeInferrerVisitor] can be thought of as a type-inference graph
-/// builder for a single element.
-///
-/// Calling [run] will start the work of visiting the body of the code to
-/// construct a set of infernece-nodes that abstractly represent what the code
-/// is doing.
-///
-/// This visitor is parameterized by an [InferenceEngine], which internally
-/// decides how to represent inference nodes.
-class SimpleTypeInferrerVisitor<T>
- extends InferrerVisitor<T, InferrerEngine<T, TypeSystem<T>>> {
- T returnType;
- bool visitingInitializers = false;
- bool isConstructorRedirect = false;
- bool seenSuperConstructorCall = false;
- SideEffects sideEffects = new SideEffects.empty();
- final Element outermostElement;
- final InferrerEngine<T, TypeSystem<T>> inferrer;
- final Setlet<Entity> capturedVariables = new Setlet<Entity>();
- final GlobalTypeInferenceElementData inTreeData;
-
- SimpleTypeInferrerVisitor.internal(
- AstElement analyzedElement,
- ResolvedAst resolvedAst,
- this.outermostElement,
- inferrer,
- compiler,
- locals)
- : super(analyzedElement, resolvedAst, inferrer, inferrer.types, compiler,
- locals),
- this.inferrer = inferrer,
- this.inTreeData = inferrer._dataOf(analyzedElement) {
- assert(outermostElement != null);
+ TypeInformation visitCascadeReceiver(ast.CascadeReceiver node) {
+ var type = visit(node.expression);
+ cascadeReceiverStack.add(type);
+ return type;
}
- SimpleTypeInferrerVisitor(Element element, ResolvedAst resolvedAst,
- Compiler compiler, InferrerEngine<T, TypeSystem<T>> inferrer,
- [LocalsHandler<T> handler])
- : this.internal(
- element,
- resolvedAst,
- element.outermostEnclosingMemberOrTopLevel.implementation,
- inferrer,
- compiler,
- handler);
+ TypeInformation visitCascade(ast.Cascade node) {
+ // Ignore the result of the cascade send and return the type of the cascade
+ // receiver.
+ visit(node.expression);
+ return cascadeReceiverStack.removeLast();
+ }
void analyzeSuperConstructorCall(
AstElement target, ArgumentsTypes arguments) {
@@ -363,7 +881,7 @@ class SimpleTypeInferrerVisitor<T>
isThisExposed = isThisExposed || inferrer.checkIfExposesThis(target);
}
- T run() {
+ TypeInformation run() {
var node;
if (resolvedAst.kind == ResolvedAstKind.PARSED) {
node = resolvedAst.node;
@@ -411,7 +929,7 @@ class SimpleTypeInferrerVisitor<T>
visitor = new SimpleTypeInferrerVisitor(element.functionDeclaration,
element.functionDeclaration.resolvedAst, compiler, inferrer);
}
- T type =
+ TypeInformation type =
(defaultValue == null) ? types.nullType : visitor.visit(defaultValue);
inferrer.setDefaultTypeOfParameter(element, type);
});
@@ -425,7 +943,7 @@ class SimpleTypeInferrerVisitor<T>
if (analyzedElement.isGenerativeConstructor) {
isThisExposed = false;
signature.forEachParameter((ParameterElement element) {
- T parameterType = inferrer.typeOfElement(element);
+ TypeInformation parameterType = inferrer.typeOfElement(element);
if (element.isInitializingFormal) {
InitializingFormalElement initializingFormal = element;
if (initializingFormal.fieldElement.isFinal) {
@@ -477,10 +995,10 @@ class SimpleTypeInferrerVisitor<T>
}
if (!isConstructorRedirect) {
// Iterate over all instance fields, and give a null type to
- // fields that we haven't initialized for sure.
+ // fields that we haven'TypeInformation initialized for sure.
cls.forEachInstanceField((_, FieldElement field) {
if (field.isFinal) return;
- T type = locals.fieldScope.readField(field);
+ TypeInformation type = locals.fieldScope.readField(field);
ResolvedAst resolvedAst = field.resolvedAst;
if (type == null && resolvedAst.body == null) {
inferrer.recordTypeOfNonFinalField(
@@ -512,7 +1030,7 @@ class SimpleTypeInferrerVisitor<T>
? types.nonNullEmpty() // Body always throws.
: types.nullType;
} else if (!locals.seenReturnOrThrow) {
- // We haven't seen returns on all branches. So the method may
+ // We haven'TypeInformation seen returns on all branches. So the method may
// also return null.
returnType = inferrer.addReturnTypeFor(
analyzedElement, returnType, types.nullType);
@@ -545,19 +1063,19 @@ class SimpleTypeInferrerVisitor<T>
return returnType;
}
- T visitFunctionExpression(ast.FunctionExpression node) {
+ TypeInformation visitFunctionExpression(ast.FunctionExpression node) {
// We loose track of [this] in closures (see issue 20840). To be on
// the safe side, we mark [this] as exposed here. We could do better by
// analyzing the closure.
// TODO(herhut): Analyze whether closure exposes this.
isThisExposed = true;
LocalFunctionElement element = elements.getFunctionDefinition(node);
- // We don't put the closure in the work queue of the
+ // We don'TypeInformation put the closure in the work queue of the
// inferrer, because it will share information with its enclosing
// method, like for example the types of local variables.
LocalsHandler closureLocals =
- new LocalsHandler<T>.from(locals, node, useOtherTryBlock: false);
- SimpleTypeInferrerVisitor visitor = new SimpleTypeInferrerVisitor<T>(
+ new LocalsHandler.from(locals, node, useOtherTryBlock: false);
+ SimpleTypeInferrerVisitor visitor = new SimpleTypeInferrerVisitor(
element, element.resolvedAst, compiler, inferrer, closureLocals);
visitor.run();
inferrer.recordReturnType(element, visitor.returnType);
@@ -584,10 +1102,11 @@ class SimpleTypeInferrerVisitor<T>
});
}
- T visitFunctionDeclaration(ast.FunctionDeclaration node) {
+ TypeInformation visitFunctionDeclaration(ast.FunctionDeclaration node) {
LocalFunctionElement element =
elements.getFunctionDefinition(node.function);
- T type = inferrer.concreteTypes.putIfAbsent(node.function, () {
+ TypeInformation type =
+ inferrer.concreteTypes.putIfAbsent(node.function, () {
return types.allocateClosure(node.function, element);
});
locals.update(element, type, node);
@@ -595,7 +1114,7 @@ class SimpleTypeInferrerVisitor<T>
return type;
}
- T visitStringInterpolation(ast.StringInterpolation node) {
+ TypeInformation visitStringInterpolation(ast.StringInterpolation node) {
// Interpolation could have any effects since it could call any toString()
// method.
// TODO(sra): This could be modelled by a call to toString() but with a
@@ -605,17 +1124,18 @@ class SimpleTypeInferrerVisitor<T>
// to have all effects. Effect annotations on JS code would be needed to
// get the benefit.
sideEffects.setAllSideEffects();
- return super.visitStringInterpolation(node);
+ node.visitChildren(this);
+ return types.stringType;
}
- T visitLiteralList(ast.LiteralList node) {
- // We only set the type once. We don't need to re-visit the children
+ TypeInformation visitLiteralList(ast.LiteralList node) {
+ // We only set the type once. We don'TypeInformation need to re-visit the children
// when re-analyzing the node.
return inferrer.concreteTypes.putIfAbsent(node, () {
- T elementType;
+ TypeInformation elementType;
int length = 0;
for (ast.Node element in node.elements.nodes) {
- T type = visit(element);
+ TypeInformation type = visit(element);
elementType = elementType == null
? types.allocatePhi(null, null, type)
: types.addPhiInput(null, elementType, type);
@@ -624,25 +1144,25 @@ class SimpleTypeInferrerVisitor<T>
elementType = elementType == null
? types.nonNullEmpty()
: types.simplifyPhi(null, null, elementType);
- T containerType =
+ TypeInformation containerType =
node.isConst ? types.constListType : types.growableListType;
return types.allocateList(
containerType, node, outermostElement, elementType, length);
});
}
- T visitLiteralMap(ast.LiteralMap node) {
+ TypeInformation visitLiteralMap(ast.LiteralMap node) {
return inferrer.concreteTypes.putIfAbsent(node, () {
ast.NodeList entries = node.entries;
- List<T> keyTypes = [];
- List<T> valueTypes = [];
+ List keyTypes = [];
+ List valueTypes = [];
for (ast.LiteralMapEntry entry in entries) {
keyTypes.add(visit(entry.key));
valueTypes.add(visit(entry.value));
}
- T type = node.isConst ? types.constMapType : types.mapType;
+ TypeInformation type = node.isConst ? types.constMapType : types.mapType;
return types.allocateMap(
type, node, outermostElement, keyTypes, valueTypes);
});
@@ -693,7 +1213,7 @@ class SimpleTypeInferrerVisitor<T>
}
@override
- T handleSendSet(ast.SendSet node) {
+ TypeInformation handleSendSet(ast.SendSet node) {
Element element = elements[node];
if (!Elements.isUnresolved(element) && element.impliesType) {
node.visitChildren(this);
@@ -709,7 +1229,7 @@ class SimpleTypeInferrerVisitor<T>
String op = node.assignmentOperator.source;
bool isIncrementOrDecrement = op == '++' || op == '--';
- T receiverType;
+ TypeInformation receiverType;
bool isCallOnThis = false;
if (node.receiver == null) {
if (treatAsInstanceMember(element)) {
@@ -727,7 +1247,7 @@ class SimpleTypeInferrerVisitor<T>
isCallOnThis = isThisOrSuper(node.receiver);
}
- T rhsType;
+ TypeInformation rhsType;
if (isIncrementOrDecrement) {
rhsType = types.uint31Type;
@@ -763,8 +1283,8 @@ class SimpleTypeInferrerVisitor<T>
receiverType, rhsType, node.arguments.head);
} else {
// [foo ??= bar], [: foo++ :] or [: foo += 1 :].
- T getterType;
- T newType;
+ TypeInformation getterType;
+ TypeInformation newType;
if (Elements.isMalformed(element)) return types.dynamicType;
@@ -791,17 +1311,17 @@ class SimpleTypeInferrerVisitor<T>
Selector operatorSelector =
elements.getOperatorSelectorInComplexSendSet(node);
newType = handleDynamicSend(node, operatorSelector, operatorMask,
- getterType, new ArgumentsTypes<T>([rhsType], null));
+ getterType, new ArgumentsTypes([rhsType], null));
}
if (Elements.isStaticOrTopLevelField(element)) {
handleStaticSend(node, setterSelector, setterMask, element,
- new ArgumentsTypes<T>([newType], null));
+ new ArgumentsTypes([newType], null));
} else if (Elements.isUnresolved(element) ||
element.isSetter ||
element.isField) {
handleDynamicSend(node, setterSelector, setterMask, receiverType,
- new ArgumentsTypes<T>([newType], null));
+ new ArgumentsTypes([newType], null));
} else if (element.isLocal) {
locals.update(element, newType, node);
}
@@ -811,8 +1331,11 @@ class SimpleTypeInferrerVisitor<T>
}
/// Handle compound index set, like `foo[0] += 42` or `foo[0]++`.
- T handleCompoundIndexSet(
- ast.SendSet node, T receiverType, T indexType, T rhsType) {
+ TypeInformation handleCompoundIndexSet(
+ ast.SendSet node,
+ TypeInformation receiverType,
+ TypeInformation indexType,
+ TypeInformation rhsType) {
Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
TypeMask getterMask = inTreeData.typeOfGetter(node);
@@ -822,18 +1345,18 @@ class SimpleTypeInferrerVisitor<T>
Selector setterSelector = elements.getSelector(node);
TypeMask setterMask = inTreeData.typeOfSend(node);
- T getterType = handleDynamicSend(node, getterSelector, getterMask,
- receiverType, new ArgumentsTypes<T>([indexType], null));
+ TypeInformation getterType = handleDynamicSend(node, getterSelector,
+ getterMask, receiverType, new ArgumentsTypes([indexType], null));
- T returnType;
+ TypeInformation returnType;
if (node.isIfNullAssignment) {
returnType = types.allocateDiamondPhi(getterType, rhsType);
} else {
returnType = handleDynamicSend(node, operatorSelector, operatorMask,
- getterType, new ArgumentsTypes<T>([rhsType], null));
+ getterType, new ArgumentsTypes([rhsType], null));
}
handleDynamicSend(node, setterSelector, setterMask, receiverType,
- new ArgumentsTypes<T>([indexType, returnType], null));
+ new ArgumentsTypes([indexType, returnType], null));
if (node.isPostfix) {
return getterType;
@@ -843,87 +1366,88 @@ class SimpleTypeInferrerVisitor<T>
}
/// Handle compound prefix/postfix operations, like `a[0]++`.
- T handleCompoundPrefixPostfix(ast.Send node, T receiverType, T indexType) {
+ TypeInformation handleCompoundPrefixPostfix(
+ ast.Send node, TypeInformation receiverType, TypeInformation indexType) {
return handleCompoundIndexSet(
node, receiverType, indexType, types.uint31Type);
}
@override
- T visitIndexPostfix(ast.Send node, ast.Node receiver, ast.Node index,
- op.IncDecOperator operator, _) {
- T receiverType = visit(receiver);
- T indexType = visit(index);
+ TypeInformation visitIndexPostfix(ast.Send node, ast.Node receiver,
+ ast.Node index, op.IncDecOperator operator, _) {
+ TypeInformation receiverType = visit(receiver);
+ TypeInformation indexType = visit(index);
return handleCompoundPrefixPostfix(node, receiverType, indexType);
}
@override
- T visitIndexPrefix(ast.Send node, ast.Node receiver, ast.Node index,
- op.IncDecOperator operator, _) {
- T receiverType = visit(receiver);
- T indexType = visit(index);
+ TypeInformation visitIndexPrefix(ast.Send node, ast.Node receiver,
+ ast.Node index, op.IncDecOperator operator, _) {
+ TypeInformation receiverType = visit(receiver);
+ TypeInformation indexType = visit(index);
return handleCompoundPrefixPostfix(node, receiverType, indexType);
}
@override
- T visitCompoundIndexSet(ast.SendSet node, ast.Node receiver, ast.Node index,
- op.AssignmentOperator operator, ast.Node rhs, _) {
- T receiverType = visit(receiver);
- T indexType = visit(index);
- T rhsType = visit(rhs);
+ TypeInformation visitCompoundIndexSet(ast.SendSet node, ast.Node receiver,
+ ast.Node index, op.AssignmentOperator operator, ast.Node rhs, _) {
+ TypeInformation receiverType = visit(receiver);
+ TypeInformation indexType = visit(index);
+ TypeInformation rhsType = visit(rhs);
return handleCompoundIndexSet(node, receiverType, indexType, rhsType);
}
@override
- T visitIndexSetIfNull(
+ TypeInformation visitIndexSetIfNull(
ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) {
- T receiverType = visit(receiver);
- T indexType = visit(index);
- T rhsType = visit(rhs);
+ TypeInformation receiverType = visit(receiver);
+ TypeInformation indexType = visit(index);
+ TypeInformation rhsType = visit(rhs);
return handleCompoundIndexSet(node, receiverType, indexType, rhsType);
}
@override
- T visitSuperIndexPrefix(ast.Send node, MethodElement getter,
+ TypeInformation visitSuperIndexPrefix(ast.Send node, MethodElement getter,
MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
- T indexType = visit(index);
+ TypeInformation indexType = visit(index);
return handleSuperIndexPrefixPostfix(node, getter, setter, indexType);
}
@override
- T visitSuperIndexPostfix(ast.Send node, MethodElement getter,
+ TypeInformation visitSuperIndexPostfix(ast.Send node, MethodElement getter,
MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
- T indexType = visit(index);
+ TypeInformation indexType = visit(index);
return handleSuperIndexPrefixPostfix(node, getter, setter, indexType);
}
/// Handle compound prefix/postfix operations, like `super[0]++`.
- T handleSuperIndexPrefixPostfix(
- ast.Send node, Element getter, Element setter, T indexType) {
+ TypeInformation handleSuperIndexPrefixPostfix(ast.Send node, Element getter,
+ Element setter, TypeInformation indexType) {
return _handleSuperCompoundIndexSet(
node, getter, setter, indexType, types.uint31Type);
}
/// Handle compound super index set, like `super[42] =+ 2`.
- T handleSuperCompoundIndexSet(ast.SendSet node, Element getter,
+ TypeInformation handleSuperCompoundIndexSet(ast.SendSet node, Element getter,
Element setter, ast.Node index, ast.Node rhs) {
- T indexType = visit(index);
- T rhsType = visit(rhs);
+ TypeInformation indexType = visit(index);
+ TypeInformation rhsType = visit(rhs);
return _handleSuperCompoundIndexSet(
node, getter, setter, indexType, rhsType);
}
- T _handleSuperCompoundIndexSet(ast.SendSet node, Element getter,
- Element setter, T indexType, T rhsType) {
+ TypeInformation _handleSuperCompoundIndexSet(ast.SendSet node, Element getter,
+ Element setter, TypeInformation indexType, TypeInformation rhsType) {
Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
TypeMask getterMask = inTreeData.typeOfGetter(node);
Selector setterSelector = elements.getSelector(node);
TypeMask setterMask = inTreeData.typeOfSend(node);
- T getterType = handleSuperSend(node, getterSelector, getterMask, getter,
- new ArgumentsTypes<T>([indexType], null));
+ TypeInformation getterType = handleSuperSend(node, getterSelector,
+ getterMask, getter, new ArgumentsTypes([indexType], null));
- T returnType;
+ TypeInformation returnType;
if (node.isIfNullAssignment) {
returnType = types.allocateDiamondPhi(getterType, rhsType);
} else {
@@ -931,16 +1455,16 @@ class SimpleTypeInferrerVisitor<T>
elements.getOperatorSelectorInComplexSendSet(node);
TypeMask operatorMask = inTreeData.typeOfOperator(node);
returnType = handleDynamicSend(node, operatorSelector, operatorMask,
- getterType, new ArgumentsTypes<T>([rhsType], null));
+ getterType, new ArgumentsTypes([rhsType], null));
}
handleSuperSend(node, setterSelector, setterMask, setter,
- new ArgumentsTypes<T>([indexType, returnType], null));
+ new ArgumentsTypes([indexType, returnType], null));
return node.isPostfix ? getterType : returnType;
}
- T handleSuperSend(ast.Node node, Selector selector, TypeMask mask,
- Element element, ArgumentsTypes arguments) {
+ TypeInformation handleSuperSend(ast.Node node, Selector selector,
+ TypeMask mask, Element element, ArgumentsTypes arguments) {
if (element.isMalformed) {
return handleSuperNoSuchMethod(node, selector, mask, arguments);
} else {
@@ -949,7 +1473,7 @@ class SimpleTypeInferrerVisitor<T>
}
@override
- T visitSuperCompoundIndexSet(
+ TypeInformation visitSuperCompoundIndexSet(
ast.SendSet node,
MethodElement getter,
MethodElement setter,
@@ -961,25 +1485,35 @@ class SimpleTypeInferrerVisitor<T>
}
@override
- T visitSuperIndexSetIfNull(ast.SendSet node, MethodElement getter,
- MethodElement setter, ast.Node index, ast.Node rhs, _) {
+ TypeInformation visitSuperIndexSetIfNull(
+ ast.SendSet node,
+ MethodElement getter,
+ MethodElement setter,
+ ast.Node index,
+ ast.Node rhs,
+ _) {
return handleSuperCompoundIndexSet(node, getter, setter, index, rhs);
}
@override
- T visitUnresolvedSuperCompoundIndexSet(ast.Send node, Element element,
- ast.Node index, op.AssignmentOperator operator, ast.Node rhs, _) {
+ TypeInformation visitUnresolvedSuperCompoundIndexSet(
+ ast.Send node,
+ Element element,
+ ast.Node index,
+ op.AssignmentOperator operator,
+ ast.Node rhs,
+ _) {
return handleSuperCompoundIndexSet(node, element, element, index, rhs);
}
@override
- T visitUnresolvedSuperIndexSetIfNull(
+ TypeInformation visitUnresolvedSuperIndexSetIfNull(
ast.Send node, Element element, ast.Node index, ast.Node rhs, _) {
return handleSuperCompoundIndexSet(node, element, element, index, rhs);
}
@override
- T visitUnresolvedSuperGetterCompoundIndexSet(
+ TypeInformation visitUnresolvedSuperGetterCompoundIndexSet(
ast.SendSet node,
Element element,
MethodElement setter,
@@ -991,13 +1525,13 @@ class SimpleTypeInferrerVisitor<T>
}
@override
- T visitUnresolvedSuperGetterIndexSetIfNull(ast.SendSet node, Element element,
- MethodElement setter, ast.Node index, ast.Node rhs, _) {
+ TypeInformation visitUnresolvedSuperGetterIndexSetIfNull(ast.SendSet node,
+ Element element, MethodElement setter, ast.Node index, ast.Node rhs, _) {
return handleSuperCompoundIndexSet(node, element, setter, index, rhs);
}
@override
- T visitUnresolvedSuperSetterCompoundIndexSet(
+ TypeInformation visitUnresolvedSuperSetterCompoundIndexSet(
ast.SendSet node,
MethodElement getter,
Element element,
@@ -1009,282 +1543,363 @@ class SimpleTypeInferrerVisitor<T>
}
@override
- T visitUnresolvedSuperSetterIndexSetIfNull(ast.SendSet node,
+ TypeInformation visitUnresolvedSuperSetterIndexSetIfNull(ast.SendSet node,
MethodElement getter, Element element, ast.Node index, ast.Node rhs, _) {
return handleSuperCompoundIndexSet(node, getter, element, index, rhs);
}
@override
- T visitUnresolvedSuperIndexPrefix(ast.Send node, Element element,
- ast.Node index, op.IncDecOperator operator, _) {
- T indexType = visit(index);
+ TypeInformation visitUnresolvedSuperIndexPrefix(ast.Send node,
+ Element element, ast.Node index, op.IncDecOperator operator, _) {
+ TypeInformation indexType = visit(index);
return handleSuperIndexPrefixPostfix(node, element, element, indexType);
}
@override
- T visitUnresolvedSuperGetterIndexPrefix(ast.SendSet node, Element element,
- MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
- T indexType = visit(index);
+ TypeInformation visitUnresolvedSuperGetterIndexPrefix(
+ ast.SendSet node,
+ Element element,
+ MethodElement setter,
+ ast.Node index,
+ op.IncDecOperator operator,
+ _) {
+ TypeInformation indexType = visit(index);
return handleSuperIndexPrefixPostfix(node, element, setter, indexType);
}
@override
- T visitUnresolvedSuperSetterIndexPrefix(
+ TypeInformation visitUnresolvedSuperSetterIndexPrefix(
ast.SendSet node,
MethodElement getter,
Element element,
ast.Node index,
op.IncDecOperator operator,
_) {
- T indexType = visit(index);
+ TypeInformation indexType = visit(index);
return handleSuperIndexPrefixPostfix(node, getter, element, indexType);
}
@override
- T visitUnresolvedSuperIndexPostfix(ast.Send node, Element element,
- ast.Node index, op.IncDecOperator operator, _) {
- T indexType = visit(index);
+ TypeInformation visitUnresolvedSuperIndexPostfix(ast.Send node,
+ Element element, ast.Node index, op.IncDecOperator operator, _) {
+ TypeInformation indexType = visit(index);
return handleSuperIndexPrefixPostfix(node, element, element, indexType);
}
@override
- T visitUnresolvedSuperGetterIndexPostfix(ast.SendSet node, Element element,
- MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
- T indexType = visit(index);
+ TypeInformation visitUnresolvedSuperGetterIndexPostfix(
+ ast.SendSet node,
+ Element element,
+ MethodElement setter,
+ ast.Node index,
+ op.IncDecOperator operator,
+ _) {
+ TypeInformation indexType = visit(index);
return handleSuperIndexPrefixPostfix(node, element, setter, indexType);
}
@override
- T visitUnresolvedSuperSetterIndexPostfix(
+ TypeInformation visitUnresolvedSuperSetterIndexPostfix(
ast.SendSet node,
MethodElement getter,
Element element,
ast.Node index,
op.IncDecOperator operator,
_) {
- T indexType = visit(index);
+ TypeInformation indexType = visit(index);
return handleSuperIndexPrefixPostfix(node, getter, element, indexType);
}
@override
- T visitSuperFieldCompound(ast.Send node, FieldElement field,
+ TypeInformation visitSuperFieldCompound(ast.Send node, FieldElement field,
op.AssignmentOperator operator, ast.Node rhs, _) {
return handleSuperCompound(node, field, field, rhs);
}
@override
- T visitSuperFieldSetterCompound(ast.Send node, FieldElement field,
- FunctionElement setter, op.AssignmentOperator operator, ast.Node rhs, _) {
+ TypeInformation visitSuperFieldSetterCompound(
+ ast.Send node,
+ FieldElement field,
+ FunctionElement setter,
+ op.AssignmentOperator operator,
+ ast.Node rhs,
+ _) {
return handleSuperCompound(node, field, setter, rhs);
}
@override
- T visitSuperGetterFieldCompound(ast.Send node, FunctionElement getter,
- FieldElement field, op.AssignmentOperator operator, ast.Node rhs, _) {
+ TypeInformation visitSuperGetterFieldCompound(
+ ast.Send node,
+ FunctionElement getter,
+ FieldElement field,
+ op.AssignmentOperator operator,
+ ast.Node rhs,
+ _) {
return handleSuperCompound(node, getter, field, rhs);
}
@override
- T visitSuperGetterSetterCompound(ast.Send node, FunctionElement getter,
- FunctionElement setter, op.AssignmentOperator operator, ast.Node rhs, _) {
+ TypeInformation visitSuperGetterSetterCompound(
+ ast.Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ op.AssignmentOperator operator,
+ ast.Node rhs,
+ _) {
return handleSuperCompound(node, getter, setter, rhs);
}
@override
- T visitSuperMethodSetterCompound(ast.Send node, FunctionElement method,
- FunctionElement setter, op.AssignmentOperator operator, ast.Node rhs, _) {
+ TypeInformation visitSuperMethodSetterCompound(
+ ast.Send node,
+ FunctionElement method,
+ FunctionElement setter,
+ op.AssignmentOperator operator,
+ ast.Node rhs,
+ _) {
return handleSuperCompound(node, method, setter, rhs);
}
@override
- T visitUnresolvedSuperCompound(ast.Send node, Element element,
+ TypeInformation visitUnresolvedSuperCompound(ast.Send node, Element element,
op.AssignmentOperator operator, ast.Node rhs, _) {
return handleSuperCompound(node, element, element, rhs);
}
@override
- T visitUnresolvedSuperGetterCompound(ast.Send node, Element getter,
- SetterElement setter, op.AssignmentOperator operator, ast.Node rhs, _) {
+ TypeInformation visitUnresolvedSuperGetterCompound(
+ ast.Send node,
+ Element getter,
+ SetterElement setter,
+ op.AssignmentOperator operator,
+ ast.Node rhs,
+ _) {
return handleSuperCompound(node, getter, setter, rhs);
}
@override
- T visitUnresolvedSuperSetterCompound(ast.Send node, GetterElement getter,
- Element setter, op.AssignmentOperator operator, ast.Node rhs, _) {
+ TypeInformation visitUnresolvedSuperSetterCompound(
+ ast.Send node,
+ GetterElement getter,
+ Element setter,
+ op.AssignmentOperator operator,
+ ast.Node rhs,
+ _) {
return handleSuperCompound(node, getter, setter, rhs);
}
@override
- T visitSuperFieldFieldSetIfNull(ast.Send node, FieldElement readField,
- FieldElement writtenField, ast.Node rhs, _) {
+ TypeInformation visitSuperFieldFieldSetIfNull(ast.Send node,
+ FieldElement readField, FieldElement writtenField, ast.Node rhs, _) {
return handleSuperCompound(node, readField, writtenField, rhs);
}
@override
- T visitSuperFieldSetIfNull(
+ TypeInformation visitSuperFieldSetIfNull(
ast.Send node, FieldElement field, ast.Node rhs, _) {
return handleSuperCompound(node, field, field, rhs);
}
@override
- T visitSuperFieldSetterSetIfNull(ast.Send node, FieldElement field,
- FunctionElement setter, ast.Node rhs, _) {
+ TypeInformation visitSuperFieldSetterSetIfNull(ast.Send node,
+ FieldElement field, FunctionElement setter, ast.Node rhs, _) {
return handleSuperCompound(node, field, setter, rhs);
}
@override
- T visitSuperGetterFieldSetIfNull(ast.Send node, FunctionElement getter,
- FieldElement field, ast.Node rhs, _) {
+ TypeInformation visitSuperGetterFieldSetIfNull(ast.Send node,
+ FunctionElement getter, FieldElement field, ast.Node rhs, _) {
return handleSuperCompound(node, getter, field, rhs);
}
@override
- T visitSuperGetterSetterSetIfNull(ast.Send node, FunctionElement getter,
- FunctionElement setter, ast.Node rhs, _) {
+ TypeInformation visitSuperGetterSetterSetIfNull(ast.Send node,
+ FunctionElement getter, FunctionElement setter, ast.Node rhs, _) {
return handleSuperCompound(node, getter, setter, rhs);
}
@override
- T visitSuperMethodSetIfNull(
+ TypeInformation visitSuperMethodSetIfNull(
ast.Send node, FunctionElement method, ast.Node rhs, _) {
return handleSuperCompound(node, method, null, rhs);
}
@override
- T visitSuperMethodSetterSetIfNull(ast.Send node, FunctionElement method,
- FunctionElement setter, ast.Node rhs, _) {
+ TypeInformation visitSuperMethodSetterSetIfNull(ast.Send node,
+ FunctionElement method, FunctionElement setter, ast.Node rhs, _) {
return handleSuperCompound(node, method, setter, rhs);
}
- T handleSuperCompound(
+ TypeInformation handleSuperCompound(
ast.SendSet node, Element getter, Element setter, ast.Node rhs) {
- T rhsType = visit(rhs);
+ TypeInformation rhsType = visit(rhs);
return _handleSuperCompound(node, getter, setter, rhsType);
}
@override
- T visitSuperFieldFieldPostfix(ast.SendSet node, FieldElement readField,
- FieldElement writtenField, op.IncDecOperator operator, _) {
+ TypeInformation visitSuperFieldFieldPostfix(
+ ast.SendSet node,
+ FieldElement readField,
+ FieldElement writtenField,
+ op.IncDecOperator operator,
+ _) {
return handleSuperPrefixPostfix(node, readField, writtenField);
}
@override
- T visitSuperFieldFieldPrefix(ast.SendSet node, FieldElement readField,
- FieldElement writtenField, op.IncDecOperator operator, _) {
+ TypeInformation visitSuperFieldFieldPrefix(
+ ast.SendSet node,
+ FieldElement readField,
+ FieldElement writtenField,
+ op.IncDecOperator operator,
+ _) {
return handleSuperPrefixPostfix(node, readField, writtenField);
}
@override
- T visitSuperFieldPostfix(
+ TypeInformation visitSuperFieldPostfix(
ast.SendSet node, FieldElement field, op.IncDecOperator operator, _) {
return handleSuperPrefixPostfix(node, field, field);
}
@override
- T visitSuperFieldPrefix(
+ TypeInformation visitSuperFieldPrefix(
ast.SendSet node, FieldElement field, op.IncDecOperator operator, _) {
return handleSuperPrefixPostfix(node, field, field);
}
@override
- T visitSuperFieldSetterPostfix(ast.SendSet node, FieldElement field,
- FunctionElement setter, op.IncDecOperator operator, _) {
+ TypeInformation visitSuperFieldSetterPostfix(
+ ast.SendSet node,
+ FieldElement field,
+ FunctionElement setter,
+ op.IncDecOperator operator,
+ _) {
return handleSuperPrefixPostfix(node, field, setter);
}
@override
- T visitSuperFieldSetterPrefix(ast.SendSet node, FieldElement field,
- FunctionElement setter, op.IncDecOperator operator, _) {
+ TypeInformation visitSuperFieldSetterPrefix(
+ ast.SendSet node,
+ FieldElement field,
+ FunctionElement setter,
+ op.IncDecOperator operator,
+ _) {
return handleSuperPrefixPostfix(node, field, setter);
}
@override
- T visitSuperGetterFieldPostfix(ast.SendSet node, FunctionElement getter,
- FieldElement field, op.IncDecOperator operator, _) {
+ TypeInformation visitSuperGetterFieldPostfix(
+ ast.SendSet node,
+ FunctionElement getter,
+ FieldElement field,
+ op.IncDecOperator operator,
+ _) {
return handleSuperPrefixPostfix(node, getter, field);
}
@override
- T visitSuperGetterFieldPrefix(ast.SendSet node, FunctionElement getter,
- FieldElement field, op.IncDecOperator operator, _) {
+ TypeInformation visitSuperGetterFieldPrefix(
+ ast.SendSet node,
+ FunctionElement getter,
+ FieldElement field,
+ op.IncDecOperator operator,
+ _) {
return handleSuperPrefixPostfix(node, getter, field);
}
@override
- T visitSuperGetterSetterPostfix(ast.SendSet node, FunctionElement getter,
- FunctionElement setter, op.IncDecOperator operator, _) {
+ TypeInformation visitSuperGetterSetterPostfix(
+ ast.SendSet node,
+ FunctionElement getter,
+ FunctionElement setter,
+ op.IncDecOperator operator,
+ _) {
return handleSuperPrefixPostfix(node, getter, setter);
}
@override
- T visitSuperGetterSetterPrefix(ast.SendSet node, FunctionElement getter,
- FunctionElement setter, op.IncDecOperator operator, _) {
+ TypeInformation visitSuperGetterSetterPrefix(
+ ast.SendSet node,
+ FunctionElement getter,
+ FunctionElement setter,
+ op.IncDecOperator operator,
+ _) {
return handleSuperPrefixPostfix(node, getter, setter);
}
@override
- T visitSuperMethodSetterPostfix(ast.SendSet node, FunctionElement method,
- FunctionElement setter, op.IncDecOperator operator, _) {
+ TypeInformation visitSuperMethodSetterPostfix(
+ ast.SendSet node,
+ FunctionElement method,
+ FunctionElement setter,
+ op.IncDecOperator operator,
+ _) {
return handleSuperPrefixPostfix(node, method, setter);
}
@override
- T visitSuperMethodSetterPrefix(ast.SendSet node, FunctionElement method,
- FunctionElement setter, op.IncDecOperator operator, _) {
+ TypeInformation visitSuperMethodSetterPrefix(
+ ast.SendSet node,
+ FunctionElement method,
+ FunctionElement setter,
+ op.IncDecOperator operator,
+ _) {
return handleSuperPrefixPostfix(node, method, setter);
}
@override
- T visitUnresolvedSuperPrefix(
+ TypeInformation visitUnresolvedSuperPrefix(
ast.SendSet node, Element element, op.IncDecOperator operator, _) {
return handleSuperPrefixPostfix(node, element, element);
}
@override
- T visitUnresolvedSuperPostfix(
+ TypeInformation visitUnresolvedSuperPostfix(
ast.SendSet node, Element element, op.IncDecOperator operator, _) {
return handleSuperPrefixPostfix(node, element, element);
}
@override
- T visitUnresolvedSuperGetterPrefix(ast.SendSet node, Element getter,
- SetterElement setter, op.IncDecOperator operator, _) {
+ TypeInformation visitUnresolvedSuperGetterPrefix(ast.SendSet node,
+ Element getter, SetterElement setter, op.IncDecOperator operator, _) {
return handleSuperPrefixPostfix(node, getter, setter);
}
@override
- T visitUnresolvedSuperGetterPostfix(ast.SendSet node, Element getter,
- SetterElement setter, op.IncDecOperator operator, _) {
+ TypeInformation visitUnresolvedSuperGetterPostfix(ast.SendSet node,
+ Element getter, SetterElement setter, op.IncDecOperator operator, _) {
return handleSuperPrefixPostfix(node, getter, setter);
}
@override
- T visitUnresolvedSuperSetterPrefix(ast.SendSet node, GetterElement getter,
- Element setter, op.IncDecOperator operator, _) {
+ TypeInformation visitUnresolvedSuperSetterPrefix(ast.SendSet node,
+ GetterElement getter, Element setter, op.IncDecOperator operator, _) {
return handleSuperPrefixPostfix(node, getter, setter);
}
@override
- T visitUnresolvedSuperSetterPostfix(ast.SendSet node, GetterElement getter,
- Element setter, op.IncDecOperator operator, _) {
+ TypeInformation visitUnresolvedSuperSetterPostfix(ast.SendSet node,
+ GetterElement getter, Element setter, op.IncDecOperator operator, _) {
return handleSuperPrefixPostfix(node, getter, setter);
}
- T handleSuperPrefixPostfix(ast.SendSet node, Element getter, Element setter) {
+ TypeInformation handleSuperPrefixPostfix(
+ ast.SendSet node, Element getter, Element setter) {
return _handleSuperCompound(node, getter, setter, types.uint31Type);
}
- T _handleSuperCompound(
- ast.SendSet node, Element getter, Element setter, T rhsType) {
+ TypeInformation _handleSuperCompound(ast.SendSet node, Element getter,
+ Element setter, TypeInformation rhsType) {
Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
TypeMask getterMask = inTreeData.typeOfGetter(node);
Selector setterSelector = elements.getSelector(node);
TypeMask setterMask = inTreeData.typeOfSend(node);
- T getterType =
+ TypeInformation getterType =
handleSuperSend(node, getterSelector, getterMask, getter, null);
- T returnType;
+ TypeInformation returnType;
if (node.isIfNullAssignment) {
returnType = types.allocateDiamondPhi(getterType, rhsType);
} else {
@@ -1292,65 +1907,66 @@ class SimpleTypeInferrerVisitor<T>
elements.getOperatorSelectorInComplexSendSet(node);
TypeMask operatorMask = inTreeData.typeOfOperator(node);
returnType = handleDynamicSend(node, operatorSelector, operatorMask,
- getterType, new ArgumentsTypes<T>([rhsType], null));
+ getterType, new ArgumentsTypes([rhsType], null));
}
handleSuperSend(node, setterSelector, setterMask, setter,
- new ArgumentsTypes<T>([returnType], null));
+ new ArgumentsTypes([returnType], null));
return node.isPostfix ? getterType : returnType;
}
/// Handle index set, like `foo[0] = 42`.
- T handleIndexSet(ast.SendSet node, T receiverType, T indexType, T rhsType) {
+ TypeInformation handleIndexSet(ast.SendSet node, TypeInformation receiverType,
+ TypeInformation indexType, TypeInformation rhsType) {
Selector setterSelector = elements.getSelector(node);
TypeMask setterMask = inTreeData.typeOfSend(node);
handleDynamicSend(node, setterSelector, setterMask, receiverType,
- new ArgumentsTypes<T>([indexType, rhsType], null));
+ new ArgumentsTypes([indexType, rhsType], null));
return rhsType;
}
@override
- T visitIndexSet(
+ TypeInformation visitIndexSet(
ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) {
- T receiverType = visit(receiver);
- T indexType = visit(index);
- T rhsType = visit(rhs);
+ TypeInformation receiverType = visit(receiver);
+ TypeInformation indexType = visit(index);
+ TypeInformation rhsType = visit(rhs);
return handleIndexSet(node, receiverType, indexType, rhsType);
}
/// Handle super index set, like `super[42] = true`.
- T handleSuperIndexSet(
+ TypeInformation handleSuperIndexSet(
ast.SendSet node, Element element, ast.Node index, ast.Node rhs) {
- T indexType = visit(index);
- T rhsType = visit(rhs);
+ TypeInformation indexType = visit(index);
+ TypeInformation rhsType = visit(rhs);
Selector setterSelector = elements.getSelector(node);
TypeMask setterMask = inTreeData.typeOfSend(node);
handleStaticSend(node, setterSelector, setterMask, element,
- new ArgumentsTypes<T>([indexType, rhsType], null));
+ new ArgumentsTypes([indexType, rhsType], null));
return rhsType;
}
@override
- T visitSuperIndexSet(ast.SendSet node, FunctionElement function,
+ TypeInformation visitSuperIndexSet(ast.SendSet node, FunctionElement function,
ast.Node index, ast.Node rhs, _) {
return handleSuperIndexSet(node, function, index, rhs);
}
@override
- T visitUnresolvedSuperIndexSet(
+ TypeInformation visitUnresolvedSuperIndexSet(
ast.SendSet node, Element element, ast.Node index, ast.Node rhs, _) {
return handleSuperIndexSet(node, element, index, rhs);
}
- T handlePlainAssignment(
+ TypeInformation handlePlainAssignment(
ast.Node node,
Element element,
Selector setterSelector,
TypeMask setterMask,
- T receiverType,
- T rhsType,
+ TypeInformation receiverType,
+ TypeInformation rhsType,
ast.Node rhs) {
- ArgumentsTypes arguments = new ArgumentsTypes<T>([rhsType], null);
+ ArgumentsTypes arguments = new ArgumentsTypes([rhsType], null);
if (Elements.isMalformed(element)) {
// Code will always throw.
} else if (Elements.isStaticOrTopLevelField(element)) {
@@ -1396,7 +2012,7 @@ class SimpleTypeInferrerVisitor<T>
}
/// Handle a super access or invocation that results in a `noSuchMethod` call.
- T handleErroneousSuperSend(ast.Send node) {
+ TypeInformation handleErroneousSuperSend(ast.Send node) {
ArgumentsTypes arguments =
node.isPropertyAccess ? null : analyzeArguments(node.arguments);
Selector selector = elements.getSelector(node);
@@ -1408,8 +2024,8 @@ class SimpleTypeInferrerVisitor<T>
return handleSuperNoSuchMethod(node, selector, mask, arguments);
}
- T handleSuperNoSuchMethod(ast.Send node, Selector selector, TypeMask mask,
- ArgumentsTypes arguments) {
+ TypeInformation handleSuperNoSuchMethod(ast.Send node, Selector selector,
+ TypeMask mask, ArgumentsTypes arguments) {
// Ensure we create a node, to make explicit the call to the
// `noSuchMethod` handler.
ClassElement cls = outermostElement.enclosingClass.declaration;
@@ -1423,7 +2039,7 @@ class SimpleTypeInferrerVisitor<T>
/// Handle a .call invocation on the values retrieved from the super
/// [element]. For instance `super.foo(bar)` where `foo` is a field or getter.
- T handleSuperClosureCall(
+ TypeInformation handleSuperClosureCall(
ast.Send node, Element element, ast.NodeList arguments) {
ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes);
Selector selector = elements.getSelector(node);
@@ -1443,7 +2059,7 @@ class SimpleTypeInferrerVisitor<T>
}
/// Handle an invocation of super [method].
- T handleSuperMethodInvoke(
+ TypeInformation handleSuperMethodInvoke(
ast.Send node, MethodElement method, ArgumentsTypes arguments) {
// TODO(herhut): We could do better here if we knew what we
// are calling does not expose this.
@@ -1454,7 +2070,7 @@ class SimpleTypeInferrerVisitor<T>
}
/// Handle access to a super field or getter [element].
- T handleSuperGet(ast.Send node, Element element) {
+ TypeInformation handleSuperGet(ast.Send node, Element element) {
// TODO(herhut): We could do better here if we knew what we
// are calling does not expose this.
isThisExposed = true;
@@ -1464,131 +2080,137 @@ class SimpleTypeInferrerVisitor<T>
}
/// Handle update to a super field or setter [element].
- T handleSuperSet(ast.Send node, Element element, ast.Node rhs) {
- T rhsType = visit(rhs);
+ TypeInformation handleSuperSet(ast.Send node, Element element, ast.Node rhs) {
+ TypeInformation rhsType = visit(rhs);
// TODO(herhut): We could do better here if we knew what we
// are calling does not expose this.
isThisExposed = true;
Selector selector = elements.getSelector(node);
TypeMask mask = inTreeData.typeOfSend(node);
handleStaticSend(
- node, selector, mask, element, new ArgumentsTypes<T>([rhsType], null));
+ node, selector, mask, element, new ArgumentsTypes([rhsType], null));
return rhsType;
}
@override
- T visitSuperFieldSet(ast.Send node, FieldElement method, ast.Node rhs, _) {
+ TypeInformation visitSuperFieldSet(
+ ast.Send node, FieldElement method, ast.Node rhs, _) {
return handleSuperSet(node, method, rhs);
}
@override
- T visitSuperSetterSet(ast.Send node, SetterElement field, ast.Node rhs, _) {
+ TypeInformation visitSuperSetterSet(
+ ast.Send node, SetterElement field, ast.Node rhs, _) {
return handleSuperSet(node, field, rhs);
}
@override
- T visitUnresolvedSuperIndex(
+ TypeInformation visitUnresolvedSuperIndex(
ast.Send node, Element element, ast.Node index, _) {
return handleErroneousSuperSend(node);
}
@override
- T visitUnresolvedSuperUnary(
+ TypeInformation visitUnresolvedSuperUnary(
ast.Send node, op.UnaryOperator operator, Element element, _) {
return handleErroneousSuperSend(node);
}
@override
- T visitUnresolvedSuperBinary(ast.Send node, Element element,
+ TypeInformation visitUnresolvedSuperBinary(ast.Send node, Element element,
op.BinaryOperator operator, ast.Node argument, _) {
return handleErroneousSuperSend(node);
}
@override
- T visitUnresolvedSuperGet(ast.Send node, Element element, _) {
+ TypeInformation visitUnresolvedSuperGet(ast.Send node, Element element, _) {
return handleErroneousSuperSend(node);
}
@override
- T visitSuperSetterGet(ast.Send node, MethodElement setter, _) {
+ TypeInformation visitSuperSetterGet(ast.Send node, MethodElement setter, _) {
return handleErroneousSuperSend(node);
}
@override
- T visitSuperGetterSet(ast.Send node, MethodElement getter, ast.Node rhs, _) {
+ TypeInformation visitSuperGetterSet(
+ ast.Send node, MethodElement getter, ast.Node rhs, _) {
return handleErroneousSuperSend(node);
}
@override
- T visitSuperMethodSet(ast.Send node, MethodElement method, ast.Node rhs, _) {
+ TypeInformation visitSuperMethodSet(
+ ast.Send node, MethodElement method, ast.Node rhs, _) {
return handleErroneousSuperSend(node);
}
@override
- T visitFinalSuperFieldSet(
+ TypeInformation visitFinalSuperFieldSet(
ast.Send node, FieldElement method, ast.Node rhs, _) {
return handleErroneousSuperSend(node);
}
@override
- T visitUnresolvedSuperSet(ast.Send node, Element element, ast.Node rhs, _) {
+ TypeInformation visitUnresolvedSuperSet(
+ ast.Send node, Element element, ast.Node rhs, _) {
return handleErroneousSuperSend(node);
}
@override
- T visitUnresolvedSuperInvoke(
+ TypeInformation visitUnresolvedSuperInvoke(
ast.Send node, Element element, ast.Node argument, Selector selector, _) {
return handleErroneousSuperSend(node);
}
@override
- T visitSuperFieldGet(ast.Send node, FieldElement field, _) {
+ TypeInformation visitSuperFieldGet(ast.Send node, FieldElement field, _) {
return handleSuperGet(node, field);
}
@override
- T visitSuperGetterGet(ast.Send node, MethodElement method, _) {
+ TypeInformation visitSuperGetterGet(ast.Send node, MethodElement method, _) {
return handleSuperGet(node, method);
}
@override
- T visitSuperMethodGet(ast.Send node, MethodElement method, _) {
+ TypeInformation visitSuperMethodGet(ast.Send node, MethodElement method, _) {
return handleSuperGet(node, method);
}
@override
- T visitSuperFieldInvoke(ast.Send node, FieldElement field,
+ TypeInformation visitSuperFieldInvoke(ast.Send node, FieldElement field,
ast.NodeList arguments, CallStructure callStructure, _) {
return handleSuperClosureCall(node, field, arguments);
}
@override
- T visitSuperGetterInvoke(ast.Send node, MethodElement getter,
+ TypeInformation visitSuperGetterInvoke(ast.Send node, MethodElement getter,
ast.NodeList arguments, CallStructure callStructure, _) {
return handleSuperClosureCall(node, getter, arguments);
}
@override
- T visitSuperMethodInvoke(ast.Send node, MethodElement method,
+ TypeInformation visitSuperMethodInvoke(ast.Send node, MethodElement method,
ast.NodeList arguments, CallStructure callStructure, _) {
return handleSuperMethodInvoke(
node, method, analyzeArguments(arguments.nodes));
}
@override
- T visitSuperSetterInvoke(ast.Send node, FunctionElement setter,
+ TypeInformation visitSuperSetterInvoke(ast.Send node, FunctionElement setter,
ast.NodeList arguments, CallStructure callStructure, _) {
return handleErroneousSuperSend(node);
}
@override
- T visitSuperIndex(ast.Send node, MethodElement method, ast.Node index, _) {
+ TypeInformation visitSuperIndex(
+ ast.Send node, MethodElement method, ast.Node index, _) {
return handleSuperMethodInvoke(
node, method, analyzeArguments(node.arguments));
}
@override
- T visitSuperEquals(
+ TypeInformation visitSuperEquals(
ast.Send node, MethodElement method, ast.Node argument, _) {
// TODO(johnniwinther): Special case ==.
return handleSuperMethodInvoke(
@@ -1596,7 +2218,7 @@ class SimpleTypeInferrerVisitor<T>
}
@override
- T visitSuperNotEquals(
+ TypeInformation visitSuperNotEquals(
ast.Send node, MethodElement method, ast.Node argument, _) {
// TODO(johnniwinther): Special case !=.
return handleSuperMethodInvoke(
@@ -1604,22 +2226,26 @@ class SimpleTypeInferrerVisitor<T>
}
@override
- T visitSuperBinary(ast.Send node, MethodElement method,
+ TypeInformation visitSuperBinary(ast.Send node, MethodElement method,
op.BinaryOperator operator, ast.Node argument, _) {
return handleSuperMethodInvoke(
node, method, analyzeArguments(node.arguments));
}
@override
- T visitSuperUnary(
+ TypeInformation visitSuperUnary(
ast.Send node, op.UnaryOperator operator, MethodElement method, _) {
return handleSuperMethodInvoke(
node, method, analyzeArguments(node.arguments));
}
@override
- T visitSuperMethodIncompatibleInvoke(ast.Send node, MethodElement method,
- ast.NodeList arguments, CallStructure callStructure, _) {
+ TypeInformation visitSuperMethodIncompatibleInvoke(
+ ast.Send node,
+ MethodElement method,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
return handleErroneousSuperSend(node);
}
@@ -1645,23 +2271,24 @@ class SimpleTypeInferrerVisitor<T>
return null;
}
- T visitAwait(ast.Await node) {
- T futureType = node.expression.accept(this);
+ TypeInformation visitAwait(ast.Await node) {
+ TypeInformation futureType = node.expression.accept(this);
return inferrer.registerAwait(node, futureType);
}
@override
- T handleTypeLiteralInvoke(ast.NodeList arguments) {
+ TypeInformation handleTypeLiteralInvoke(ast.NodeList arguments) {
// This is reached when users forget to put a `new` in front of a type
// literal. The emitter will generate an actual call (even though it is
// likely invalid), and for that it needs to have the arguments processed
// as well.
analyzeArguments(arguments.nodes);
- return super.handleTypeLiteralInvoke(arguments);
+ return types.dynamicType;
}
/// Handle constructor invocation of [constructor].
- T handleConstructorSend(ast.Send node, ConstructorElement constructor) {
+ TypeInformation handleConstructorSend(
+ ast.Send node, ConstructorElement constructor) {
ConstructorElement target = constructor.implementation;
ArgumentsTypes arguments = analyzeArguments(node.arguments);
if (visitingInitializers) {
@@ -1687,13 +2314,14 @@ class SimpleTypeInferrerVisitor<T>
TypeMask mask = inTreeData.typeOfSend(node);
// In erroneous code the number of arguments in the selector might not
// match the function element.
- // TODO(polux): return nonNullEmpty and check it doesn't break anything
+ // TODO(polux): return nonNullEmpty and check it doesn'TypeInformation break anything
if (target.isMalformed ||
!callStructure.signatureApplies(target.functionSignature)) {
return types.dynamicType;
}
- T returnType = handleStaticSend(node, selector, mask, target, arguments);
+ TypeInformation returnType =
+ handleStaticSend(node, selector, mask, target, arguments);
if (Elements.isGrowableListConstructorCall(
constructor, node, closedWorld.commonElements)) {
return inferrer.concreteTypes.putIfAbsent(
@@ -1705,7 +2333,7 @@ class SimpleTypeInferrerVisitor<T>
Elements.isFilledListConstructorCall(
constructor, node, closedWorld.commonElements)) {
int length = findLength(node);
- T elementType = Elements.isFixedListConstructorCall(
+ TypeInformation elementType = Elements.isFixedListConstructorCall(
constructor, node, closedWorld.commonElements)
? types.nullType
: arguments.positional[1];
@@ -1717,7 +2345,7 @@ class SimpleTypeInferrerVisitor<T>
} else if (Elements.isConstructorOfTypedArraySubclass(
constructor, closedWorld)) {
int length = findLength(node);
- T elementType = inferrer
+ TypeInformation elementType = inferrer
.returnTypeOfElement(target.enclosingClass.lookupMember('[]'));
return inferrer.concreteTypes.putIfAbsent(
node,
@@ -1729,13 +2357,13 @@ class SimpleTypeInferrerVisitor<T>
}
@override
- T bulkHandleNew(ast.NewExpression node, _) {
+ TypeInformation bulkHandleNew(ast.NewExpression node, _) {
Element element = elements[node.send];
return handleConstructorSend(node.send, element);
}
@override
- T errorNonConstantConstructorInvoke(
+ TypeInformation errorNonConstantConstructorInvoke(
ast.NewExpression node,
Element element,
ResolutionDartType type,
@@ -1746,7 +2374,8 @@ class SimpleTypeInferrerVisitor<T>
}
/// Handle invocation of a top level or static field or getter [element].
- T handleStaticFieldOrGetterInvoke(ast.Send node, Element element) {
+ TypeInformation handleStaticFieldOrGetterInvoke(
+ ast.Send node, Element element) {
ArgumentsTypes arguments = analyzeArguments(node.arguments);
Selector selector = elements.getSelector(node);
TypeMask mask = inTreeData.typeOfSend(node);
@@ -1763,7 +2392,8 @@ class SimpleTypeInferrerVisitor<T>
}
/// Handle invocation of a top level or static [function].
- T handleStaticFunctionInvoke(ast.Send node, MethodElement function) {
+ TypeInformation handleStaticFunctionInvoke(
+ ast.Send node, MethodElement function) {
if (compiler.backend.isForeign(function)) {
return handleForeignSend(node, function);
}
@@ -1775,49 +2405,61 @@ class SimpleTypeInferrerVisitor<T>
/// Handle an static invocation of an unresolved target or with incompatible
/// arguments to a resolved target.
- T handleInvalidStaticInvoke(ast.Send node) {
+ TypeInformation handleInvalidStaticInvoke(ast.Send node) {
analyzeArguments(node.arguments);
return types.dynamicType;
}
@override
- T visitStaticFieldInvoke(ast.Send node, FieldElement field,
+ TypeInformation visitStaticFieldInvoke(ast.Send node, FieldElement field,
ast.NodeList arguments, CallStructure callStructure, _) {
return handleStaticFieldOrGetterInvoke(node, field);
}
@override
- T visitStaticFunctionInvoke(ast.Send node, MethodElement function,
- ast.NodeList arguments, CallStructure callStructure, _) {
+ TypeInformation visitStaticFunctionInvoke(
+ ast.Send node,
+ MethodElement function,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
return handleStaticFunctionInvoke(node, function);
}
@override
- T visitStaticFunctionIncompatibleInvoke(ast.Send node, MethodElement function,
- ast.NodeList arguments, CallStructure callStructure, _) {
+ TypeInformation visitStaticFunctionIncompatibleInvoke(
+ ast.Send node,
+ MethodElement function,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
return handleInvalidStaticInvoke(node);
}
@override
- T visitStaticGetterInvoke(ast.Send node, FunctionElement getter,
+ TypeInformation visitStaticGetterInvoke(ast.Send node, FunctionElement getter,
ast.NodeList arguments, CallStructure callStructure, _) {
return handleStaticFieldOrGetterInvoke(node, getter);
}
@override
- T visitTopLevelFieldInvoke(ast.Send node, FieldElement field,
+ TypeInformation visitTopLevelFieldInvoke(ast.Send node, FieldElement field,
ast.NodeList arguments, CallStructure callStructure, _) {
return handleStaticFieldOrGetterInvoke(node, field);
}
@override
- T visitTopLevelFunctionInvoke(ast.Send node, MethodElement function,
- ast.NodeList arguments, CallStructure callStructure, _) {
+ TypeInformation visitTopLevelFunctionInvoke(
+ ast.Send node,
+ MethodElement function,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
return handleStaticFunctionInvoke(node, function);
}
@override
- T visitTopLevelFunctionIncompatibleInvoke(
+ TypeInformation visitTopLevelFunctionIncompatibleInvoke(
ast.Send node,
MethodElement function,
ast.NodeList arguments,
@@ -1827,30 +2469,34 @@ class SimpleTypeInferrerVisitor<T>
}
@override
- T visitTopLevelGetterInvoke(ast.Send node, FunctionElement getter,
- ast.NodeList arguments, CallStructure callStructure, _) {
+ TypeInformation visitTopLevelGetterInvoke(
+ ast.Send node,
+ FunctionElement getter,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
return handleStaticFieldOrGetterInvoke(node, getter);
}
@override
- T visitStaticSetterInvoke(ast.Send node, MethodElement setter,
+ TypeInformation visitStaticSetterInvoke(ast.Send node, MethodElement setter,
ast.NodeList arguments, CallStructure callStructure, _) {
return handleInvalidStaticInvoke(node);
}
@override
- T visitTopLevelSetterInvoke(ast.Send node, MethodElement setter,
+ TypeInformation visitTopLevelSetterInvoke(ast.Send node, MethodElement setter,
ast.NodeList arguments, CallStructure callStructure, _) {
return handleInvalidStaticInvoke(node);
}
@override
- T visitUnresolvedInvoke(ast.Send node, Element element,
+ TypeInformation visitUnresolvedInvoke(ast.Send node, Element element,
ast.NodeList arguments, Selector selector, _) {
return handleInvalidStaticInvoke(node);
}
- T handleForeignSend(ast.Send node, Element element) {
+ TypeInformation handleForeignSend(ast.Send node, Element element) {
ArgumentsTypes arguments = analyzeArguments(node.arguments);
Selector selector = elements.getSelector(node);
TypeMask mask = inTreeData.typeOfSend(node);
@@ -1871,13 +2517,13 @@ class SimpleTypeInferrerVisitor<T>
}
ArgumentsTypes analyzeArguments(Link<ast.Node> arguments) {
- List<T> positional = [];
- Map<String, T> named;
+ List positional = [];
+ Map<String, TypeInformation> named;
for (var argument in arguments) {
ast.NamedArgument namedArgument = argument.asNamedArgument();
if (namedArgument != null) {
argument = namedArgument.expression;
- if (named == null) named = new Map<String, T>();
+ if (named == null) named = new Map<String, TypeInformation>();
named[namedArgument.name.source] = argument.accept(this);
} else {
positional.add(argument.accept(this));
@@ -1886,114 +2532,124 @@ class SimpleTypeInferrerVisitor<T>
// are calling does not expose this.
isThisExposed = isThisExposed || argument.isThis();
}
- return new ArgumentsTypes<T>(positional, named);
+ return new ArgumentsTypes(positional, named);
}
/// Read a local variable, function or parameter.
- T handleLocalGet(ast.Send node, LocalElement local) {
+ TypeInformation handleLocalGet(ast.Send node, LocalElement local) {
assert(locals.use(local) != null);
return locals.use(local);
}
/// Read a static or top level field.
- T handleStaticFieldGet(ast.Send node, FieldElement field) {
+ TypeInformation handleStaticFieldGet(ast.Send node, FieldElement field) {
Selector selector = elements.getSelector(node);
TypeMask mask = inTreeData.typeOfSend(node);
return handleStaticSend(node, selector, mask, field, null);
}
/// Invoke a static or top level getter.
- T handleStaticGetterGet(ast.Send node, MethodElement getter) {
+ TypeInformation handleStaticGetterGet(ast.Send node, MethodElement getter) {
Selector selector = elements.getSelector(node);
TypeMask mask = inTreeData.typeOfSend(node);
return handleStaticSend(node, selector, mask, getter, null);
}
/// Closurize a static or top level function.
- T handleStaticFunctionGet(ast.Send node, MethodElement function) {
+ TypeInformation handleStaticFunctionGet(
+ ast.Send node, MethodElement function) {
Selector selector = elements.getSelector(node);
TypeMask mask = inTreeData.typeOfSend(node);
return handleStaticSend(node, selector, mask, function, null);
}
@override
- T visitDynamicPropertyGet(ast.Send node, ast.Node receiver, Name name, _) {
+ TypeInformation visitDynamicPropertyGet(
+ ast.Send node, ast.Node receiver, Name name, _) {
return handleDynamicGet(node);
}
@override
- T visitIfNotNullDynamicPropertyGet(
+ TypeInformation visitIfNotNullDynamicPropertyGet(
ast.Send node, ast.Node receiver, Name name, _) {
return handleDynamicGet(node);
}
@override
- T visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) {
+ TypeInformation visitLocalVariableGet(
+ ast.Send node, LocalVariableElement variable, _) {
return handleLocalGet(node, variable);
}
@override
- T visitParameterGet(ast.Send node, ParameterElement parameter, _) {
+ TypeInformation visitParameterGet(
+ ast.Send node, ParameterElement parameter, _) {
return handleLocalGet(node, parameter);
}
@override
- T visitLocalFunctionGet(ast.Send node, LocalFunctionElement function, _) {
+ TypeInformation visitLocalFunctionGet(
+ ast.Send node, LocalFunctionElement function, _) {
return handleLocalGet(node, function);
}
@override
- T visitStaticFieldGet(ast.Send node, FieldElement field, _) {
+ TypeInformation visitStaticFieldGet(ast.Send node, FieldElement field, _) {
return handleStaticFieldGet(node, field);
}
@override
- T visitStaticFunctionGet(ast.Send node, MethodElement function, _) {
+ TypeInformation visitStaticFunctionGet(
+ ast.Send node, MethodElement function, _) {
return handleStaticFunctionGet(node, function);
}
@override
- T visitStaticGetterGet(ast.Send node, FunctionElement getter, _) {
+ TypeInformation visitStaticGetterGet(
+ ast.Send node, FunctionElement getter, _) {
return handleStaticGetterGet(node, getter);
}
@override
- T visitThisPropertyGet(ast.Send node, Name name, _) {
+ TypeInformation visitThisPropertyGet(ast.Send node, Name name, _) {
return handleDynamicGet(node);
}
@override
- T visitTopLevelFieldGet(ast.Send node, FieldElement field, _) {
+ TypeInformation visitTopLevelFieldGet(ast.Send node, FieldElement field, _) {
return handleStaticFieldGet(node, field);
}
@override
- T visitTopLevelFunctionGet(ast.Send node, MethodElement function, _) {
+ TypeInformation visitTopLevelFunctionGet(
+ ast.Send node, MethodElement function, _) {
return handleStaticFunctionGet(node, function);
}
@override
- T visitTopLevelGetterGet(ast.Send node, FunctionElement getter, _) {
+ TypeInformation visitTopLevelGetterGet(
+ ast.Send node, FunctionElement getter, _) {
return handleStaticGetterGet(node, getter);
}
@override
- T visitStaticSetterGet(ast.Send node, MethodElement setter, _) {
+ TypeInformation visitStaticSetterGet(ast.Send node, MethodElement setter, _) {
return types.dynamicType;
}
@override
- T visitTopLevelSetterGet(ast.Send node, MethodElement setter, _) {
+ TypeInformation visitTopLevelSetterGet(
+ ast.Send node, MethodElement setter, _) {
return types.dynamicType;
}
@override
- T visitUnresolvedGet(ast.Send node, Element element, _) {
+ TypeInformation visitUnresolvedGet(ast.Send node, Element element, _) {
return types.dynamicType;
}
/// Handle .call invocation on [closure].
- T handleCallInvoke(ast.Send node, T closure) {
+ TypeInformation handleCallInvoke(ast.Send node, TypeInformation closure) {
ArgumentsTypes arguments = analyzeArguments(node.arguments);
Selector selector = elements.getSelector(node);
TypeMask mask = inTreeData.typeOfSend(node);
@@ -2002,32 +2658,44 @@ class SimpleTypeInferrerVisitor<T>
}
@override
- T visitExpressionInvoke(ast.Send node, ast.Node expression,
+ TypeInformation visitExpressionInvoke(ast.Send node, ast.Node expression,
ast.NodeList arguments, CallStructure callStructure, _) {
return handleCallInvoke(node, expression.accept(this));
}
@override
- T visitThisInvoke(
+ TypeInformation visitThisInvoke(
ast.Send node, ast.NodeList arguments, CallStructure callStructure, _) {
return handleCallInvoke(node, thisType);
}
@override
- T visitParameterInvoke(ast.Send node, ParameterElement parameter,
- ast.NodeList arguments, CallStructure callStructure, _) {
+ TypeInformation visitParameterInvoke(
+ ast.Send node,
+ ParameterElement parameter,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
return handleCallInvoke(node, locals.use(parameter));
}
@override
- T visitLocalVariableInvoke(ast.Send node, LocalVariableElement variable,
- ast.NodeList arguments, CallStructure callStructure, _) {
+ TypeInformation visitLocalVariableInvoke(
+ ast.Send node,
+ LocalVariableElement variable,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
return handleCallInvoke(node, locals.use(variable));
}
@override
- T visitLocalFunctionInvoke(ast.Send node, LocalFunctionElement function,
- ast.NodeList arguments, CallStructure callStructure, _) {
+ TypeInformation visitLocalFunctionInvoke(
+ ast.Send node,
+ LocalFunctionElement function,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
ArgumentsTypes argumentTypes = analyzeArguments(node.arguments);
Selector selector = elements.getSelector(node);
TypeMask mask = inTreeData.typeOfSend(node);
@@ -2039,7 +2707,7 @@ class SimpleTypeInferrerVisitor<T>
}
@override
- T visitLocalFunctionIncompatibleInvoke(
+ TypeInformation visitLocalFunctionIncompatibleInvoke(
ast.Send node,
LocalFunctionElement function,
ast.NodeList arguments,
@@ -2049,8 +2717,8 @@ class SimpleTypeInferrerVisitor<T>
return types.dynamicType;
}
- T handleStaticSend(ast.Node node, Selector selector, TypeMask mask,
- Element element, ArgumentsTypes arguments) {
+ TypeInformation handleStaticSend(ast.Node node, Selector selector,
+ TypeMask mask, Element element, ArgumentsTypes arguments) {
assert(!element.isFactoryConstructor ||
!(element as ConstructorElement).isRedirectingFactory);
// Erroneous elements may be unresolved, for example missing getters.
@@ -2062,8 +2730,8 @@ class SimpleTypeInferrerVisitor<T>
outermostElement, element, arguments, sideEffects, inLoop);
}
- T handleDynamicSend(ast.Node node, Selector selector, TypeMask mask,
- T receiverType, ArgumentsTypes arguments) {
+ TypeInformation handleDynamicSend(ast.Node node, Selector selector,
+ TypeMask mask, TypeInformation receiverType, ArgumentsTypes arguments) {
assert(receiverType != null);
if (types.selectorNeedsUpdate(receiverType, mask)) {
mask = receiverType == types.dynamicType
@@ -2081,7 +2749,7 @@ class SimpleTypeInferrerVisitor<T>
if (receiver != null) {
Element element = elements[receiver];
if (Elements.isLocal(element) && !capturedVariables.contains(element)) {
- T refinedType = types.refineReceiver(
+ TypeInformation refinedType = types.refineReceiver(
selector, mask, receiverType, send.isConditional);
locals.update(element, refinedType, node);
}
@@ -2092,17 +2760,17 @@ class SimpleTypeInferrerVisitor<T>
outermostElement, arguments, sideEffects, inLoop);
}
- T handleDynamicInvoke(ast.Send node) {
+ TypeInformation handleDynamicInvoke(ast.Send node) {
return _handleDynamicSend(node);
}
- T handleDynamicGet(ast.Send node) {
+ TypeInformation handleDynamicGet(ast.Send node) {
return _handleDynamicSend(node);
}
- T _handleDynamicSend(ast.Send node) {
+ TypeInformation _handleDynamicSend(ast.Send node) {
Element element = elements[node];
- T receiverType;
+ TypeInformation receiverType;
bool isCallOnThis = false;
if (node.receiver == null) {
if (treatAsInstanceMember(element)) {
@@ -2135,11 +2803,12 @@ class SimpleTypeInferrerVisitor<T>
return handleDynamicSend(node, selector, mask, receiverType, arguments);
}
- void recordReturnType(T type) {
+ void recordReturnType(TypeInformation type) {
returnType = inferrer.addReturnTypeFor(analyzedElement, returnType, type);
}
- T synthesizeForwardingCall(Spannable node, FunctionElement element) {
+ TypeInformation synthesizeForwardingCall(
+ Spannable node, FunctionElement element) {
element = element.implementation;
FunctionElement function = analyzedElement;
FunctionSignature signature = function.functionSignature;
@@ -2148,15 +2817,15 @@ class SimpleTypeInferrerVisitor<T>
return types.nonNullEmpty();
}
- List<T> unnamed = <T>[];
+ List<TypeInformation> unnamed = <TypeInformation>[];
signature.forEachRequiredParameter((ParameterElement element) {
assert(locals.use(element) != null);
unnamed.add(locals.use(element));
});
- Map<String, T> named;
+ Map<String, TypeInformation> named;
if (signature.optionalParametersAreNamed) {
- named = new Map<String, T>();
+ named = new Map<String, TypeInformation>();
signature.forEachOptionalParameter((ParameterElement element) {
named[element.name] = locals.use(element);
});
@@ -2166,28 +2835,29 @@ class SimpleTypeInferrerVisitor<T>
});
}
- ArgumentsTypes arguments = new ArgumentsTypes<T>(unnamed, named);
+ ArgumentsTypes arguments = new ArgumentsTypes(unnamed, named);
return inferrer.registerCalledElement(node, null, null, outermostElement,
element, arguments, sideEffects, inLoop);
}
- T visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
+ TypeInformation visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
Element element = elements.getRedirectingTargetConstructor(node);
if (Elements.isMalformed(element)) {
recordReturnType(types.dynamicType);
} else {
- // We don't create a selector for redirecting factories, and
+ // We don'TypeInformation create a selector for redirecting factories, and
// the send is just a property access. Therefore we must
// manually create the [ArgumentsTypes] of the call, and
// manually register [analyzedElement] as a caller of [element].
- T mask = synthesizeForwardingCall(node.constructorReference, element);
+ TypeInformation mask =
+ synthesizeForwardingCall(node.constructorReference, element);
recordReturnType(mask);
}
locals.seenReturnOrThrow = true;
return null;
}
- T visitReturn(ast.Return node) {
+ TypeInformation visitReturn(ast.Return node) {
ast.Node expression = node.expression;
recordReturnType(
expression == null ? types.nullType : expression.accept(this));
@@ -2195,12 +2865,17 @@ class SimpleTypeInferrerVisitor<T>
return null;
}
- T handleForInLoop(ast.ForIn node, T iteratorType, Selector currentSelector,
- TypeMask currentMask, Selector moveNextSelector, TypeMask moveNextMask) {
+ TypeInformation handleForInLoop(
+ ast.ForIn node,
+ TypeInformation iteratorType,
+ Selector currentSelector,
+ TypeMask currentMask,
+ Selector moveNextSelector,
+ TypeMask moveNextMask) {
handleDynamicSend(node, moveNextSelector, moveNextMask, iteratorType,
- new ArgumentsTypes<T>.empty());
- T currentType = handleDynamicSend(node, currentSelector, currentMask,
- iteratorType, new ArgumentsTypes<T>.empty());
+ new ArgumentsTypes.empty());
+ TypeInformation currentType = handleDynamicSend(node, currentSelector,
+ currentMask, iteratorType, new ArgumentsTypes.empty());
if (node.expression.isThis()) {
// Any reasonable implementation of an iterator would expose
@@ -2213,7 +2888,7 @@ class SimpleTypeInferrerVisitor<T>
Selector selector = elements.getSelector(identifier);
TypeMask mask = inTreeData.typeOfSend(identifier);
- T receiverType;
+ TypeInformation receiverType;
if (element != null && element.isInstanceMember) {
receiverType = thisType;
} else {
@@ -2227,8 +2902,8 @@ class SimpleTypeInferrerVisitor<T>
});
}
- T visitAsyncForIn(ast.AsyncForIn node) {
- T expressionType = visit(node.expression);
+ TypeInformation visitAsyncForIn(ast.AsyncForIn node) {
+ TypeInformation expressionType = visit(node.expression);
Selector currentSelector = Selectors.current;
TypeMask currentMask = inTreeData.typeOfIteratorCurrent(node);
@@ -2239,15 +2914,15 @@ class SimpleTypeInferrerVisitor<T>
Element ctor = backend.helpers.streamIteratorConstructor;
/// Synthesize a call to the [StreamIterator] constructor.
- T iteratorType = handleStaticSend(
- node, null, null, ctor, new ArgumentsTypes<T>([expressionType], null));
+ TypeInformation iteratorType = handleStaticSend(
+ node, null, null, ctor, new ArgumentsTypes([expressionType], null));
return handleForInLoop(node, iteratorType, currentSelector, currentMask,
moveNextSelector, moveNextMask);
}
- T visitSyncForIn(ast.SyncForIn node) {
- T expressionType = visit(node.expression);
+ TypeInformation visitSyncForIn(ast.SyncForIn node) {
+ TypeInformation expressionType = visit(node.expression);
Selector iteratorSelector = Selectors.iterator;
TypeMask iteratorMask = inTreeData.typeOfIterator(node);
Selector currentSelector = Selectors.current;
@@ -2255,8 +2930,8 @@ class SimpleTypeInferrerVisitor<T>
Selector moveNextSelector = Selectors.moveNext;
TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node);
- T iteratorType = handleDynamicSend(node, iteratorSelector, iteratorMask,
- expressionType, new ArgumentsTypes<T>.empty());
+ TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector,
+ iteratorMask, expressionType, new ArgumentsTypes.empty());
return handleForInLoop(node, iteratorType, currentSelector, currentMask,
moveNextSelector, moveNextMask);
« no previous file with comments | « pkg/compiler/lib/src/inferrer/node_tracer.dart ('k') | pkg/compiler/lib/src/inferrer/type_graph_dump.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698