KT-2701 Prevent redeclaration in multi-declaration

#KT-2701 Fixed
This commit is contained in:
Natalia.Ukhorskaya
2012-10-24 17:52:44 +04:00
parent 34a9d6a469
commit bf489c9ed8
6 changed files with 37 additions and 7 deletions
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.types.expressions;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet; import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -25,6 +26,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.JetNodeTypes;
import org.jetbrains.jet.lang.ModuleConfiguration; import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
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.*; import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallMaker;
@@ -341,10 +343,22 @@ public class ExpressionTypingUtils {
VariableDescriptor variableDescriptor = context.expressionTypingServices.getDescriptorResolver(). VariableDescriptor variableDescriptor = context.expressionTypingServices.getDescriptorResolver().
resolveLocalVariableDescriptorWithType(writableScope.getContainingDeclaration(), entry, componentType, context.trace); resolveLocalVariableDescriptorWithType(writableScope.getContainingDeclaration(), entry, componentType, context.trace);
VariableDescriptor olderVariable = writableScope.getLocalVariable(variableDescriptor.getName());
checkVariableShadowing(context, variableDescriptor, olderVariable);
writableScope.addVariableDescriptor(variableDescriptor); writableScope.addVariableDescriptor(variableDescriptor);
} }
} }
public static void checkVariableShadowing(@NotNull ExpressionTypingContext context, @NotNull VariableDescriptor variableDescriptor, VariableDescriptor oldDescriptor) {
if (oldDescriptor != null && DescriptorUtils.isLocal(variableDescriptor.getContainingDeclaration(), oldDescriptor)) {
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context.trace.getBindingContext(), variableDescriptor);
if (declaration != null) {
context.trace.report(Errors.NAME_SHADOWING.on(declaration, variableDescriptor.getName().getName()));
}
}
}
@NotNull @NotNull
private static JetType getExpectedTypeForComponent(ExpressionTypingContext context, JetMultiDeclarationEntry entry) { private static JetType getExpectedTypeForComponent(ExpressionTypingContext context, JetMultiDeclarationEntry entry) {
JetTypeReference entryTypeRef = entry.getTypeRef(); JetTypeReference entryTypeRef = entry.getTypeRef();
@@ -117,10 +117,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
{ {
VariableDescriptor olderVariable = scope.getLocalVariable(propertyDescriptor.getName()); VariableDescriptor olderVariable = scope.getLocalVariable(propertyDescriptor.getName());
if (olderVariable != null && DescriptorUtils.isLocal(propertyDescriptor.getContainingDeclaration(), olderVariable)) { ExpressionTypingUtils.checkVariableShadowing(context, propertyDescriptor, olderVariable);
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context.trace.getBindingContext(), propertyDescriptor);
context.trace.report(Errors.NAME_SHADOWING.on(declaration, propertyDescriptor.getName().getName()));
}
} }
scope.addVariableDescriptor(propertyDescriptor); scope.addVariableDescriptor(propertyDescriptor);
@@ -4,11 +4,11 @@ class A {
} }
fun a() { fun a() {
val (<!REDECLARATION, UNUSED_VARIABLE!>a<!>, <!REDECLARATION, UNUSED_VARIABLE!>a<!>) = A() val (<!REDECLARATION, UNUSED_VARIABLE!>a<!>, <!NAME_SHADOWING, REDECLARATION, UNUSED_VARIABLE!>a<!>) = A()
val (<!UNUSED_VARIABLE!>x<!>, <!REDECLARATION, UNUSED_VARIABLE!>y<!>) = A(); val (<!UNUSED_VARIABLE!>x<!>, <!REDECLARATION, UNUSED_VARIABLE!>y<!>) = A();
val <!REDECLARATION!>b<!> = 1 val <!REDECLARATION!>b<!> = 1
use(b) use(b)
val (<!REDECLARATION, UNUSED_VARIABLE!>b<!>, <!REDECLARATION, UNUSED_VARIABLE!>y<!>) = A(); val (<!NAME_SHADOWING, REDECLARATION, UNUSED_VARIABLE!>b<!>, <!NAME_SHADOWING, REDECLARATION, UNUSED_VARIABLE!>y<!>) = A();
} }
@@ -8,7 +8,7 @@ class C {
} }
fun test() { fun test() {
for ((<!REDECLARATION!>x<!>, <!REDECLARATION!>x<!>) in C()) { for ((<!REDECLARATION!>x<!>, <!NAME_SHADOWING, REDECLARATION!>x<!>) in C()) {
} }
} }
@@ -0,0 +1,14 @@
class A {
fun component1() = 42
fun component2() = 42
}
fun foo(a: A, c: Int) {
val (<!NAME_SHADOWING!>a<!>, b) = a
val arr = Array(2) { A() }
for ((<!NAME_SHADOWING!>c<!>, d) in arr) {
}
val <!UNUSED_VARIABLE!>e<!> = a.toString() + b + c
}
@@ -3386,6 +3386,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve", new File("compiler/testData/diagnostics/tests/shadowing"), "kt", true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve", new File("compiler/testData/diagnostics/tests/shadowing"), "kt", true);
} }
@TestMetadata("ShadowMultiDeclarationWithFunParameter.kt")
public void testShadowMultiDeclarationWithFunParameter() throws Exception {
doTest("compiler/testData/diagnostics/tests/shadowing/ShadowMultiDeclarationWithFunParameter.kt");
}
@TestMetadata("ShadowParameterInFunctionBody.kt") @TestMetadata("ShadowParameterInFunctionBody.kt")
public void testShadowParameterInFunctionBody() throws Exception { public void testShadowParameterInFunctionBody() throws Exception {
doTest("compiler/testData/diagnostics/tests/shadowing/ShadowParameterInFunctionBody.kt"); doTest("compiler/testData/diagnostics/tests/shadowing/ShadowParameterInFunctionBody.kt");