diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt index e1b9c088afb..9c7c1345d05 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt @@ -62,9 +62,8 @@ internal class ExplicitReceiverScopeTowerProcessor( } private fun resolveAsMember(): Collection { - val members = ReceiverScopeTowerLevel(context.scopeTower, explicitReceiver).collectCandidates(name).filter { candidate -> - candidate.dispatchReceiver != null && !candidate.requiresExtensionReceiver - } + val members = ReceiverScopeTowerLevel(context.scopeTower, explicitReceiver) + .collectCandidates(name).filter { !it.requiresExtensionReceiver } return members.map { context.createCandidate(it, ExplicitReceiverKind.DISPATCH_RECEIVER, extensionReceiver = null) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt index 62ee1fadadb..23e9908fdf1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.isDynamic +import org.jetbrains.kotlin.types.typeUtil.getImmediateSuperclassNotAny import org.jetbrains.kotlin.utils.addIfNotNull 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 Future plan: move constructors and fake variables for objects to class member scope. -internal abstract class ConstructorsAndFakeVariableHackLevelScope(scopeTower: ScopeTower) : AbstractScopeTowerLevel(scopeTower) { - - protected fun createConstructors( - classifier: ClassifierDescriptor?, - dispatchReceiver: ReceiverValue?, - dispatchReceiverSmartCastType: KotlinType? = null, - checkClass: (ClassDescriptor) -> ResolutionDiagnostic? = { null } - ): Collection> { - 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? { - 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) - } -} - +// todo add static methods & fields with error internal class ReceiverScopeTowerLevel( scopeTower: ScopeTower, val dispatchReceiver: ReceiverValue -): ConstructorsAndFakeVariableHackLevelScope(scopeTower) { - private val memberScope = dispatchReceiver.type.memberScope +): AbstractScopeTowerLevel(scopeTower) { private fun collectMembers( - members: ResolutionScope.() -> Collection, - additionalDescriptors: ResolutionScope.(smartCastType: KotlinType?) -> Collection> // todo + getMembers: ResolutionScope.(KotlinType?) -> Collection ): Collection> { val result = ArrayList>(0) - memberScope.members().mapTo(result) { + dispatchReceiver.type.memberScope.getMembers(dispatchReceiver.type).mapTo(result) { createCandidateDescriptor(it, dispatchReceiver) } - result.addAll(memberScope.additionalDescriptors(null)) val smartCastPossibleTypes = scopeTower.dataFlowInfo.getSmartCastTypes(dispatchReceiver) val unstableError = if (scopeTower.dataFlowInfo.isStableReceiver(dispatchReceiver)) null else UnstableSmartCastDiagnostic for (possibleType in smartCastPossibleTypes) { - possibleType.memberScope.members().mapTo(result) { + possibleType.memberScope.getMembers(possibleType).mapTo(result) { createCandidateDescriptor(it, dispatchReceiver, unstableError, dispatchReceiverSmartCastType = possibleType) } - - possibleType.memberScope.additionalDescriptors(possibleType).mapTo(result) { - it.addDiagnostic(unstableError) - } } if (dispatchReceiver.type.isDynamic()) { - scopeTower.dynamicScope.members().mapTo(result) { + scopeTower.dynamicScope.getMembers(null).mapTo(result) { createCandidateDescriptor(it, dispatchReceiver, DynamicDescriptorDiagnostic) } } @@ -160,79 +98,46 @@ internal class ReceiverScopeTowerLevel( return result } - // todo add static methods & fields with error override fun getVariables(name: Name): Collection> { - return collectMembers({ getContributedVariables(name, location) }) { - smartCastType -> - listOfNotNull(createVariableDescriptor(getContributedClassifier(name, location), smartCastType){ NestedClassViaInstanceReference(it) } ) - } + return collectMembers { getContributedVariables(name, location) } } override fun getFunctions(name: Name): Collection> { - return collectMembers({ getContributedFunctions(name, location) }) { - smartCastType -> - createConstructors(getContributedClassifier(name, location), dispatchReceiver, smartCastType) { - if (it.isInner) null else NestedClassViaInstanceReference(it) + return collectMembers { + getContributedFunctions(name, location) + it.getInnerConstructors(name, location) + } + } +} + +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> { - val result = ArrayList>(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> { - 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( scopeTower: ScopeTower, private val resolutionScope: ResolutionScope -) : ConstructorsAndFakeVariableHackLevelScope(scopeTower) { +) : AbstractScopeTowerLevel(scopeTower) { internal constructor(scopeTower: ScopeTower, lexicalScope: LexicalScope): this(scopeTower, lexicalScope as ResolutionScope) - override fun getVariables(name: Name): Collection> { - val result = ArrayList>(0) - resolutionScope.getContributedVariables(name, location).mapTo(result) { - createCandidateDescriptor(it, dispatchReceiver = null) - } - result.addIfNotNull(createVariableDescriptor(resolutionScope.getContributedClassifier(name, location))) - return result - } + override fun getVariables(name: Name): Collection> + = resolutionScope.getContributedVariablesAndObjects(name, location).map { + createCandidateDescriptor(it, dispatchReceiver = null) + } - override fun getFunctions(name: Name): Collection> { - val result = ArrayList>(0) - resolutionScope.getContributedFunctions(name, location).mapTo(result) { - 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 - } + override fun getFunctions(name: Name): Collection> + = resolutionScope.getContributedFunctionsAndConstructors(name, location).map { + createCandidateDescriptor(it, dispatchReceiver = null) + } } internal class ImportingScopeBasedTowerLevel( @@ -254,4 +159,48 @@ internal class ImportingScopeBasedTowerLevel( } 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 { + val classifierDescriptor = getClassWithConstructors(this?.getClassifierFromMeAndSuperclasses(name, location)) + return classifierDescriptor?.constructors?.filter { it.dispatchReceiverParameter != null } ?: emptyList() +} + +private fun ResolutionScope.getContributedFunctionsAndConstructors(name: Name, location: LookupLocation): Collection { + 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 { + 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 + } } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/TowerUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/TowerUtils.kt index 94d41c59a06..b3755d4d171 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/TowerUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/TowerUtils.kt @@ -23,12 +23,6 @@ import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResolution import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue - -internal fun CandidateWithBoundDispatchReceiver.addDiagnostic(error: ResolutionDiagnostic?): CandidateWithBoundDispatchReceiver { - if (error == null) return this - return CandidateWithBoundDispatchReceiverImpl(dispatchReceiver, descriptor, diagnostics + error) -} - @Deprecated("Temporary error") internal class PreviousResolutionError(candidateLevel: ResolutionCandidateApplicability): ResolutionDiagnostic(candidateLevel) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java index 147c2954614..43525094c9a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java @@ -258,19 +258,31 @@ public class TypeUtils { @NotNull public static List getImmediateSupertypes(@NotNull KotlinType type) { - boolean isNullable = type.isMarkedNullable(); TypeSubstitutor substitutor = TypeSubstitutor.create(type); Collection originalSupertypes = type.getConstructor().getSupertypes(); List result = new ArrayList(originalSupertypes.size()); for (KotlinType supertype : originalSupertypes) { - KotlinType substitutedType = substitutor.substitute(supertype, Variance.INVARIANT); + KotlinType substitutedType = createSubstitutedSupertype(type, supertype, substitutor); if (substitutedType != null) { - result.add(makeNullableIfNeeded(substitutedType, isNullable)); + result.add(substitutedType); } } 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 result) { List immediateSupertypes = getImmediateSupertypes(type); result.addAll(immediateSupertypes); diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt index a46ff9138a9..ba37ec5a1e7 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt @@ -17,11 +17,9 @@ package org.jetbrains.kotlin.types.typeUtil import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.utils.toReadOnlyList @@ -162,3 +160,14 @@ private fun constituentTypes(result: MutableSet, types: Collection