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

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 ///
1671 Identifier typeName) { 1671 /// Returns that element paired with true if the [prefixName] was referring
1672 /// to a deferred library prefix.
1673 Pair<Element, bool> resolveTypeName(Identifier prefixName,
floitsch 2014/02/28 12:58:15 I really don't like that we return a pair now. ma
sigurdm 2014/03/03 13:18:49 With Johnni's help I found a better way.
1674 Identifier typeName,
1675 Scope scope) {
1676 Element element;
1677 bool deferredTypeAnnotation = false;
1672 if (prefixName != null) { 1678 if (prefixName != null) {
1673 Element element = 1679 Element prefixElement =
1674 lookupInScope(compiler, prefixName, scope, prefixName.source); 1680 lookupInScope(compiler, prefixName, scope, prefixName.source);
1675 if (element != null && element.isPrefix()) { 1681 if (prefixElement != null && prefixElement.isPrefix()) {
1676 // The receiver is a prefix. Lookup in the imported members. 1682 // The receiver is a prefix. Lookup in the imported members.
1677 PrefixElement prefix = element; 1683 PrefixElement prefix = prefixElement;
1678 return prefix.lookupLocalMember(typeName.source); 1684 element = prefix.lookupLocalMember(typeName.source);
1685 if (element != null && prefix.isDeferred) {
1686 deferredTypeAnnotation = true;
1687 }
1688 } else {
1689 // The caller of this method will create the ErroneousElement for
1690 // the MalformedType.
1691 element = null;
1679 } 1692 }
1680 // The caller of this method will create the ErroneousElement for
1681 // the MalformedType.
1682 return null;
1683 } else { 1693 } else {
1684 String stringValue = typeName.source; 1694 String stringValue = typeName.source;
1685 if (identical(stringValue, 'void')) { 1695 if (identical(stringValue, 'void')) {
1686 return compiler.types.voidType.element; 1696 element = compiler.types.voidType.element;
1687 } else if (identical(stringValue, 'dynamic')) { 1697 } else if (identical(stringValue, 'dynamic')) {
1688 return compiler.dynamicClass; 1698 element = compiler.dynamicClass;
1689 } else { 1699 } else {
1690 return lookupInScope(compiler, typeName, scope, typeName.source); 1700 element = lookupInScope(compiler, typeName, scope, typeName.source);
1691 } 1701 }
1692 } 1702 }
1703 return new Pair<Element, bool>(element, deferredTypeAnnotation);
1693 } 1704 }
1694 1705
1695 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, 1706 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node,
1696 {bool malformedIsError: false}) { 1707 {bool malformedIsError: false,
1708 bool deferredIsMalformed: true}) {
1697 Identifier typeName; 1709 Identifier typeName;
1698 Identifier prefixName; 1710 Identifier prefixName;
1699 Send send = node.typeName.asSend(); 1711 Send send = node.typeName.asSend();
1700 if (send != null) { 1712 if (send != null) {
1701 // The type name is of the form [: prefix . identifier :]. 1713 // The type name is of the form [: prefix . identifier :].
1702 prefixName = send.receiver.asIdentifier(); 1714 prefixName = send.receiver.asIdentifier();
1703 typeName = send.selector.asIdentifier(); 1715 typeName = send.selector.asIdentifier();
1704 } else { 1716 } else {
1705 typeName = node.typeName.asIdentifier(); 1717 typeName = node.typeName.asIdentifier();
1706 } 1718 }
1707 1719
1708 Element element = resolveTypeName(visitor.scope, prefixName, typeName); 1720 Pair<Element, bool> p = resolveTypeName(prefixName,
1721 typeName,
1722 visitor.scope);
1723 Element element = p.first;
1724 bool deferredTypeAnnotation = p.second;
1709 1725
1710 DartType reportFailureAndCreateType(MessageKind messageKind, 1726 DartType reportFailureAndCreateType(MessageKind messageKind,
1711 Map messageArguments, 1727 Map messageArguments,
1712 {DartType userProvidedBadType}) { 1728 {DartType userProvidedBadType}) {
1713 if (malformedIsError) { 1729 if (malformedIsError) {
1714 visitor.error(node, messageKind, messageArguments); 1730 visitor.error(node, messageKind, messageArguments);
1715 } else { 1731 } else {
1716 compiler.backend.registerThrowRuntimeError(visitor.mapping); 1732 compiler.backend.registerThrowRuntimeError(visitor.mapping);
1717 visitor.warning(node, messageKind, messageArguments); 1733 visitor.warning(node, messageKind, messageArguments);
1718 } 1734 }
(...skipping 12 matching lines...) Expand all
1731 visitor, node, const Link<DartType>(), arguments); 1747 visitor, node, const Link<DartType>(), arguments);
1732 if (hasTypeArgumentMismatch) { 1748 if (hasTypeArgumentMismatch) {
1733 return new MalformedType( 1749 return new MalformedType(
1734 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, 1750 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
1735 {'type': node}, typeName.source, visitor.enclosingElement), 1751 {'type': node}, typeName.source, visitor.enclosingElement),
1736 type, arguments.toLink()); 1752 type, arguments.toLink());
1737 } 1753 }
1738 return type; 1754 return type;
1739 } 1755 }
1740 1756
1757 // Now try to construct the type from the element.
1741 DartType type; 1758 DartType type;
1742 if (element == null) { 1759 if (element == null) {
1743 type = reportFailureAndCreateType( 1760 type = reportFailureAndCreateType(
1744 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); 1761 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName});
1745 } else if (element.isAmbiguous()) { 1762 } else if (element.isAmbiguous()) {
1746 AmbiguousElement ambiguous = element; 1763 AmbiguousElement ambiguous = element;
1747 type = reportFailureAndCreateType( 1764 type = reportFailureAndCreateType(
1748 ambiguous.messageKind, ambiguous.messageArguments); 1765 ambiguous.messageKind, ambiguous.messageArguments);
1749 ambiguous.diagnose(visitor.mapping.currentElement, compiler); 1766 ambiguous.diagnose(visitor.mapping.currentElement, compiler);
1750 } else if (!element.impliesType()) { 1767 } else if (!element.impliesType()) {
1751 type = reportFailureAndCreateType( 1768 type = reportFailureAndCreateType(
1752 MessageKind.NOT_A_TYPE, {'node': node.typeName}); 1769 MessageKind.NOT_A_TYPE, {'node': node.typeName});
1770 } else if (deferredTypeAnnotation &&
1771 deferredIsMalformed &&
1772 compiler.deferredLoadTask.splitProgram) {
1773 type = reportFailureAndCreateType(
1774 MessageKind.DEFERRED_TYPE_ANNOTATION, {'node': node.typeName});
1753 } else { 1775 } else {
1754 bool addTypeVariableBoundsCheck = false; 1776 bool addTypeVariableBoundsCheck = false;
1755 if (identical(element, compiler.types.voidType.element) || 1777 if (identical(element, compiler.types.voidType.element) ||
1756 identical(element, compiler.dynamicClass)) { 1778 identical(element, compiler.dynamicClass)) {
1757 type = checkNoTypeArguments(element.computeType(compiler)); 1779 type = checkNoTypeArguments(element.computeType(compiler));
1758 } else if (element.isClass()) { 1780 } else if (element.isClass()) {
1759 ClassElement cls = element; 1781 ClassElement cls = element;
1760 compiler.resolver._ensureClassWillBeResolved(cls); 1782 compiler.resolver._ensureClassWillBeResolved(cls);
1761 element.computeType(compiler); 1783 element.computeType(compiler);
1762 var arguments = new LinkBuilder<DartType>(); 1784 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)); 3175 return node.accept(new ConstructorResolver(compiler, this));
3154 } 3176 }
3155 3177
3156 FunctionElement resolveRedirectingFactory(Return node, 3178 FunctionElement resolveRedirectingFactory(Return node,
3157 {bool inConstContext: false}) { 3179 {bool inConstContext: false}) {
3158 return node.accept(new ConstructorResolver(compiler, this, 3180 return node.accept(new ConstructorResolver(compiler, this,
3159 inConstContext: inConstContext)); 3181 inConstContext: inConstContext));
3160 } 3182 }
3161 3183
3162 DartType resolveTypeAnnotation(TypeAnnotation node, 3184 DartType resolveTypeAnnotation(TypeAnnotation node,
3163 {bool malformedIsError: false}) { 3185 {bool malformedIsError: false,
3186 bool deferredIsMalformed: true}) {
3164 DartType type = typeResolver.resolveTypeAnnotation( 3187 DartType type = typeResolver.resolveTypeAnnotation(
3165 this, node, malformedIsError: malformedIsError); 3188 this, node, malformedIsError: malformedIsError,
3189 deferredIsMalformed: deferredIsMalformed);
3166 if (type == null) return null; 3190 if (type == null) return null;
3167 if (inCheckContext) { 3191 if (inCheckContext) {
3168 compiler.enqueuer.resolution.registerIsCheck(type, mapping); 3192 compiler.enqueuer.resolution.registerIsCheck(type, mapping);
3169 compiler.backend.registerRequiredType(type, enclosingElement); 3193 compiler.backend.registerRequiredType(type, enclosingElement);
3170 } 3194 }
3171 return type; 3195 return type;
3172 } 3196 }
3173 3197
3174 visitModifiers(Modifiers node) { 3198 visitModifiers(Modifiers node) {
3175 internalError(node, 'modifiers'); 3199 internalError(node, 'modifiers');
(...skipping 1275 matching lines...) Expand 10 before | Expand all | Expand 10 after
4451 type = element.getEnclosingClass().computeType(compiler).asRaw(); 4475 type = element.getEnclosingClass().computeType(compiler).asRaw();
4452 } 4476 }
4453 } 4477 }
4454 resolver.mapping.setType(expression, type); 4478 resolver.mapping.setType(expression, type);
4455 return element; 4479 return element;
4456 } 4480 }
4457 4481
4458 Element visitTypeAnnotation(TypeAnnotation node) { 4482 Element visitTypeAnnotation(TypeAnnotation node) {
4459 assert(invariant(node, type == null)); 4483 assert(invariant(node, type == null));
4460 type = resolver.resolveTypeAnnotation(node, 4484 type = resolver.resolveTypeAnnotation(node,
4461 malformedIsError: inConstContext); 4485 malformedIsError: inConstContext,
4486 deferredIsMalformed: false);
floitsch 2014/02/28 12:58:15 Why is it not an error here?
sigurdm 2014/03/03 13:18:49 I added an explanatory comment. The problem is th
4462 compiler.backend.registerRequiredType(type, resolver.enclosingElement); 4487 compiler.backend.registerRequiredType(type, resolver.enclosingElement);
4463 return type.element; 4488 return type.element;
4464 } 4489 }
4465 4490
4466 Element visitSend(Send node) { 4491 Element visitSend(Send node) {
4467 Element element = visit(node.receiver); 4492 Element element = visit(node.receiver);
4468 assert(invariant(node.receiver, element != null, 4493 assert(invariant(node.receiver, element != null,
4469 message: 'No element return for $node.receiver.')); 4494 message: 'No element return for $node.receiver.'));
4470 if (Elements.isUnresolved(element)) return element; 4495 if (Elements.isUnresolved(element)) return element;
4471 Identifier name = node.selector.asIdentifier(); 4496 Identifier name = node.selector.asIdentifier();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4523 return finishConstructorReference(visit(expression), 4548 return finishConstructorReference(visit(expression),
4524 expression, expression); 4549 expression, expression);
4525 } 4550 }
4526 } 4551 }
4527 4552
4528 /// Looks up [name] in [scope] and unwraps the result. 4553 /// Looks up [name] in [scope] and unwraps the result.
4529 Element lookupInScope(Compiler compiler, Node node, 4554 Element lookupInScope(Compiler compiler, Node node,
4530 Scope scope, String name) { 4555 Scope scope, String name) {
4531 return Elements.unwrap(scope.lookup(name), compiler, node); 4556 return Elements.unwrap(scope.lookup(name), compiler, node);
4532 } 4557 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698