| Index: sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
|
| ===================================================================
|
| --- sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart (revision 27995)
|
| +++ sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart (working copy)
|
| @@ -61,10 +61,14 @@
|
| }
|
|
|
| void addAssignment(TypeInformation assignment) {
|
| - if (abandonInferencing) return;
|
| // Cheap one-level cycle detection.
|
| if (assignment == this) return;
|
| - assignments.add(assignment);
|
| + if (!abandonInferencing) {
|
| + assignments.add(assignment);
|
| + }
|
| + // Even if we abandon inferencing on this [TypeInformation] we
|
| + // need to collect the users, so that phases that track where
|
| + // elements flow in still work.
|
| assignment.addUser(this);
|
| }
|
|
|
| @@ -92,6 +96,17 @@
|
| assignments = const <TypeInformation>[];
|
| users = const <TypeInformation>[];
|
| }
|
| +
|
| + bool reachedBy(TypeInformation info, TypeGraphInferrerEngine inferrer) {
|
| + return true;
|
| + }
|
| +
|
| + accept(TypeInformationVisitor visitor);
|
| +
|
| + /// The [Element] where this [TypeInformation] was created. May be
|
| + /// for some [TypeInformation] nodes, where we do not need to store
|
| + /// the information.
|
| + Element get owner => null;
|
| }
|
|
|
| /**
|
| @@ -268,6 +283,12 @@
|
| }
|
|
|
| String toString() => 'Element $element $type';
|
| +
|
| + accept(TypeInformationVisitor visitor) {
|
| + return visitor.visitElementTypeInformation(this);
|
| + }
|
| +
|
| + Element get owner => element.getOutermostEnclosingMemberOrTopLevel();
|
| }
|
|
|
| /**
|
| @@ -301,6 +322,8 @@
|
|
|
| /// Return an iterable over the targets of this call.
|
| Iterable<Element> get callees;
|
| +
|
| + Element get owner => caller;
|
| }
|
|
|
| class StaticCallSiteTypeInformation extends CallSiteTypeInformation {
|
| @@ -344,6 +367,14 @@
|
| }
|
|
|
| Iterable<Element> get callees => [calledElement.implementation];
|
| +
|
| + bool reachedBy(TypeInformation info, TypeGraphInferrerEngine inferrer) {
|
| + return info == inferrer.types.getInferredTypeOf(calledElement);
|
| + }
|
| +
|
| + accept(TypeInformationVisitor visitor) {
|
| + return visitor.visitStaticCallSiteTypeInformation(this);
|
| + }
|
| }
|
|
|
| class DynamicCallSiteTypeInformation extends CallSiteTypeInformation {
|
| @@ -506,7 +537,17 @@
|
| super.giveUp(inferrer);
|
| }
|
|
|
| - String toString() => 'Call site $call ${receiver.type} $type';
|
| + bool reachedBy(TypeInformation info, TypeGraphInferrerEngine inferrer) {
|
| + return targets
|
| + .map((element) => inferrer.types.getInferredTypeOf(element))
|
| + .any((other) => other == info);
|
| + }
|
| +
|
| + String toString() => 'Call site $call on ${receiver.type} $type';
|
| +
|
| + accept(TypeInformationVisitor visitor) {
|
| + return visitor.visitDynamicCallSiteTypeInformation(this);
|
| + }
|
| }
|
|
|
| class ClosureCallSiteTypeInformation extends CallSiteTypeInformation {
|
| @@ -529,10 +570,14 @@
|
| }
|
|
|
| Iterable<Element> get callees {
|
| - throw new UnsupportedError("Cannot compute callees of a closure.");
|
| + throw new UnsupportedError("Cannot compute callees of a closure call.");
|
| }
|
|
|
| String toString() => 'Closure call $call on $closure';
|
| +
|
| + accept(TypeInformationVisitor visitor) {
|
| + return visitor.visitClosureCallSiteTypeInformation(this);
|
| + }
|
| }
|
|
|
| /**
|
| @@ -569,6 +614,10 @@
|
| }
|
|
|
| String toString() => 'Type $type';
|
| +
|
| + accept(TypeInformationVisitor visitor) {
|
| + return visitor.visitConcreteTypeInformation(this);
|
| + }
|
| }
|
|
|
| /**
|
| @@ -602,23 +651,28 @@
|
| }
|
|
|
| String toString() => 'Narrow ${assignments.first} to $typeAnnotation $type';
|
| +
|
| + accept(TypeInformationVisitor visitor) {
|
| + return visitor.visitNarrowTypeInformation(this);
|
| + }
|
| }
|
|
|
| /**
|
| - * A [ContainerTypeInformation] is a [ConcreteTypeInformation] created
|
| + * A [ContainerTypeInformation] is a [TypeInformation] created
|
| * for each `List` instantiations.
|
| */
|
| -class ContainerTypeInformation extends ConcreteTypeInformation {
|
| - final TypeInformation elementType;
|
| +class ContainerTypeInformation extends TypeInformation {
|
| + final ElementInContainerTypeInformation elementType;
|
|
|
| - ContainerTypeInformation(containerType, this.elementType)
|
| - : super(containerType);
|
| -
|
| - void addUser(TypeInformation user) {
|
| - elementType.addUser(user);
|
| + ContainerTypeInformation(containerType, this.elementType) {
|
| + type = containerType;
|
| }
|
|
|
| String toString() => 'Container type $type';
|
| +
|
| + accept(TypeInformationVisitor visitor) {
|
| + return visitor.visitContainerTypeInformation(this);
|
| + }
|
| }
|
|
|
| /**
|
| @@ -629,17 +683,27 @@
|
| final ContainerTypeMask container;
|
|
|
| ElementInContainerTypeInformation(elementType, this.container) {
|
| - // [elementType] is not null for const lists.
|
| if (elementType != null) addAssignment(elementType);
|
| }
|
|
|
| + bool get isInConstContainer {
|
| + LiteralList literal = container.allocationNode.asLiteralList();
|
| + return (literal != null) && literal.isConst();
|
| + }
|
| +
|
| TypeMask refine(TypeGraphInferrerEngine inferrer) {
|
| - if (assignments.isEmpty) return inferrer.types.dynamicType.type;
|
| + if (!isInConstContainer) {
|
| + return inferrer.types.dynamicType.type;
|
| + }
|
| return container.elementType =
|
| inferrer.types.computeTypeMask(assignments);
|
| }
|
|
|
| String toString() => 'Element in container $type';
|
| +
|
| + accept(TypeInformationVisitor visitor) {
|
| + return visitor.visitElementInContainerTypeInformation(this);
|
| + }
|
| }
|
|
|
| /**
|
| @@ -658,4 +722,21 @@
|
| }
|
|
|
| String toString() => 'Phi $element $type';
|
| +
|
| + accept(TypeInformationVisitor visitor) {
|
| + return visitor.visitPhiElementTypeInformation(this);
|
| + }
|
| }
|
| +
|
| +abstract class TypeInformationVisitor<T> {
|
| + T visitNarrowTypeInformation(NarrowTypeInformation info);
|
| + T visitPhiElementTypeInformation(PhiElementTypeInformation info);
|
| + T visitElementInContainerTypeInformation(
|
| + ElementInContainerTypeInformation info);
|
| + T visitContainerTypeInformation(ContainerTypeInformation info);
|
| + T visitConcreteTypeInformation(ConcreteTypeInformation info);
|
| + T visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info);
|
| + T visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info);
|
| + T visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info);
|
| + T visitElementTypeInformation(ElementTypeInformation info);
|
| +}
|
|
|