diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationResolver.kt index 7f22eb1b7d6..9fa02286101 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationResolver.kt @@ -21,6 +21,7 @@ import com.google.common.collect.Multimap import com.google.common.collect.Sets import com.intellij.psi.PsiElement import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.diagnostics.Errors @@ -54,7 +55,7 @@ class DeclarationResolver( for (classDescriptor in c.declaredClasses.values) { val descriptorMap = HashMultimap.create() for (desc in classDescriptor.unsubstitutedMemberScope.getContributedDescriptors()) { - if (desc is ClassDescriptor || desc is PropertyDescriptor) { + if (desc is ClassifierDescriptor || desc is PropertyDescriptor) { descriptorMap.put(desc.name, desc) } } @@ -72,7 +73,7 @@ class DeclarationResolver( } // We mustn't compare PropertyDescriptor with PropertyDescriptor because we do this at OverloadResolver for (descriptor in descriptors) { - if (descriptor is ClassDescriptor) { + if (descriptor is ClassifierDescriptor) { for (descriptor2 in descriptors) { if (descriptor === descriptor2) { continue @@ -116,7 +117,7 @@ class DeclarationResolver( val descriptors = HashSet() descriptors.addIfNotNull(topLevelDescriptorProvider.getPackageFragment(fqName)) - descriptors.addAll(topLevelDescriptorProvider.getTopLevelClassDescriptors(fqName, location)) + descriptors.addAll(topLevelDescriptorProvider.getTopLevelClassifierDescriptors(fqName, location)) return descriptors } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ResolveSession.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ResolveSession.java index d0f1958e93f..fef3ad71530 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ResolveSession.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ResolveSession.java @@ -45,8 +45,10 @@ import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor; import org.jetbrains.kotlin.resolve.scopes.LexicalScope; import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.storage.*; +import org.jetbrains.kotlin.utils.SmartList; import javax.inject.Inject; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -234,15 +236,17 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext { @Override @NotNull @ReadOnly - public Collection getTopLevelClassDescriptors(@NotNull FqName fqName, @NotNull final LookupLocation location) { + public Collection getTopLevelClassifierDescriptors(@NotNull FqName fqName, @NotNull final LookupLocation location) { if (fqName.isRoot()) return Collections.emptyList(); PackageMemberDeclarationProvider provider = declarationProviderFactory.getPackageMemberDeclarationProvider(fqName.parent()); if (provider == null) return Collections.emptyList(); - return ContainerUtil.mapNotNull( + Collection result = new SmartList(); + + result.addAll(ContainerUtil.mapNotNull( provider.getClassOrObjectDeclarations(fqName.shortName()), - new Function() { + new Function() { @Override public ClassDescriptor fun(KtClassLikeInfo classLikeInfo) { if (classLikeInfo instanceof KtClassOrObjectInfo) { @@ -259,7 +263,19 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext { } } } - ); + )); + + result.addAll(ContainerUtil.map( + provider.getTypeAliasDeclarations(fqName.shortName()), + new Function() { + @Override + public ClassifierDescriptor fun(KtTypeAlias alias) { + return (ClassifierDescriptor) lazyDeclarationResolver.resolveToDescriptor(alias); + } + } + )); + + return result; } @Override diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/TopLevelDescriptorProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/TopLevelDescriptorProvider.kt index 09ba4a59cf2..284b7ca0a31 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/TopLevelDescriptorProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/TopLevelDescriptorProvider.kt @@ -16,7 +16,7 @@ package org.jetbrains.kotlin.resolve.lazy -import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor interface TopLevelDescriptorProvider { fun getPackageFragment(fqName: FqName): LazyPackageDescriptor? - fun getTopLevelClassDescriptors(fqName: FqName, location: LookupLocation): Collection + fun getTopLevelClassifierDescriptors(fqName: FqName, location: LookupLocation): Collection } object NoTopLevelDescriptorProvider : TopLevelDescriptorProvider { @@ -34,7 +34,7 @@ object NoTopLevelDescriptorProvider : TopLevelDescriptorProvider { shouldNotBeCalled() } - override fun getTopLevelClassDescriptors(fqName: FqName, location: LookupLocation): Collection { + override fun getTopLevelClassifierDescriptors(fqName: FqName, location: LookupLocation): Collection { shouldNotBeCalled() } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt index ae9e71d96ab..7f719c04817 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt @@ -60,7 +60,10 @@ protected constructor( override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { recordLookup(name, location) - return classDescriptors(name).firstOrNull() ?: typeAliasDescriptors(name).firstOrNull() + // NB we should resolve type alias descriptors even if a class descriptor with corresponding name is present + val firstClassDescriptor = classDescriptors(name).firstOrNull() + val firstTypeAliasDescriptor = typeAliasDescriptors(name).firstOrNull() + return firstClassDescriptor ?: firstTypeAliasDescriptor } override fun getContributedFunctions(name: Name, location: LookupLocation): Collection { diff --git a/compiler/testData/diagnostics/tests/redeclarations/TypeAliasVsClass.kt b/compiler/testData/diagnostics/tests/redeclarations/TypeAliasVsClass.kt new file mode 100644 index 00000000000..41ece3c7c86 --- /dev/null +++ b/compiler/testData/diagnostics/tests/redeclarations/TypeAliasVsClass.kt @@ -0,0 +1,17 @@ +// FILE: file1.kt +class SomeClass + +typealias SomeClass = Any +typealias SomeClass = Any +typealias SomeClass = Any + +class Outer { + class Nested + + typealias Nested = Any + typealias Nested = Any + typealias Nested = Any +} + +// FILE: file2.kt +typealias SomeClass = Any \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/redeclarations/TypeAliasVsClass.txt b/compiler/testData/diagnostics/tests/redeclarations/TypeAliasVsClass.txt new file mode 100644 index 00000000000..a0c21c7e85a --- /dev/null +++ b/compiler/testData/diagnostics/tests/redeclarations/TypeAliasVsClass.txt @@ -0,0 +1,30 @@ +package + +public typealias SomeClass = kotlin.Any +public typealias SomeClass = kotlin.Any +public typealias SomeClass = kotlin.Any +public typealias SomeClass = kotlin.Any + +public final class Outer { + public typealias Nested = kotlin.Any + public typealias Nested = kotlin.Any + public typealias Nested = kotlin.Any + public constructor Outer() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public final class Nested { + public constructor Nested() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public final class SomeClass { + public constructor SomeClass() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 0e0f1ab72e0..17d311b05ae 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -13890,6 +13890,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("TypeAliasVsClass.kt") + public void testTypeAliasVsClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/redeclarations/TypeAliasVsClass.kt"); + doTest(fileName); + } + @TestMetadata("typeParameterWithTwoBounds.kt") public void testTypeParameterWithTwoBounds() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/redeclarations/typeParameterWithTwoBounds.kt");