Redeclaration errors for type aliases: type alias vs function.
This commit is contained in:
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.results.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.getTypeAliasConstructors
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResolution
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
@@ -99,14 +100,25 @@ class OverloadChecker(val specificityComparator: TypeSpecificityComparator) {
|
||||
): MultiMap<FqNameUnsafe, DeclarationDescriptorNonRoot> {
|
||||
val packageMembersByName = MultiMap<FqNameUnsafe, DeclarationDescriptorNonRoot>()
|
||||
|
||||
collectModulePackageMembersWithSameName(packageMembersByName, c.functions.values + c.declaredClasses.values, overloadFilter) {
|
||||
collectModulePackageMembersWithSameName(
|
||||
packageMembersByName,
|
||||
c.functions.values + c.declaredClasses.values + c.typeAliases.values,
|
||||
overloadFilter
|
||||
) {
|
||||
scope, name ->
|
||||
val functions = scope.getContributedFunctions(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
|
||||
val classifier = scope.getContributedClassifier(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
|
||||
if (classifier is ClassDescriptor && !classifier.kind.isSingleton)
|
||||
functions + classifier.constructors
|
||||
else
|
||||
functions
|
||||
when (classifier) {
|
||||
is ClassDescriptor ->
|
||||
if (!classifier.kind.isSingleton)
|
||||
functions + classifier.constructors
|
||||
else
|
||||
functions
|
||||
is TypeAliasDescriptor ->
|
||||
functions + classifier.getTypeAliasConstructors()
|
||||
else ->
|
||||
functions
|
||||
}
|
||||
}
|
||||
|
||||
collectModulePackageMembersWithSameName(packageMembersByName, c.properties.values, overloadFilter) {
|
||||
|
||||
@@ -18,10 +18,12 @@ package org.jetbrains.kotlin.resolve
|
||||
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.getTypeAliasConstructors
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
|
||||
class OverloadResolver(
|
||||
@@ -31,7 +33,7 @@ class OverloadResolver(
|
||||
) {
|
||||
|
||||
fun checkOverloads(c: BodiesResolveContext) {
|
||||
val inClasses = findConstructorsInNestedClasses(c)
|
||||
val inClasses = findConstructorsInNestedClassesAndTypeAliases(c)
|
||||
|
||||
for (entry in c.declaredClasses.entries) {
|
||||
checkOverloadsInClass(entry.value, inClasses.get(entry.value))
|
||||
@@ -39,8 +41,8 @@ class OverloadResolver(
|
||||
checkOverloadsInPackages(c)
|
||||
}
|
||||
|
||||
private fun findConstructorsInNestedClasses(c: BodiesResolveContext): MultiMap<ClassDescriptor, ConstructorDescriptor> {
|
||||
val constructorsInNestedClasses = MultiMap.create<ClassDescriptor, ConstructorDescriptor>()
|
||||
private fun findConstructorsInNestedClassesAndTypeAliases(c: BodiesResolveContext): MultiMap<ClassDescriptor, ConstructorDescriptor> {
|
||||
val constructorsByOuterClass = MultiMap.create<ClassDescriptor, ConstructorDescriptor>()
|
||||
|
||||
for (klass in c.declaredClasses.values) {
|
||||
if (klass.kind.isSingleton || klass.name.isSpecial) {
|
||||
@@ -52,7 +54,7 @@ class OverloadResolver(
|
||||
// TODO: check overload conflicts of functions with constructors in scripts
|
||||
}
|
||||
else if (containingDeclaration is ClassDescriptor) {
|
||||
constructorsInNestedClasses.putValues(containingDeclaration, klass.constructors)
|
||||
constructorsByOuterClass.putValues(containingDeclaration, klass.constructors)
|
||||
}
|
||||
else if (!(containingDeclaration is FunctionDescriptor ||
|
||||
containingDeclaration is PropertyDescriptor ||
|
||||
@@ -61,7 +63,14 @@ class OverloadResolver(
|
||||
}
|
||||
}
|
||||
|
||||
return constructorsInNestedClasses
|
||||
for (typeAlias in c.typeAliases.values) {
|
||||
val containingDeclaration = typeAlias.containingDeclaration
|
||||
if (containingDeclaration is ClassDescriptor) {
|
||||
constructorsByOuterClass.putValues(containingDeclaration, typeAlias.getTypeAliasConstructors())
|
||||
}
|
||||
}
|
||||
|
||||
return constructorsByOuterClass
|
||||
}
|
||||
|
||||
private fun checkOverloadsInPackages(c: BodiesResolveContext) {
|
||||
@@ -82,8 +91,14 @@ class OverloadResolver(
|
||||
functionsByName.putValue(function.name, function)
|
||||
}
|
||||
|
||||
for (nestedClassConstructor in nestedClassConstructors) {
|
||||
functionsByName.putValue(nestedClassConstructor.containingDeclaration.name, nestedClassConstructor)
|
||||
for (nestedConstructor in nestedClassConstructors) {
|
||||
val name =
|
||||
if (nestedConstructor is TypeAliasConstructorDescriptor)
|
||||
nestedConstructor.typeAliasDescriptor.name
|
||||
else
|
||||
nestedConstructor.containingDeclaration.name
|
||||
|
||||
functionsByName.putValue(name, nestedConstructor)
|
||||
}
|
||||
|
||||
for (e in functionsByName.entrySet()) {
|
||||
|
||||
@@ -244,7 +244,7 @@ private fun ResolutionScope.getContributedFunctionsAndConstructors(name: Name, l
|
||||
val classifier = getContributedClassifier(name, location)
|
||||
return getContributedFunctions(name, location) +
|
||||
(getClassWithConstructors(classifier)?.constructors?.filter { it.dispatchReceiverParameter == null } ?: emptyList()) +
|
||||
(classifier?.getTypeAliasConstructors(false) ?: emptyList())
|
||||
(classifier?.getTypeAliasConstructors() ?: emptyList())
|
||||
}
|
||||
|
||||
private fun ResolutionScope.getContributedVariablesAndObjects(name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||
@@ -274,7 +274,7 @@ private fun getClassWithConstructors(classifier: ClassifierDescriptor?): ClassDe
|
||||
private val ClassDescriptor.canHaveCallableConstructors: Boolean
|
||||
get() = !ErrorUtils.isError(this) && !kind.isSingleton
|
||||
|
||||
private fun ClassifierDescriptor.getTypeAliasConstructors(inner: Boolean): Collection<ConstructorDescriptor> {
|
||||
fun ClassifierDescriptor.getTypeAliasConstructors(): Collection<ConstructorDescriptor> {
|
||||
if (this !is TypeAliasDescriptor) return emptyList()
|
||||
|
||||
val classDescriptor = this.classDescriptor ?: return emptyList()
|
||||
@@ -282,10 +282,11 @@ private fun ClassifierDescriptor.getTypeAliasConstructors(inner: Boolean): Colle
|
||||
|
||||
val substitutor = this.getTypeSubstitutorForUnderlyingClass() ?: throw AssertionError("classDescriptor should be non-null for $this")
|
||||
|
||||
return classDescriptor.constructors.filter {
|
||||
if (inner) it.dispatchReceiverParameter != null else it.dispatchReceiverParameter == null
|
||||
}.mapNotNull {
|
||||
TypeAliasConstructorDescriptorImpl.create(this, it, substitutor)
|
||||
return classDescriptor.constructors.mapNotNull {
|
||||
if (it.dispatchReceiverParameter == null)
|
||||
TypeAliasConstructorDescriptorImpl.create(this, it, substitutor)
|
||||
else
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
class C(val x: Int)
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>typealias CC = C<!>
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>fun CC(x: Int)<!> = x
|
||||
|
||||
class Outer {
|
||||
class C(val x: Int)
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>typealias CC = C<!>
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>fun CC(x: Int)<!> = x
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package
|
||||
|
||||
public typealias CC = C
|
||||
public fun CC(/*0*/ x: kotlin.Int): kotlin.Int
|
||||
|
||||
public final class C {
|
||||
public constructor C(/*0*/ x: kotlin.Int)
|
||||
public final val x: kotlin.Int
|
||||
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 Outer {
|
||||
public typealias CC = Outer.C
|
||||
public constructor Outer()
|
||||
public final fun CC(/*0*/ x: kotlin.Int): kotlin.Int
|
||||
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 C {
|
||||
public constructor C(/*0*/ x: kotlin.Int)
|
||||
public final val x: kotlin.Int
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,11 @@ typealias <!REDECLARATION!>SomeClass<!> = Any
|
||||
typealias <!REDECLARATION!>SomeClass<!> = Any
|
||||
|
||||
class Outer {
|
||||
class <!REDECLARATION!>Nested<!>
|
||||
class <!REDECLARATION, CONFLICTING_OVERLOADS!>Nested<!>
|
||||
|
||||
typealias <!REDECLARATION!>Nested<!> = Any
|
||||
typealias <!REDECLARATION!>Nested<!> = Any
|
||||
typealias <!REDECLARATION!>Nested<!> = Any
|
||||
<!CONFLICTING_OVERLOADS!>typealias <!REDECLARATION!>Nested<!> = Any<!>
|
||||
<!CONFLICTING_OVERLOADS!>typealias <!REDECLARATION!>Nested<!> = Any<!>
|
||||
<!CONFLICTING_OVERLOADS!>typealias <!REDECLARATION!>Nested<!> = Any<!>
|
||||
}
|
||||
|
||||
// FILE: file2.kt
|
||||
|
||||
@@ -13902,6 +13902,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAliasCtorVsFun.kt")
|
||||
public void testTypeAliasCtorVsFun() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/redeclarations/TypeAliasCtorVsFun.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAliasVsClass.kt")
|
||||
public void testTypeAliasVsClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/redeclarations/TypeAliasVsClass.kt");
|
||||
|
||||
+23
-15
@@ -20,25 +20,30 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
interface TypeAliasConstructorDescriptor : ConstructorDescriptor {
|
||||
val typeAliasDescriptor: TypeAliasDescriptor
|
||||
val underlyingConstructorDescriptor: ConstructorDescriptor
|
||||
}
|
||||
|
||||
class TypeAliasConstructorDescriptorImpl private constructor(
|
||||
override val typeAliasDescriptor: TypeAliasDescriptor,
|
||||
override val underlyingConstructorDescriptor: ConstructorDescriptor,
|
||||
containingDeclaration: ClassDescriptor,
|
||||
original: ConstructorDescriptor,
|
||||
original: TypeAliasConstructorDescriptor?,
|
||||
annotations: Annotations,
|
||||
primary: Boolean,
|
||||
kind: Kind,
|
||||
source: SourceElement
|
||||
) : TypeAliasConstructorDescriptor,
|
||||
ConstructorDescriptorImpl(containingDeclaration, original, annotations, primary, kind, source)
|
||||
ConstructorDescriptorImpl(containingDeclaration, original, annotations,
|
||||
primary, kind, source)
|
||||
{
|
||||
override fun getOriginal(): TypeAliasConstructorDescriptor =
|
||||
super.getOriginal() as TypeAliasConstructorDescriptor
|
||||
|
||||
override fun substitute(substitutor: TypeSubstitutor): TypeAliasConstructorDescriptor =
|
||||
super.substitute(substitutor) as TypeAliasConstructorDescriptor
|
||||
|
||||
@@ -70,28 +75,31 @@ class TypeAliasConstructorDescriptorImpl private constructor(
|
||||
}
|
||||
assert(newName == null) { "Renaming type alias constructor: $this" }
|
||||
return TypeAliasConstructorDescriptorImpl(
|
||||
typeAliasDescriptor,
|
||||
typeAliasDescriptor, underlyingConstructorDescriptor,
|
||||
newOwner as ClassDescriptor,
|
||||
this, annotations, isPrimary, Kind.DECLARATION,
|
||||
source)
|
||||
this,
|
||||
annotations, isPrimary, Kind.DECLARATION, source)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(
|
||||
typeAliasDescriptor: TypeAliasDescriptor,
|
||||
original: ConstructorDescriptor,
|
||||
underlyingConstructor: ConstructorDescriptor,
|
||||
substitutor: TypeSubstitutor
|
||||
): TypeAliasConstructorDescriptor? {
|
||||
val descriptor = TypeAliasConstructorDescriptorImpl(typeAliasDescriptor, original.containingDeclaration, original,
|
||||
original.annotations, original.isPrimary, original.kind, original.source)
|
||||
val valueParameters = FunctionDescriptorImpl.getSubstitutedValueParameters(descriptor, original.valueParameters, substitutor, false)
|
||||
?: return null
|
||||
): TypeAliasConstructorDescriptor? = with(underlyingConstructor) {
|
||||
val typeAliasConstructor =
|
||||
TypeAliasConstructorDescriptorImpl(typeAliasDescriptor, underlyingConstructor, containingDeclaration, null,
|
||||
annotations, isPrimary, kind, typeAliasDescriptor.source)
|
||||
|
||||
descriptor.initialize(valueParameters, original.visibility, typeAliasDescriptor.typeConstructor.parameters)
|
||||
val valueParameters =
|
||||
FunctionDescriptorImpl.getSubstitutedValueParameters(typeAliasConstructor, valueParameters, substitutor, false)
|
||||
?: return null
|
||||
|
||||
descriptor.returnType = substitutor.substitute(original.returnType, Variance.OUT_VARIANCE) ?: return null
|
||||
typeAliasConstructor.initialize(valueParameters, visibility, typeAliasDescriptor.typeConstructor.parameters)
|
||||
|
||||
return descriptor
|
||||
typeAliasConstructor.returnType = substitutor.substitute(returnType, Variance.OUT_VARIANCE) ?: return null
|
||||
|
||||
typeAliasConstructor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user