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 AnalyzableElement get analyzedElement; | 8 AnalyzableElement get analyzedElement; |
9 Iterable<Node> get superUses; | 9 Iterable<Node> get superUses; |
10 | 10 |
(...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 if (mixin == null) return; | 1111 if (mixin == null) return; |
1112 | 1112 |
1113 // Check that we're not trying to use Object as a mixin. | 1113 // Check that we're not trying to use Object as a mixin. |
1114 if (mixin.superclass == null) { | 1114 if (mixin.superclass == null) { |
1115 compiler.reportError(mixinApplication, | 1115 compiler.reportError(mixinApplication, |
1116 MessageKind.ILLEGAL_MIXIN_OBJECT); | 1116 MessageKind.ILLEGAL_MIXIN_OBJECT); |
1117 // Avoid reporting additional errors for the Object class. | 1117 // Avoid reporting additional errors for the Object class. |
1118 return; | 1118 return; |
1119 } | 1119 } |
1120 | 1120 |
| 1121 if (mixin.isEnumClass) { |
| 1122 // Mixing in an enum has already caused a compile-time error. |
| 1123 return; |
| 1124 } |
| 1125 |
1121 // Check that the mixed in class has Object as its superclass. | 1126 // Check that the mixed in class has Object as its superclass. |
1122 if (!mixin.superclass.isObject) { | 1127 if (!mixin.superclass.isObject) { |
1123 compiler.reportError(mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS); | 1128 compiler.reportError(mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS); |
1124 } | 1129 } |
1125 | 1130 |
1126 // Check that the mixed in class doesn't have any constructors and | 1131 // Check that the mixed in class doesn't have any constructors and |
1127 // make sure we aren't mixing in methods that use 'super'. | 1132 // make sure we aren't mixing in methods that use 'super'. |
1128 mixin.forEachLocalMember((AstElement member) { | 1133 mixin.forEachLocalMember((AstElement member) { |
1129 if (member.isGenerativeConstructor && !member.isSynthesized) { | 1134 if (member.isGenerativeConstructor && !member.isSynthesized) { |
1130 compiler.reportError(member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR); | 1135 compiler.reportError(member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR); |
(...skipping 2232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3363 } | 3368 } |
3364 constructor.computeSignature(compiler); | 3369 constructor.computeSignature(compiler); |
3365 if (!callSelector.applies(constructor, compiler.world)) { | 3370 if (!callSelector.applies(constructor, compiler.world)) { |
3366 registry.registerThrowNoSuchMethod(); | 3371 registry.registerThrowNoSuchMethod(); |
3367 } | 3372 } |
3368 | 3373 |
3369 // [constructor] might be the implementation element | 3374 // [constructor] might be the implementation element |
3370 // and only declaration elements may be registered. | 3375 // and only declaration elements may be registered. |
3371 registry.registerStaticUse(constructor.declaration); | 3376 registry.registerStaticUse(constructor.declaration); |
3372 ClassElement cls = constructor.enclosingClass; | 3377 ClassElement cls = constructor.enclosingClass; |
| 3378 if (cls.isEnumClass && currentClass != cls) { |
| 3379 compiler.reportError(node, |
| 3380 MessageKind.CANNOT_INSTANTIATE_ENUM, |
| 3381 {'enumName': cls.name}); |
| 3382 } |
| 3383 |
3373 InterfaceType type = registry.getType(node); | 3384 InterfaceType type = registry.getType(node); |
3374 if (node.isConst && type.containsTypeVariables) { | 3385 if (node.isConst && type.containsTypeVariables) { |
3375 compiler.reportError(node.send.selector, | 3386 compiler.reportError(node.send.selector, |
3376 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 3387 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
3377 } | 3388 } |
3378 // TODO(johniwinther): Avoid registration of `type` in face of redirecting | 3389 // TODO(johniwinther): Avoid registration of `type` in face of redirecting |
3379 // factory constructors. | 3390 // factory constructors. |
3380 registry.registerInstantiatedType(type); | 3391 registry.registerInstantiatedType(type); |
3381 if (constructor.isFactoryConstructor && !type.typeArguments.isEmpty) { | 3392 if (constructor.isFactoryConstructor && !type.typeArguments.isEmpty) { |
3382 registry.registerFactoryWithTypeArguments(); | 3393 registry.registerFactoryWithTypeArguments(); |
(...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4360 DartType checkMixinType(TypeAnnotation mixinNode) { | 4371 DartType checkMixinType(TypeAnnotation mixinNode) { |
4361 DartType mixinType = resolveType(mixinNode); | 4372 DartType mixinType = resolveType(mixinNode); |
4362 if (isBlackListed(mixinType)) { | 4373 if (isBlackListed(mixinType)) { |
4363 compiler.reportError(mixinNode, | 4374 compiler.reportError(mixinNode, |
4364 MessageKind.CANNOT_MIXIN, {'type': mixinType}); | 4375 MessageKind.CANNOT_MIXIN, {'type': mixinType}); |
4365 } else if (mixinType.isTypeVariable) { | 4376 } else if (mixinType.isTypeVariable) { |
4366 compiler.reportError(mixinNode, MessageKind.CLASS_NAME_EXPECTED); | 4377 compiler.reportError(mixinNode, MessageKind.CLASS_NAME_EXPECTED); |
4367 } else if (mixinType.isMalformed) { | 4378 } else if (mixinType.isMalformed) { |
4368 compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED, | 4379 compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED, |
4369 {'className': element.name, 'malformedType': mixinType}); | 4380 {'className': element.name, 'malformedType': mixinType}); |
| 4381 } else if (mixinType.isEnumType) { |
| 4382 compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_ENUM, |
| 4383 {'className': element.name, 'enumType': mixinType}); |
4370 } | 4384 } |
4371 return mixinType; | 4385 return mixinType; |
4372 } | 4386 } |
4373 | 4387 |
4374 DartType visitNamedMixinApplication(NamedMixinApplication node) { | 4388 DartType visitNamedMixinApplication(NamedMixinApplication node) { |
4375 invariant(node, element != null); | 4389 invariant(node, element != null); |
4376 invariant(element, element.resolutionState == STATE_STARTED, | 4390 invariant(element, element.resolutionState == STATE_STARTED, |
4377 message: () => 'cyclic resolution of class $element'); | 4391 message: () => 'cyclic resolution of class $element'); |
4378 | 4392 |
4379 if (identical(node.classKeyword.stringValue, 'typedef')) { | 4393 if (identical(node.classKeyword.stringValue, 'typedef')) { |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4544 return mixinType; | 4558 return mixinType; |
4545 } | 4559 } |
4546 | 4560 |
4547 DartType resolveType(TypeAnnotation node) { | 4561 DartType resolveType(TypeAnnotation node) { |
4548 return typeResolver.resolveTypeAnnotation(this, node); | 4562 return typeResolver.resolveTypeAnnotation(this, node); |
4549 } | 4563 } |
4550 | 4564 |
4551 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { | 4565 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { |
4552 DartType supertype = resolveType(superclass); | 4566 DartType supertype = resolveType(superclass); |
4553 if (supertype != null) { | 4567 if (supertype != null) { |
4554 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) { | 4568 if (supertype.isMalformed) { |
4555 compiler.reportError(superclass, MessageKind.CANNOT_EXTEND_MALFORMED, | 4569 compiler.reportError(superclass, MessageKind.CANNOT_EXTEND_MALFORMED, |
4556 {'className': element.name, 'malformedType': supertype}); | 4570 {'className': element.name, 'malformedType': supertype}); |
4557 return objectType; | 4571 return objectType; |
4558 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) { | 4572 } else if (supertype.isEnumType) { |
| 4573 compiler.reportError(superclass, MessageKind.CANNOT_EXTEND_ENUM, |
| 4574 {'className': element.name, 'enumType': supertype}); |
| 4575 return objectType; |
| 4576 } else if (!supertype.isInterfaceType) { |
4559 compiler.reportError(superclass.typeName, | 4577 compiler.reportError(superclass.typeName, |
4560 MessageKind.CLASS_NAME_EXPECTED); | 4578 MessageKind.CLASS_NAME_EXPECTED); |
4561 return objectType; | 4579 return objectType; |
4562 } else if (isBlackListed(supertype)) { | 4580 } else if (isBlackListed(supertype)) { |
4563 compiler.reportError(superclass, MessageKind.CANNOT_EXTEND, | 4581 compiler.reportError(superclass, MessageKind.CANNOT_EXTEND, |
4564 {'type': supertype}); | 4582 {'type': supertype}); |
4565 return objectType; | 4583 return objectType; |
4566 } | 4584 } |
4567 } | 4585 } |
4568 return supertype; | 4586 return supertype; |
4569 } | 4587 } |
4570 | 4588 |
4571 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { | 4589 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { |
4572 Link<DartType> result = const Link<DartType>(); | 4590 Link<DartType> result = const Link<DartType>(); |
4573 if (interfaces == null) return result; | 4591 if (interfaces == null) return result; |
4574 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { | 4592 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { |
4575 DartType interfaceType = resolveType(link.head); | 4593 DartType interfaceType = resolveType(link.head); |
4576 if (interfaceType != null) { | 4594 if (interfaceType != null) { |
4577 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) { | 4595 if (interfaceType.isMalformed) { |
4578 compiler.reportError(superclass, | 4596 compiler.reportError(superclass, |
4579 MessageKind.CANNOT_IMPLEMENT_MALFORMED, | 4597 MessageKind.CANNOT_IMPLEMENT_MALFORMED, |
4580 {'className': element.name, 'malformedType': interfaceType}); | 4598 {'className': element.name, 'malformedType': interfaceType}); |
4581 } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) { | 4599 } else if (interfaceType.isEnumType) { |
| 4600 compiler.reportError(superclass, |
| 4601 MessageKind.CANNOT_IMPLEMENT_ENUM, |
| 4602 {'className': element.name, 'enumType': interfaceType}); |
| 4603 } else if (!interfaceType.isInterfaceType) { |
4582 // TODO(johnniwinther): Handle dynamic. | 4604 // TODO(johnniwinther): Handle dynamic. |
4583 TypeAnnotation typeAnnotation = link.head; | 4605 TypeAnnotation typeAnnotation = link.head; |
4584 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); | 4606 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); |
4585 } else { | 4607 } else { |
4586 if (interfaceType == element.supertype) { | 4608 if (interfaceType == element.supertype) { |
4587 compiler.reportError( | 4609 compiler.reportError( |
4588 superclass, | 4610 superclass, |
4589 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, | 4611 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, |
4590 {'type': interfaceType}); | 4612 {'type': interfaceType}); |
4591 compiler.reportError( | 4613 compiler.reportError( |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5069 } | 5091 } |
5070 | 5092 |
5071 /// The result for the resolution of the `assert` method. | 5093 /// The result for the resolution of the `assert` method. |
5072 class AssertResult implements ResolutionResult { | 5094 class AssertResult implements ResolutionResult { |
5073 const AssertResult(); | 5095 const AssertResult(); |
5074 | 5096 |
5075 Element get element => null; | 5097 Element get element => null; |
5076 | 5098 |
5077 String toString() => 'AssertResult()'; | 5099 String toString() => 'AssertResult()'; |
5078 } | 5100 } |
OLD | NEW |