Index: compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java |
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java |
index e8e541346ae429ebf37d89d6edc5a83f4cd17ffb..882db1097c23aaddf34940c39dbf984a62f3141b 100644 |
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java |
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java |
@@ -61,7 +61,7 @@ import com.google.dart.compiler.ast.DartNode; |
import com.google.dart.compiler.ast.DartNodeTraverser; |
import com.google.dart.compiler.ast.DartNullLiteral; |
import com.google.dart.compiler.ast.DartParameter; |
-import com.google.dart.compiler.ast.DartParameterizedNode; |
+import com.google.dart.compiler.ast.DartParameterizedTypeNode; |
import com.google.dart.compiler.ast.DartParenthesizedExpression; |
import com.google.dart.compiler.ast.DartPlainVisitor; |
import com.google.dart.compiler.ast.DartPropertyAccess; |
@@ -562,7 +562,8 @@ public class TypeAnalyzer implements DartCompilationPhase { |
case INTERFACE: { |
InterfaceType itype = (InterfaceType) type; |
validateBounds(node.getTypeArguments(), |
- itype.getArguments(), itype.getElement().getTypeParameters(), |
+ itype.getArguments(), |
+ itype.getElement().getTypeParameters(), |
badBoundIsError); |
return itype; |
} |
@@ -723,9 +724,7 @@ public class TypeAnalyzer implements DartCompilationPhase { |
validateTypeNode(interfaceNode, true); |
} |
} |
- if (node.getDefaultClass() != null) { |
- validateTypeNode(node.getDefaultClass(), true); |
- } |
+ |
visit(node.getMembers()); |
checkInterfaceConstructors(element); |
// Report unimplemented members. |
@@ -771,7 +770,7 @@ public class TypeAnalyzer implements DartCompilationPhase { |
&& !interfaceTypes.equals(defaultTypes)) { |
onError( |
interfaceConstructor.getNode(), |
- TypeErrorCode.FACTORY_CONSTRUCTOR_TYPES, |
+ TypeErrorCode.DEFAULT_CONSTRUCTOR_TYPES, |
Elements.getRawMethodName(interfaceConstructor), |
interfaceClassName, |
Joiner.on(",").join(interfaceTypes), |
@@ -997,13 +996,8 @@ public class TypeAnalyzer implements DartCompilationPhase { |
@Override |
public Type visitMethodDefinition(DartMethodDefinition node) { |
MethodElement methodElement = node.getSymbol(); |
- FunctionType type = methodElement.getFunctionType(); |
if (methodElement.getModifiers().isFactory()) { |
analyzeFactory(node.getName(), (ConstructorElement) methodElement); |
- } else { |
- if (!type.getTypeVariables().isEmpty()) { |
- internalError(node, "generic methods are not supported"); |
- } |
} |
return typeAsVoid(node); |
} |
@@ -1011,7 +1005,7 @@ public class TypeAnalyzer implements DartCompilationPhase { |
private void analyzeFactory(DartExpression name, final ConstructorElement methodElement) { |
DartNodeTraverser<Void> visitor = new DartNodeTraverser<Void>() { |
@Override |
- public Void visitParameterizedNode(DartParameterizedNode node) { |
+ public Void visitParameterizedTypeNode(DartParameterizedTypeNode node) { |
DartExpression expression = node.getExpression(); |
Element e = null; |
if (expression instanceof DartIdentifier) { |
@@ -1022,16 +1016,8 @@ public class TypeAnalyzer implements DartCompilationPhase { |
if (!ElementKind.of(e).equals(ElementKind.CLASS)) { |
return null; |
} |
- ClassElement cls = (ClassElement) e; |
- InterfaceType type = cls.getType(); |
List<DartTypeParameter> parameterNodes = node.getTypeParameters(); |
- List<? extends Type> arguments = type.getArguments(); |
- if (parameterNodes.size() == 0) { |
- return null; |
- } |
- Analyzer.this.visit(parameterNodes); |
- List<TypeVariable> typeVariables = methodElement.getFunctionType().getTypeVariables(); |
- validateBounds(parameterNodes, arguments, typeVariables, true); |
+ assert (parameterNodes.size() == 0); |
return null; |
} |
}; |
@@ -1069,14 +1055,22 @@ public class TypeAnalyzer implements DartCompilationPhase { |
} |
// Check type arguments. |
FunctionType ftype = (FunctionType) constructorElement.getType(); |
+ |
if (ftype != null && TypeKind.of(type).equals(TypeKind.INTERFACE)) { |
InterfaceType ifaceType = (InterfaceType) type; |
- List<? extends Type> arguments = ifaceType.getArguments(); |
- ftype = (FunctionType) ftype.subst(arguments, ifaceType.getElement().getTypeParameters()); |
- List<TypeVariable> typeVariables = ftype.getTypeVariables(); |
- if (arguments.size() == typeVariables.size()) { |
- ftype = (FunctionType) ftype.subst(arguments, typeVariables); |
+ |
+ List<? extends Type> substParams; |
+ if (ifaceType.getElement().isInterface()) { |
+ // The constructor in the interface is resolved to the type parameters declared in |
+ // the interface, but the constructor body has type parameters resolved to the type |
+ // parameters in the default class. This substitution patches up the type variable |
+ // references used in parameters so they match the concrete class. |
+ substParams = ((ClassElement)constructorElement.getEnclosingElement()).getType().getArguments(); |
+ } else { |
+ substParams = ifaceType.getElement().getTypeParameters(); |
} |
+ List<? extends Type> arguments = ifaceType.getArguments(); |
+ ftype = (FunctionType) ftype.subst(arguments, substParams); |
checkInvocation(node, node, null, ftype); |
} |
} |
@@ -1501,8 +1495,9 @@ public class TypeAnalyzer implements DartCompilationPhase { |
} |
@Override |
- public Type visitParameterizedNode(DartParameterizedNode node) { |
- throw internalError(node, "unexpected node"); |
+ public Type visitParameterizedTypeNode(DartParameterizedTypeNode node) { |
+ visit(node.getTypeParameters()); |
+ return node.getType(); |
} |
@Override |