| Index: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
|
| index 96b094540f230ffe0a00a57bc5e15785336c88c6..383cb2b8af76c2f7731a0893483dd462b8a6970e 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
|
| @@ -1435,7 +1435,7 @@ class CreateBox extends Primitive {
|
| /// Creates an instance of a class and initializes its fields and runtime type
|
| /// information.
|
| class CreateInstance extends Primitive {
|
| - final ClassElement classElement;
|
| + final InterfaceType dartType;
|
|
|
| /// Initial values for the fields on the class.
|
| /// The order corresponds to the order of fields on the class.
|
| @@ -1450,7 +1450,9 @@ class CreateInstance extends Primitive {
|
|
|
| final SourceInformation sourceInformation;
|
|
|
| - CreateInstance(this.classElement, List<Primitive> arguments,
|
| + ClassElement get classElement => dartType.element;
|
| +
|
| + CreateInstance(this.dartType, List<Primitive> arguments,
|
| List<Primitive> typeInformation,
|
| this.sourceInformation)
|
| : this.arguments = _referenceList(arguments),
|
| @@ -1462,7 +1464,7 @@ class CreateInstance extends Primitive {
|
| bool get isSafeForElimination => true;
|
| bool get isSafeForReordering => true;
|
|
|
| - toString() => 'CreateInstance($classElement)';
|
| + toString() => 'CreateInstance($dartType)';
|
|
|
| void setParentPointers() {
|
| _setParentsOnList(arguments, this);
|
| @@ -1575,7 +1577,7 @@ class Constant extends Primitive {
|
|
|
| class LiteralList extends Primitive {
|
| /// The List type being created; this is not the type argument.
|
| - final InterfaceType dartType;
|
| + InterfaceType dartType;
|
| final List<Reference<Primitive>> values;
|
|
|
| /// If non-null, this is an allocation site-specific type for the list
|
| @@ -1606,7 +1608,7 @@ class LiteralMapEntry {
|
| }
|
|
|
| class LiteralMap extends Primitive {
|
| - final InterfaceType dartType;
|
| + InterfaceType dartType;
|
| final List<LiteralMapEntry> entries;
|
|
|
| LiteralMap(this.dartType, this.entries);
|
| @@ -2472,7 +2474,8 @@ class RemovalVisitor extends TrampolineRecursiveVisitor {
|
| /// definition assumes that the definitions of all references have already
|
| /// been copied by the same visitor.
|
| class DefinitionCopyingVisitor extends Visitor<Definition> {
|
| - Map<Definition, Definition> _copies = <Definition, Definition>{};
|
| + final Map<Definition, Definition> _copies = <Definition, Definition>{};
|
| + DartType concreteType;
|
|
|
| /// Put a copy into the map.
|
| ///
|
| @@ -2492,6 +2495,12 @@ class DefinitionCopyingVisitor extends Visitor<Definition> {
|
| /// Map a list of [Reference]s to the list of their definition's copies.
|
| List<Definition> getList(List<Reference> list) => list.map(getCopy).toList();
|
|
|
| + DartType substType(DartType dartType) {
|
| + return concreteType != null
|
| + ? dartType.substByContext(concreteType)
|
| + : dartType;
|
| + }
|
| +
|
| /// Copy a non-[Continuation] [Definition].
|
| Definition copy(Definition node) {
|
| assert (node is! Continuation);
|
| @@ -2533,13 +2542,14 @@ class DefinitionCopyingVisitor extends Visitor<Definition> {
|
| }
|
|
|
| Definition visitInvokeConstructor(InvokeConstructor node) {
|
| - return new InvokeConstructor(node.dartType, node.target, node.selector,
|
| + return new InvokeConstructor(substType(node.dartType), node.target,
|
| + node.selector,
|
| getList(node.arguments),
|
| node.sourceInformation);
|
| }
|
|
|
| Definition visitTypeCast(TypeCast node) {
|
| - return new TypeCast(getCopy(node.value), node.dartType,
|
| + return new TypeCast(getCopy(node.value), substType(node.dartType),
|
| getList(node.typeArguments));
|
| }
|
|
|
| @@ -2569,14 +2579,14 @@ class DefinitionCopyingVisitor extends Visitor<Definition> {
|
| }
|
|
|
| Definition visitLiteralList(LiteralList node) {
|
| - return new LiteralList(node.dartType, getList(node.values));
|
| + return new LiteralList(substType(node.dartType), getList(node.values));
|
| }
|
|
|
| Definition visitLiteralMap(LiteralMap node) {
|
| List<LiteralMapEntry> entries = node.entries.map((LiteralMapEntry entry) {
|
| return new LiteralMapEntry(getCopy(entry.key), getCopy(entry.value));
|
| }).toList();
|
| - return new LiteralMap(node.dartType, entries);
|
| + return new LiteralMap(substType(node.dartType), entries);
|
| }
|
|
|
| Definition visitConstant(Constant node) {
|
| @@ -2605,7 +2615,8 @@ class DefinitionCopyingVisitor extends Visitor<Definition> {
|
| }
|
|
|
| Definition visitCreateInstance(CreateInstance node) {
|
| - return new CreateInstance(node.classElement, getList(node.arguments),
|
| + return new CreateInstance(substType(node.dartType),
|
| + getList(node.arguments),
|
| getList(node.typeInformation),
|
| node.sourceInformation);
|
| }
|
| @@ -2628,6 +2639,9 @@ class DefinitionCopyingVisitor extends Visitor<Definition> {
|
| }
|
|
|
| Definition visitTypeExpression(TypeExpression node) {
|
| + // Note: Do not use substType for the TypeExpression's DartType. The type
|
| + // variables in TypeExpression are not "free", they are bound by the
|
| + // TypeExpression itself.
|
| return new TypeExpression(node.dartType, getList(node.arguments));
|
| }
|
|
|
| @@ -2636,12 +2650,13 @@ class DefinitionCopyingVisitor extends Visitor<Definition> {
|
| }
|
|
|
| Definition visitTypeTest(TypeTest node) {
|
| - return new TypeTest(getCopy(node.value), node.dartType,
|
| + return new TypeTest(getCopy(node.value), substType(node.dartType),
|
| getList(node.typeArguments));
|
| }
|
|
|
| Definition visitTypeTestViaFlag(TypeTestViaFlag node) {
|
| - return new TypeTestViaFlag(getCopy(node.interceptor), node.dartType);
|
| + return new TypeTestViaFlag(getCopy(node.interceptor),
|
| + substType(node.dartType));
|
| }
|
|
|
| Definition visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
|
| @@ -2744,9 +2759,17 @@ class CopyingVisitor extends TrampolineRecursiveVisitor {
|
| });
|
| }
|
|
|
| - FunctionDefinition copy(FunctionDefinition node) {
|
| + /// Creates a copy of [node].
|
| + ///
|
| + /// If [concreteType] is given, type variables declared in [concreteType]'s
|
| + /// class are subsituted with the type arguments used in [concreteType].
|
| + /// For example, if `List<String>` is given, the type variable of `List`
|
| + /// is replaced with `String`. It is for performance reasons that type
|
| + /// substitution is integrated into the copying operation.
|
| + FunctionDefinition copy(FunctionDefinition node, {DartType concreteType}) {
|
| assert(_first == null && _current == null);
|
| _first = _current = null;
|
| + _definitions.concreteType = concreteType;
|
| // Definitions are copied where they are bound, before processing
|
| // expressions in the scope of their binding.
|
| Parameter thisParameter = node.thisParameter == null
|
|
|