| 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;
|
| }
|
|
|
|
|