sometimes it not permitted to redeclare variable in nested scope (KT-527)
This commit is contained in:
@@ -44,7 +44,10 @@ public interface Errors {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
UnresolvedReferenceDiagnosticFactory UNRESOLVED_REFERENCE = new UnresolvedReferenceDiagnosticFactory("Unresolved reference");
|
UnresolvedReferenceDiagnosticFactory UNRESOLVED_REFERENCE = new UnresolvedReferenceDiagnosticFactory("Unresolved reference");
|
||||||
RedeclarationDiagnosticFactory REDECLARATION = RedeclarationDiagnosticFactory.INSTANCE;
|
|
||||||
|
RedeclarationDiagnosticFactory REDECLARATION = RedeclarationDiagnosticFactory.REDECLARATION;
|
||||||
|
RedeclarationDiagnosticFactory NAME_SHADOWING = RedeclarationDiagnosticFactory.NAME_SHADOWING;
|
||||||
|
|
||||||
PsiElementOnlyDiagnosticFactory2<PsiElement, JetType, JetType> TYPE_MISMATCH = PsiElementOnlyDiagnosticFactory2.create(ERROR, "Type mismatch: inferred type is {1} but {0} was expected");
|
PsiElementOnlyDiagnosticFactory2<PsiElement, JetType, JetType> TYPE_MISMATCH = PsiElementOnlyDiagnosticFactory2.create(ERROR, "Type mismatch: inferred type is {1} but {0} was expected");
|
||||||
ParameterizedDiagnosticFactory1<Collection<JetKeywordToken>> INCOMPATIBLE_MODIFIERS = new ParameterizedDiagnosticFactory1<Collection<JetKeywordToken>>(ERROR, "Incompatible modifiers: ''{0}''") {
|
ParameterizedDiagnosticFactory1<Collection<JetKeywordToken>> INCOMPATIBLE_MODIFIERS = new ParameterizedDiagnosticFactory1<Collection<JetKeywordToken>>(ERROR, "Incompatible modifiers: ''{0}''") {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+8
-6
@@ -15,8 +15,8 @@ import static org.jetbrains.jet.lang.diagnostics.Severity.ERROR;
|
|||||||
public interface RedeclarationDiagnostic extends DiagnosticWithPsiElement<PsiElement> {
|
public interface RedeclarationDiagnostic extends DiagnosticWithPsiElement<PsiElement> {
|
||||||
public class SimpleRedeclarationDiagnostic extends DiagnosticWithPsiElementImpl<PsiElement> implements RedeclarationDiagnostic {
|
public class SimpleRedeclarationDiagnostic extends DiagnosticWithPsiElementImpl<PsiElement> implements RedeclarationDiagnostic {
|
||||||
|
|
||||||
public SimpleRedeclarationDiagnostic(@NotNull PsiElement psiElement, @NotNull String name) {
|
public SimpleRedeclarationDiagnostic(@NotNull PsiElement psiElement, @NotNull String name, RedeclarationDiagnosticFactory factory) {
|
||||||
super(RedeclarationDiagnosticFactory.INSTANCE, ERROR, "Redeclaration: " + name, psiElement);
|
super(factory, factory.severity, factory.makeMessage(name), psiElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,11 +24,13 @@ public interface RedeclarationDiagnostic extends DiagnosticWithPsiElement<PsiEle
|
|||||||
|
|
||||||
private final DeclarationDescriptor duplicatingDescriptor;
|
private final DeclarationDescriptor duplicatingDescriptor;
|
||||||
private final BindingContext contextToResolveToDeclaration;
|
private final BindingContext contextToResolveToDeclaration;
|
||||||
|
private final RedeclarationDiagnosticFactory factory;
|
||||||
private PsiElement element;
|
private PsiElement element;
|
||||||
|
|
||||||
public RedeclarationDiagnosticWithDeferredResolution(@NotNull DeclarationDescriptor duplicatingDescriptor, @NotNull BindingContext contextToResolveToDeclaration) {
|
public RedeclarationDiagnosticWithDeferredResolution(@NotNull DeclarationDescriptor duplicatingDescriptor, @NotNull BindingContext contextToResolveToDeclaration, RedeclarationDiagnosticFactory factory) {
|
||||||
this.duplicatingDescriptor = duplicatingDescriptor;
|
this.duplicatingDescriptor = duplicatingDescriptor;
|
||||||
this.contextToResolveToDeclaration = contextToResolveToDeclaration;
|
this.contextToResolveToDeclaration = contextToResolveToDeclaration;
|
||||||
|
this.factory = factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PsiElement resolve() {
|
private PsiElement resolve() {
|
||||||
@@ -60,19 +62,19 @@ public interface RedeclarationDiagnostic extends DiagnosticWithPsiElement<PsiEle
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public DiagnosticFactory getFactory() {
|
public DiagnosticFactory getFactory() {
|
||||||
return Errors.REDECLARATION;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return "Redeclaration: " + duplicatingDescriptor.getName();
|
return factory.makeMessage(duplicatingDescriptor.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Severity getSeverity() {
|
public Severity getSeverity() {
|
||||||
return ERROR;
|
return factory.severity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+20
-5
@@ -11,17 +11,28 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
|||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class RedeclarationDiagnosticFactory extends AbstractDiagnosticFactory {
|
public class RedeclarationDiagnosticFactory extends AbstractDiagnosticFactory {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
final Severity severity;
|
||||||
|
private final String messagePrefix;
|
||||||
|
|
||||||
public static final RedeclarationDiagnosticFactory INSTANCE = new RedeclarationDiagnosticFactory();
|
public static final RedeclarationDiagnosticFactory REDECLARATION = new RedeclarationDiagnosticFactory(
|
||||||
|
"REDECLARATION", Severity.ERROR, "Redeclaration: ");
|
||||||
|
public static final RedeclarationDiagnosticFactory NAME_SHADOWING = new RedeclarationDiagnosticFactory(
|
||||||
|
"NAME_SHADOWING", Severity.WARNING, "Name shadowed: ");
|
||||||
|
|
||||||
public RedeclarationDiagnosticFactory() {}
|
public RedeclarationDiagnosticFactory(String name, Severity severity, String messagePrefix) {
|
||||||
|
this.name = name;
|
||||||
|
this.severity = severity;
|
||||||
|
this.messagePrefix = messagePrefix;
|
||||||
|
}
|
||||||
|
|
||||||
public RedeclarationDiagnostic on(@NotNull PsiElement duplicatingElement, @NotNull String name) {
|
public RedeclarationDiagnostic on(@NotNull PsiElement duplicatingElement, @NotNull String name) {
|
||||||
return new RedeclarationDiagnostic.SimpleRedeclarationDiagnostic(duplicatingElement, name);
|
return new RedeclarationDiagnostic.SimpleRedeclarationDiagnostic(duplicatingElement, name, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Diagnostic on(DeclarationDescriptor duplicatingDescriptor, BindingContext contextToResolveToDeclaration) {
|
public Diagnostic on(DeclarationDescriptor duplicatingDescriptor, BindingContext contextToResolveToDeclaration) {
|
||||||
return new RedeclarationDiagnostic.RedeclarationDiagnosticWithDeferredResolution(duplicatingDescriptor, contextToResolveToDeclaration);
|
return new RedeclarationDiagnostic.RedeclarationDiagnosticWithDeferredResolution(duplicatingDescriptor, contextToResolveToDeclaration, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -40,7 +51,11 @@ public class RedeclarationDiagnosticFactory extends AbstractDiagnosticFactory {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "REDECLARATION";
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String makeMessage(String identifier) {
|
||||||
|
return messagePrefix + identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+13
@@ -6,9 +6,12 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.TaskPrioritizers;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
@@ -211,6 +214,16 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
}
|
}
|
||||||
variableDescriptor = context.getDescriptorResolver().resolveLocalVariableDescriptor(context.scope.getContainingDeclaration(), loopParameter, expectedParameterType);
|
variableDescriptor = context.getDescriptorResolver().resolveLocalVariableDescriptor(context.scope.getContainingDeclaration(), loopParameter, expectedParameterType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// http://youtrack.jetbrains.net/issue/KT-527
|
||||||
|
|
||||||
|
VariableDescriptor olderVariable = context.scope.getVariable(variableDescriptor.getName());
|
||||||
|
if (olderVariable != null && DescriptorUtils.isLocal(context.scope.getContainingDeclaration(), olderVariable)) {
|
||||||
|
context.trace.report(Errors.NAME_SHADOWING.on(variableDescriptor, context.trace.getBindingContext()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loopScope.addVariableDescriptor(variableDescriptor);
|
loopScope.addVariableDescriptor(variableDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
@@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.descriptors.*;
|
|||||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
||||||
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
|
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
||||||
@@ -89,6 +90,13 @@ public class ExpressionTypingVisitorForStatements extends BasicExpressionTypingV
|
|||||||
JetType outType = propertyDescriptor.getOutType();
|
JetType outType = propertyDescriptor.getOutType();
|
||||||
JetType initializerType = facade.getType(initializer, context.replaceExpectedType(outType).replaceScope(scope));
|
JetType initializerType = facade.getType(initializer, context.replaceExpectedType(outType).replaceScope(scope));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
VariableDescriptor olderVariable = scope.getVariable(propertyDescriptor.getName());
|
||||||
|
if (olderVariable != null && DescriptorUtils.isLocal(propertyDescriptor.getContainingDeclaration(), olderVariable)) {
|
||||||
|
context.trace.report(Errors.NAME_SHADOWING.on(propertyDescriptor, context.trace.getBindingContext()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scope.addVariableDescriptor(propertyDescriptor);
|
scope.addVariableDescriptor(propertyDescriptor);
|
||||||
return checkExpectedType(property, context);
|
return checkExpectedType(property, context);
|
||||||
|
|||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
fun f(p: Int): Int {
|
||||||
|
val <!NAME_SHADOWING!>p<!> = 2
|
||||||
|
return p
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
fun f(i: Int) {
|
||||||
|
for (j in 1..100) {
|
||||||
|
{
|
||||||
|
var <!NAME_SHADOWING!>i<!> = 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
val i = 17
|
||||||
|
|
||||||
|
val f = { (): Int => var i = 17; i }
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
class RedefinePropertyInFor() {
|
||||||
|
|
||||||
|
var i = 1
|
||||||
|
|
||||||
|
fun ff() {
|
||||||
|
for (i in 0..10) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
class RedefinePropertyInFunction() {
|
||||||
|
|
||||||
|
var i = 17
|
||||||
|
|
||||||
|
fun f(): Int {
|
||||||
|
var i = 18
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun ff(): Int {
|
||||||
|
var i = 1
|
||||||
|
for (<!NAME_SHADOWING!>i<!> in 0..10) {
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
fun ff(): Int {
|
||||||
|
var i = 1
|
||||||
|
{
|
||||||
|
val <!NAME_SHADOWING!>i<!> = 2
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
fun f(): Int {
|
||||||
|
var i = 17
|
||||||
|
{ (): Unit => var <!NAME_SHADOWING!>i<!> = 18 }
|
||||||
|
return i
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
fun ff(): Int {
|
||||||
|
var i = 1
|
||||||
|
{ (i: Int) => i }
|
||||||
|
return i
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user