| Index: sdk/lib/_internal/compiler/implementation/typechecker.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
|
| index 22c0ad92c14fca1bd4270a2f076cd2b8dd17f848..644ec908df644dbb857981534421319afb549382 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
|
| @@ -51,7 +51,7 @@ abstract class ElementAccess {
|
|
|
| /// Returns [: true :] if the element can be access as an invocation.
|
| bool isCallable(Compiler compiler) {
|
| - if (element.isAbstractField) {
|
| + if (element != null && element.isAbstractField) {
|
| AbstractFieldElement abstractFieldElement = element;
|
| if (abstractFieldElement.getter == null) {
|
| // Setters cannot be invoked as function invocations.
|
| @@ -82,7 +82,7 @@ class DynamicAccess implements ElementAccess {
|
|
|
| Element get element => null;
|
|
|
| - DartType computeType(Compiler compiler) => compiler.types.dynamicType;
|
| + DartType computeType(Compiler compiler) => const DynamicType();
|
|
|
| bool isCallable(Compiler compiler) => true;
|
|
|
| @@ -151,14 +151,17 @@ class TypeAccess extends ElementAccess {
|
| * An access of a type literal.
|
| */
|
| class TypeLiteralAccess extends ElementAccess {
|
| - final Element element;
|
| - TypeLiteralAccess(Element this.element) {
|
| - assert(element != null);
|
| + final DartType type;
|
| +
|
| + TypeLiteralAccess(this.type) {
|
| + assert(type != null);
|
| }
|
|
|
| + Element get element => type.element;
|
| +
|
| DartType computeType(Compiler compiler) => compiler.typeClass.rawType;
|
|
|
| - String toString() => 'TypeLiteralAccess($element)';
|
| + String toString() => 'TypeLiteralAccess($type)';
|
| }
|
|
|
|
|
| @@ -349,7 +352,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
|
|
| // TODO(karlklose): remove these functions.
|
| - DartType unhandledExpression() => types.dynamicType;
|
| + DartType unhandledExpression() => const DynamicType();
|
|
|
| DartType analyzeNonVoid(Node node) {
|
| DartType type = analyze(node);
|
| @@ -557,10 +560,10 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| final FunctionElement element = elements[node];
|
| assert(invariant(node, element != null,
|
| message: 'FunctionExpression with no element'));
|
| - if (Elements.isUnresolved(element)) return types.dynamicType;
|
| + if (Elements.isUnresolved(element)) return const DynamicType();
|
| if (identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR) ||
|
| identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR_BODY)) {
|
| - type = types.dynamicType;
|
| + type = const DynamicType();
|
| returnType = const VoidType();
|
|
|
| element.functionSignature.forEachParameter((ParameterElement parameter) {
|
| @@ -659,8 +662,8 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| type = compiler.objectClass.rawType;
|
| }
|
| }
|
| - if (type.kind == TypeKind.MALFORMED_TYPE) {
|
| - return types.dynamicType;
|
| + if (type.isMalformed) {
|
| + return const DynamicType();
|
| }
|
| return type.unalias(compiler);
|
| }
|
| @@ -669,10 +672,10 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| // interface type of the bound, for function types and typedefs it is the
|
| // `Function` type.
|
| InterfaceType computeInterfaceType(DartType type) {
|
| - if (type.kind == TypeKind.FUNCTION) {
|
| + if (type.isFunctionType) {
|
| type = compiler.functionClass.rawType;
|
| }
|
| - assert(invariant(node, type.kind == TypeKind.INTERFACE,
|
| + assert(invariant(node, type.isInterfaceType,
|
| message: "unexpected type kind ${type.kind}."));
|
| return type;
|
| }
|
| @@ -690,15 +693,12 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| // 'call' method into account.
|
| ElementAccess getAccess(Name name,
|
| DartType unaliasedBound, InterfaceType interface) {
|
| - if (interface.treatAsDynamic) {
|
| - return new DynamicAccess();
|
| - }
|
| MemberSignature member = lookupMemberSignature(memberName, interface);
|
| if (member != null) {
|
| return new MemberAccess(member);
|
| }
|
| if (name == const PublicName('call')) {
|
| - if (unaliasedBound.kind == TypeKind.FUNCTION) {
|
| + if (unaliasedBound.isFunctionType) {
|
| // This is an access the implicit 'call' method of a function type.
|
| return new FunctionCallAccess(receiverElement, unaliasedBound);
|
| }
|
| @@ -706,13 +706,16 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| // This is an access of the special 'call' method implicitly defined
|
| // on 'Function'. This method can be called with any arguments, which
|
| // we ensure by giving it the type 'dynamic'.
|
| - return new FunctionCallAccess(null, types.dynamicType);
|
| + return new FunctionCallAccess(null, const DynamicType());
|
| }
|
| }
|
| return null;
|
| }
|
|
|
| DartType unaliasedBound = computeUnaliasedBound(receiverType);
|
| + if (unaliasedBound.treatAsDynamic) {
|
| + return new DynamicAccess();
|
| + }
|
| InterfaceType interface = computeInterfaceType(unaliasedBound);
|
| ElementAccess access = getAccess(memberName, unaliasedBound, interface);
|
| if (access != null) {
|
| @@ -726,6 +729,8 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| TypePromotion typePromotion = typePromotions.head;
|
| if (!typePromotion.isValid) {
|
| DartType unaliasedBound = computeUnaliasedBound(typePromotion.type);
|
| + if (unaliasedBound.treatAsDynamic) continue;
|
| +
|
| InterfaceType interface = computeInterfaceType(unaliasedBound);
|
| if (getAccess(memberName, unaliasedBound, interface) != null) {
|
| reportTypePromotionHint(typePromotion);
|
| @@ -902,7 +907,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| } else {
|
| reportTypeWarning(node, MessageKind.NOT_CALLABLE,
|
| {'elementName': elementAccess.element.name});
|
| - analyzeArguments(node, elementAccess.element, types.dynamicType,
|
| + analyzeArguments(node, elementAccess.element, const DynamicType(),
|
| argumentTypes);
|
| }
|
| type = type.unalias(compiler);
|
| @@ -910,7 +915,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| FunctionType funType = type;
|
| return funType.returnType;
|
| } else {
|
| - return types.dynamicType;
|
| + return const DynamicType();
|
| }
|
| }
|
|
|
| @@ -964,11 +969,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| } else if (element.impliesType) {
|
| // The literal `Foo` where Foo is a class, a typedef, or a type variable.
|
| if (elements.isTypeLiteral(node)) {
|
| - assert(invariant(node, identical(compiler.typeClass,
|
| - elements.getType(node).element),
|
| - message: 'Expected type literal type: '
|
| - '${elements.getType(node)}'));
|
| - return new TypeLiteralAccess(element);
|
| + return new TypeLiteralAccess(elements.getTypeLiteralType(node));
|
| }
|
| return createResolvedAccess(node, name, element);
|
| } else if (element.isMember) {
|
| @@ -1030,8 +1031,8 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| /// we suggest the use of `List<int>`, which would make promotion valid.
|
| DartType computeMoreSpecificType(DartType shownType,
|
| DartType knownType) {
|
| - if (knownType.kind == TypeKind.INTERFACE &&
|
| - shownType.kind == TypeKind.INTERFACE &&
|
| + if (knownType.isInterfaceType &&
|
| + shownType.isInterfaceType &&
|
| types.isSubtype(shownType.asRaw(), knownType)) {
|
| // For the comments in the block, assume the hierarchy:
|
| // class A<T, V> {}
|
| @@ -1075,7 +1076,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
| DartType constructorType = computeConstructorType(element, receiverType);
|
| analyzeArguments(node, element, constructorType);
|
| - return types.dynamicType;
|
| + return const DynamicType();
|
| }
|
|
|
| if (Elements.isClosureSend(node, element)) {
|
| @@ -1235,7 +1236,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
|
|
| /// Returns the first type in the list or [:dynamic:] if the list is empty.
|
| DartType firstType(Link<DartType> link) {
|
| - return link.isEmpty ? types.dynamicType : link.head;
|
| + return link.isEmpty ? const DynamicType() : link.head;
|
| }
|
|
|
| /**
|
| @@ -1244,7 +1245,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| */
|
| DartType secondType(Link<DartType> link) {
|
| return link.isEmpty || link.tail.isEmpty
|
| - ? types.dynamicType : link.tail.head;
|
| + ? const DynamicType() : link.tail.head;
|
| }
|
|
|
| /**
|
| @@ -1280,7 +1281,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
| return node.isPostfix ? getter : result;
|
| }
|
| - return types.dynamicType;
|
| + return const DynamicType();
|
| }
|
|
|
| /**
|
| @@ -1342,7 +1343,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| return node.isPostfix ? element : result;
|
| }
|
| }
|
| - return types.dynamicType;
|
| + return const DynamicType();
|
| }
|
|
|
| visitSendSet(SendSet node) {
|
| @@ -1455,7 +1456,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
|
|
| DartType visitLiteralNull(LiteralNull node) {
|
| - return types.dynamicType;
|
| + return const DynamicType();
|
| }
|
|
|
| DartType visitLiteralSymbol(LiteralSymbol node) {
|
| @@ -1463,7 +1464,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
|
|
| DartType computeConstructorType(Element constructor, DartType type) {
|
| - if (Elements.isUnresolved(constructor)) return types.dynamicType;
|
| + if (Elements.isUnresolved(constructor)) return const DynamicType();
|
| DartType constructorType = constructor.computeType(compiler);
|
| if (identical(type.kind, TypeKind.INTERFACE)) {
|
| if (constructor.isSynthesized) {
|
| @@ -1485,7 +1486,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
|
|
| DartType visitNewExpression(NewExpression node) {
|
| Element element = elements[node.send];
|
| - if (Elements.isUnresolved(element)) return types.dynamicType;
|
| + if (Elements.isUnresolved(element)) return const DynamicType();
|
|
|
| checkPrivateAccess(node, element, element.name);
|
|
|
| @@ -1579,7 +1580,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| DartType visitThrow(Throw node) {
|
| // TODO(johnniwinther): Handle reachability.
|
| analyze(node.expression);
|
| - return types.dynamicType;
|
| + return const DynamicType();
|
| }
|
|
|
| DartType visitTypeAnnotation(TypeAnnotation node) {
|
| @@ -1587,10 +1588,10 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
|
|
| DartType visitVariableDefinitions(VariableDefinitions node) {
|
| - DartType type = analyzeWithDefault(node.type, types.dynamicType);
|
| + DartType type = analyzeWithDefault(node.type, const DynamicType());
|
| if (type.isVoid) {
|
| reportTypeWarning(node.type, MessageKind.VOID_VARIABLE);
|
| - type = types.dynamicType;
|
| + type = const DynamicType();
|
| }
|
| for (Link<Node> link = node.definitions.nodes; !link.isEmpty;
|
| link = link.tail) {
|
|
|