Chromium Code Reviews| 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 Set<Node> get superUses; | 9 Set<Node> get superUses; |
| 10 | 10 |
| (...skipping 1626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1637 | 1637 |
| 1638 DartType reportFailureAndCreateType(DualKind messageKind, | 1638 DartType reportFailureAndCreateType(DualKind messageKind, |
| 1639 Map messageArguments, | 1639 Map messageArguments, |
| 1640 {DartType userProvidedBadType}) { | 1640 {DartType userProvidedBadType}) { |
| 1641 if (malformedIsError) { | 1641 if (malformedIsError) { |
| 1642 visitor.error(node, messageKind.error, messageArguments); | 1642 visitor.error(node, messageKind.error, messageArguments); |
| 1643 } else { | 1643 } else { |
| 1644 compiler.backend.registerThrowRuntimeError(visitor.mapping); | 1644 compiler.backend.registerThrowRuntimeError(visitor.mapping); |
| 1645 visitor.warning(node, messageKind.warning, messageArguments); | 1645 visitor.warning(node, messageKind.warning, messageArguments); |
| 1646 } | 1646 } |
| 1647 var erroneousElement = new ErroneousElementX( | 1647 Element erroneousElement = new ErroneousElementX( |
| 1648 messageKind.error, messageArguments, typeName.source, | 1648 messageKind.error, messageArguments, typeName.source, |
| 1649 visitor.enclosingElement); | 1649 visitor.enclosingElement); |
| 1650 var arguments = new LinkBuilder<DartType>(); | 1650 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); |
| 1651 resolveTypeArguments(visitor, node, null, arguments); | 1651 resolveTypeArguments(visitor, node, null, arguments); |
| 1652 return new MalformedType(erroneousElement, | 1652 return new MalformedType(erroneousElement, |
| 1653 userProvidedBadType, arguments.toLink()); | 1653 userProvidedBadType, arguments.toLink()); |
| 1654 } | 1654 } |
| 1655 | 1655 |
| 1656 DartType checkNoTypeArguments(DartType type) { | 1656 DartType checkNoTypeArguments(DartType type) { |
| 1657 var arguments = new LinkBuilder<DartType>(); | 1657 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); |
| 1658 bool hasTypeArgumentMismatch = resolveTypeArguments( | 1658 bool hasTypeArgumentMismatch = resolveTypeArguments( |
| 1659 visitor, node, const Link<DartType>(), arguments); | 1659 visitor, node, const Link<DartType>(), arguments); |
| 1660 if (hasTypeArgumentMismatch) { | 1660 if (hasTypeArgumentMismatch) { |
| 1661 type = new MalformedType( | 1661 return new MalformedType( |
| 1662 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 1662 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, |
| 1663 {'type': node}, typeName.source, visitor.enclosingElement), | 1663 {'type': node}, typeName.source, visitor.enclosingElement), |
| 1664 type, arguments.toLink()); | 1664 type, arguments.toLink()); |
| 1665 } | 1665 } |
| 1666 return type; | 1666 return type; |
| 1667 } | 1667 } |
| 1668 | 1668 |
| 1669 if (element == null) { | 1669 if (element == null) { |
| 1670 type = reportFailureAndCreateType( | 1670 type = reportFailureAndCreateType( |
| 1671 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); | 1671 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); |
| (...skipping 2099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3771 compiler.backend.registerThrowNoSuchMethod(mapping); | 3771 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 3772 } | 3772 } |
| 3773 FunctionElement constructor = | 3773 FunctionElement constructor = |
| 3774 new SynthesizedConstructorElementX.forDefault(superMember, element); | 3774 new SynthesizedConstructorElementX.forDefault(superMember, element); |
| 3775 element.setDefaultConstructor(constructor, compiler); | 3775 element.setDefaultConstructor(constructor, compiler); |
| 3776 } | 3776 } |
| 3777 return element.computeType(compiler); | 3777 return element.computeType(compiler); |
| 3778 } | 3778 } |
| 3779 | 3779 |
| 3780 /// Resolves the mixed type for [mixinNode] and checks that the the mixin type | 3780 /// Resolves the mixed type for [mixinNode] and checks that the the mixin type |
| 3781 /// is not black-listed. The mixin type is returned. | 3781 /// is a valid, non-blacklisted interface type. The mixin type is returned. |
| 3782 DartType checkMixinType(TypeAnnotation mixinNode) { | 3782 DartType checkMixinType(TypeAnnotation mixinNode) { |
| 3783 DartType mixinType = resolveType(mixinNode); | 3783 DartType mixinType = resolveType(mixinNode); |
| 3784 if (isBlackListed(mixinType)) { | 3784 if (isBlackListed(mixinType)) { |
| 3785 compiler.reportError(mixinNode, | 3785 compiler.reportError(mixinNode, |
| 3786 MessageKind.CANNOT_MIXIN, {'type': mixinType}); | 3786 MessageKind.CANNOT_MIXIN, {'type': mixinType}); |
| 3787 } else if (mixinType.kind == TypeKind.TYPE_VARIABLE) { | |
| 3788 compiler.reportError(mixinNode, MessageKind.CLASS_NAME_EXPECTED); | |
| 3789 } else if (mixinType.kind == TypeKind.MALFORMED_TYPE) { | |
| 3790 compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED); | |
| 3787 } | 3791 } |
| 3788 return mixinType; | 3792 return mixinType; |
| 3789 } | 3793 } |
| 3790 | 3794 |
| 3791 DartType visitNamedMixinApplication(NamedMixinApplication node) { | 3795 DartType visitNamedMixinApplication(NamedMixinApplication node) { |
| 3792 compiler.ensure(element != null); | 3796 compiler.ensure(element != null); |
| 3793 compiler.ensure(element.resolutionState == STATE_STARTED); | 3797 compiler.ensure(element.resolutionState == STATE_STARTED); |
| 3794 | 3798 |
| 3795 if (identical(node.classKeyword.stringValue, 'typedef')) { | 3799 if (identical(node.classKeyword.stringValue, 'typedef')) { |
| 3796 // TODO(aprelev@gmail.com): Remove this deprecation diagnostic | 3800 // TODO(aprelev@gmail.com): Remove this deprecation diagnostic |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3863 namedMixinApplication.superclass) | 3867 namedMixinApplication.superclass) |
| 3864 : const Link<DartType>(); | 3868 : const Link<DartType>(); |
| 3865 | 3869 |
| 3866 // The class that is the result of a mixin application implements | 3870 // The class that is the result of a mixin application implements |
| 3867 // the interface of the class that was mixed in so always prepend | 3871 // the interface of the class that was mixed in so always prepend |
| 3868 // that to the interface list. | 3872 // that to the interface list. |
| 3869 interfaces = interfaces.prepend(mixinType); | 3873 interfaces = interfaces.prepend(mixinType); |
| 3870 assert(mixinApplication.interfaces == null); | 3874 assert(mixinApplication.interfaces == null); |
| 3871 mixinApplication.interfaces = interfaces; | 3875 mixinApplication.interfaces = interfaces; |
| 3872 | 3876 |
| 3877 if (mixinType == null || mixinType.kind != TypeKind.INTERFACE) { | |
|
Johnni Winther
2013/10/16 12:22:23
How can mixinType be null?
karlklose
2013/10/16 12:34:51
It could before my rewrite. Removed.
| |
| 3878 mixinApplication.allSupertypes = const Link<DartType>(); | |
| 3879 return; | |
| 3880 } | |
| 3881 | |
| 3873 assert(mixinApplication.mixin == null); | 3882 assert(mixinApplication.mixin == null); |
| 3874 mixinApplication.mixin = resolveMixinFor(mixinApplication, mixinType); | 3883 Element mixin = resolveMixinFor(mixinApplication, mixinType); |
| 3884 | |
| 3885 mixinApplication.mixin = mixin; | |
| 3875 | 3886 |
| 3876 // Create forwarding constructors for constructor defined in the superclass | 3887 // Create forwarding constructors for constructor defined in the superclass |
| 3877 // because they are now hidden by the mixin application. | 3888 // because they are now hidden by the mixin application. |
| 3878 ClassElement superclass = supertype.element; | 3889 ClassElement superclass = supertype.element; |
| 3879 superclass.forEachLocalMember((Element member) { | 3890 superclass.forEachLocalMember((Element member) { |
| 3880 if (!member.isGenerativeConstructor()) return; | 3891 if (!member.isGenerativeConstructor()) return; |
| 3881 FunctionElement forwarder = | 3892 FunctionElement forwarder = |
| 3882 createForwardingConstructor(member, mixinApplication); | 3893 createForwardingConstructor(member, mixinApplication); |
| 3883 mixinApplication.addConstructor(forwarder); | 3894 mixinApplication.addConstructor(forwarder); |
| 3884 }); | 3895 }); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 3905 return null; | 3916 return null; |
| 3906 } | 3917 } |
| 3907 previous = current; | 3918 previous = current; |
| 3908 current = currentMixinApplication.mixin; | 3919 current = currentMixinApplication.mixin; |
| 3909 } | 3920 } |
| 3910 compiler.world.registerMixinUse(mixinApplication, mixin); | 3921 compiler.world.registerMixinUse(mixinApplication, mixin); |
| 3911 return mixin; | 3922 return mixin; |
| 3912 } | 3923 } |
| 3913 | 3924 |
| 3914 DartType resolveType(TypeAnnotation node) { | 3925 DartType resolveType(TypeAnnotation node) { |
| 3915 // TODO(johnniwinther): Report errors/warnings on resolution failures. | |
| 3916 return typeResolver.resolveTypeAnnotation(this, node); | 3926 return typeResolver.resolveTypeAnnotation(this, node); |
| 3917 } | 3927 } |
| 3918 | 3928 |
| 3919 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { | 3929 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { |
| 3920 DartType supertype = typeResolver.resolveTypeAnnotation( | 3930 DartType supertype = typeResolver.resolveTypeAnnotation(this, superclass); |
|
Johnni Winther
2013/10/16 12:22:23
Call resolveType instead.
karlklose
2013/10/16 12:34:51
Done.
| |
| 3921 this, superclass, malformedIsError: true); | |
| 3922 if (supertype != null) { | 3931 if (supertype != null) { |
| 3923 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) { | 3932 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) { |
| 3924 // Error has already been reported. | 3933 compiler.reportError(superclass, MessageKind.CANNOT_EXTEND_MALFORMED); |
| 3925 return null; | 3934 return null; |
| 3926 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) { | 3935 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) { |
| 3927 // TODO(johnniwinther): Handle dynamic. | 3936 compiler.reportError(superclass.typeName, |
| 3928 error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED); | 3937 MessageKind.CLASS_NAME_EXPECTED); |
| 3929 return null; | 3938 return null; |
| 3930 } else if (isBlackListed(supertype)) { | 3939 } else if (isBlackListed(supertype)) { |
| 3931 error(superclass, MessageKind.CANNOT_EXTEND, {'type': supertype}); | 3940 compiler.reportError(superclass, MessageKind.CANNOT_EXTEND, |
| 3941 {'type': supertype}); | |
| 3932 return null; | 3942 return null; |
| 3933 } | 3943 } |
| 3934 } | 3944 } |
| 3935 return supertype; | 3945 return supertype; |
| 3936 } | 3946 } |
| 3937 | 3947 |
| 3938 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { | 3948 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { |
| 3939 Link<DartType> result = const Link<DartType>(); | 3949 Link<DartType> result = const Link<DartType>(); |
| 3940 if (interfaces == null) return result; | 3950 if (interfaces == null) return result; |
| 3941 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { | 3951 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { |
| 3942 DartType interfaceType = typeResolver.resolveTypeAnnotation( | 3952 DartType interfaceType = |
| 3943 this, link.head, malformedIsError: true); | 3953 typeResolver.resolveTypeAnnotation(this, link.head); |
|
Johnni Winther
2013/10/16 12:22:23
Ditto.
karlklose
2013/10/16 12:34:51
Done.
| |
| 3944 if (interfaceType != null) { | 3954 if (interfaceType != null) { |
| 3945 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) { | 3955 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) { |
| 3946 // Error has already been reported. | 3956 compiler.reportError(superclass, |
| 3957 MessageKind.CANNOT_IMPLEMENT_MALFORMED); | |
| 3947 } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) { | 3958 } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) { |
| 3948 // TODO(johnniwinther): Handle dynamic. | 3959 // TODO(johnniwinther): Handle dynamic. |
| 3949 TypeAnnotation typeAnnotation = link.head; | 3960 TypeAnnotation typeAnnotation = link.head; |
| 3950 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); | 3961 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); |
| 3951 } else { | 3962 } else { |
| 3952 if (interfaceType == element.supertype) { | 3963 if (interfaceType == element.supertype) { |
| 3953 compiler.reportError( | 3964 compiler.reportError( |
| 3954 superclass, | 3965 superclass, |
| 3955 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, | 3966 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, |
| 3956 {'type': interfaceType}); | 3967 {'type': interfaceType}); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4109 visitNodeList(node.mixins); | 4120 visitNodeList(node.mixins); |
| 4110 visitNodeList(node.interfaces); | 4121 visitNodeList(node.interfaces); |
| 4111 } | 4122 } |
| 4112 | 4123 |
| 4113 void visitTypeAnnotation(TypeAnnotation node) { | 4124 void visitTypeAnnotation(TypeAnnotation node) { |
| 4114 node.typeName.accept(this); | 4125 node.typeName.accept(this); |
| 4115 } | 4126 } |
| 4116 | 4127 |
| 4117 void visitIdentifier(Identifier node) { | 4128 void visitIdentifier(Identifier node) { |
| 4118 Element element = lookupInScope(compiler, node, context, node.source); | 4129 Element element = lookupInScope(compiler, node, context, node.source); |
| 4119 if (element == null) { | 4130 if (element != null && element.isClass()) { |
| 4120 compiler.reportError( | 4131 loadSupertype(element, node); |
| 4121 node, MessageKind.CANNOT_RESOLVE_TYPE.error, {'typeName': node}); | |
| 4122 } else if (!element.impliesType()) { | |
| 4123 compiler.reportError(node, MessageKind.NOT_A_TYPE.error, {'node': node}); | |
| 4124 } else { | |
| 4125 if (element.isClass()) { | |
| 4126 loadSupertype(element, node); | |
| 4127 } else { | |
| 4128 compiler.reportError(node, MessageKind.CLASS_NAME_EXPECTED); | |
| 4129 } | |
| 4130 } | 4132 } |
| 4131 } | 4133 } |
| 4132 | 4134 |
| 4133 void visitSend(Send node) { | 4135 void visitSend(Send node) { |
| 4134 Identifier prefix = node.receiver.asIdentifier(); | 4136 Identifier prefix = node.receiver.asIdentifier(); |
| 4135 if (prefix == null) { | 4137 if (prefix == null) { |
| 4136 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); | 4138 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); |
| 4137 return; | 4139 return; |
| 4138 } | 4140 } |
| 4139 Element element = lookupInScope(compiler, prefix, context, prefix.source); | 4141 Element element = lookupInScope(compiler, prefix, context, prefix.source); |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4641 return finishConstructorReference(visit(expression), | 4643 return finishConstructorReference(visit(expression), |
| 4642 expression, expression); | 4644 expression, expression); |
| 4643 } | 4645 } |
| 4644 } | 4646 } |
| 4645 | 4647 |
| 4646 /// Looks up [name] in [scope] and unwraps the result. | 4648 /// Looks up [name] in [scope] and unwraps the result. |
| 4647 Element lookupInScope(Compiler compiler, Node node, | 4649 Element lookupInScope(Compiler compiler, Node node, |
| 4648 Scope scope, SourceString name) { | 4650 Scope scope, SourceString name) { |
| 4649 return Elements.unwrap(scope.lookup(name), compiler, node); | 4651 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 4650 } | 4652 } |
| OLD | NEW |