Front-end: Prohibit to create inner class with the same name as a property
This commit is contained in:
@@ -18,10 +18,8 @@ package org.jetbrains.jet.lang.resolve;
|
|||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.*;
|
||||||
import com.google.common.collect.HashMultimap;
|
import com.intellij.openapi.util.Pair;
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Multimap;
|
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -32,10 +30,7 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
|||||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||||
|
|
||||||
@@ -315,19 +310,45 @@ public class DeclarationResolver {
|
|||||||
|
|
||||||
Multimap<Name, DeclarationDescriptor> descriptorMap = HashMultimap.create();
|
Multimap<Name, DeclarationDescriptor> descriptorMap = HashMultimap.create();
|
||||||
for (DeclarationDescriptor desc : allDescriptors) {
|
for (DeclarationDescriptor desc : allDescriptors) {
|
||||||
if (desc instanceof ClassDescriptor) {
|
if (desc instanceof ClassDescriptor || desc instanceof PropertyDescriptor) {
|
||||||
descriptorMap.put(desc.getName(), desc);
|
descriptorMap.put(desc.getName(), desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reportRedeclarations(descriptorMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (Name name : descriptorMap.keySet()) {
|
private void reportRedeclarations(@NotNull Multimap<Name, DeclarationDescriptor> descriptorMap) {
|
||||||
Collection<DeclarationDescriptor> descriptors = descriptorMap.get(name);
|
Set<Pair<PsiElement, Name>> redeclarations = Sets.newHashSet();
|
||||||
if (descriptors.size() > 1) {
|
for (Name name : descriptorMap.keySet()) {
|
||||||
for (DeclarationDescriptor descriptor : descriptors) {
|
Collection<DeclarationDescriptor> descriptors = descriptorMap.get(name);
|
||||||
trace.report(REDECLARATION.on(BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), (ClassDescriptor)descriptor), descriptor.getName().getName()));
|
if (descriptors.size() > 1) {
|
||||||
|
// We mustn't compare PropertyDescriptor with PropertyDescriptor because we do this at OverloadResolver
|
||||||
|
for (DeclarationDescriptor descriptor : descriptors) {
|
||||||
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
|
for (DeclarationDescriptor descriptor2 : descriptors) {
|
||||||
|
if (descriptor == descriptor2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
redeclarations.add(Pair.create(
|
||||||
|
BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), (ClassDescriptor) descriptor),
|
||||||
|
descriptor.getName()));
|
||||||
|
if (descriptor2 instanceof PropertyDescriptor) {
|
||||||
|
redeclarations.add(Pair.create(
|
||||||
|
BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), descriptor2),
|
||||||
|
descriptor2.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Pair<PsiElement, Name> redeclaration : redeclarations) {
|
||||||
|
trace.report(REDECLARATION.on(redeclaration.getFirst(), redeclaration.getSecond().getName()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
public class A() {
|
||||||
|
public val <!REDECLARATION!>FOO<!>: String = "test"
|
||||||
|
|
||||||
|
public class <!REDECLARATION!>FOO<!>() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class B() {
|
||||||
|
class object {
|
||||||
|
public val <!REDECLARATION!>FOO<!>: String = "test"
|
||||||
|
|
||||||
|
public class <!REDECLARATION!>FOO<!>() { }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2265,6 +2265,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
|||||||
doTest("compiler/testData/diagnostics/tests/redeclarations/PropertyAndFunInClass.kt");
|
doTest("compiler/testData/diagnostics/tests/redeclarations/PropertyAndFunInClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("PropertyAndInnerClass.kt")
|
||||||
|
public void testPropertyAndInnerClass() throws Exception {
|
||||||
|
doTest("compiler/testData/diagnostics/tests/redeclarations/PropertyAndInnerClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("Redeclarations.kt")
|
@TestMetadata("Redeclarations.kt")
|
||||||
public void testRedeclarations() throws Exception {
|
public void testRedeclarations() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/redeclarations/Redeclarations.kt");
|
doTest("compiler/testData/diagnostics/tests/redeclarations/Redeclarations.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user