Merge pull request #109 from udalov/kt2438
KT-2438 Prohibit inner classes with the same name
This commit is contained in:
-6
@@ -43,7 +43,6 @@ public abstract class MutableClassDescriptorLite extends ClassDescriptorBase
|
|||||||
|
|
||||||
private List<TypeParameterDescriptor> typeParameters;
|
private List<TypeParameterDescriptor> typeParameters;
|
||||||
private Collection<JetType> supertypes = Lists.newArrayList();
|
private Collection<JetType> supertypes = Lists.newArrayList();
|
||||||
private final Collection<ClassDescriptor> innerClasses = Lists.newArrayList();
|
|
||||||
|
|
||||||
private TypeConstructor typeConstructor;
|
private TypeConstructor typeConstructor;
|
||||||
|
|
||||||
@@ -210,10 +209,6 @@ public abstract class MutableClassDescriptorLite extends ClassDescriptorBase
|
|||||||
return innerClassesScope;
|
return innerClassesScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<ClassDescriptor> getInnerClasses() {
|
|
||||||
return innerClasses;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void addSupertype(@NotNull JetType supertype) {
|
public void addSupertype(@NotNull JetType supertype) {
|
||||||
if (!ErrorUtils.isErrorType(supertype)) {
|
if (!ErrorUtils.isErrorType(supertype)) {
|
||||||
@@ -281,7 +276,6 @@ public abstract class MutableClassDescriptorLite extends ClassDescriptorBase
|
|||||||
@Override
|
@Override
|
||||||
public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
|
public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
|
||||||
getScopeForMemberLookupAsWritableScope().addClassifierDescriptor(classDescriptor);
|
getScopeForMemberLookupAsWritableScope().addClassifierDescriptor(classDescriptor);
|
||||||
innerClasses.add(classDescriptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -107,4 +107,10 @@ public abstract class AbstractScopeAdapter implements JetScope {
|
|||||||
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
||||||
return getWorkerScope().getAllDescriptors();
|
return getWorkerScope().getAllDescriptors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
|
||||||
|
return getWorkerScope().getOwnDeclaredDescriptors();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,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.Collections2;
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Multimap;
|
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;
|
||||||
@@ -93,7 +95,7 @@ public class DeclarationResolver {
|
|||||||
resolveFunctionAndPropertyHeaders();
|
resolveFunctionAndPropertyHeaders();
|
||||||
importsResolver.processMembersImports(rootScope);
|
importsResolver.processMembersImports(rootScope);
|
||||||
checkRedeclarationsInNamespaces();
|
checkRedeclarationsInNamespaces();
|
||||||
checkClassObjectInnerClassNames();
|
checkRedeclarationsInInnerClassNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -300,22 +302,31 @@ public class DeclarationResolver {
|
|||||||
return declarations;
|
return declarations;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkClassObjectInnerClassNames() {
|
private void checkRedeclarationsInInnerClassNames() {
|
||||||
for (MutableClassDescriptor classDescriptor : context.getClasses().values()) {
|
for (MutableClassDescriptor classDescriptor : context.getClasses().values()) {
|
||||||
|
Collection<DeclarationDescriptor> allDescriptors = classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors();
|
||||||
|
|
||||||
MutableClassDescriptorLite classObj = classDescriptor.getClassObjectDescriptor();
|
MutableClassDescriptorLite classObj = classDescriptor.getClassObjectDescriptor();
|
||||||
if (classObj == null) {
|
if (classObj != null) {
|
||||||
continue;
|
Collection<DeclarationDescriptor> classObjDescriptors = classObj.getScopeForMemberLookup().getOwnDeclaredDescriptors();
|
||||||
|
if (!classObjDescriptors.isEmpty()) {
|
||||||
|
allDescriptors = Lists.newArrayList(allDescriptors);
|
||||||
|
allDescriptors.addAll(classObjDescriptors);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<ClassDescriptor> myInnerClasses = classDescriptor.getInnerClasses();
|
Multimap<Name, DeclarationDescriptor> descriptorMap = HashMultimap.create();
|
||||||
Collection<ClassDescriptor> classObjInnerClasses = classObj.getInnerClasses();
|
for (DeclarationDescriptor desc : allDescriptors) {
|
||||||
|
if (desc instanceof ClassDescriptor) {
|
||||||
|
descriptorMap.put(desc.getName(), desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (ClassDescriptor myInnerClass : myInnerClasses) {
|
for (Name name : descriptorMap.keySet()) {
|
||||||
for (ClassDescriptor classObjInnerClass : classObjInnerClasses) {
|
Collection<DeclarationDescriptor> descriptors = descriptorMap.get(name);
|
||||||
if (myInnerClass.getName().equals(classObjInnerClass.getName())) {
|
if (descriptors.size() > 1) {
|
||||||
trace.report(REDECLARATION.on(BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), myInnerClass), myInnerClass.getName().getName()));
|
for (DeclarationDescriptor descriptor : descriptors) {
|
||||||
trace.report(REDECLARATION.on(BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), classObjInnerClass), classObjInnerClass.getName().getName()));
|
trace.report(REDECLARATION.on(BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), (ClassDescriptor)descriptor), descriptor.getName().getName()));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -260,4 +260,10 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
|
|||||||
// a generic implementation can't do this properly
|
// a generic implementation can't do this properly
|
||||||
@Override
|
@Override
|
||||||
public abstract String toString();
|
public abstract String toString();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
|
||||||
|
return getAllDescriptors();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,4 +166,10 @@ public class ChainedScope implements JetScope {
|
|||||||
}
|
}
|
||||||
return allDescriptors;
|
return allDescriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-7
@@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
|||||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.AbstractScopeAdapter;
|
||||||
import org.jetbrains.jet.lang.resolve.name.LabelName;
|
import org.jetbrains.jet.lang.resolve.name.LabelName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
@@ -34,13 +35,19 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @author svtk
|
* @author svtk
|
||||||
*/
|
*/
|
||||||
public class InnerClassesScopeWrapper extends JetScopeImpl {
|
public class InnerClassesScopeWrapper extends AbstractScopeAdapter {
|
||||||
private final JetScope actualScope;
|
private final JetScope actualScope;
|
||||||
|
|
||||||
public InnerClassesScopeWrapper(JetScope actualScope) {
|
public InnerClassesScopeWrapper(JetScope actualScope) {
|
||||||
this.actualScope = actualScope;
|
this.actualScope = actualScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
protected JetScope getWorkerScope() {
|
||||||
|
return actualScope;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isClass(DeclarationDescriptor descriptor) {
|
private boolean isClass(DeclarationDescriptor descriptor) {
|
||||||
return descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.OBJECT;
|
return descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.OBJECT;
|
||||||
}
|
}
|
||||||
@@ -52,12 +59,6 @@ public class InnerClassesScopeWrapper extends JetScopeImpl {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public DeclarationDescriptor getContainingDeclaration() {
|
|
||||||
return actualScope.getContainingDeclaration();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<DeclarationDescriptor> getDeclarationsByLabel(LabelName labelName) {
|
public Collection<DeclarationDescriptor> getDeclarationsByLabel(LabelName labelName) {
|
||||||
|
|||||||
@@ -97,4 +97,7 @@ public interface JetScope {
|
|||||||
* @param result
|
* @param result
|
||||||
*/
|
*/
|
||||||
void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result);
|
void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
Collection<DeclarationDescriptor> getOwnDeclaredDescriptors();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,4 +95,10 @@ public abstract class JetScopeImpl implements JetScope {
|
|||||||
@Override
|
@Override
|
||||||
public void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result) {
|
public void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,4 +162,10 @@ public class SubstitutingScope implements JetScope {
|
|||||||
}
|
}
|
||||||
return allDescriptors;
|
return allDescriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
|
||||||
|
return substitute(workerScope.getOwnDeclaredDescriptors());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -533,4 +533,10 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
|||||||
public Multimap<Name, DeclarationDescriptor> getDeclaredDescriptorsAccessibleBySimpleName() {
|
public Multimap<Name, DeclarationDescriptor> getDeclaredDescriptorsAccessibleBySimpleName() {
|
||||||
return declaredDescriptorsAccessibleBySimpleName;
|
return declaredDescriptorsAccessibleBySimpleName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
|
||||||
|
return declaredDescriptorsAccessibleBySimpleName.values();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,11 @@ public class ErrorUtils {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final ClassDescriptorImpl ERROR_CLASS = new ClassDescriptorImpl(ERROR_MODULE, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Name.special("<ERROR CLASS>")) {
|
private static final ClassDescriptorImpl ERROR_CLASS = new ClassDescriptorImpl(ERROR_MODULE, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Name.special("<ERROR CLASS>")) {
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
//KT-2438 Prohibit inner classes with the same name
|
||||||
|
|
||||||
|
package kt2438
|
||||||
|
|
||||||
|
class B {
|
||||||
|
class <!REDECLARATION!>C<!>
|
||||||
|
class <!REDECLARATION!>C<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class A {
|
||||||
|
class <!REDECLARATION!>B<!>
|
||||||
|
|
||||||
|
class object {
|
||||||
|
class <!REDECLARATION!>B<!>
|
||||||
|
class <!REDECLARATION!>B<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
class <!REDECLARATION!>B<!>
|
||||||
|
}
|
||||||
@@ -1900,6 +1900,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
|||||||
doTest("compiler/testData/diagnostics/tests/redeclarations/kt2247.kt");
|
doTest("compiler/testData/diagnostics/tests/redeclarations/kt2247.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt2438.kt")
|
||||||
|
public void testKt2438() throws Exception {
|
||||||
|
doTest("compiler/testData/diagnostics/tests/redeclarations/kt2438.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("MultiFilePackageRedeclaration.kt")
|
@TestMetadata("MultiFilePackageRedeclaration.kt")
|
||||||
public void testMultiFilePackageRedeclaration() throws Exception {
|
public void testMultiFilePackageRedeclaration() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/redeclarations/MultiFilePackageRedeclaration.kt");
|
doTest("compiler/testData/diagnostics/tests/redeclarations/MultiFilePackageRedeclaration.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user