Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(980)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 177543002: Constrain type annotations with deferred types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 1648 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 breakTargetStack = breakTargetStack.tail; 1659 breakTargetStack = breakTargetStack.tail;
1660 labels = labels.outer; 1660 labels = labels.outer;
1661 } 1661 }
1662 } 1662 }
1663 1663
1664 class TypeResolver { 1664 class TypeResolver {
1665 final Compiler compiler; 1665 final Compiler compiler;
1666 1666
1667 TypeResolver(this.compiler); 1667 TypeResolver(this.compiler);
1668 1668
1669 Element resolveTypeName(Scope scope, 1669 /// Tries to resolve the type name as an element.
1670 Identifier prefixName, 1670 Element resolveTypeName(Identifier prefixName,
1671 Identifier typeName) { 1671 Identifier typeName,
1672 Scope scope,
1673 {bool deferredIsMalformed: true}) {
1674 Element element;
1675 bool deferredTypeAnnotation = false;
1672 if (prefixName != null) { 1676 if (prefixName != null) {
1673 Element element = 1677 Element prefixElement =
1674 lookupInScope(compiler, prefixName, scope, prefixName.source); 1678 lookupInScope(compiler, prefixName, scope, prefixName.source);
1675 if (element != null && element.isPrefix()) { 1679 if (prefixElement != null && prefixElement.isPrefix()) {
1676 // The receiver is a prefix. Lookup in the imported members. 1680 // The receiver is a prefix. Lookup in the imported members.
1677 PrefixElement prefix = element; 1681 PrefixElement prefix = prefixElement;
1678 return prefix.lookupLocalMember(typeName.source); 1682 element = prefix.lookupLocalMember(typeName.source);
1683 // TODO(17260, sigurdm): The test for DartBackend is there because
1684 // dart2dart outputs malformed types with prefix.
1685 if (element != null &&
1686 prefix.isDeferred &&
1687 deferredIsMalformed &&
1688 compiler.backend is! DartBackend) {
1689 element = new ErroneousElementX(MessageKind.DEFERRED_TYPE_ANNOTATION,
1690 {'node': typeName},
1691 element.name,
1692 element);
1693 }
1694 } else {
1695 // The caller of this method will create the ErroneousElement for
1696 // the MalformedType.
1697 element = null;
1679 } 1698 }
1680 // The caller of this method will create the ErroneousElement for
1681 // the MalformedType.
1682 return null;
1683 } else { 1699 } else {
1684 String stringValue = typeName.source; 1700 String stringValue = typeName.source;
1685 if (identical(stringValue, 'void')) { 1701 if (identical(stringValue, 'void')) {
1686 return compiler.types.voidType.element; 1702 element = compiler.types.voidType.element;
1687 } else if (identical(stringValue, 'dynamic')) { 1703 } else if (identical(stringValue, 'dynamic')) {
1688 return compiler.dynamicClass; 1704 element = compiler.dynamicClass;
1689 } else { 1705 } else {
1690 return lookupInScope(compiler, typeName, scope, typeName.source); 1706 element = lookupInScope(compiler, typeName, scope, typeName.source);
1691 } 1707 }
1692 } 1708 }
1709 return element;
1693 } 1710 }
1694 1711
1695 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, 1712 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node,
1696 {bool malformedIsError: false}) { 1713 {bool malformedIsError: false,
1714 bool deferredIsMalformed: true}) {
1697 Identifier typeName; 1715 Identifier typeName;
1698 Identifier prefixName; 1716 Identifier prefixName;
1699 Send send = node.typeName.asSend(); 1717 Send send = node.typeName.asSend();
1700 if (send != null) { 1718 if (send != null) {
1701 // The type name is of the form [: prefix . identifier :]. 1719 // The type name is of the form [: prefix . identifier :].
1702 prefixName = send.receiver.asIdentifier(); 1720 prefixName = send.receiver.asIdentifier();
1703 typeName = send.selector.asIdentifier(); 1721 typeName = send.selector.asIdentifier();
1704 } else { 1722 } else {
1705 typeName = node.typeName.asIdentifier(); 1723 typeName = node.typeName.asIdentifier();
1706 } 1724 }
1707 1725
1708 Element element = resolveTypeName(visitor.scope, prefixName, typeName); 1726 Element element = resolveTypeName(prefixName, typeName, visitor.scope,
1727 deferredIsMalformed: deferredIsMalformed);
1709 1728
1710 DartType reportFailureAndCreateType(MessageKind messageKind, 1729 DartType reportFailureAndCreateType(MessageKind messageKind,
1711 Map messageArguments, 1730 Map messageArguments,
1712 {DartType userProvidedBadType}) { 1731 {DartType userProvidedBadType,
1732 Element erroneousElement}) {
1713 if (malformedIsError) { 1733 if (malformedIsError) {
1714 visitor.error(node, messageKind, messageArguments); 1734 visitor.error(node, messageKind, messageArguments);
1715 } else { 1735 } else {
1716 compiler.backend.registerThrowRuntimeError(visitor.mapping); 1736 compiler.backend.registerThrowRuntimeError(visitor.mapping);
1717 visitor.warning(node, messageKind, messageArguments); 1737 visitor.warning(node, messageKind, messageArguments);
1718 } 1738 }
1719 Element erroneousElement = new ErroneousElementX( 1739 if (erroneousElement == null) {
1720 messageKind, messageArguments, typeName.source, 1740 erroneousElement = new ErroneousElementX(
1721 visitor.enclosingElement); 1741 messageKind, messageArguments, typeName.source,
1742 visitor.enclosingElement);
1743 }
1722 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); 1744 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>();
1723 resolveTypeArguments(visitor, node, null, arguments); 1745 resolveTypeArguments(visitor, node, null, arguments);
1724 return new MalformedType(erroneousElement, 1746 return new MalformedType(erroneousElement,
1725 userProvidedBadType, arguments.toLink()); 1747 userProvidedBadType, arguments.toLink());
1726 } 1748 }
1727 1749
1728 DartType checkNoTypeArguments(DartType type) { 1750 DartType checkNoTypeArguments(DartType type) {
1729 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); 1751 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>();
1730 bool hasTypeArgumentMismatch = resolveTypeArguments( 1752 bool hasTypeArgumentMismatch = resolveTypeArguments(
1731 visitor, node, const Link<DartType>(), arguments); 1753 visitor, node, const Link<DartType>(), arguments);
1732 if (hasTypeArgumentMismatch) { 1754 if (hasTypeArgumentMismatch) {
1733 return new MalformedType( 1755 return new MalformedType(
1734 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, 1756 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
1735 {'type': node}, typeName.source, visitor.enclosingElement), 1757 {'type': node}, typeName.source, visitor.enclosingElement),
1736 type, arguments.toLink()); 1758 type, arguments.toLink());
1737 } 1759 }
1738 return type; 1760 return type;
1739 } 1761 }
1740 1762
1763 // Try to construct the type from the element.
1741 DartType type; 1764 DartType type;
1742 if (element == null) { 1765 if (element == null) {
1743 type = reportFailureAndCreateType( 1766 type = reportFailureAndCreateType(
1744 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); 1767 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName});
1745 } else if (element.isAmbiguous()) { 1768 } else if (element.isAmbiguous()) {
1746 AmbiguousElement ambiguous = element; 1769 AmbiguousElement ambiguous = element;
1747 type = reportFailureAndCreateType( 1770 type = reportFailureAndCreateType(
1748 ambiguous.messageKind, ambiguous.messageArguments); 1771 ambiguous.messageKind, ambiguous.messageArguments);
1749 ambiguous.diagnose(visitor.mapping.currentElement, compiler); 1772 ambiguous.diagnose(visitor.mapping.currentElement, compiler);
1773 } else if (element.isErroneous()) {
1774 ErroneousElement erroneousElement = element;
1775 type = reportFailureAndCreateType(
1776 erroneousElement.messageKind, erroneousElement.messageArguments,
1777 erroneousElement: erroneousElement);
1750 } else if (!element.impliesType()) { 1778 } else if (!element.impliesType()) {
1751 type = reportFailureAndCreateType( 1779 type = reportFailureAndCreateType(
1752 MessageKind.NOT_A_TYPE, {'node': node.typeName}); 1780 MessageKind.NOT_A_TYPE, {'node': node.typeName});
1753 } else { 1781 } else {
1754 bool addTypeVariableBoundsCheck = false; 1782 bool addTypeVariableBoundsCheck = false;
1755 if (identical(element, compiler.types.voidType.element) || 1783 if (identical(element, compiler.types.voidType.element) ||
1756 identical(element, compiler.dynamicClass)) { 1784 identical(element, compiler.dynamicClass)) {
1757 type = checkNoTypeArguments(element.computeType(compiler)); 1785 type = checkNoTypeArguments(element.computeType(compiler));
1758 } else if (element.isClass()) { 1786 } else if (element.isClass()) {
1759 ClassElement cls = element; 1787 ClassElement cls = element;
(...skipping 1414 matching lines...) Expand 10 before | Expand all | Expand 10 after
3174 return node.accept(new ConstructorResolver(compiler, this)); 3202 return node.accept(new ConstructorResolver(compiler, this));
3175 } 3203 }
3176 3204
3177 FunctionElement resolveRedirectingFactory(Return node, 3205 FunctionElement resolveRedirectingFactory(Return node,
3178 {bool inConstContext: false}) { 3206 {bool inConstContext: false}) {
3179 return node.accept(new ConstructorResolver(compiler, this, 3207 return node.accept(new ConstructorResolver(compiler, this,
3180 inConstContext: inConstContext)); 3208 inConstContext: inConstContext));
3181 } 3209 }
3182 3210
3183 DartType resolveTypeAnnotation(TypeAnnotation node, 3211 DartType resolveTypeAnnotation(TypeAnnotation node,
3184 {bool malformedIsError: false}) { 3212 {bool malformedIsError: false,
3213 bool deferredIsMalformed: true}) {
3185 DartType type = typeResolver.resolveTypeAnnotation( 3214 DartType type = typeResolver.resolveTypeAnnotation(
3186 this, node, malformedIsError: malformedIsError); 3215 this, node, malformedIsError: malformedIsError,
3216 deferredIsMalformed: deferredIsMalformed);
3187 if (type == null) return null; 3217 if (type == null) return null;
3188 if (inCheckContext) { 3218 if (inCheckContext) {
3189 compiler.enqueuer.resolution.registerIsCheck(type, mapping); 3219 compiler.enqueuer.resolution.registerIsCheck(type, mapping);
3190 compiler.backend.registerRequiredType(type, enclosingElement); 3220 compiler.backend.registerRequiredType(type, enclosingElement);
3191 } 3221 }
3192 return type; 3222 return type;
3193 } 3223 }
3194 3224
3195 visitModifiers(Modifiers node) { 3225 visitModifiers(Modifiers node) {
3196 internalError(node, 'modifiers'); 3226 internalError(node, 'modifiers');
(...skipping 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after
4560 } else { 4590 } else {
4561 type = element.getEnclosingClass().computeType(compiler).asRaw(); 4591 type = element.getEnclosingClass().computeType(compiler).asRaw();
4562 } 4592 }
4563 } 4593 }
4564 resolver.mapping.setType(expression, type); 4594 resolver.mapping.setType(expression, type);
4565 return element; 4595 return element;
4566 } 4596 }
4567 4597
4568 Element visitTypeAnnotation(TypeAnnotation node) { 4598 Element visitTypeAnnotation(TypeAnnotation node) {
4569 assert(invariant(node, type == null)); 4599 assert(invariant(node, type == null));
4600 // This is not really resolving a type-annotation, but the name of the
4601 // constructor. Therefore we allow deferred types.
4570 type = resolver.resolveTypeAnnotation(node, 4602 type = resolver.resolveTypeAnnotation(node,
4571 malformedIsError: inConstContext); 4603 malformedIsError: inConstContext,
4604 deferredIsMalformed: false);
4572 compiler.backend.registerRequiredType(type, resolver.enclosingElement); 4605 compiler.backend.registerRequiredType(type, resolver.enclosingElement);
4573 return type.element; 4606 return type.element;
4574 } 4607 }
4575 4608
4576 Element visitSend(Send node) { 4609 Element visitSend(Send node) {
4577 Element element = visit(node.receiver); 4610 Element element = visit(node.receiver);
4578 assert(invariant(node.receiver, element != null, 4611 assert(invariant(node.receiver, element != null,
4579 message: 'No element return for $node.receiver.')); 4612 message: 'No element return for $node.receiver.'));
4580 if (Elements.isUnresolved(element)) return element; 4613 if (Elements.isUnresolved(element)) return element;
4581 Identifier name = node.selector.asIdentifier(); 4614 Identifier name = node.selector.asIdentifier();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4633 return finishConstructorReference(visit(expression), 4666 return finishConstructorReference(visit(expression),
4634 expression, expression); 4667 expression, expression);
4635 } 4668 }
4636 } 4669 }
4637 4670
4638 /// Looks up [name] in [scope] and unwraps the result. 4671 /// Looks up [name] in [scope] and unwraps the result.
4639 Element lookupInScope(Compiler compiler, Node node, 4672 Element lookupInScope(Compiler compiler, Node node,
4640 Scope scope, String name) { 4673 Scope scope, String name) {
4641 return Elements.unwrap(scope.lookup(name), compiler, node); 4674 return Elements.unwrap(scope.lookup(name), compiler, node);
4642 } 4675 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698