Merge pull request #109 from udalov/kt2438

KT-2438 Prohibit inner classes with the same name
This commit is contained in:
Andrey Breslav
2012-07-24 07:51:35 -07:00
13 changed files with 101 additions and 25 deletions
@@ -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();
}
} }
@@ -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");