| 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) {
|
|
|