Report redeclaration errors for type aliases vs class/interface/object.
This commit is contained in:
@@ -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<Name, DeclarationDescriptor>()
|
||||
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<DeclarationDescriptor>()
|
||||
|
||||
descriptors.addIfNotNull(topLevelDescriptorProvider.getPackageFragment(fqName))
|
||||
descriptors.addAll(topLevelDescriptorProvider.getTopLevelClassDescriptors(fqName, location))
|
||||
descriptors.addAll(topLevelDescriptorProvider.getTopLevelClassifierDescriptors(fqName, location))
|
||||
return descriptors
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ClassDescriptor> getTopLevelClassDescriptors(@NotNull FqName fqName, @NotNull final LookupLocation location) {
|
||||
public Collection<ClassifierDescriptor> 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<ClassifierDescriptor> result = new SmartList<ClassifierDescriptor>();
|
||||
|
||||
result.addAll(ContainerUtil.mapNotNull(
|
||||
provider.getClassOrObjectDeclarations(fqName.shortName()),
|
||||
new Function<KtClassLikeInfo, ClassDescriptor>() {
|
||||
new Function<KtClassLikeInfo, ClassifierDescriptor>() {
|
||||
@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<KtTypeAlias, ClassifierDescriptor>() {
|
||||
@Override
|
||||
public ClassifierDescriptor fun(KtTypeAlias alias) {
|
||||
return (ClassifierDescriptor) lazyDeclarationResolver.resolveToDescriptor(alias);
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-3
@@ -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<ClassDescriptor>
|
||||
fun getTopLevelClassifierDescriptors(fqName: FqName, location: LookupLocation): Collection<ClassifierDescriptor>
|
||||
}
|
||||
|
||||
object NoTopLevelDescriptorProvider : TopLevelDescriptorProvider {
|
||||
@@ -34,7 +34,7 @@ object NoTopLevelDescriptorProvider : TopLevelDescriptorProvider {
|
||||
shouldNotBeCalled()
|
||||
}
|
||||
|
||||
override fun getTopLevelClassDescriptors(fqName: FqName, location: LookupLocation): Collection<ClassDescriptor> {
|
||||
override fun getTopLevelClassifierDescriptors(fqName: FqName, location: LookupLocation): Collection<ClassifierDescriptor> {
|
||||
shouldNotBeCalled()
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -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<SimpleFunctionDescriptor> {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// FILE: file1.kt
|
||||
class <!REDECLARATION!>SomeClass<!>
|
||||
|
||||
typealias <!REDECLARATION!>SomeClass<!> = Any
|
||||
typealias <!REDECLARATION!>SomeClass<!> = Any
|
||||
typealias <!REDECLARATION!>SomeClass<!> = Any
|
||||
|
||||
class Outer {
|
||||
class <!REDECLARATION!>Nested<!>
|
||||
|
||||
typealias <!REDECLARATION!>Nested<!> = Any
|
||||
typealias <!REDECLARATION!>Nested<!> = Any
|
||||
typealias <!REDECLARATION!>Nested<!> = Any
|
||||
}
|
||||
|
||||
// FILE: file2.kt
|
||||
typealias <!REDECLARATION!>SomeClass<!> = Any
|
||||
@@ -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
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user