diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java index 068a695751c..29146968b7f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java @@ -43,7 +43,6 @@ public abstract class MutableClassDescriptorLite extends ClassDescriptorBase private List typeParameters; private Collection supertypes = Lists.newArrayList(); - private final Collection innerClasses = Lists.newArrayList(); private TypeConstructor typeConstructor; @@ -210,10 +209,6 @@ public abstract class MutableClassDescriptorLite extends ClassDescriptorBase return innerClassesScope; } - public Collection getInnerClasses() { - return innerClasses; - } - public void addSupertype(@NotNull JetType supertype) { if (!ErrorUtils.isErrorType(supertype)) { @@ -281,7 +276,6 @@ public abstract class MutableClassDescriptorLite extends ClassDescriptorBase @Override public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) { getScopeForMemberLookupAsWritableScope().addClassifierDescriptor(classDescriptor); - innerClasses.add(classDescriptor); } @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java index 97fc0e2cdca..25373dab6d9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java @@ -107,4 +107,10 @@ public abstract class AbstractScopeAdapter implements JetScope { public Collection getAllDescriptors() { return getWorkerScope().getAllDescriptors(); } + + @NotNull + @Override + public Collection getOwnDeclaredDescriptors() { + return getWorkerScope().getOwnDeclaredDescriptors(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java index 1a805f5e54d..0e9c5e2b204 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java @@ -19,6 +19,8 @@ package org.jetbrains.jet.lang.resolve; import com.google.common.base.Function; import com.google.common.base.Predicate; 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.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; @@ -93,7 +95,7 @@ public class DeclarationResolver { resolveFunctionAndPropertyHeaders(); importsResolver.processMembersImports(rootScope); checkRedeclarationsInNamespaces(); - checkClassObjectInnerClassNames(); + checkRedeclarationsInInnerClassNames(); } @@ -300,22 +302,31 @@ public class DeclarationResolver { return declarations; } - private void checkClassObjectInnerClassNames() { + private void checkRedeclarationsInInnerClassNames() { for (MutableClassDescriptor classDescriptor : context.getClasses().values()) { + Collection allDescriptors = classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors(); + MutableClassDescriptorLite classObj = classDescriptor.getClassObjectDescriptor(); - if (classObj == null) { - continue; + if (classObj != null) { + Collection classObjDescriptors = classObj.getScopeForMemberLookup().getOwnDeclaredDescriptors(); + if (!classObjDescriptors.isEmpty()) { + allDescriptors = Lists.newArrayList(allDescriptors); + allDescriptors.addAll(classObjDescriptors); + } } - Collection myInnerClasses = classDescriptor.getInnerClasses(); - Collection classObjInnerClasses = classObj.getInnerClasses(); + Multimap descriptorMap = HashMultimap.create(); + for (DeclarationDescriptor desc : allDescriptors) { + if (desc instanceof ClassDescriptor) { + descriptorMap.put(desc.getName(), desc); + } + } - for (ClassDescriptor myInnerClass : myInnerClasses) { - for (ClassDescriptor classObjInnerClass : classObjInnerClasses) { - if (myInnerClass.getName().equals(classObjInnerClass.getName())) { - trace.report(REDECLARATION.on(BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), myInnerClass), myInnerClass.getName().getName())); - trace.report(REDECLARATION.on(BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), classObjInnerClass), classObjInnerClass.getName().getName())); - break; + for (Name name : descriptorMap.keySet()) { + Collection descriptors = descriptorMap.get(name); + if (descriptors.size() > 1) { + for (DeclarationDescriptor descriptor : descriptors) { + trace.report(REDECLARATION.on(BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), (ClassDescriptor)descriptor), descriptor.getName().getName())); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java index ff6294d9f67..95e48124b05 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java @@ -260,4 +260,10 @@ public abstract class AbstractLazyMemberScope getOwnDeclaredDescriptors() { + return getAllDescriptors(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java index d47f4d57124..b34b69fb10b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java @@ -166,4 +166,10 @@ public class ChainedScope implements JetScope { } return allDescriptors; } + + @NotNull + @Override + public Collection getOwnDeclaredDescriptors() { + throw new UnsupportedOperationException(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/InnerClassesScopeWrapper.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/InnerClassesScopeWrapper.java index 744811a42cf..26f0049a654 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/InnerClassesScopeWrapper.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/InnerClassesScopeWrapper.java @@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; 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.Name; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; @@ -34,13 +35,19 @@ import java.util.List; /** * @author svtk */ -public class InnerClassesScopeWrapper extends JetScopeImpl { +public class InnerClassesScopeWrapper extends AbstractScopeAdapter { private final JetScope actualScope; public InnerClassesScopeWrapper(JetScope actualScope) { this.actualScope = actualScope; } + @NotNull + @Override + protected JetScope getWorkerScope() { + return actualScope; + } + private boolean isClass(DeclarationDescriptor descriptor) { return descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.OBJECT; } @@ -52,12 +59,6 @@ public class InnerClassesScopeWrapper extends JetScopeImpl { return null; } - @NotNull - @Override - public DeclarationDescriptor getContainingDeclaration() { - return actualScope.getContainingDeclaration(); - } - @NotNull @Override public Collection getDeclarationsByLabel(LabelName labelName) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java index 07eec60d39e..b3f9ca55935 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java @@ -97,4 +97,7 @@ public interface JetScope { * @param result */ void getImplicitReceiversHierarchy(@NotNull List result); + + @NotNull + Collection getOwnDeclaredDescriptors(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java index eb37ce906e7..7c26307ecd9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java @@ -95,4 +95,10 @@ public abstract class JetScopeImpl implements JetScope { @Override public void getImplicitReceiversHierarchy(@NotNull List result) { } + + @NotNull + @Override + public Collection getOwnDeclaredDescriptors() { + return Collections.emptyList(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java index e42273defa3..6353a7d0665 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java @@ -162,4 +162,10 @@ public class SubstitutingScope implements JetScope { } return allDescriptors; } + + @NotNull + @Override + public Collection getOwnDeclaredDescriptors() { + return substitute(workerScope.getOwnDeclaredDescriptors()); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java index 4bc59570f26..469cfcf4e82 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java @@ -533,4 +533,10 @@ public class WritableScopeImpl extends WritableScopeWithImports { public Multimap getDeclaredDescriptorsAccessibleBySimpleName() { return declaredDescriptorsAccessibleBySimpleName; } + + @NotNull + @Override + public Collection getOwnDeclaredDescriptors() { + return declaredDescriptorsAccessibleBySimpleName.values(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java index f07c259b58b..2e966b7ff5c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java @@ -116,6 +116,11 @@ public class ErrorUtils { return Collections.emptyList(); } + @NotNull + @Override + public Collection getOwnDeclaredDescriptors() { + return Collections.emptyList(); + } } private static final ClassDescriptorImpl ERROR_CLASS = new ClassDescriptorImpl(ERROR_MODULE, Collections.emptyList(), Modality.OPEN, Name.special("")) { diff --git a/compiler/testData/diagnostics/tests/redeclarations/kt2438.kt b/compiler/testData/diagnostics/tests/redeclarations/kt2438.kt new file mode 100644 index 00000000000..a9ebccdadbd --- /dev/null +++ b/compiler/testData/diagnostics/tests/redeclarations/kt2438.kt @@ -0,0 +1,21 @@ +//KT-2438 Prohibit inner classes with the same name + +package kt2438 + +class B { + class C + class C +} + + + +class A { + class B + + class object { + class B + class B + } + + class B +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index ba90a421315..5ff62bb5fd0 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -1900,6 +1900,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage 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") public void testMultiFilePackageRedeclaration() throws Exception { doTest("compiler/testData/diagnostics/tests/redeclarations/MultiFilePackageRedeclaration.kt");