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

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 if (element != null &&
1684 prefix.isDeferred &&
1685 deferredIsMalformed &&
1686 compiler.deferredLoadTask.splitProgram) {
floitsch 2014/03/03 14:18:06 why the check for compiler.deferredLoadTast.splitP
sigurdm 2014/03/04 12:36:19 Added a comment explaining why.
1687 element = new ErroneousElementX(MessageKind.DEFERRED_TYPE_ANNOTATION,
1688 {'node': typeName},
1689 element.name,
1690 element);
1691 }
1692 } else {
1693 // The caller of this method will create the ErroneousElement for
1694 // the MalformedType.
1695 element = null;
1679 } 1696 }
1680 // The caller of this method will create the ErroneousElement for
1681 // the MalformedType.
1682 return null;
1683 } else { 1697 } else {
1684 String stringValue = typeName.source; 1698 String stringValue = typeName.source;
1685 if (identical(stringValue, 'void')) { 1699 if (identical(stringValue, 'void')) {
1686 return compiler.types.voidType.element; 1700 element = compiler.types.voidType.element;
1687 } else if (identical(stringValue, 'dynamic')) { 1701 } else if (identical(stringValue, 'dynamic')) {
1688 return compiler.dynamicClass; 1702 element = compiler.dynamicClass;
1689 } else { 1703 } else {
1690 return lookupInScope(compiler, typeName, scope, typeName.source); 1704 element = lookupInScope(compiler, typeName, scope, typeName.source);
1691 } 1705 }
1692 } 1706 }
1707 return element;
floitsch 2014/03/03 14:18:06 nit: I preferred the individual returns. But keep
sigurdm 2014/03/04 12:36:19 Done.
1693 } 1708 }
1694 1709
1695 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, 1710 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node,
1696 {bool malformedIsError: false}) { 1711 {bool malformedIsError: false,
1712 bool deferredIsMalformed: true}) {
1697 Identifier typeName; 1713 Identifier typeName;
1698 Identifier prefixName; 1714 Identifier prefixName;
1699 Send send = node.typeName.asSend(); 1715 Send send = node.typeName.asSend();
1700 if (send != null) { 1716 if (send != null) {
1701 // The type name is of the form [: prefix . identifier :]. 1717 // The type name is of the form [: prefix . identifier :].
1702 prefixName = send.receiver.asIdentifier(); 1718 prefixName = send.receiver.asIdentifier();
1703 typeName = send.selector.asIdentifier(); 1719 typeName = send.selector.asIdentifier();
1704 } else { 1720 } else {
1705 typeName = node.typeName.asIdentifier(); 1721 typeName = node.typeName.asIdentifier();
1706 } 1722 }
1707 1723
1708 Element element = resolveTypeName(visitor.scope, prefixName, typeName); 1724 Element element = resolveTypeName(prefixName, typeName, visitor.scope,
1725 deferredIsMalformed: deferredIsMalformed);
1709 1726
1710 DartType reportFailureAndCreateType(MessageKind messageKind, 1727 DartType reportFailureAndCreateType(MessageKind messageKind,
1711 Map messageArguments, 1728 Map messageArguments,
1712 {DartType userProvidedBadType}) { 1729 {DartType userProvidedBadType,
1730 Element erroneousElement}) {
1713 if (malformedIsError) { 1731 if (malformedIsError) {
1714 visitor.error(node, messageKind, messageArguments); 1732 visitor.error(node, messageKind, messageArguments);
1715 } else { 1733 } else {
1716 compiler.backend.registerThrowRuntimeError(visitor.mapping); 1734 compiler.backend.registerThrowRuntimeError(visitor.mapping);
1717 visitor.warning(node, messageKind, messageArguments); 1735 visitor.warning(node, messageKind, messageArguments);
1718 } 1736 }
1719 Element erroneousElement = new ErroneousElementX( 1737 if (erroneousElement == null) {
1720 messageKind, messageArguments, typeName.source, 1738 erroneousElement = new ErroneousElementX(
1721 visitor.enclosingElement); 1739 messageKind, messageArguments, typeName.source,
1740 visitor.enclosingElement);
1741 }
1722 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); 1742 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>();
1723 resolveTypeArguments(visitor, node, null, arguments); 1743 resolveTypeArguments(visitor, node, null, arguments);
1724 return new MalformedType(erroneousElement, 1744 return new MalformedType(erroneousElement,
1725 userProvidedBadType, arguments.toLink()); 1745 userProvidedBadType, arguments.toLink());
1726 } 1746 }
1727 1747
1728 DartType checkNoTypeArguments(DartType type) { 1748 DartType checkNoTypeArguments(DartType type) {
1729 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); 1749 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>();
1730 bool hasTypeArgumentMismatch = resolveTypeArguments( 1750 bool hasTypeArgumentMismatch = resolveTypeArguments(
1731 visitor, node, const Link<DartType>(), arguments); 1751 visitor, node, const Link<DartType>(), arguments);
1732 if (hasTypeArgumentMismatch) { 1752 if (hasTypeArgumentMismatch) {
1733 return new MalformedType( 1753 return new MalformedType(
1734 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, 1754 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
1735 {'type': node}, typeName.source, visitor.enclosingElement), 1755 {'type': node}, typeName.source, visitor.enclosingElement),
1736 type, arguments.toLink()); 1756 type, arguments.toLink());
1737 } 1757 }
1738 return type; 1758 return type;
1739 } 1759 }
1740 1760
1761 // Now try to construct the type from the element.
floitsch 2014/03/03 14:18:06 -Now-
sigurdm 2014/03/04 12:36:19 Done.
1741 DartType type; 1762 DartType type;
1742 if (element == null) { 1763 if (element == null) {
1743 type = reportFailureAndCreateType( 1764 type = reportFailureAndCreateType(
1744 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); 1765 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName});
1745 } else if (element.isAmbiguous()) { 1766 } else if (element.isAmbiguous()) {
1746 AmbiguousElement ambiguous = element; 1767 AmbiguousElement ambiguous = element;
1747 type = reportFailureAndCreateType( 1768 type = reportFailureAndCreateType(
1748 ambiguous.messageKind, ambiguous.messageArguments); 1769 ambiguous.messageKind, ambiguous.messageArguments);
1749 ambiguous.diagnose(visitor.mapping.currentElement, compiler); 1770 ambiguous.diagnose(visitor.mapping.currentElement, compiler);
1750 } else if (!element.impliesType()) { 1771 } else if (!element.impliesType()) {
1751 type = reportFailureAndCreateType( 1772 type = reportFailureAndCreateType(
1752 MessageKind.NOT_A_TYPE, {'node': node.typeName}); 1773 MessageKind.NOT_A_TYPE, {'node': node.typeName});
1774 } else if (element.isErroneous()) {
1775 ErroneousElement erroneousElement = element;
1776 type = reportFailureAndCreateType(
1777 erroneousElement.messageKind, erroneousElement.messageArguments,
1778 erroneousElement: erroneousElement);
1753 } else { 1779 } else {
1754 bool addTypeVariableBoundsCheck = false; 1780 bool addTypeVariableBoundsCheck = false;
1755 if (identical(element, compiler.types.voidType.element) || 1781 if (identical(element, compiler.types.voidType.element) ||
1756 identical(element, compiler.dynamicClass)) { 1782 identical(element, compiler.dynamicClass)) {
1757 type = checkNoTypeArguments(element.computeType(compiler)); 1783 type = checkNoTypeArguments(element.computeType(compiler));
1758 } else if (element.isClass()) { 1784 } else if (element.isClass()) {
1759 ClassElement cls = element; 1785 ClassElement cls = element;
1760 compiler.resolver._ensureClassWillBeResolved(cls); 1786 compiler.resolver._ensureClassWillBeResolved(cls);
1761 element.computeType(compiler); 1787 element.computeType(compiler);
1762 var arguments = new LinkBuilder<DartType>(); 1788 var arguments = new LinkBuilder<DartType>();
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after
3153 return node.accept(new ConstructorResolver(compiler, this)); 3179 return node.accept(new ConstructorResolver(compiler, this));
3154 } 3180 }
3155 3181
3156 FunctionElement resolveRedirectingFactory(Return node, 3182 FunctionElement resolveRedirectingFactory(Return node,
3157 {bool inConstContext: false}) { 3183 {bool inConstContext: false}) {
3158 return node.accept(new ConstructorResolver(compiler, this, 3184 return node.accept(new ConstructorResolver(compiler, this,
3159 inConstContext: inConstContext)); 3185 inConstContext: inConstContext));
3160 } 3186 }
3161 3187
3162 DartType resolveTypeAnnotation(TypeAnnotation node, 3188 DartType resolveTypeAnnotation(TypeAnnotation node,
3163 {bool malformedIsError: false}) { 3189 {bool malformedIsError: false,
3190 bool deferredIsMalformed: true}) {
3164 DartType type = typeResolver.resolveTypeAnnotation( 3191 DartType type = typeResolver.resolveTypeAnnotation(
3165 this, node, malformedIsError: malformedIsError); 3192 this, node, malformedIsError: malformedIsError,
3193 deferredIsMalformed: deferredIsMalformed);
3166 if (type == null) return null; 3194 if (type == null) return null;
3167 if (inCheckContext) { 3195 if (inCheckContext) {
3168 compiler.enqueuer.resolution.registerIsCheck(type, mapping); 3196 compiler.enqueuer.resolution.registerIsCheck(type, mapping);
3169 compiler.backend.registerRequiredType(type, enclosingElement); 3197 compiler.backend.registerRequiredType(type, enclosingElement);
3170 } 3198 }
3171 return type; 3199 return type;
3172 } 3200 }
3173 3201
3174 visitModifiers(Modifiers node) { 3202 visitModifiers(Modifiers node) {
3175 internalError(node, 'modifiers'); 3203 internalError(node, 'modifiers');
(...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after
4450 } else { 4478 } else {
4451 type = element.getEnclosingClass().computeType(compiler).asRaw(); 4479 type = element.getEnclosingClass().computeType(compiler).asRaw();
4452 } 4480 }
4453 } 4481 }
4454 resolver.mapping.setType(expression, type); 4482 resolver.mapping.setType(expression, type);
4455 return element; 4483 return element;
4456 } 4484 }
4457 4485
4458 Element visitTypeAnnotation(TypeAnnotation node) { 4486 Element visitTypeAnnotation(TypeAnnotation node) {
4459 assert(invariant(node, type == null)); 4487 assert(invariant(node, type == null));
4488 // This is not really resolving a type-annotation, but the name of the
4489 // constructor. Therefore we allow deferred types.
4460 type = resolver.resolveTypeAnnotation(node, 4490 type = resolver.resolveTypeAnnotation(node,
4461 malformedIsError: inConstContext); 4491 malformedIsError: inConstContext,
4492 deferredIsMalformed: false);
4462 compiler.backend.registerRequiredType(type, resolver.enclosingElement); 4493 compiler.backend.registerRequiredType(type, resolver.enclosingElement);
4463 return type.element; 4494 return type.element;
4464 } 4495 }
4465 4496
4466 Element visitSend(Send node) { 4497 Element visitSend(Send node) {
4467 Element element = visit(node.receiver); 4498 Element element = visit(node.receiver);
4468 assert(invariant(node.receiver, element != null, 4499 assert(invariant(node.receiver, element != null,
4469 message: 'No element return for $node.receiver.')); 4500 message: 'No element return for $node.receiver.'));
4470 if (Elements.isUnresolved(element)) return element; 4501 if (Elements.isUnresolved(element)) return element;
4471 Identifier name = node.selector.asIdentifier(); 4502 Identifier name = node.selector.asIdentifier();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4523 return finishConstructorReference(visit(expression), 4554 return finishConstructorReference(visit(expression),
4524 expression, expression); 4555 expression, expression);
4525 } 4556 }
4526 } 4557 }
4527 4558
4528 /// Looks up [name] in [scope] and unwraps the result. 4559 /// Looks up [name] in [scope] and unwraps the result.
4529 Element lookupInScope(Compiler compiler, Node node, 4560 Element lookupInScope(Compiler compiler, Node node,
4530 Scope scope, String name) { 4561 Scope scope, String name) {
4531 return Elements.unwrap(scope.lookup(name), compiler, node); 4562 return Elements.unwrap(scope.lookup(name), compiler, node);
4532 } 4563 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698