| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a | 
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. | 
| 4 | 4 | 
| 5 library dart2js.typechecker; | 5 library dart2js.typechecker; | 
| 6 | 6 | 
| 7 import 'common/names.dart' show | 7 import 'common/names.dart' show | 
| 8     Identifiers; | 8     Identifiers; | 
| 9 import 'common/resolution.dart' show | 9 import 'common/resolution.dart' show | 
| 10     Resolution; | 10     Resolution; | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 52     TypedefElement, | 52     TypedefElement, | 
| 53     VariableElement; | 53     VariableElement; | 
| 54 import 'resolution/tree_elements.dart' show | 54 import 'resolution/tree_elements.dart' show | 
| 55     TreeElements; | 55     TreeElements; | 
| 56 import 'resolution/class_members.dart' show | 56 import 'resolution/class_members.dart' show | 
| 57     MembersCreator; | 57     MembersCreator; | 
| 58 import 'tree/tree.dart'; | 58 import 'tree/tree.dart'; | 
| 59 import 'util/util.dart' show | 59 import 'util/util.dart' show | 
| 60     Link, | 60     Link, | 
| 61     LinkBuilder; | 61     LinkBuilder; | 
| 62 import '../compiler_new.dart' as api; |  | 
| 63 | 62 | 
| 64 class TypeCheckerTask extends CompilerTask { | 63 class TypeCheckerTask extends CompilerTask { | 
| 65   TypeCheckerTask(Compiler compiler) : super(compiler); | 64   TypeCheckerTask(Compiler compiler) : super(compiler); | 
| 66   String get name => "Type checker"; | 65   String get name => "Type checker"; | 
| 67 | 66 | 
| 68   void check(AstElement element) { | 67   void check(AstElement element) { | 
| 69     if (element.isClass) return; | 68     if (element.isClass) return; | 
| 70     if (element.isTypedef) return; | 69     if (element.isTypedef) return; | 
| 71     ResolvedAst resolvedAst = element.resolvedAst; | 70     ResolvedAst resolvedAst = element.resolvedAst; | 
| 72     reporter.withCurrentElement(element.implementation, () { | 71     reporter.withCurrentElement(element.implementation, () { | 
| (...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 768           // This is an access of the special 'call' method implicitly defined | 767           // This is an access of the special 'call' method implicitly defined | 
| 769           // on 'Function'. This method can be called with any arguments, which | 768           // on 'Function'. This method can be called with any arguments, which | 
| 770           // we ensure by giving it the type 'dynamic'. | 769           // we ensure by giving it the type 'dynamic'. | 
| 771           return new FunctionCallAccess(null, const DynamicType()); | 770           return new FunctionCallAccess(null, const DynamicType()); | 
| 772         } | 771         } | 
| 773       } | 772       } | 
| 774       return null; | 773       return null; | 
| 775     } | 774     } | 
| 776 | 775 | 
| 777     DartType unaliasedBound = | 776     DartType unaliasedBound = | 
| 778         Types.computeUnaliasedBound(compiler, receiverType); | 777         Types.computeUnaliasedBound(resolution, receiverType); | 
| 779     if (unaliasedBound.treatAsDynamic) { | 778     if (unaliasedBound.treatAsDynamic) { | 
| 780       return new DynamicAccess(); | 779       return new DynamicAccess(); | 
| 781     } | 780     } | 
| 782     InterfaceType interface = | 781     InterfaceType interface = | 
| 783         Types.computeInterfaceType(compiler, unaliasedBound); | 782         Types.computeInterfaceType(resolution, unaliasedBound); | 
| 784     ElementAccess access = getAccess(memberName, unaliasedBound, interface); | 783     ElementAccess access = getAccess(memberName, unaliasedBound, interface); | 
| 785     if (access != null) { | 784     if (access != null) { | 
| 786       return access; | 785       return access; | 
| 787     } | 786     } | 
| 788     if (receiverElement != null && | 787     if (receiverElement != null && | 
| 789         (receiverElement.isVariable || receiverElement.isParameter)) { | 788         (receiverElement.isVariable || receiverElement.isParameter)) { | 
| 790       Link<TypePromotion> typePromotions = typePromotionsMap[receiverElement]; | 789       Link<TypePromotion> typePromotions = typePromotionsMap[receiverElement]; | 
| 791       if (typePromotions != null) { | 790       if (typePromotions != null) { | 
| 792         while (!typePromotions.isEmpty) { | 791         while (!typePromotions.isEmpty) { | 
| 793           TypePromotion typePromotion = typePromotions.head; | 792           TypePromotion typePromotion = typePromotions.head; | 
| 794           if (!typePromotion.isValid) { | 793           if (!typePromotion.isValid) { | 
| 795             DartType unaliasedBound = | 794             DartType unaliasedBound = | 
| 796                 Types.computeUnaliasedBound(compiler, typePromotion.type); | 795                 Types.computeUnaliasedBound(resolution, typePromotion.type); | 
| 797             if (!unaliasedBound.treatAsDynamic) { | 796             if (!unaliasedBound.treatAsDynamic) { | 
| 798               InterfaceType interface = | 797               InterfaceType interface = | 
| 799                   Types.computeInterfaceType(compiler, unaliasedBound); | 798                   Types.computeInterfaceType(resolution, unaliasedBound); | 
| 800               if (getAccess(memberName, unaliasedBound, interface) != null) { | 799               if (getAccess(memberName, unaliasedBound, interface) != null) { | 
| 801                 reportTypePromotionHint(typePromotion); | 800                 reportTypePromotionHint(typePromotion); | 
| 802               } | 801               } | 
| 803             } | 802             } | 
| 804           } | 803           } | 
| 805           typePromotions = typePromotions.tail; | 804           typePromotions = typePromotions.tail; | 
| 806         } | 805         } | 
| 807       } | 806       } | 
| 808     } | 807     } | 
| 809     // We didn't find a member with the correct name.  If this lookup is for a | 808     // We didn't find a member with the correct name.  If this lookup is for a | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 884   DartType lookupMemberType(Node node, DartType type, String name, | 883   DartType lookupMemberType(Node node, DartType type, String name, | 
| 885                             MemberKind memberKind, | 884                             MemberKind memberKind, | 
| 886                             {bool isHint: false}) { | 885                             {bool isHint: false}) { | 
| 887     return lookupMember(node, type, name, memberKind, null, isHint: isHint) | 886     return lookupMember(node, type, name, memberKind, null, isHint: isHint) | 
| 888         .computeType(resolution); | 887         .computeType(resolution); | 
| 889   } | 888   } | 
| 890 | 889 | 
| 891   void analyzeArguments(Send send, Element element, DartType type, | 890   void analyzeArguments(Send send, Element element, DartType type, | 
| 892                         [LinkBuilder<DartType> argumentTypes]) { | 891                         [LinkBuilder<DartType> argumentTypes]) { | 
| 893     Link<Node> arguments = send.arguments; | 892     Link<Node> arguments = send.arguments; | 
| 894     DartType unaliasedType = type.unalias(resolution); | 893     type.computeUnaliased(resolution); | 
|  | 894     DartType unaliasedType = type.unaliased; | 
| 895     if (identical(unaliasedType.kind, TypeKind.FUNCTION)) { | 895     if (identical(unaliasedType.kind, TypeKind.FUNCTION)) { | 
| 896 | 896 | 
| 897       /// Report [warning] including info(s) about the declaration of [element] | 897       /// Report [warning] including info(s) about the declaration of [element] | 
| 898       /// or [type]. | 898       /// or [type]. | 
| 899       void reportWarning(DiagnosticMessage warning) { | 899       void reportWarning(DiagnosticMessage warning) { | 
| 900         // TODO(johnniwinther): Support pointing to individual parameters on | 900         // TODO(johnniwinther): Support pointing to individual parameters on | 
| 901         // assignability warnings. | 901         // assignability warnings. | 
| 902         List<DiagnosticMessage> infos = <DiagnosticMessage>[]; | 902         List<DiagnosticMessage> infos = <DiagnosticMessage>[]; | 
| 903         Element declaration = element; | 903         Element declaration = element; | 
| 904         if (declaration == null) { | 904         if (declaration == null) { | 
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1006                              [LinkBuilder<DartType> argumentTypes]) { | 1006                              [LinkBuilder<DartType> argumentTypes]) { | 
| 1007     DartType type = elementAccess.computeType(resolution); | 1007     DartType type = elementAccess.computeType(resolution); | 
| 1008     if (elementAccess.isCallable(compiler)) { | 1008     if (elementAccess.isCallable(compiler)) { | 
| 1009       analyzeArguments(node, elementAccess.element, type, argumentTypes); | 1009       analyzeArguments(node, elementAccess.element, type, argumentTypes); | 
| 1010     } else { | 1010     } else { | 
| 1011       reportTypeWarning(node, MessageKind.NOT_CALLABLE, | 1011       reportTypeWarning(node, MessageKind.NOT_CALLABLE, | 
| 1012           {'elementName': elementAccess.name}); | 1012           {'elementName': elementAccess.name}); | 
| 1013       analyzeArguments(node, elementAccess.element, const DynamicType(), | 1013       analyzeArguments(node, elementAccess.element, const DynamicType(), | 
| 1014                        argumentTypes); | 1014                        argumentTypes); | 
| 1015     } | 1015     } | 
| 1016     type = type.unalias(resolution); | 1016     type.computeUnaliased(resolution); | 
| 1017     if (identical(type.kind, TypeKind.FUNCTION)) { | 1017     type = type.unaliased; | 
|  | 1018     if (type.isFunctionType) { | 
| 1018       FunctionType funType = type; | 1019       FunctionType funType = type; | 
| 1019       return funType.returnType; | 1020       return funType.returnType; | 
| 1020     } else { | 1021     } else { | 
| 1021       return const DynamicType(); | 1022       return const DynamicType(); | 
| 1022     } | 1023     } | 
| 1023   } | 1024   } | 
| 1024 | 1025 | 
| 1025   /** | 1026   /** | 
| 1026    * Computes the [ElementAccess] for [name] on the [node] possibly using the | 1027    * Computes the [ElementAccess] for [name] on the [node] possibly using the | 
| 1027    * [element] provided for [node] by the resolver. | 1028    * [element] provided for [node] by the resolver. | 
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1144       //     class A<T, V> {} | 1145       //     class A<T, V> {} | 
| 1145       //     class B<S, U> extends A<S, int> {} | 1146       //     class B<S, U> extends A<S, int> {} | 
| 1146       // and a promotion from a [knownType] of `A<double, int>` to a | 1147       // and a promotion from a [knownType] of `A<double, int>` to a | 
| 1147       // [shownType] of `B`. | 1148       // [shownType] of `B`. | 
| 1148       InterfaceType knownInterfaceType = knownType; | 1149       InterfaceType knownInterfaceType = knownType; | 
| 1149       ClassElement shownClass = shownType.element; | 1150       ClassElement shownClass = shownType.element; | 
| 1150 | 1151 | 
| 1151       // Compute `B<double, dynamic>` as the subtype of `A<double, int>` using | 1152       // Compute `B<double, dynamic>` as the subtype of `A<double, int>` using | 
| 1152       // the relation between `A<S, int>` and `A<double, int>`. | 1153       // the relation between `A<S, int>` and `A<double, int>`. | 
| 1153       MoreSpecificSubtypeVisitor visitor = | 1154       MoreSpecificSubtypeVisitor visitor = | 
| 1154           new MoreSpecificSubtypeVisitor(compiler); | 1155           new MoreSpecificSubtypeVisitor(types); | 
| 1155       InterfaceType shownTypeGeneric = visitor.computeMoreSpecific( | 1156       InterfaceType shownTypeGeneric = visitor.computeMoreSpecific( | 
| 1156           shownClass, knownInterfaceType); | 1157           shownClass, knownInterfaceType); | 
| 1157 | 1158 | 
| 1158       if (shownTypeGeneric != null && | 1159       if (shownTypeGeneric != null && | 
| 1159           types.isMoreSpecific(shownTypeGeneric, knownType)) { | 1160           types.isMoreSpecific(shownTypeGeneric, knownType)) { | 
| 1160         // This should be the case but we double-check. | 1161         // This should be the case but we double-check. | 
| 1161         // TODO(johnniwinther): Ensure that we don't suggest malbounded types. | 1162         // TODO(johnniwinther): Ensure that we don't suggest malbounded types. | 
| 1162         return shownTypeGeneric; | 1163         return shownTypeGeneric; | 
| 1163       } | 1164       } | 
| 1164     } | 1165     } | 
| (...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1838     // TODO(johnniwinther): Move this to _CompilerCoreTypes. | 1839     // TODO(johnniwinther): Move this to _CompilerCoreTypes. | 
| 1839     compiler.streamClass.ensureResolved(resolution); | 1840     compiler.streamClass.ensureResolved(resolution); | 
| 1840     DartType streamOfDynamic = coreTypes.streamType(); | 1841     DartType streamOfDynamic = coreTypes.streamType(); | 
| 1841     if (!types.isAssignable(expressionType, streamOfDynamic)) { | 1842     if (!types.isAssignable(expressionType, streamOfDynamic)) { | 
| 1842       reportMessage(node.expression, | 1843       reportMessage(node.expression, | 
| 1843           MessageKind.NOT_ASSIGNABLE, | 1844           MessageKind.NOT_ASSIGNABLE, | 
| 1844           {'fromType': expressionType, 'toType': streamOfDynamic}, | 1845           {'fromType': expressionType, 'toType': streamOfDynamic}, | 
| 1845           isHint: true); | 1846           isHint: true); | 
| 1846     } else { | 1847     } else { | 
| 1847       InterfaceType interfaceType = | 1848       InterfaceType interfaceType = | 
| 1848           Types.computeInterfaceType(compiler, expressionType); | 1849           Types.computeInterfaceType(resolution, expressionType); | 
| 1849       if (interfaceType != null) { | 1850       if (interfaceType != null) { | 
| 1850         InterfaceType streamType = | 1851         InterfaceType streamType = | 
| 1851             interfaceType.asInstanceOf(compiler.streamClass); | 1852             interfaceType.asInstanceOf(compiler.streamClass); | 
| 1852         if (streamType != null) { | 1853         if (streamType != null) { | 
| 1853           DartType streamElementType = streamType.typeArguments.first; | 1854           DartType streamElementType = streamType.typeArguments.first; | 
| 1854           if (!types.isAssignable(streamElementType, elementType)) { | 1855           if (!types.isAssignable(streamElementType, elementType)) { | 
| 1855             reportMessage(node.expression, | 1856             reportMessage(node.expression, | 
| 1856                 MessageKind.FORIN_NOT_ASSIGNABLE, | 1857                 MessageKind.FORIN_NOT_ASSIGNABLE, | 
| 1857                 {'currentType': streamElementType, | 1858                 {'currentType': streamElementType, | 
| 1858                  'expressionType': expressionType, | 1859                  'expressionType': expressionType, | 
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2005 | 2006 | 
| 2006   visitTypedef(Typedef node) { | 2007   visitTypedef(Typedef node) { | 
| 2007     // Do not typecheck [Typedef] nodes. | 2008     // Do not typecheck [Typedef] nodes. | 
| 2008   } | 2009   } | 
| 2009 | 2010 | 
| 2010   visitNode(Node node) { | 2011   visitNode(Node node) { | 
| 2011     reporter.internalError(node, | 2012     reporter.internalError(node, | 
| 2012         'Unexpected node ${node.getObjectDescription()} in the type checker.'); | 2013         'Unexpected node ${node.getObjectDescription()} in the type checker.'); | 
| 2013   } | 2014   } | 
| 2014 } | 2015 } | 
| OLD | NEW | 
|---|