Index: compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java |
diff --git a/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java b/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java |
index df9aa182272c2faccabf58ea8f33a8edae91a94c..dfe781d8dc07d400f20794c0edf23b39374eb91f 100644 |
--- a/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java |
+++ b/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java |
@@ -8,11 +8,13 @@ import com.google.common.annotations.VisibleForTesting; |
import com.google.dart.compiler.DartCompilationError; |
import com.google.dart.compiler.DartCompilerContext; |
import com.google.dart.compiler.ErrorCode; |
+import com.google.dart.compiler.ast.DartExpression; |
import com.google.dart.compiler.ast.DartFunctionExpression; |
import com.google.dart.compiler.ast.DartFunctionTypeAlias; |
import com.google.dart.compiler.ast.DartIdentifier; |
import com.google.dart.compiler.ast.DartNode; |
import com.google.dart.compiler.ast.DartNodeTraverser; |
+import com.google.dart.compiler.ast.DartParameterizedNode; |
import com.google.dart.compiler.ast.DartPropertyAccess; |
import com.google.dart.compiler.ast.DartTypeNode; |
import com.google.dart.compiler.ast.LibraryUnit; |
@@ -110,7 +112,7 @@ public class ResolutionContext implements ResolutionErrorListener { |
private boolean isClassType(Type type) { |
return isInterfaceEquals(type, false); |
} |
- |
+ |
/** |
* Returns <code>true</code> if the type is a class or interface type. |
*/ |
@@ -119,12 +121,15 @@ public class ResolutionContext implements ResolutionErrorListener { |
&& ((InterfaceType) type).getElement() != null; |
} |
- InterfaceType resolveClass(DartTypeNode node, boolean isStatic) { |
+ /** |
+ * To resolve the factory class<typeparameters?> specified on an interface. |
+ */ |
+ InterfaceType resolveClass(DartTypeNode node, boolean isStatic, boolean isFactory) { |
if (node == null) { |
return null; |
} |
- Type type = resolveType(node, isStatic, ResolverErrorCode.NO_SUCH_TYPE); |
+ Type type = resolveType(node, isStatic, isFactory, ResolverErrorCode.NO_SUCH_TYPE); |
if (!isClassType(type)) { |
onError(node.getIdentifier(), ResolverErrorCode.NOT_A_CLASS, type); |
type = typeProvider.getDynamicType(); |
@@ -134,8 +139,32 @@ public class ResolutionContext implements ResolutionErrorListener { |
return (InterfaceType) type; |
} |
- InterfaceType resolveInterface(DartTypeNode node, boolean isStatic) { |
- Type type = resolveType(node, isStatic, ResolverErrorCode.NO_SUCH_TYPE); |
+ InterfaceType resolveClass(DartExpression maybeParameterizedType, |
+ boolean isStatic) { |
+ if (maybeParameterizedType == null) { |
+ return null; |
+ } |
+ |
+ DartExpression typeName; |
+ if (maybeParameterizedType instanceof DartParameterizedNode) { |
+ typeName = ((DartParameterizedNode) maybeParameterizedType).getExpression(); |
+ } else { |
+ typeName = maybeParameterizedType; |
+ } |
+ Element element = resolveName(typeName); |
+ if (element == null) { |
+ onError(maybeParameterizedType, ResolverErrorCode.NO_SUCH_TYPE, typeName); |
+ } |
+ |
+ if (!ElementKind.of(element).equals(ElementKind.CLASS)) { |
+ onError(maybeParameterizedType, ResolverErrorCode.NOT_A_CLASS_OR_INTERFACE, typeName); |
+ } |
+ |
+ return (InterfaceType) element.getType(); |
+ } |
+ |
+ InterfaceType resolveInterface(DartTypeNode node, boolean isStatic, boolean isFactory) { |
+ Type type = resolveType(node, isStatic, isFactory, ResolverErrorCode.NO_SUCH_TYPE); |
if (type.getKind() != TypeKind.DYNAMIC && !isClassOrInterfaceType(type)) { |
onError(node.getIdentifier(), ResolverErrorCode.NOT_A_CLASS_OR_INTERFACE, type); |
type = typeProvider.getDynamicType(); |
@@ -145,22 +174,22 @@ public class ResolutionContext implements ResolutionErrorListener { |
return (InterfaceType) type; |
} |
- Type resolveType(DartTypeNode node, boolean isStatic, ErrorCode errorCode) { |
+ Type resolveType(DartTypeNode node, boolean isStatic, boolean isFactory, ErrorCode errorCode) { |
if (node == null) { |
return null; |
} else { |
- return resolveType(node, node.getIdentifier(), node.getTypeArguments(), isStatic, errorCode); |
+ return resolveType(node, node.getIdentifier(), node.getTypeArguments(), isStatic, isFactory, errorCode); |
} |
} |
Type resolveType(DartNode diagnosticNode, DartNode identifier, List<DartTypeNode> typeArguments, |
- boolean isStatic, ErrorCode errorCode) { |
+ boolean isStatic, boolean isFactory, ErrorCode errorCode) { |
Element element = resolveName(identifier); |
ElementKind elementKind = ElementKind.of(element); |
switch (elementKind) { |
case TYPE_VARIABLE: { |
TypeVariableElement typeVariableElement = (TypeVariableElement) element; |
- if (isStatic && |
+ if (!isFactory && isStatic && |
typeVariableElement.getDeclaringElement().getKind().equals(ElementKind.CLASS)) { |
onError(identifier, ResolverErrorCode.TYPE_VARIABLE_IN_STATIC_CONTEXT, |
identifier); |
@@ -175,6 +204,7 @@ public class ResolutionContext implements ResolutionErrorListener { |
diagnosticNode, |
typeArguments, |
isStatic, |
+ isFactory, |
errorCode); |
case NONE: |
if (identifier.toString().equals("void")) { |
@@ -194,6 +224,7 @@ public class ResolutionContext implements ResolutionErrorListener { |
InterfaceType instantiateParameterizedType(ClassElement element, DartNode node, |
List<DartTypeNode> typeArgumentNodes, |
boolean isStatic, |
+ boolean isFactory, |
ErrorCode errorCode) { |
List<? extends Type> typeParameters = element.getTypeParameters(); |
Type[] typeArguments; |
@@ -212,7 +243,7 @@ public class ResolutionContext implements ResolutionErrorListener { |
int index = 0; |
if (typeArgumentNodes != null) { |
for (DartTypeNode typeNode : typeArgumentNodes) { |
- Type type = resolveType(typeNode, isStatic, errorCode); |
+ Type type = resolveType(typeNode, isStatic, isFactory, errorCode); |
typeNode.setType(type); |
if (index < typeArguments.length) { |
typeArguments[index] = type; |
@@ -223,7 +254,7 @@ public class ResolutionContext implements ResolutionErrorListener { |
} else { |
typeArguments = new Type[typeArgumentNodes.size()]; |
for (int i = 0; i < typeArguments.length; i++) { |
- typeArguments[i] = resolveType(typeArgumentNodes.get(i), isStatic, errorCode); |
+ typeArguments[i] = resolveType(typeArgumentNodes.get(i), isStatic, isFactory, errorCode); |
typeArgumentNodes.get(i).setType(typeArguments[i]); |
} |
} |