Report redeclaration errors for type aliases vs class/interface/object.

This commit is contained in:
Dmitry Petrov
2016-06-08 17:52:12 +03:00
parent d3721872b2
commit 44829a61e7
7 changed files with 84 additions and 11 deletions
@@ -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
@@ -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()
}
}
@@ -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");