| 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 part of resolution; | 5 part of resolution; |
| 6 | 6 |
| 7 abstract class TreeElements { | 7 abstract class TreeElements { |
| 8 Element get currentElement; | 8 Element get currentElement; |
| 9 Setlet<Node> get superUses; | 9 Setlet<Node> get superUses; |
| 10 | 10 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 void setIteratorSelector(ForIn node, Selector selector); | 30 void setIteratorSelector(ForIn node, Selector selector); |
| 31 void setMoveNextSelector(ForIn node, Selector selector); | 31 void setMoveNextSelector(ForIn node, Selector selector); |
| 32 void setCurrentSelector(ForIn node, Selector selector); | 32 void setCurrentSelector(ForIn node, Selector selector); |
| 33 void setConstant(Node node, Constant constant); | 33 void setConstant(Node node, Constant constant); |
| 34 Constant getConstant(Node node); | 34 Constant getConstant(Node node); |
| 35 | 35 |
| 36 /** | 36 /** |
| 37 * Returns [:true:] if [node] is a type literal. | 37 * Returns [:true:] if [node] is a type literal. |
| 38 * | 38 * |
| 39 * Resolution marks this by setting the type on the node to be the | 39 * Resolution marks this by setting the type on the node to be the |
| 40 * [:Type:] type. | 40 * type that the literal refers to. |
| 41 */ | 41 */ |
| 42 bool isTypeLiteral(Send node); | 42 bool isTypeLiteral(Send node); |
| 43 | 43 |
| 44 /// Returns the type that the type literal [node] refers to. |
| 45 DartType getTypeLiteralType(Send node); |
| 46 |
| 44 /// Register additional dependencies required by [currentElement]. | 47 /// Register additional dependencies required by [currentElement]. |
| 45 /// For example, elements that are used by a backend. | 48 /// For example, elements that are used by a backend. |
| 46 void registerDependency(Element element); | 49 void registerDependency(Element element); |
| 47 | 50 |
| 48 /// Returns a list of nodes that potentially mutate [element] anywhere in its | 51 /// Returns a list of nodes that potentially mutate [element] anywhere in its |
| 49 /// scope. | 52 /// scope. |
| 50 List<Node> getPotentialMutations(VariableElement element); | 53 List<Node> getPotentialMutations(VariableElement element); |
| 51 | 54 |
| 52 /// Returns a list of nodes that potentially mutate [element] in [node]. | 55 /// Returns a list of nodes that potentially mutate [element] in [node]. |
| 53 List<Node> getPotentialMutationsIn(Node node, VariableElement element); | 56 List<Node> getPotentialMutationsIn(Node node, VariableElement element); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 } | 179 } |
| 177 | 180 |
| 178 Constant getConstant(Node node) { | 181 Constant getConstant(Node node) { |
| 179 return constants[node]; | 182 return constants[node]; |
| 180 } | 183 } |
| 181 | 184 |
| 182 bool isTypeLiteral(Send node) { | 185 bool isTypeLiteral(Send node) { |
| 183 return getType(node) != null; | 186 return getType(node) != null; |
| 184 } | 187 } |
| 185 | 188 |
| 189 DartType getTypeLiteralType(Send node) { |
| 190 return getType(node); |
| 191 } |
| 192 |
| 186 void registerDependency(Element element) { | 193 void registerDependency(Element element) { |
| 187 if (element == null) return; | 194 if (element == null) return; |
| 188 otherDependencies.add(element.implementation); | 195 otherDependencies.add(element.implementation); |
| 189 } | 196 } |
| 190 | 197 |
| 191 List<Node> getPotentialMutations(VariableElement element) { | 198 List<Node> getPotentialMutations(VariableElement element) { |
| 192 List<Node> mutations = potentiallyMutated[element]; | 199 List<Node> mutations = potentiallyMutated[element]; |
| 193 if (mutations == null) return const <Node>[]; | 200 if (mutations == null) return const <Node>[]; |
| 194 return mutations; | 201 return mutations; |
| 195 } | 202 } |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 error(element.modifiers.getStatic(), | 576 error(element.modifiers.getStatic(), |
| 570 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); | 577 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); |
| 571 } | 578 } |
| 572 ResolverVisitor visitor = visitorFor(element); | 579 ResolverVisitor visitor = visitorFor(element); |
| 573 ResolutionRegistry registry = visitor.registry; | 580 ResolutionRegistry registry = visitor.registry; |
| 574 // TODO(johnniwinther): Share the resolved type between all variables | 581 // TODO(johnniwinther): Share the resolved type between all variables |
| 575 // declared in the same declaration. | 582 // declared in the same declaration. |
| 576 if (tree.type != null) { | 583 if (tree.type != null) { |
| 577 element.variables.type = visitor.resolveTypeAnnotation(tree.type); | 584 element.variables.type = visitor.resolveTypeAnnotation(tree.type); |
| 578 } else { | 585 } else { |
| 579 element.variables.type = compiler.types.dynamicType; | 586 element.variables.type = const DynamicType(); |
| 580 } | 587 } |
| 581 registry.useElement(tree, element); | 588 registry.useElement(tree, element); |
| 582 | 589 |
| 583 Expression initializer = element.initializer; | 590 Expression initializer = element.initializer; |
| 584 Modifiers modifiers = element.modifiers; | 591 Modifiers modifiers = element.modifiers; |
| 585 if (initializer != null) { | 592 if (initializer != null) { |
| 586 // TODO(johnniwinther): Avoid analyzing initializers if | 593 // TODO(johnniwinther): Avoid analyzing initializers if |
| 587 // [Compiler.analyzeSignaturesOnly] is set. | 594 // [Compiler.analyzeSignaturesOnly] is set. |
| 588 visitor.visit(initializer); | 595 visitor.visit(initializer); |
| 589 } else if (modifiers.isConst) { | 596 } else if (modifiers.isConst) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 619 | 626 |
| 620 DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) { | 627 DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) { |
| 621 DartType type = resolveReturnType(element, annotation); | 628 DartType type = resolveReturnType(element, annotation); |
| 622 if (type.isVoid) { | 629 if (type.isVoid) { |
| 623 error(annotation, MessageKind.VOID_NOT_ALLOWED); | 630 error(annotation, MessageKind.VOID_NOT_ALLOWED); |
| 624 } | 631 } |
| 625 return type; | 632 return type; |
| 626 } | 633 } |
| 627 | 634 |
| 628 DartType resolveReturnType(Element element, TypeAnnotation annotation) { | 635 DartType resolveReturnType(Element element, TypeAnnotation annotation) { |
| 629 if (annotation == null) return compiler.types.dynamicType; | 636 if (annotation == null) return const DynamicType(); |
| 630 DartType result = visitorFor(element).resolveTypeAnnotation(annotation); | 637 DartType result = visitorFor(element).resolveTypeAnnotation(annotation); |
| 631 if (result == null) { | 638 if (result == null) { |
| 632 // TODO(karklose): warning. | 639 // TODO(karklose): warning. |
| 633 return compiler.types.dynamicType; | 640 return const DynamicType(); |
| 634 } | 641 } |
| 635 return result; | 642 return result; |
| 636 } | 643 } |
| 637 | 644 |
| 638 void resolveRedirectionChain(ConstructorElementX constructor, | 645 void resolveRedirectionChain(ConstructorElementX constructor, |
| 639 Spannable node) { | 646 Spannable node) { |
| 640 ConstructorElementX target = constructor; | 647 ConstructorElementX target = constructor; |
| 641 InterfaceType targetType; | 648 InterfaceType targetType; |
| 642 List<Element> seen = new List<Element>(); | 649 List<Element> seen = new List<Element>(); |
| 643 // Follow the chain of redirections and check for cycles. | 650 // Follow the chain of redirections and check for cycles. |
| (...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1676 element.name, | 1683 element.name, |
| 1677 element); | 1684 element); |
| 1678 } | 1685 } |
| 1679 } else { | 1686 } else { |
| 1680 // The caller of this method will create the ErroneousElement for | 1687 // The caller of this method will create the ErroneousElement for |
| 1681 // the MalformedType. | 1688 // the MalformedType. |
| 1682 element = null; | 1689 element = null; |
| 1683 } | 1690 } |
| 1684 } else { | 1691 } else { |
| 1685 String stringValue = typeName.source; | 1692 String stringValue = typeName.source; |
| 1686 if (identical(stringValue, 'dynamic')) { | 1693 element = lookupInScope(compiler, typeName, scope, typeName.source); |
| 1687 element = compiler.dynamicClass; | |
| 1688 } else { | |
| 1689 element = lookupInScope(compiler, typeName, scope, typeName.source); | |
| 1690 } | |
| 1691 } | 1694 } |
| 1692 return element; | 1695 return element; |
| 1693 } | 1696 } |
| 1694 | 1697 |
| 1695 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, | 1698 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, |
| 1696 {bool malformedIsError: false, | 1699 {bool malformedIsError: false, |
| 1697 bool deferredIsMalformed: true}) { | 1700 bool deferredIsMalformed: true}) { |
| 1698 ResolutionRegistry registry = visitor.registry; | 1701 ResolutionRegistry registry = visitor.registry; |
| 1699 | 1702 |
| 1700 Identifier typeName; | 1703 Identifier typeName; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1719 // The type name is of the form [: prefix . identifier :]. | 1722 // The type name is of the form [: prefix . identifier :]. |
| 1720 prefixName = send.receiver.asIdentifier(); | 1723 prefixName = send.receiver.asIdentifier(); |
| 1721 typeName = send.selector.asIdentifier(); | 1724 typeName = send.selector.asIdentifier(); |
| 1722 } else { | 1725 } else { |
| 1723 typeName = node.typeName.asIdentifier(); | 1726 typeName = node.typeName.asIdentifier(); |
| 1724 if (identical(typeName.source, 'void')) { | 1727 if (identical(typeName.source, 'void')) { |
| 1725 type = const VoidType(); | 1728 type = const VoidType(); |
| 1726 checkNoTypeArguments(type); | 1729 checkNoTypeArguments(type); |
| 1727 registry.useType(node, type); | 1730 registry.useType(node, type); |
| 1728 return type; | 1731 return type; |
| 1732 } else if (identical(typeName.source, 'dynamic')) { |
| 1733 type = const DynamicType(); |
| 1734 checkNoTypeArguments(type); |
| 1735 registry.useType(node, type); |
| 1736 return type; |
| 1729 } | 1737 } |
| 1730 } | 1738 } |
| 1731 | 1739 |
| 1732 Element element = resolveTypeName(prefixName, typeName, visitor.scope, | 1740 Element element = resolveTypeName(prefixName, typeName, visitor.scope, |
| 1733 deferredIsMalformed: deferredIsMalformed); | 1741 deferredIsMalformed: deferredIsMalformed); |
| 1734 | 1742 |
| 1735 DartType reportFailureAndCreateType(MessageKind messageKind, | 1743 DartType reportFailureAndCreateType(MessageKind messageKind, |
| 1736 Map messageArguments, | 1744 Map messageArguments, |
| 1737 {DartType userProvidedBadType, | 1745 {DartType userProvidedBadType, |
| 1738 Element erroneousElement}) { | 1746 Element erroneousElement}) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1765 } else if (element.isErroneous) { | 1773 } else if (element.isErroneous) { |
| 1766 ErroneousElement erroneousElement = element; | 1774 ErroneousElement erroneousElement = element; |
| 1767 type = reportFailureAndCreateType( | 1775 type = reportFailureAndCreateType( |
| 1768 erroneousElement.messageKind, erroneousElement.messageArguments, | 1776 erroneousElement.messageKind, erroneousElement.messageArguments, |
| 1769 erroneousElement: erroneousElement); | 1777 erroneousElement: erroneousElement); |
| 1770 } else if (!element.impliesType) { | 1778 } else if (!element.impliesType) { |
| 1771 type = reportFailureAndCreateType( | 1779 type = reportFailureAndCreateType( |
| 1772 MessageKind.NOT_A_TYPE, {'node': node.typeName}); | 1780 MessageKind.NOT_A_TYPE, {'node': node.typeName}); |
| 1773 } else { | 1781 } else { |
| 1774 bool addTypeVariableBoundsCheck = false; | 1782 bool addTypeVariableBoundsCheck = false; |
| 1775 if (identical(element, compiler.dynamicClass)) { | 1783 if (element.isClass) { |
| 1776 type = checkNoTypeArguments(element.computeType(compiler)); | |
| 1777 } else if (element.isClass) { | |
| 1778 ClassElement cls = element; | 1784 ClassElement cls = element; |
| 1779 // TODO(johnniwinther): [_ensureClassWillBeResolved] should imply | 1785 // TODO(johnniwinther): [_ensureClassWillBeResolved] should imply |
| 1780 // [computeType]. | 1786 // [computeType]. |
| 1781 compiler.resolver._ensureClassWillBeResolved(cls); | 1787 compiler.resolver._ensureClassWillBeResolved(cls); |
| 1782 element.computeType(compiler); | 1788 element.computeType(compiler); |
| 1783 var arguments = new LinkBuilder<DartType>(); | 1789 var arguments = new LinkBuilder<DartType>(); |
| 1784 bool hasTypeArgumentMismatch = resolveTypeArguments( | 1790 bool hasTypeArgumentMismatch = resolveTypeArguments( |
| 1785 visitor, node, cls.typeVariables, arguments); | 1791 visitor, node, cls.typeVariables, arguments); |
| 1786 if (hasTypeArgumentMismatch) { | 1792 if (hasTypeArgumentMismatch) { |
| 1787 type = new BadInterfaceType(cls.declaration, | 1793 type = new BadInterfaceType(cls.declaration, |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2114 } else if (node.isSuper()) { | 2120 } else if (node.isSuper()) { |
| 2115 if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC); | 2121 if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC); |
| 2116 if ((ElementCategory.SUPER & allowedCategory) == 0) { | 2122 if ((ElementCategory.SUPER & allowedCategory) == 0) { |
| 2117 error(node, MessageKind.INVALID_USE_OF_SUPER); | 2123 error(node, MessageKind.INVALID_USE_OF_SUPER); |
| 2118 } | 2124 } |
| 2119 return null; | 2125 return null; |
| 2120 } else { | 2126 } else { |
| 2121 String name = node.source; | 2127 String name = node.source; |
| 2122 Element element = lookupInScope(compiler, node, scope, name); | 2128 Element element = lookupInScope(compiler, node, scope, name); |
| 2123 if (Elements.isUnresolved(element) && name == 'dynamic') { | 2129 if (Elements.isUnresolved(element) && name == 'dynamic') { |
| 2124 element = compiler.dynamicClass; | 2130 // TODO(johnniwinther): Remove this hack when we can return more complex |
| 2131 // objects than [Element] from this method. |
| 2132 element = compiler.typeClass; |
| 2133 // Set the type to be `dynamic` to mark that this is a type literal. |
| 2134 registry.setType(node, const DynamicType()); |
| 2125 } | 2135 } |
| 2126 element = reportLookupErrorIfAny(element, node, node.source); | 2136 element = reportLookupErrorIfAny(element, node, node.source); |
| 2127 if (element == null) { | 2137 if (element == null) { |
| 2128 if (!inInstanceContext) { | 2138 if (!inInstanceContext) { |
| 2129 element = warnAndCreateErroneousElement( | 2139 element = warnAndCreateErroneousElement( |
| 2130 node, node.source, MessageKind.CANNOT_RESOLVE, | 2140 node, node.source, MessageKind.CANNOT_RESOLVE, |
| 2131 {'name': node}); | 2141 {'name': node}); |
| 2132 registry.registerThrowNoSuchMethod(); | 2142 registry.registerThrowNoSuchMethod(); |
| 2133 } | 2143 } |
| 2134 } else if (element.isErroneous) { | 2144 } else if (element.isErroneous) { |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2586 warnAndCreateErroneousElement(node.selector, field.name, | 2596 warnAndCreateErroneousElement(node.selector, field.name, |
| 2587 MessageKind.CANNOT_RESOLVE_GETTER); | 2597 MessageKind.CANNOT_RESOLVE_GETTER); |
| 2588 } | 2598 } |
| 2589 } else if (target.isTypeVariable) { | 2599 } else if (target.isTypeVariable) { |
| 2590 ClassElement cls = target.enclosingClass; | 2600 ClassElement cls = target.enclosingClass; |
| 2591 assert(enclosingElement.enclosingClass == cls); | 2601 assert(enclosingElement.enclosingClass == cls); |
| 2592 registry.registerClassUsingVariableExpression(cls); | 2602 registry.registerClassUsingVariableExpression(cls); |
| 2593 registry.registerTypeVariableExpression(); | 2603 registry.registerTypeVariableExpression(); |
| 2594 // Set the type of the node to [Type] to mark this send as a | 2604 // Set the type of the node to [Type] to mark this send as a |
| 2595 // type variable expression. | 2605 // type variable expression. |
| 2596 registry.setType(node, compiler.typeClass.computeType(compiler)); | 2606 registry.registerTypeLiteral(node, target.computeType(compiler)); |
| 2597 registry.registerTypeLiteral(target); | |
| 2598 } else if (target.impliesType && (!sendIsMemberAccess || node.isCall)) { | 2607 } else if (target.impliesType && (!sendIsMemberAccess || node.isCall)) { |
| 2599 // Set the type of the node to [Type] to mark this send as a | 2608 // Set the type of the node to [Type] to mark this send as a |
| 2600 // type literal. | 2609 // type literal. |
| 2601 registry.setType(node, compiler.typeClass.computeType(compiler)); | 2610 DartType type; |
| 2602 registry.registerTypeLiteral(target); | 2611 |
| 2612 // TODO(johnniwinther): Remove this hack when we can pass more complex |
| 2613 // information between methods than resolved elements. |
| 2614 if (target == compiler.typeClass && node.receiver == null) { |
| 2615 // Potentially a 'dynamic' type literal. |
| 2616 type = registry.getType(node.selector); |
| 2617 } |
| 2618 if (type == null) { |
| 2619 type = target.computeType(compiler); |
| 2620 } |
| 2621 registry.registerTypeLiteral(node, type); |
| 2603 | 2622 |
| 2604 // Don't try to make constants of calls to type literals. | 2623 // Don't try to make constants of calls to type literals. |
| 2605 if (!node.isCall) { | 2624 if (!node.isCall) { |
| 2606 analyzeConstant(node); | 2625 analyzeConstant(node); |
| 2607 } else { | 2626 } else { |
| 2608 // The node itself is not a constant but we register the selector (the | 2627 // The node itself is not a constant but we register the selector (the |
| 2609 // identifier that refers to the class/typedef) as a constant. | 2628 // identifier that refers to the class/typedef) as a constant. |
| 2610 analyzeConstant(node.selector); | 2629 analyzeConstant(node.selector); |
| 2611 } | 2630 } |
| 2612 } | 2631 } |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2978 visitThrow(Throw node) { | 2997 visitThrow(Throw node) { |
| 2979 registry.registerThrowExpression(); | 2998 registry.registerThrowExpression(); |
| 2980 visit(node.expression); | 2999 visit(node.expression); |
| 2981 } | 3000 } |
| 2982 | 3001 |
| 2983 visitVariableDefinitions(VariableDefinitions node) { | 3002 visitVariableDefinitions(VariableDefinitions node) { |
| 2984 DartType type; | 3003 DartType type; |
| 2985 if (node.type != null) { | 3004 if (node.type != null) { |
| 2986 type = resolveTypeAnnotation(node.type); | 3005 type = resolveTypeAnnotation(node.type); |
| 2987 } else { | 3006 } else { |
| 2988 type = compiler.types.dynamicType; | 3007 type = const DynamicType(); |
| 2989 } | 3008 } |
| 2990 VariableList variables = new VariableList.node(node, type); | 3009 VariableList variables = new VariableList.node(node, type); |
| 2991 VariableDefinitionsVisitor visitor = | 3010 VariableDefinitionsVisitor visitor = |
| 2992 new VariableDefinitionsVisitor(compiler, node, this, variables); | 3011 new VariableDefinitionsVisitor(compiler, node, this, variables); |
| 2993 | 3012 |
| 2994 Modifiers modifiers = node.modifiers; | 3013 Modifiers modifiers = node.modifiers; |
| 2995 void reportExtraModifier(String modifier) { | 3014 void reportExtraModifier(String modifier) { |
| 2996 Node modifierNode; | 3015 Node modifierNode; |
| 2997 for (Link<Node> nodes = modifiers.nodes.nodes; | 3016 for (Link<Node> nodes = modifiers.nodes.nodes; |
| 2998 !nodes.isEmpty; | 3017 !nodes.isEmpty; |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3774 if (typeNode.bound != null) { | 3793 if (typeNode.bound != null) { |
| 3775 DartType boundType = typeResolver.resolveTypeAnnotation( | 3794 DartType boundType = typeResolver.resolveTypeAnnotation( |
| 3776 this, typeNode.bound); | 3795 this, typeNode.bound); |
| 3777 variableElement.boundCache = boundType; | 3796 variableElement.boundCache = boundType; |
| 3778 | 3797 |
| 3779 void checkTypeVariableBound() { | 3798 void checkTypeVariableBound() { |
| 3780 Link<TypeVariableElement> seenTypeVariables = | 3799 Link<TypeVariableElement> seenTypeVariables = |
| 3781 const Link<TypeVariableElement>(); | 3800 const Link<TypeVariableElement>(); |
| 3782 seenTypeVariables = seenTypeVariables.prepend(variableElement); | 3801 seenTypeVariables = seenTypeVariables.prepend(variableElement); |
| 3783 DartType bound = boundType; | 3802 DartType bound = boundType; |
| 3784 while (bound.kind == TypeKind.TYPE_VARIABLE) { | 3803 while (bound.isTypeVariable) { |
| 3785 TypeVariableElement element = bound.element; | 3804 TypeVariableElement element = bound.element; |
| 3786 if (seenTypeVariables.contains(element)) { | 3805 if (seenTypeVariables.contains(element)) { |
| 3787 if (identical(element, variableElement)) { | 3806 if (identical(element, variableElement)) { |
| 3788 // Only report an error on the checked type variable to avoid | 3807 // Only report an error on the checked type variable to avoid |
| 3789 // generating multiple errors for the same cyclicity. | 3808 // generating multiple errors for the same cyclicity. |
| 3790 warning(typeNode.name, MessageKind.CYCLIC_TYPE_VARIABLE, | 3809 warning(typeNode.name, MessageKind.CYCLIC_TYPE_VARIABLE, |
| 3791 {'typeVariableName': variableElement.name}); | 3810 {'typeVariableName': variableElement.name}); |
| 3792 } | 3811 } |
| 3793 break; | 3812 break; |
| 3794 } | 3813 } |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4027 return element.computeType(compiler); | 4046 return element.computeType(compiler); |
| 4028 } | 4047 } |
| 4029 | 4048 |
| 4030 /// Resolves the mixed type for [mixinNode] and checks that the the mixin type | 4049 /// Resolves the mixed type for [mixinNode] and checks that the the mixin type |
| 4031 /// is a valid, non-blacklisted interface type. The mixin type is returned. | 4050 /// is a valid, non-blacklisted interface type. The mixin type is returned. |
| 4032 DartType checkMixinType(TypeAnnotation mixinNode) { | 4051 DartType checkMixinType(TypeAnnotation mixinNode) { |
| 4033 DartType mixinType = resolveType(mixinNode); | 4052 DartType mixinType = resolveType(mixinNode); |
| 4034 if (isBlackListed(mixinType)) { | 4053 if (isBlackListed(mixinType)) { |
| 4035 compiler.reportError(mixinNode, | 4054 compiler.reportError(mixinNode, |
| 4036 MessageKind.CANNOT_MIXIN, {'type': mixinType}); | 4055 MessageKind.CANNOT_MIXIN, {'type': mixinType}); |
| 4037 } else if (mixinType.kind == TypeKind.TYPE_VARIABLE) { | 4056 } else if (mixinType.isTypeVariable) { |
| 4038 compiler.reportError(mixinNode, MessageKind.CLASS_NAME_EXPECTED); | 4057 compiler.reportError(mixinNode, MessageKind.CLASS_NAME_EXPECTED); |
| 4039 } else if (mixinType.kind == TypeKind.MALFORMED_TYPE) { | 4058 } else if (mixinType.isMalformed) { |
| 4040 compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED); | 4059 compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED); |
| 4041 } | 4060 } |
| 4042 return mixinType; | 4061 return mixinType; |
| 4043 } | 4062 } |
| 4044 | 4063 |
| 4045 DartType visitNamedMixinApplication(NamedMixinApplication node) { | 4064 DartType visitNamedMixinApplication(NamedMixinApplication node) { |
| 4046 invariant(node, element != null); | 4065 invariant(node, element != null); |
| 4047 invariant(element, element.resolutionState == STATE_STARTED, | 4066 invariant(element, element.resolutionState == STATE_STARTED, |
| 4048 message: () => 'cyclic resolution of class $element'); | 4067 message: () => 'cyclic resolution of class $element'); |
| 4049 | 4068 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4144 node.asNamedMixinApplication(); | 4163 node.asNamedMixinApplication(); |
| 4145 Link<DartType> interfaces = (namedMixinApplication != null) | 4164 Link<DartType> interfaces = (namedMixinApplication != null) |
| 4146 ? resolveInterfaces(namedMixinApplication.interfaces, | 4165 ? resolveInterfaces(namedMixinApplication.interfaces, |
| 4147 namedMixinApplication.superclass) | 4166 namedMixinApplication.superclass) |
| 4148 : const Link<DartType>(); | 4167 : const Link<DartType>(); |
| 4149 | 4168 |
| 4150 // The class that is the result of a mixin application implements | 4169 // The class that is the result of a mixin application implements |
| 4151 // the interface of the class that was mixed in so always prepend | 4170 // the interface of the class that was mixed in so always prepend |
| 4152 // that to the interface list. | 4171 // that to the interface list. |
| 4153 if (mixinApplication.interfaces == null) { | 4172 if (mixinApplication.interfaces == null) { |
| 4154 if (mixinType.kind == TypeKind.INTERFACE) { | 4173 if (mixinType.isInterfaceType) { |
| 4155 // Avoid malformed types in the interfaces. | 4174 // Avoid malformed types in the interfaces. |
| 4156 interfaces = interfaces.prepend(mixinType); | 4175 interfaces = interfaces.prepend(mixinType); |
| 4157 } | 4176 } |
| 4158 mixinApplication.interfaces = interfaces; | 4177 mixinApplication.interfaces = interfaces; |
| 4159 } else { | 4178 } else { |
| 4160 assert(invariant(mixinApplication, | 4179 assert(invariant(mixinApplication, |
| 4161 mixinApplication.hasIncompleteHierarchy)); | 4180 mixinApplication.hasIncompleteHierarchy)); |
| 4162 } | 4181 } |
| 4163 | 4182 |
| 4164 ClassElement superclass = supertype.element; | 4183 ClassElement superclass = supertype.element; |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4334 supertypes = supertypes.tail; | 4353 supertypes = supertypes.tail; |
| 4335 } | 4354 } |
| 4336 } | 4355 } |
| 4337 | 4356 |
| 4338 isBlackListed(DartType type) { | 4357 isBlackListed(DartType type) { |
| 4339 LibraryElement lib = element.library; | 4358 LibraryElement lib = element.library; |
| 4340 return | 4359 return |
| 4341 !identical(lib, compiler.coreLibrary) && | 4360 !identical(lib, compiler.coreLibrary) && |
| 4342 !identical(lib, compiler.jsHelperLibrary) && | 4361 !identical(lib, compiler.jsHelperLibrary) && |
| 4343 !identical(lib, compiler.interceptorsLibrary) && | 4362 !identical(lib, compiler.interceptorsLibrary) && |
| 4344 (identical(type, compiler.types.dynamicType) || | 4363 (type.isDynamic || |
| 4345 identical(type.element, compiler.boolClass) || | 4364 identical(type.element, compiler.boolClass) || |
| 4346 identical(type.element, compiler.numClass) || | 4365 identical(type.element, compiler.numClass) || |
| 4347 identical(type.element, compiler.intClass) || | 4366 identical(type.element, compiler.intClass) || |
| 4348 identical(type.element, compiler.doubleClass) || | 4367 identical(type.element, compiler.doubleClass) || |
| 4349 identical(type.element, compiler.stringClass) || | 4368 identical(type.element, compiler.stringClass) || |
| 4350 identical(type.element, compiler.nullClass)); | 4369 identical(type.element, compiler.nullClass)); |
| 4351 } | 4370 } |
| 4352 } | 4371 } |
| 4353 | 4372 |
| 4354 class ClassSupertypeResolver extends CommonResolverVisitor { | 4373 class ClassSupertypeResolver extends CommonResolverVisitor { |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4575 // The unnamed constructor may not exist, so [e] may become unresolved. | 4594 // The unnamed constructor may not exist, so [e] may become unresolved. |
| 4576 element = resolveConstructor(cls, diagnosticNode, ''); | 4595 element = resolveConstructor(cls, diagnosticNode, ''); |
| 4577 } else { | 4596 } else { |
| 4578 element = failOrReturnErroneousElement( | 4597 element = failOrReturnErroneousElement( |
| 4579 element, diagnosticNode, element.name, MessageKind.NOT_A_TYPE, | 4598 element, diagnosticNode, element.name, MessageKind.NOT_A_TYPE, |
| 4580 {'node': diagnosticNode}); | 4599 {'node': diagnosticNode}); |
| 4581 } | 4600 } |
| 4582 } | 4601 } |
| 4583 if (type == null) { | 4602 if (type == null) { |
| 4584 if (Elements.isUnresolved(element)) { | 4603 if (Elements.isUnresolved(element)) { |
| 4585 type = compiler.types.dynamicType; | 4604 type = const DynamicType(); |
| 4586 } else { | 4605 } else { |
| 4587 type = element.enclosingClass.rawType; | 4606 type = element.enclosingClass.rawType; |
| 4588 } | 4607 } |
| 4589 } | 4608 } |
| 4590 resolver.registry.setType(expression, type); | 4609 resolver.registry.setType(expression, type); |
| 4591 return element; | 4610 return element; |
| 4592 } | 4611 } |
| 4593 | 4612 |
| 4594 Element visitTypeAnnotation(TypeAnnotation node) { | 4613 Element visitTypeAnnotation(TypeAnnotation node) { |
| 4595 assert(invariant(node, type == null)); | 4614 assert(invariant(node, type == null)); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4682 TreeElements _treeElements; | 4701 TreeElements _treeElements; |
| 4683 | 4702 |
| 4684 bool get hasTreeElements => _treeElements != null; | 4703 bool get hasTreeElements => _treeElements != null; |
| 4685 | 4704 |
| 4686 TreeElements get treeElements { | 4705 TreeElements get treeElements { |
| 4687 assert(invariant(this, _treeElements !=null, | 4706 assert(invariant(this, _treeElements !=null, |
| 4688 message: "TreeElements have not been computed for $this.")); | 4707 message: "TreeElements have not been computed for $this.")); |
| 4689 return _treeElements; | 4708 return _treeElements; |
| 4690 } | 4709 } |
| 4691 } | 4710 } |
| OLD | NEW |