| Index: compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
|
| diff --git a/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java b/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
|
| index 6e1b911ecd316aa2baa72c34f45e7262a520e3c7..ed9505e4f11232bb344f78af9285cf8d5e468f4d 100644
|
| --- a/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
|
| +++ b/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
|
| @@ -8,9 +8,12 @@ import com.google.common.base.Objects;
|
| import com.google.common.collect.ImmutableSet;
|
| import com.google.common.collect.Sets;
|
| import com.google.dart.compiler.DartCompilerContext;
|
| +import com.google.dart.compiler.Source;
|
| import com.google.dart.compiler.ast.ASTVisitor;
|
| import com.google.dart.compiler.ast.DartClass;
|
| +import com.google.dart.compiler.ast.DartClassTypeAlias;
|
| import com.google.dart.compiler.ast.DartFunctionTypeAlias;
|
| +import com.google.dart.compiler.ast.DartParameterizedTypeNode;
|
| import com.google.dart.compiler.ast.DartTypeNode;
|
| import com.google.dart.compiler.ast.DartTypeParameter;
|
| import com.google.dart.compiler.ast.DartUnit;
|
| @@ -60,6 +63,34 @@ public class SupertypeResolver {
|
| ResolutionContext classContext = topLevelContext.extend(classElement);
|
|
|
| DartTypeNode superclassNode = node.getSuperclass();
|
| + List<DartTypeNode> mixins = node.getMixins();
|
| + List<DartTypeNode> interfaces = node.getInterfaces();
|
| +
|
| + visitClassLike(classElement, classContext, superclassNode, mixins, interfaces,
|
| + node.getDefaultClass());
|
| + return null;
|
| + }
|
| +
|
| + @Override
|
| + public Void visitClassTypeAlias(DartClassTypeAlias node) {
|
| + ClassElement classElement = node.getElement();
|
| +
|
| + // Make sure that the type parameters are in scope before resolving the
|
| + // super class and interfaces
|
| + ResolutionContext classContext = topLevelContext.extend(classElement);
|
| +
|
| + DartTypeNode superclassNode = node.getSuperclass();
|
| + List<DartTypeNode> mixins = node.getMixins();
|
| + List<DartTypeNode> interfaces = node.getInterfaces();
|
| +
|
| + visitClassLike(classElement, classContext, superclassNode, mixins, interfaces, null);
|
| + return null;
|
| + }
|
| +
|
| + private void visitClassLike(ClassElement classElement, ResolutionContext classContext,
|
| + DartTypeNode superclassNode, List<DartTypeNode> mixins, List<DartTypeNode> interfaces,
|
| + DartParameterizedTypeNode defaultClassNode) {
|
| + Source source = classElement.getSourceInfo().getSource();
|
| InterfaceType supertype;
|
| if (superclassNode == null) {
|
| supertype = typeProvider.getObjectType();
|
| @@ -73,7 +104,7 @@ public class SupertypeResolver {
|
| }
|
| if (supertype != null) {
|
| if (Elements.isTypeNode(superclassNode, BLACK_LISTED_TYPES)
|
| - && !Elements.isCoreLibrarySource(node.getSourceInfo().getSource())) {
|
| + && !Elements.isCoreLibrarySource(source)) {
|
| topLevelContext.onError(
|
| superclassNode,
|
| ResolverErrorCode.BLACK_LISTED_EXTENDS,
|
| @@ -84,21 +115,21 @@ public class SupertypeResolver {
|
| assert classElement.getName().equals("Object") : classElement;
|
| }
|
|
|
| - if (node.getDefaultClass() != null) {
|
| - Element defaultClassElement = classContext.resolveName(node.getDefaultClass().getExpression());
|
| + if (defaultClassNode != null) {
|
| + Element defaultClassElement = classContext.resolveName(defaultClassNode.getExpression());
|
| if (ElementKind.of(defaultClassElement).equals(ElementKind.CLASS)) {
|
| Elements.setDefaultClass(classElement, (InterfaceType)defaultClassElement.getType());
|
| - node.getDefaultClass().setType(defaultClassElement.getType());
|
| + defaultClassNode.setType(defaultClassElement.getType());
|
| }
|
| }
|
|
|
| - if (node.getInterfaces() != null) {
|
| + if (interfaces != null) {
|
| Set<InterfaceType> seenImplement = Sets.newHashSet();
|
| - for (DartTypeNode intNode : node.getInterfaces()) {
|
| + for (DartTypeNode intNode : interfaces) {
|
| InterfaceType intType = classContext.resolveInterface(intNode, false, false);
|
| // May be type which can not be used as interface.
|
| if (Elements.isTypeNode(intNode, BLACK_LISTED_TYPES)
|
| - && !Elements.isCoreLibrarySource(node.getSourceInfo().getSource())) {
|
| + && !Elements.isCoreLibrarySource(source)) {
|
| topLevelContext.onError(intNode, ResolverErrorCode.BLACK_LISTED_IMPLEMENTS, intNode);
|
| continue;
|
| }
|
| @@ -122,8 +153,36 @@ public class SupertypeResolver {
|
| Elements.addInterface(classElement, intType);
|
| }
|
| }
|
| +
|
| + if (mixins != null) {
|
| + Set<InterfaceType> seenMixin = Sets.newHashSet();
|
| + for (DartTypeNode mixNode : mixins) {
|
| + InterfaceType mixType = classContext.resolveInterface(mixNode, false, false);
|
| + // May be type which can not be used as interface.
|
| + if (Elements.isTypeNode(mixNode, BLACK_LISTED_TYPES)
|
| + && !Elements.isCoreLibrarySource(source)) {
|
| + topLevelContext.onError(mixNode, ResolverErrorCode.BLACK_LISTED_MIXINS, mixNode);
|
| + continue;
|
| + }
|
| + // May be unresolved type, error already reported, ignore.
|
| + if (mixType.getKind() == TypeKind.DYNAMIC) {
|
| + continue;
|
| + }
|
| + // check for uniqueness
|
| + if (seenMixin.contains(mixType)) {
|
| + topLevelContext.onError(mixNode, ResolverErrorCode.DUPLICATE_WITH_TYPE);
|
| + continue;
|
| + }
|
| + if (Objects.equal(mixType, supertype)) {
|
| + topLevelContext.onError(mixNode, ResolverErrorCode.SUPER_CLASS_IN_WITH);
|
| + continue;
|
| + }
|
| + seenMixin.add(mixType);
|
| + // OK, add
|
| + Elements.addMixin(classElement, mixType);
|
| + }
|
| + }
|
| setBoundsOnTypeParameters(classElement.getTypeParameters(), classContext);
|
| - return null;
|
| }
|
|
|
| @Override
|
|
|