Index: compiler/java/com/google/dart/compiler/resolver/Resolver.java |
diff --git a/compiler/java/com/google/dart/compiler/resolver/Resolver.java b/compiler/java/com/google/dart/compiler/resolver/Resolver.java |
index 0e2c4e1fb36cff978140216b00aff76b6fe09985..043f67712c28c4d3e5916a3adac17be096c96e11 100644 |
--- a/compiler/java/com/google/dart/compiler/resolver/Resolver.java |
+++ b/compiler/java/com/google/dart/compiler/resolver/Resolver.java |
@@ -227,6 +227,10 @@ public class Resolver { |
onError(cls, ResolverErrorCode.DUPLICATED_INTERFACE, |
e.getFirst(), e.getSecond()); |
} |
+ |
+ checkClassTypeVariables(classElement); |
+ |
+ // Push new resolution context. |
ResolutionContext previousContext = context; |
EnclosingElement previousHolder = currentHolder; |
currentHolder = classElement; |
@@ -256,6 +260,36 @@ public class Resolver { |
} |
/** |
+ * Check that used type variables are unique and don't shadow and existing elements. |
+ */ |
+ private void checkClassTypeVariables(ClassElement classElement) { |
+ Scope scope = context.getScope(); |
+ Set<String> declaredVariableNames = Sets.newHashSet(); |
+ for (Type type : classElement.getTypeParameters()) { |
+ if (type instanceof TypeVariable) { |
+ Element typeVariableElement = type.getElement(); |
+ String name = typeVariableElement.getName(); |
+ // Check that type variables are unique in this Class declaration. |
+ if (declaredVariableNames.contains(name)) { |
+ onError(typeVariableElement.getNode(), ResolverErrorCode.DUPLICATE_TYPE_VARIABLE, name); |
+ } else { |
+ declaredVariableNames.add(name); |
+ } |
+ // Check that type variable is not shadowing any element in enclosing context. |
+ Element existingElement = scope.findElement(scope.getLibrary(), name); |
+ if (existingElement != null) { |
+ onError( |
+ typeVariableElement.getNode(), |
+ ResolverErrorCode.DUPLICATE_TYPE_VARIABLE_WARNING, |
+ name, |
+ existingElement, |
+ Elements.getRelativeElementLocation(typeVariableElement, existingElement)); |
+ } |
+ } |
+ } |
+ } |
+ |
+ /** |
* Checks that interface constructors have corresponding methods in default class. |
*/ |
private void checkInteraceConstructors(ClassElement interfaceElement) { |
@@ -361,7 +395,10 @@ public class Resolver { |
FunctionType type = (FunctionType) member.getType(); |
for (TypeVariable typeVariable : type.getTypeVariables()) { |
- context.declare(typeVariable.getElement()); |
+ context.declare( |
+ typeVariable.getElement(), |
+ ResolverErrorCode.DUPLICATE_TYPE_VARIABLE, |
+ ResolverErrorCode.DUPLICATE_TYPE_VARIABLE_WARNING); |
} |
// First declare all normal parameters in the scope, putting them in the |
@@ -371,7 +408,10 @@ public class Resolver { |
if (parameter.getQualifier() instanceof DartThisExpression) { |
checkParameterInitializer(node, parameter); |
} else { |
- getContext().declare(parameter.getSymbol()); |
+ getContext().declare( |
+ parameter.getSymbol(), |
+ ResolverErrorCode.DUPLICATE_PARAMETER, |
+ ResolverErrorCode.DUPLICATE_PARAMETER_WARNING); |
} |
} |
for (DartParameter parameter : parameters) { |
@@ -509,7 +549,10 @@ public class Resolver { |
public Element visitParameter(DartParameter x) { |
Element element = super.visitParameter(x); |
resolve(x.getDefaultExpr()); |
- getContext().declare(element); |
+ getContext().declare( |
+ element, |
+ ResolverErrorCode.DUPLICATE_PARAMETER, |
+ ResolverErrorCode.DUPLICATE_PARAMETER_WARNING); |
return element; |
} |
@@ -517,7 +560,10 @@ public class Resolver { |
// Visit the initializer first. |
resolve(x.getValue()); |
VariableElement element = Elements.variableElement(x, x.getVariableName(), modifiers); |
- getContext().declare(recordElement(x, element)); |
+ getContext().declare( |
+ recordElement(x, element), |
+ ResolverErrorCode.DUPLICATE_LOCAL_VARIABLE_ERROR, |
+ ResolverErrorCode.DUPLICATE_LOCAL_VARIABLE_WARNING); |
return element; |
} |