Index: lib/compiler/implementation/typechecker.dart |
diff --git a/lib/compiler/implementation/typechecker.dart b/lib/compiler/implementation/typechecker.dart |
index 6f3dacc53efd2b0cb66bd92c10d575c63b3a8a22..1bc286096ee2caeb624ca49d4386761b80407b33 100644 |
--- a/lib/compiler/implementation/typechecker.dart |
+++ b/lib/compiler/implementation/typechecker.dart |
@@ -33,6 +33,8 @@ class TypeVariableType implements Type { |
final SourceString name; |
Element element; |
TypeVariableType(this.name, [this.element]); |
+ |
+ toString() => name.toString(); |
} |
/** |
@@ -58,12 +60,29 @@ class StatementType implements Type { |
String toString() => stringName; |
} |
-class SimpleType implements Type { |
+class InterfaceType implements Type { |
final SourceString name; |
- final Element element; |
+ final ClassElement element; |
+ final Link<Type> arguments; |
- const SimpleType(SourceString this.name, Element this.element); |
+ const InterfaceType(this.name, this.element, this.arguments); |
+ |
+ toString() { |
+ StringBuffer sb = new StringBuffer(); |
+ sb.add(name.slowToString()); |
+ if (!arguments.isEmpty()) { |
+ sb.add('<'); |
+ arguments.printOn(sb); |
+ sb.add('>'); |
+ } |
+ return sb.toString(); |
+ } |
+} |
+// TODO(karlklose): merge into InterfaceType as a named constructor. |
+class SimpleType extends InterfaceType { |
+ const SimpleType(SourceString name, Element element) |
+ : super(name, element, const EmptyLink<Type>()); |
String toString() => name.slowToString(); |
} |
@@ -101,6 +120,7 @@ class Types { |
final SimpleType dynamicType; |
Types() : this.with(new LibraryElement(new Script(null, null))); |
+ |
Types.with(LibraryElement library) |
: voidType = new SimpleType(VOID, new ClassElement(VOID, library)), |
dynamicType = new SimpleType(DYNAMIC, new ClassElement(DYNAMIC, library)); |
@@ -172,9 +192,9 @@ Type lookupType(SourceString name, Compiler compiler, types) { |
class TypeCheckerVisitor implements Visitor<Type> { |
final Compiler compiler; |
final TreeElements elements; |
- Node lastSeenNode; |
final Types types; |
+ Node lastSeenNode; |
Type expectedReturnType; |
ClassElement currentClass; |
@@ -187,8 +207,7 @@ class TypeCheckerVisitor implements Visitor<Type> { |
Type objectType; |
Type listType; |
- TypeCheckerVisitor(Compiler this.compiler, TreeElements this.elements, |
- Types this.types) { |
+ TypeCheckerVisitor(this.compiler, this.elements, this.types) { |
intType = lookupType(Types.INT, compiler, types); |
doubleType = lookupType(Types.DOUBLE, compiler, types); |
boolType = lookupType(Types.BOOL, compiler, types); |
@@ -456,19 +475,19 @@ class TypeCheckerVisitor implements Visitor<Type> { |
FunctionType computeFunType() { |
if (node.receiver !== null) { |
Type receiverType = analyze(node.receiver); |
- if (receiverType === types.dynamicType) return null; |
- if (receiverType === null) { |
- fail(node.receiver, 'receivertype is null'); |
- } |
- if (receiverType.element.kind !== ElementKind.CLASS) { |
- fail(node.receiver, 'receivertype is not a class'); |
- } |
- ClassElement classElement = receiverType.element; |
- // TODO(karlklose): substitute type arguments. |
- Type memberType = |
- lookupMethodType(selector, classElement, selector.source); |
- if (memberType === types.dynamicType) return null; |
- return memberType; |
+ if (receiverType.element == compiler.dynamicClass) return null; |
+ if (receiverType === null) { |
+ fail(node.receiver, 'receivertype is null'); |
+ } |
+ if (receiverType.element.kind !== ElementKind.CLASS) { |
+ fail(node.receiver, 'receivertype is not a class'); |
+ } |
+ ClassElement classElement = receiverType.element; |
+ // TODO(karlklose): substitute type arguments. |
+ Type memberType = |
+ lookupMethodType(selector, classElement, selector.source); |
+ if (memberType.element === compiler.dynamicClass) return null; |
+ return memberType; |
} else { |
Element element = elements[node]; |
if (element === null) { |