| 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 Identifiers; | 7 import 'common/names.dart' show Identifiers; |
| 8 import 'common/resolution.dart' show Resolution; | 8 import 'common/resolution.dart' show Resolution; |
| 9 import 'common/tasks.dart' show CompilerTask; | 9 import 'common/tasks.dart' show CompilerTask; |
| 10 import 'common.dart'; | 10 import 'common.dart'; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 /// Returns [: true :] if the element can be access as an invocation. | 105 /// Returns [: true :] if the element can be access as an invocation. |
| 106 bool isCallable(Compiler compiler) { | 106 bool isCallable(Compiler compiler) { |
| 107 if (element != null && element.isAbstractField) { | 107 if (element != null && element.isAbstractField) { |
| 108 AbstractFieldElement abstractFieldElement = element; | 108 AbstractFieldElement abstractFieldElement = element; |
| 109 if (abstractFieldElement.getter == null) { | 109 if (abstractFieldElement.getter == null) { |
| 110 // Setters cannot be invoked as function invocations. | 110 // Setters cannot be invoked as function invocations. |
| 111 return false; | 111 return false; |
| 112 } | 112 } |
| 113 } | 113 } |
| 114 return compiler.types.isAssignable( | 114 return compiler.types.isAssignable( |
| 115 computeType(compiler.resolution), compiler.coreTypes.functionType); | 115 computeType(compiler.resolution), compiler.commonElements.functionType); |
| 116 } | 116 } |
| 117 } | 117 } |
| 118 | 118 |
| 119 /// An access of a instance member. | 119 /// An access of a instance member. |
| 120 class MemberAccess extends ElementAccess { | 120 class MemberAccess extends ElementAccess { |
| 121 final MemberSignature member; | 121 final MemberSignature member; |
| 122 | 122 |
| 123 MemberAccess(MemberSignature this.member); | 123 MemberAccess(MemberSignature this.member); |
| 124 | 124 |
| 125 Element get element => member.declarations.first.element; | 125 Element get element => member.declarations.first.element; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 final DartType type; | 222 final DartType type; |
| 223 | 223 |
| 224 TypeLiteralAccess(this.type) { | 224 TypeLiteralAccess(this.type) { |
| 225 assert(type != null); | 225 assert(type != null); |
| 226 } | 226 } |
| 227 | 227 |
| 228 Element get element => type.element; | 228 Element get element => type.element; |
| 229 | 229 |
| 230 String get name => type.name; | 230 String get name => type.name; |
| 231 | 231 |
| 232 DartType computeType(Resolution resolution) => resolution.coreTypes.typeType; | 232 DartType computeType(Resolution resolution) => |
| 233 resolution.commonElements.typeType; |
| 233 | 234 |
| 234 String toString() => 'TypeLiteralAccess($type)'; | 235 String toString() => 'TypeLiteralAccess($type)'; |
| 235 } | 236 } |
| 236 | 237 |
| 237 /// An access to the 'call' method of a function type. | 238 /// An access to the 'call' method of a function type. |
| 238 class FunctionCallAccess implements ElementAccess { | 239 class FunctionCallAccess implements ElementAccess { |
| 239 final Element element; | 240 final Element element; |
| 240 final DartType type; | 241 final DartType type; |
| 241 | 242 |
| 242 const FunctionCallAccess(this.element, this.type); | 243 const FunctionCallAccess(this.element, this.type); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 | 291 |
| 291 Node lastSeenNode; | 292 Node lastSeenNode; |
| 292 DartType expectedReturnType; | 293 DartType expectedReturnType; |
| 293 AsyncMarker currentAsyncMarker = AsyncMarker.SYNC; | 294 AsyncMarker currentAsyncMarker = AsyncMarker.SYNC; |
| 294 | 295 |
| 295 final ClassElement currentClass; | 296 final ClassElement currentClass; |
| 296 | 297 |
| 297 /// The immediately enclosing field, method or constructor being analyzed. | 298 /// The immediately enclosing field, method or constructor being analyzed. |
| 298 ExecutableElement executableContext; | 299 ExecutableElement executableContext; |
| 299 | 300 |
| 300 CoreTypes get coreTypes => compiler.coreTypes; | 301 CommonElements get commonElements => compiler.commonElements; |
| 301 | 302 |
| 302 DiagnosticReporter get reporter => compiler.reporter; | 303 DiagnosticReporter get reporter => compiler.reporter; |
| 303 | 304 |
| 304 Resolution get resolution => compiler.resolution; | 305 Resolution get resolution => compiler.resolution; |
| 305 | 306 |
| 306 InterfaceType get intType => coreTypes.intType; | 307 InterfaceType get intType => commonElements.intType; |
| 307 InterfaceType get doubleType => coreTypes.doubleType; | 308 InterfaceType get doubleType => commonElements.doubleType; |
| 308 InterfaceType get boolType => coreTypes.boolType; | 309 InterfaceType get boolType => commonElements.boolType; |
| 309 InterfaceType get stringType => coreTypes.stringType; | 310 InterfaceType get stringType => commonElements.stringType; |
| 310 | 311 |
| 311 DartType thisType; | 312 DartType thisType; |
| 312 DartType superType; | 313 DartType superType; |
| 313 | 314 |
| 314 Link<DartType> cascadeTypes = const Link<DartType>(); | 315 Link<DartType> cascadeTypes = const Link<DartType>(); |
| 315 | 316 |
| 316 bool analyzingInitializer = false; | 317 bool analyzingInitializer = false; |
| 317 | 318 |
| 318 Map<Node, List<TypePromotion>> shownTypePromotionsMap = | 319 Map<Node, List<TypePromotion>> shownTypePromotionsMap = |
| 319 new Map<Node, List<TypePromotion>>(); | 320 new Map<Node, List<TypePromotion>>(); |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 return const DynamicAccess(); | 742 return const DynamicAccess(); |
| 742 } else { | 743 } else { |
| 743 return new MemberAccess(member); | 744 return new MemberAccess(member); |
| 744 } | 745 } |
| 745 } | 746 } |
| 746 if (name == const PublicName('call')) { | 747 if (name == const PublicName('call')) { |
| 747 if (unaliasedBound.isFunctionType) { | 748 if (unaliasedBound.isFunctionType) { |
| 748 // This is an access the implicit 'call' method of a function type. | 749 // This is an access the implicit 'call' method of a function type. |
| 749 return new FunctionCallAccess(receiverElement, unaliasedBound); | 750 return new FunctionCallAccess(receiverElement, unaliasedBound); |
| 750 } | 751 } |
| 751 if (types.isSubtype(interface, coreTypes.functionType)) { | 752 if (types.isSubtype(interface, commonElements.functionType)) { |
| 752 // This is an access of the special 'call' method implicitly defined | 753 // This is an access of the special 'call' method implicitly defined |
| 753 // on 'Function'. This method can be called with any arguments, which | 754 // on 'Function'. This method can be called with any arguments, which |
| 754 // we ensure by giving it the type 'dynamic'. | 755 // we ensure by giving it the type 'dynamic'. |
| 755 return new FunctionCallAccess(null, const DynamicType()); | 756 return new FunctionCallAccess(null, const DynamicType()); |
| 756 } | 757 } |
| 757 } | 758 } |
| 758 return null; | 759 return null; |
| 759 } | 760 } |
| 760 | 761 |
| 761 DartType unaliasedBound = | 762 DartType unaliasedBound = |
| (...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1591 analyze(node.first); | 1592 analyze(node.first); |
| 1592 analyze(node.second); | 1593 analyze(node.second); |
| 1593 return stringType; | 1594 return stringType; |
| 1594 } | 1595 } |
| 1595 | 1596 |
| 1596 DartType visitLiteralNull(LiteralNull node) { | 1597 DartType visitLiteralNull(LiteralNull node) { |
| 1597 return const DynamicType(); | 1598 return const DynamicType(); |
| 1598 } | 1599 } |
| 1599 | 1600 |
| 1600 DartType visitLiteralSymbol(LiteralSymbol node) { | 1601 DartType visitLiteralSymbol(LiteralSymbol node) { |
| 1601 return coreTypes.symbolType; | 1602 return commonElements.symbolType; |
| 1602 } | 1603 } |
| 1603 | 1604 |
| 1604 DartType computeConstructorType( | 1605 DartType computeConstructorType( |
| 1605 ConstructorElement constructor, DartType type) { | 1606 ConstructorElement constructor, DartType type) { |
| 1606 if (Elements.isUnresolved(constructor)) return const DynamicType(); | 1607 if (Elements.isUnresolved(constructor)) return const DynamicType(); |
| 1607 DartType constructorType = constructor.computeType(resolution); | 1608 DartType constructorType = constructor.computeType(resolution); |
| 1608 if (identical(type.kind, TypeKind.INTERFACE)) { | 1609 if (identical(type.kind, TypeKind.INTERFACE)) { |
| 1609 if (constructor.isSynthesized) { | 1610 if (constructor.isSynthesized) { |
| 1610 // TODO(johnniwinther): Remove this when synthesized constructors handle | 1611 // TODO(johnniwinther): Remove this when synthesized constructors handle |
| 1611 // type variables correctly. | 1612 // type variables correctly. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1678 | 1679 |
| 1679 // Executing a return statement return e; [...] It is a static type warning | 1680 // Executing a return statement return e; [...] It is a static type warning |
| 1680 // if the type of e may not be assigned to the declared return type of the | 1681 // if the type of e may not be assigned to the declared return type of the |
| 1681 // immediately enclosing function. | 1682 // immediately enclosing function. |
| 1682 if (expression != null) { | 1683 if (expression != null) { |
| 1683 DartType expressionType = analyze(expression); | 1684 DartType expressionType = analyze(expression); |
| 1684 if (executableContext.isGenerativeConstructor) { | 1685 if (executableContext.isGenerativeConstructor) { |
| 1685 // The resolver already emitted an error for this expression. | 1686 // The resolver already emitted an error for this expression. |
| 1686 } else { | 1687 } else { |
| 1687 if (currentAsyncMarker == AsyncMarker.ASYNC) { | 1688 if (currentAsyncMarker == AsyncMarker.ASYNC) { |
| 1688 expressionType = coreTypes.futureType(types.flatten(expressionType)); | 1689 expressionType = |
| 1690 commonElements.futureType(types.flatten(expressionType)); |
| 1689 } | 1691 } |
| 1690 if (expectedReturnType.isVoid && | 1692 if (expectedReturnType.isVoid && |
| 1691 !types.isAssignable(expressionType, const VoidType())) { | 1693 !types.isAssignable(expressionType, const VoidType())) { |
| 1692 reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID); | 1694 reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID); |
| 1693 } else { | 1695 } else { |
| 1694 checkAssignable(expression, expressionType, expectedReturnType); | 1696 checkAssignable(expression, expressionType, expectedReturnType); |
| 1695 } | 1697 } |
| 1696 } | 1698 } |
| 1697 } else if (currentAsyncMarker != AsyncMarker.SYNC) { | 1699 } else if (currentAsyncMarker != AsyncMarker.SYNC) { |
| 1698 // `return;` is allowed. | 1700 // `return;` is allowed. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1720 return types.flatten(expressionType); | 1722 return types.flatten(expressionType); |
| 1721 } else { | 1723 } else { |
| 1722 return const DynamicType(); | 1724 return const DynamicType(); |
| 1723 } | 1725 } |
| 1724 } | 1726 } |
| 1725 | 1727 |
| 1726 DartType visitYield(Yield node) { | 1728 DartType visitYield(Yield node) { |
| 1727 DartType resultType = analyze(node.expression); | 1729 DartType resultType = analyze(node.expression); |
| 1728 if (!node.hasStar) { | 1730 if (!node.hasStar) { |
| 1729 if (currentAsyncMarker.isAsync) { | 1731 if (currentAsyncMarker.isAsync) { |
| 1730 resultType = coreTypes.streamType(resultType); | 1732 resultType = commonElements.streamType(resultType); |
| 1731 } else { | 1733 } else { |
| 1732 resultType = coreTypes.iterableType(resultType); | 1734 resultType = commonElements.iterableType(resultType); |
| 1733 } | 1735 } |
| 1734 } else { | 1736 } else { |
| 1735 if (currentAsyncMarker.isAsync) { | 1737 if (currentAsyncMarker.isAsync) { |
| 1736 // The static type of expression must be assignable to Stream. | 1738 // The static type of expression must be assignable to Stream. |
| 1737 checkAssignable(node, resultType, coreTypes.streamType()); | 1739 checkAssignable(node, resultType, commonElements.streamType()); |
| 1738 } else { | 1740 } else { |
| 1739 // The static type of expression must be assignable to Iterable. | 1741 // The static type of expression must be assignable to Iterable. |
| 1740 checkAssignable(node, resultType, coreTypes.iterableType()); | 1742 checkAssignable(node, resultType, commonElements.iterableType()); |
| 1741 } | 1743 } |
| 1742 } | 1744 } |
| 1743 // The static type of the result must be assignable to the declared type. | 1745 // The static type of the result must be assignable to the declared type. |
| 1744 checkAssignable(node, resultType, expectedReturnType); | 1746 checkAssignable(node, resultType, expectedReturnType); |
| 1745 return const StatementType(); | 1747 return const StatementType(); |
| 1746 } | 1748 } |
| 1747 | 1749 |
| 1748 DartType visitTypeAnnotation(TypeAnnotation node) { | 1750 DartType visitTypeAnnotation(TypeAnnotation node) { |
| 1749 return elements.getType(node); | 1751 return elements.getType(node); |
| 1750 } | 1752 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1850 return analyzeWithDefault(declaredIdentifier.type, const DynamicType()); | 1852 return analyzeWithDefault(declaredIdentifier.type, const DynamicType()); |
| 1851 } else { | 1853 } else { |
| 1852 return analyze(node.declaredIdentifier); | 1854 return analyze(node.declaredIdentifier); |
| 1853 } | 1855 } |
| 1854 } | 1856 } |
| 1855 | 1857 |
| 1856 visitAsyncForIn(AsyncForIn node) { | 1858 visitAsyncForIn(AsyncForIn node) { |
| 1857 DartType elementType = computeForInElementType(node); | 1859 DartType elementType = computeForInElementType(node); |
| 1858 DartType expressionType = analyze(node.expression); | 1860 DartType expressionType = analyze(node.expression); |
| 1859 if (resolution.target.supportsAsyncAwait) { | 1861 if (resolution.target.supportsAsyncAwait) { |
| 1860 DartType streamOfDynamic = coreTypes.streamType(); | 1862 DartType streamOfDynamic = commonElements.streamType(); |
| 1861 if (!types.isAssignable(expressionType, streamOfDynamic)) { | 1863 if (!types.isAssignable(expressionType, streamOfDynamic)) { |
| 1862 reportMessage(node.expression, MessageKind.NOT_ASSIGNABLE, | 1864 reportMessage(node.expression, MessageKind.NOT_ASSIGNABLE, |
| 1863 {'fromType': expressionType, 'toType': streamOfDynamic}, | 1865 {'fromType': expressionType, 'toType': streamOfDynamic}, |
| 1864 isHint: true); | 1866 isHint: true); |
| 1865 } else { | 1867 } else { |
| 1866 InterfaceType interfaceType = | 1868 InterfaceType interfaceType = |
| 1867 Types.computeInterfaceType(resolution, expressionType); | 1869 Types.computeInterfaceType(resolution, expressionType); |
| 1868 if (interfaceType != null) { | 1870 if (interfaceType != null) { |
| 1869 InterfaceType streamType = | 1871 InterfaceType streamType = |
| 1870 interfaceType.asInstanceOf(streamOfDynamic.element); | 1872 interfaceType.asInstanceOf(streamOfDynamic.element); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2032 | 2034 |
| 2033 visitTypedef(Typedef node) { | 2035 visitTypedef(Typedef node) { |
| 2034 // Do not typecheck [Typedef] nodes. | 2036 // Do not typecheck [Typedef] nodes. |
| 2035 } | 2037 } |
| 2036 | 2038 |
| 2037 visitNode(Node node) { | 2039 visitNode(Node node) { |
| 2038 reporter.internalError(node, | 2040 reporter.internalError(node, |
| 2039 'Unexpected node ${node.getObjectDescription()} in the type checker.'); | 2041 'Unexpected node ${node.getObjectDescription()} in the type checker.'); |
| 2040 } | 2042 } |
| 2041 } | 2043 } |
| OLD | NEW |