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

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

Issue 27494002: Report compile-time error when extending, mixing in or implementing a malformed type. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 7 years, 2 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
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/warnings.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 Set<Node> get superUses; 9 Set<Node> get superUses;
10 10
(...skipping 1626 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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.kind != TypeKind.INTERFACE) {
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
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 = resolveType(superclass);
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 = resolveType(link.head);
3943 this, link.head, malformedIsError: true);
3944 if (interfaceType != null) { 3953 if (interfaceType != null) {
3945 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) { 3954 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) {
3946 // Error has already been reported. 3955 compiler.reportError(superclass,
3956 MessageKind.CANNOT_IMPLEMENT_MALFORMED);
3947 } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) { 3957 } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) {
3948 // TODO(johnniwinther): Handle dynamic. 3958 // TODO(johnniwinther): Handle dynamic.
3949 TypeAnnotation typeAnnotation = link.head; 3959 TypeAnnotation typeAnnotation = link.head;
3950 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); 3960 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED);
3951 } else { 3961 } else {
3952 if (interfaceType == element.supertype) { 3962 if (interfaceType == element.supertype) {
3953 compiler.reportError( 3963 compiler.reportError(
3954 superclass, 3964 superclass,
3955 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, 3965 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
3956 {'type': interfaceType}); 3966 {'type': interfaceType});
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
4109 visitNodeList(node.mixins); 4119 visitNodeList(node.mixins);
4110 visitNodeList(node.interfaces); 4120 visitNodeList(node.interfaces);
4111 } 4121 }
4112 4122
4113 void visitTypeAnnotation(TypeAnnotation node) { 4123 void visitTypeAnnotation(TypeAnnotation node) {
4114 node.typeName.accept(this); 4124 node.typeName.accept(this);
4115 } 4125 }
4116 4126
4117 void visitIdentifier(Identifier node) { 4127 void visitIdentifier(Identifier node) {
4118 Element element = lookupInScope(compiler, node, context, node.source); 4128 Element element = lookupInScope(compiler, node, context, node.source);
4119 if (element == null) { 4129 if (element != null && element.isClass()) {
4120 compiler.reportError( 4130 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 } 4131 }
4131 } 4132 }
4132 4133
4133 void visitSend(Send node) { 4134 void visitSend(Send node) {
4134 Identifier prefix = node.receiver.asIdentifier(); 4135 Identifier prefix = node.receiver.asIdentifier();
4135 if (prefix == null) { 4136 if (prefix == null) {
4136 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); 4137 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
4137 return; 4138 return;
4138 } 4139 }
4139 Element element = lookupInScope(compiler, prefix, context, prefix.source); 4140 Element element = lookupInScope(compiler, prefix, context, prefix.source);
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
4641 return finishConstructorReference(visit(expression), 4642 return finishConstructorReference(visit(expression),
4642 expression, expression); 4643 expression, expression);
4643 } 4644 }
4644 } 4645 }
4645 4646
4646 /// Looks up [name] in [scope] and unwraps the result. 4647 /// Looks up [name] in [scope] and unwraps the result.
4647 Element lookupInScope(Compiler compiler, Node node, 4648 Element lookupInScope(Compiler compiler, Node node,
4648 Scope scope, SourceString name) { 4649 Scope scope, SourceString name) {
4649 return Elements.unwrap(scope.lookup(name), compiler, node); 4650 return Elements.unwrap(scope.lookup(name), compiler, node);
4650 } 4651 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/warnings.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698