Rewrite TowerLevels.
This commit is contained in:
+2
-3
@@ -62,9 +62,8 @@ internal class ExplicitReceiverScopeTowerProcessor<C>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveAsMember(): Collection<C> {
|
private fun resolveAsMember(): Collection<C> {
|
||||||
val members = ReceiverScopeTowerLevel(context.scopeTower, explicitReceiver).collectCandidates(name).filter { candidate ->
|
val members = ReceiverScopeTowerLevel(context.scopeTower, explicitReceiver)
|
||||||
candidate.dispatchReceiver != null && !candidate.requiresExtensionReceiver
|
.collectCandidates(name).filter { !it.requiresExtensionReceiver }
|
||||||
}
|
|
||||||
return members.map { context.createCandidate(it, ExplicitReceiverKind.DISPATCH_RECEIVER, extensionReceiver = null) }
|
return members.map { context.createCandidate(it, ExplicitReceiverKind.DISPATCH_RECEIVER, extensionReceiver = null) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
|||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.isDynamic
|
import org.jetbrains.kotlin.types.isDynamic
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.getImmediateSuperclassNotAny
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -64,95 +65,32 @@ internal abstract class AbstractScopeTowerLevel(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo create error for constructors call and for implicit receiver
|
|
||||||
// todo KT-9538 Unresolved inner class via subclass reference
|
// todo KT-9538 Unresolved inner class via subclass reference
|
||||||
// todo Future plan: move constructors and fake variables for objects to class member scope.
|
// todo add static methods & fields with error
|
||||||
internal abstract class ConstructorsAndFakeVariableHackLevelScope(scopeTower: ScopeTower) : AbstractScopeTowerLevel(scopeTower) {
|
|
||||||
|
|
||||||
protected fun createConstructors(
|
|
||||||
classifier: ClassifierDescriptor?,
|
|
||||||
dispatchReceiver: ReceiverValue?,
|
|
||||||
dispatchReceiverSmartCastType: KotlinType? = null,
|
|
||||||
checkClass: (ClassDescriptor) -> ResolutionDiagnostic? = { null }
|
|
||||||
): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
|
|
||||||
val classDescriptor = getClassWithConstructors(classifier) ?: return emptyList()
|
|
||||||
|
|
||||||
val specialError = checkClass(classDescriptor)
|
|
||||||
return classDescriptor.constructors.map {
|
|
||||||
|
|
||||||
val dispatchReceiverHack = if (dispatchReceiver == null && it.dispatchReceiverParameter != null) {
|
|
||||||
it.dispatchReceiverParameter?.value // todo this is hack for Scope Level
|
|
||||||
}
|
|
||||||
else if (dispatchReceiver != null && it.dispatchReceiverParameter == null) { // should be reported error
|
|
||||||
null
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dispatchReceiver
|
|
||||||
}
|
|
||||||
|
|
||||||
createCandidateDescriptor(it, dispatchReceiverHack, specialError, dispatchReceiverSmartCastType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun createVariableDescriptor(
|
|
||||||
classifier: ClassifierDescriptor?,
|
|
||||||
dispatchReceiverSmartCastType: KotlinType? = null,
|
|
||||||
checkClass: (ClassDescriptor) -> ResolutionDiagnostic? = { null }
|
|
||||||
): CandidateWithBoundDispatchReceiver<VariableDescriptor>? {
|
|
||||||
val fakeVariable = getFakeDescriptorForObject(classifier) ?: return null
|
|
||||||
return createCandidateDescriptor(fakeVariable, null, checkClass(fakeVariable.classDescriptor), dispatchReceiverSmartCastType)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun getClassWithConstructors(classifier: ClassifierDescriptor?): ClassDescriptor? {
|
|
||||||
if (classifier !is ClassDescriptor || ErrorUtils.isError(classifier)
|
|
||||||
// Constructors of singletons shouldn't be callable from the code
|
|
||||||
|| classifier.kind.isSingleton) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return classifier
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getFakeDescriptorForObject(classifier: ClassifierDescriptor?): FakeCallableDescriptorForObject? {
|
|
||||||
if (classifier !is ClassDescriptor || !classifier.hasClassValueDescriptor) return null // todo
|
|
||||||
|
|
||||||
return FakeCallableDescriptorForObject(classifier)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class ReceiverScopeTowerLevel(
|
internal class ReceiverScopeTowerLevel(
|
||||||
scopeTower: ScopeTower,
|
scopeTower: ScopeTower,
|
||||||
val dispatchReceiver: ReceiverValue
|
val dispatchReceiver: ReceiverValue
|
||||||
): ConstructorsAndFakeVariableHackLevelScope(scopeTower) {
|
): AbstractScopeTowerLevel(scopeTower) {
|
||||||
private val memberScope = dispatchReceiver.type.memberScope
|
|
||||||
|
|
||||||
private fun <D: CallableDescriptor> collectMembers(
|
private fun <D: CallableDescriptor> collectMembers(
|
||||||
members: ResolutionScope.() -> Collection<D>,
|
getMembers: ResolutionScope.(KotlinType?) -> Collection<D>
|
||||||
additionalDescriptors: ResolutionScope.(smartCastType: KotlinType?) -> Collection<CandidateWithBoundDispatchReceiver<D>> // todo
|
|
||||||
): Collection<CandidateWithBoundDispatchReceiver<D>> {
|
): Collection<CandidateWithBoundDispatchReceiver<D>> {
|
||||||
val result = ArrayList<CandidateWithBoundDispatchReceiver<D>>(0)
|
val result = ArrayList<CandidateWithBoundDispatchReceiver<D>>(0)
|
||||||
memberScope.members().mapTo(result) {
|
dispatchReceiver.type.memberScope.getMembers(dispatchReceiver.type).mapTo(result) {
|
||||||
createCandidateDescriptor(it, dispatchReceiver)
|
createCandidateDescriptor(it, dispatchReceiver)
|
||||||
}
|
}
|
||||||
result.addAll(memberScope.additionalDescriptors(null))
|
|
||||||
|
|
||||||
val smartCastPossibleTypes = scopeTower.dataFlowInfo.getSmartCastTypes(dispatchReceiver)
|
val smartCastPossibleTypes = scopeTower.dataFlowInfo.getSmartCastTypes(dispatchReceiver)
|
||||||
val unstableError = if (scopeTower.dataFlowInfo.isStableReceiver(dispatchReceiver)) null else UnstableSmartCastDiagnostic
|
val unstableError = if (scopeTower.dataFlowInfo.isStableReceiver(dispatchReceiver)) null else UnstableSmartCastDiagnostic
|
||||||
|
|
||||||
for (possibleType in smartCastPossibleTypes) {
|
for (possibleType in smartCastPossibleTypes) {
|
||||||
possibleType.memberScope.members().mapTo(result) {
|
possibleType.memberScope.getMembers(possibleType).mapTo(result) {
|
||||||
createCandidateDescriptor(it, dispatchReceiver, unstableError, dispatchReceiverSmartCastType = possibleType)
|
createCandidateDescriptor(it, dispatchReceiver, unstableError, dispatchReceiverSmartCastType = possibleType)
|
||||||
}
|
}
|
||||||
|
|
||||||
possibleType.memberScope.additionalDescriptors(possibleType).mapTo(result) {
|
|
||||||
it.addDiagnostic(unstableError)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dispatchReceiver.type.isDynamic()) {
|
if (dispatchReceiver.type.isDynamic()) {
|
||||||
scopeTower.dynamicScope.members().mapTo(result) {
|
scopeTower.dynamicScope.getMembers(null).mapTo(result) {
|
||||||
createCandidateDescriptor(it, dispatchReceiver, DynamicDescriptorDiagnostic)
|
createCandidateDescriptor(it, dispatchReceiver, DynamicDescriptorDiagnostic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,79 +98,46 @@ internal class ReceiverScopeTowerLevel(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo add static methods & fields with error
|
|
||||||
override fun getVariables(name: Name): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
|
override fun getVariables(name: Name): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
|
||||||
return collectMembers({ getContributedVariables(name, location) }) {
|
return collectMembers { getContributedVariables(name, location) }
|
||||||
smartCastType ->
|
|
||||||
listOfNotNull(createVariableDescriptor(getContributedClassifier(name, location), smartCastType){ NestedClassViaInstanceReference(it) } )
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFunctions(name: Name): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
|
override fun getFunctions(name: Name): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
|
||||||
return collectMembers({ getContributedFunctions(name, location) }) {
|
return collectMembers {
|
||||||
smartCastType ->
|
getContributedFunctions(name, location) + it.getInnerConstructors(name, location)
|
||||||
createConstructors(getContributedClassifier(name, location), dispatchReceiver, smartCastType) {
|
}
|
||||||
if (it.isInner) null else NestedClassViaInstanceReference(it)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class QualifierScopeTowerLevel(scopeTower: ScopeTower, val qualifier: QualifierReceiver) : AbstractScopeTowerLevel(scopeTower) {
|
||||||
|
override fun getVariables(name: Name) = qualifier.getNestedClassesAndPackageMembersScope()
|
||||||
|
.getContributedVariablesAndObjects(name, location).map {
|
||||||
|
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFunctions(name: Name) = qualifier.getNestedClassesAndPackageMembersScope()
|
||||||
|
.getContributedFunctionsAndConstructors(name, location).map {
|
||||||
|
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class QualifierScopeTowerLevel(scopeTower: ScopeTower, qualifier: QualifierReceiver) : ConstructorsAndFakeVariableHackLevelScope(scopeTower) {
|
|
||||||
private val qualifierScope = qualifier.getNestedClassesAndPackageMembersScope()
|
|
||||||
|
|
||||||
override fun getVariables(name: Name): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
|
|
||||||
val result = ArrayList<CandidateWithBoundDispatchReceiver<VariableDescriptor>>(0)
|
|
||||||
qualifierScope.getContributedVariables(name, location).mapTo(result) {
|
|
||||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
|
||||||
}
|
|
||||||
result.addIfNotNull(createVariableDescriptor(qualifierScope.getContributedClassifier(name, location)))
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getFunctions(name: Name): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
|
|
||||||
val functions = qualifierScope.getContributedFunctions(name, location).map {
|
|
||||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
|
||||||
}
|
|
||||||
val constructors = createConstructors(qualifierScope.getContributedClassifier(name, location), dispatchReceiver = null) {
|
|
||||||
if (it.isInner) InnerClassViaStaticReference(it) else null
|
|
||||||
}
|
|
||||||
return functions + constructors
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KT-3335 Creating imported super class' inner class fails in codegen
|
||||||
internal open class ScopeBasedTowerLevel protected constructor(
|
internal open class ScopeBasedTowerLevel protected constructor(
|
||||||
scopeTower: ScopeTower,
|
scopeTower: ScopeTower,
|
||||||
private val resolutionScope: ResolutionScope
|
private val resolutionScope: ResolutionScope
|
||||||
) : ConstructorsAndFakeVariableHackLevelScope(scopeTower) {
|
) : AbstractScopeTowerLevel(scopeTower) {
|
||||||
|
|
||||||
internal constructor(scopeTower: ScopeTower, lexicalScope: LexicalScope): this(scopeTower, lexicalScope as ResolutionScope)
|
internal constructor(scopeTower: ScopeTower, lexicalScope: LexicalScope): this(scopeTower, lexicalScope as ResolutionScope)
|
||||||
|
|
||||||
override fun getVariables(name: Name): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
|
override fun getVariables(name: Name): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
|
||||||
val result = ArrayList<CandidateWithBoundDispatchReceiver<VariableDescriptor>>(0)
|
= resolutionScope.getContributedVariablesAndObjects(name, location).map {
|
||||||
resolutionScope.getContributedVariables(name, location).mapTo(result) {
|
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
}
|
||||||
}
|
|
||||||
result.addIfNotNull(createVariableDescriptor(resolutionScope.getContributedClassifier(name, location)))
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getFunctions(name: Name): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
|
override fun getFunctions(name: Name): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>>
|
||||||
val result = ArrayList<CandidateWithBoundDispatchReceiver<FunctionDescriptor>>(0)
|
= resolutionScope.getContributedFunctionsAndConstructors(name, location).map {
|
||||||
resolutionScope.getContributedFunctions(name, location).mapTo(result) {
|
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// todo report errors for constructors if there is no match receiver
|
|
||||||
result.addAll(createConstructors(resolutionScope.getContributedClassifier(name, location), dispatchReceiver = null) {
|
|
||||||
if (!it.isInner) return@createConstructors null
|
|
||||||
|
|
||||||
// todo add constructors functions to member class member scope
|
|
||||||
// KT-3335 Creating imported super class' inner class fails in codegen
|
|
||||||
UnsupportedInnerClassCall("Constructor call for inner class from subclass unsupported")
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ImportingScopeBasedTowerLevel(
|
internal class ImportingScopeBasedTowerLevel(
|
||||||
@@ -254,4 +159,48 @@ internal class ImportingScopeBasedTowerLevel(
|
|||||||
}
|
}
|
||||||
return super.getFunctions(name) + synthetic
|
return super.getFunctions(name) + synthetic
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KotlinType.getClassifierFromMeAndSuperclasses(name: Name, location: LookupLocation): ClassifierDescriptor? {
|
||||||
|
var superclass: KotlinType? = this
|
||||||
|
while (superclass != null) {
|
||||||
|
superclass.memberScope.getContributedClassifier(name, location)?.let { return it }
|
||||||
|
superclass = superclass.getImmediateSuperclassNotAny()
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KotlinType?.getInnerConstructors(name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||||
|
val classifierDescriptor = getClassWithConstructors(this?.getClassifierFromMeAndSuperclasses(name, location))
|
||||||
|
return classifierDescriptor?.constructors?.filter { it.dispatchReceiverParameter != null } ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ResolutionScope.getContributedFunctionsAndConstructors(name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||||
|
val classWithConstructors = getClassWithConstructors(getContributedClassifier(name, location))
|
||||||
|
return getContributedFunctions(name, location) +
|
||||||
|
(classWithConstructors?.constructors?.filter { it.dispatchReceiverParameter == null } ?: emptyList())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ResolutionScope.getContributedVariablesAndObjects(name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||||
|
val objectDescriptor = getFakeDescriptorForObject(getContributedClassifier(name, location))
|
||||||
|
|
||||||
|
return getContributedVariables(name, location) + listOfNotNull(objectDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun getFakeDescriptorForObject(classifier: ClassifierDescriptor?): FakeCallableDescriptorForObject? {
|
||||||
|
if (classifier !is ClassDescriptor || !classifier.hasClassValueDescriptor) return null // todo
|
||||||
|
|
||||||
|
return FakeCallableDescriptorForObject(classifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getClassWithConstructors(classifier: ClassifierDescriptor?): ClassDescriptor? {
|
||||||
|
if (classifier !is ClassDescriptor || ErrorUtils.isError(classifier)
|
||||||
|
// Constructors of singletons shouldn't be callable from the code
|
||||||
|
|| classifier.kind.isSingleton) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return classifier
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -23,12 +23,6 @@ import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResolution
|
import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResolution
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
|
|
||||||
|
|
||||||
internal fun <D : CallableDescriptor> CandidateWithBoundDispatchReceiver<D>.addDiagnostic(error: ResolutionDiagnostic?): CandidateWithBoundDispatchReceiver<D> {
|
|
||||||
if (error == null) return this
|
|
||||||
return CandidateWithBoundDispatchReceiverImpl(dispatchReceiver, descriptor, diagnostics + error)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated("Temporary error")
|
@Deprecated("Temporary error")
|
||||||
internal class PreviousResolutionError(candidateLevel: ResolutionCandidateApplicability): ResolutionDiagnostic(candidateLevel)
|
internal class PreviousResolutionError(candidateLevel: ResolutionCandidateApplicability): ResolutionDiagnostic(candidateLevel)
|
||||||
|
|
||||||
|
|||||||
@@ -258,19 +258,31 @@ public class TypeUtils {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static List<KotlinType> getImmediateSupertypes(@NotNull KotlinType type) {
|
public static List<KotlinType> getImmediateSupertypes(@NotNull KotlinType type) {
|
||||||
boolean isNullable = type.isMarkedNullable();
|
|
||||||
TypeSubstitutor substitutor = TypeSubstitutor.create(type);
|
TypeSubstitutor substitutor = TypeSubstitutor.create(type);
|
||||||
Collection<KotlinType> originalSupertypes = type.getConstructor().getSupertypes();
|
Collection<KotlinType> originalSupertypes = type.getConstructor().getSupertypes();
|
||||||
List<KotlinType> result = new ArrayList<KotlinType>(originalSupertypes.size());
|
List<KotlinType> result = new ArrayList<KotlinType>(originalSupertypes.size());
|
||||||
for (KotlinType supertype : originalSupertypes) {
|
for (KotlinType supertype : originalSupertypes) {
|
||||||
KotlinType substitutedType = substitutor.substitute(supertype, Variance.INVARIANT);
|
KotlinType substitutedType = createSubstitutedSupertype(type, supertype, substitutor);
|
||||||
if (substitutedType != null) {
|
if (substitutedType != null) {
|
||||||
result.add(makeNullableIfNeeded(substitutedType, isNullable));
|
result.add(substitutedType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static KotlinType createSubstitutedSupertype(
|
||||||
|
@NotNull KotlinType subType,
|
||||||
|
@NotNull KotlinType superType,
|
||||||
|
@NotNull TypeSubstitutor substitutor
|
||||||
|
) {
|
||||||
|
KotlinType substitutedType = substitutor.substitute(superType, Variance.INVARIANT);
|
||||||
|
if (substitutedType != null) {
|
||||||
|
return makeNullableIfNeeded(substitutedType, subType.isMarkedNullable());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static void collectAllSupertypes(@NotNull KotlinType type, @NotNull Set<KotlinType> result) {
|
private static void collectAllSupertypes(@NotNull KotlinType type, @NotNull Set<KotlinType> result) {
|
||||||
List<KotlinType> immediateSupertypes = getImmediateSupertypes(type);
|
List<KotlinType> immediateSupertypes = getImmediateSupertypes(type);
|
||||||
result.addAll(immediateSupertypes);
|
result.addAll(immediateSupertypes);
|
||||||
|
|||||||
@@ -17,11 +17,9 @@
|
|||||||
package org.jetbrains.kotlin.types.typeUtil
|
package org.jetbrains.kotlin.types.typeUtil
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
import org.jetbrains.kotlin.utils.toReadOnlyList
|
import org.jetbrains.kotlin.utils.toReadOnlyList
|
||||||
@@ -162,3 +160,14 @@ private fun constituentTypes(result: MutableSet<KotlinType>, types: Collection<K
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun KotlinType.getImmediateSuperclassNotAny(): KotlinType? {
|
||||||
|
val superclasses = constructor.supertypes.filter {
|
||||||
|
val descriptor = it.constructor.declarationDescriptor
|
||||||
|
(DescriptorUtils.isClass(descriptor) || DescriptorUtils.isEnumClass(descriptor)) &&
|
||||||
|
!KotlinBuiltIns.isAnyOrNullableAny(it)
|
||||||
|
}
|
||||||
|
return superclasses.singleOrNull()?.let {
|
||||||
|
TypeUtils.createSubstitutedSupertype(this, it, TypeSubstitutor.create(this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user