Index: pkg/kernel/lib/transformations/reify/transformation/remove_generics.dart |
diff --git a/pkg/kernel/lib/transformations/reify/transformation/remove_generics.dart b/pkg/kernel/lib/transformations/reify/transformation/remove_generics.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..aafff7d93c0c32c3fd6b2aa98d2da4c21a17b80b |
--- /dev/null |
+++ b/pkg/kernel/lib/transformations/reify/transformation/remove_generics.dart |
@@ -0,0 +1,119 @@ |
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+library kernel.transformations.reify.transformation.remove_generics; |
+ |
+import 'package:kernel/ast.dart'; |
+import 'transformer.dart'; |
+ |
+class Erasure extends Transformer with DartTypeVisitor<DartType> { |
+ final ReifyVisitor reifyVisitor; |
+ |
+ Erasure(this.reifyVisitor); |
+ |
+ bool removeTypeParameters(Class cls) { |
+ return reifyVisitor.needsTypeInformation(cls); |
+ } |
+ |
+ TreeNode removeTypeArgumentsOfConstructorCall(ConstructorInvocation node) { |
+ Class cls = node.target.parent; |
+ if (removeTypeParameters(cls)) { |
+ node.arguments.types.clear(); |
+ Constructor target = node.target; |
+ target.enclosingClass.typeParameters.clear(); |
+ } |
+ return node; |
+ } |
+ |
+ TreeNode removeTypeArgumentsOfStaticCall(StaticInvocation node) { |
+ Class cls = node.target.parent; |
+ if (removeTypeParameters(cls)) { |
+ node.arguments.types.clear(); |
+ Procedure target = node.target; |
+ target.function.typeParameters.clear(); |
+ } |
+ return node; |
+ } |
+ |
+ @override |
+ defaultDartType(DartType type) => type; |
+ |
+ @override |
+ InterfaceType visitInterfaceType(InterfaceType type) { |
+ if (removeTypeParameters(type.classNode)) { |
+ return new InterfaceType(type.classNode, const <DartType>[]); |
+ } |
+ return type; |
+ } |
+ |
+ @override |
+ Supertype visitSupertype(Supertype type) { |
+ if (removeTypeParameters(type.classNode)) { |
+ return new Supertype(type.classNode, const <DartType>[]); |
+ } |
+ return type; |
+ } |
+ |
+ @override |
+ FunctionType visitFunctionType(FunctionType type) { |
+ bool partHasChanged = false; |
+ |
+ DartType translate(DartType type) { |
+ DartType newType = type.accept(this); |
+ if (newType != type) { |
+ partHasChanged = true; |
+ return newType; |
+ } else { |
+ return type; |
+ } |
+ } |
+ |
+ DartType returnType = translate(type.returnType); |
+ List<DartType> positionalTypes = |
+ type.positionalParameters.map(translate).toList(); |
+ List<NamedType> namedParameters = new List<NamedType>(); |
+ for (NamedType param in type.namedParameters) { |
+ namedParameters.add(new NamedType(param.name, translate(param.type))); |
+ } |
+ if (partHasChanged) { |
+ return new FunctionType(positionalTypes, returnType, |
+ namedParameters: namedParameters, |
+ requiredParameterCount: type.requiredParameterCount); |
+ } else { |
+ return type; |
+ } |
+ } |
+ |
+ @override |
+ DynamicType visitTypeParameterType(_) => const DynamicType(); |
+ |
+ @override |
+ DartType visitDartType(DartType type) { |
+ return type.accept(this); |
+ } |
+ |
+ @override |
+ StaticInvocation visitStaticInvocation(StaticInvocation node) { |
+ node.transformChildren(this); |
+ if (node.target.kind == ProcedureKind.Factory) { |
+ node = removeTypeArgumentsOfStaticCall(node); |
+ } |
+ return node; |
+ } |
+ |
+ @override |
+ ConstructorInvocation visitConstructorInvocation(ConstructorInvocation node) { |
+ node.transformChildren(this); |
+ return removeTypeArgumentsOfConstructorCall(node); |
+ } |
+ |
+ @override |
+ Class visitClass(Class node) { |
+ node.transformChildren(this); |
+ if (removeTypeParameters(node)) { |
+ node.typeParameters.clear(); |
+ } |
+ return node; |
+ } |
+} |