[FE 1.0] Resolve private constructors of sealed classes same as for regular classes

^KT-44866
^KT-49729
This commit is contained in:
Dmitriy Novozhilov
2021-11-16 16:57:51 +03:00
parent e2d68fd239
commit 93378b1a04
31 changed files with 294 additions and 113 deletions
@@ -490,9 +490,9 @@ class ControlFlowInformationProviderImpl private constructor(
val receiverValue = expression.getResolvedCall(trace.bindingContext)?.getDispatchReceiverWithSmartCast()
if (DescriptorVisibilities.isVisible(receiverValue, variableDescriptor, descriptor)
if (DescriptorVisibilityUtils.isVisible(receiverValue, variableDescriptor, descriptor, languageVersionSettings)
&& setterDescriptor != null
&& !DescriptorVisibilities.isVisible(receiverValue, setterDescriptor, descriptor)
&& !DescriptorVisibilityUtils.isVisible(receiverValue, setterDescriptor, descriptor, languageVersionSettings)
) {
report(
Errors.INVISIBLE_SETTER.on(
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve
import com.intellij.util.SmartList
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
@@ -29,6 +30,7 @@ import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.addIfNotNull
class LazyExplicitImportScope(
private val languageVersionSettings: LanguageVersionSettings,
private val packageOrClassDescriptor: DeclarationDescriptor,
private val packageFragmentForVisibilityCheck: PackageFragmentDescriptor?,
private val declaredName: Name,
@@ -148,6 +150,8 @@ class LazyExplicitImportScope(
else -> null
}
private fun <D : CallableMemberDescriptor> Collection<D>.choseOnlyVisibleOrAll() =
filter { isVisible(it, packageFragmentForVisibilityCheck, position = QualifierPosition.IMPORT) }.takeIf { it.isNotEmpty() } ?: this
private fun <D : CallableMemberDescriptor> Collection<D>.choseOnlyVisibleOrAll(): Collection<D> =
filter { isVisible(it, packageFragmentForVisibilityCheck, position = QualifierPosition.IMPORT, languageVersionSettings) }
.takeIf { it.isNotEmpty() }
?: this
}
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DELEGATION
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE
import org.jetbrains.kotlin.descriptors.DescriptorVisibilityUtils.useSpecialRulesForPrivateSealedConstructors
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2
import org.jetbrains.kotlin.diagnostics.DiagnosticFactoryWithPsiElement
import org.jetbrains.kotlin.diagnostics.Errors.*
@@ -41,7 +42,6 @@ import org.jetbrains.kotlin.resolve.calls.util.isOrOverridesSynthesized
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.types.checker.NewKotlinTypeCheckerImpl
import org.jetbrains.kotlin.types.TypeRefinement
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
import java.util.*
@@ -366,7 +366,7 @@ class OverrideResolver(
override fun nothingToOverride(overriding: CallableMemberDescriptor) {
trace.report(NOTHING_TO_OVERRIDE.on(member, declared))
}
}
}, languageVersionSettings
)
} else if (!overriddenDescriptors.isEmpty() && !overridesBackwardCompatibilityHelper.overrideCanBeOmitted(declared)) {
val overridden = overriddenDescriptors.first()
@@ -854,7 +854,8 @@ class OverrideResolver(
private fun checkOverridesForMemberMarkedOverride(
declared: CallableMemberDescriptor,
kotlinTypeRefiner: KotlinTypeRefiner,
reportError: CheckOverrideReportForDeclaredMemberStrategy
reportError: CheckOverrideReportForDeclaredMemberStrategy,
languageVersionSettings: LanguageVersionSettings
) {
val overriddenDescriptors = declared.overriddenDescriptors
@@ -868,7 +869,7 @@ class OverrideResolver(
val invisibleOverriddenDescriptor =
findInvisibleOverriddenDescriptor(
declared, declaringClass, kotlinTypeRefiner
declared, declaringClass, kotlinTypeRefiner, languageVersionSettings
)
if (invisibleOverriddenDescriptor != null) {
reportError.cannotOverrideInvisibleMember(declared, invisibleOverriddenDescriptor)
@@ -953,7 +954,8 @@ class OverrideResolver(
private fun findInvisibleOverriddenDescriptor(
declared: CallableMemberDescriptor,
declaringClass: ClassDescriptor,
kotlinTypeRefiner: KotlinTypeRefiner
kotlinTypeRefiner: KotlinTypeRefiner,
languageVersionSettings: LanguageVersionSettings
): CallableMemberDescriptor? {
@OptIn(TypeRefinement::class)
for (supertype in kotlinTypeRefiner.refineSupertypes(declaringClass)) {
@@ -962,7 +964,7 @@ class OverrideResolver(
all.addAll(supertype.memberScope.getContributedVariables(declared.name, NoLookupLocation.WHEN_CHECK_OVERRIDES))
for (fromSuper in all) {
if (OverridingUtil.DEFAULT.isOverridableBy(fromSuper, declared, null).result == OVERRIDABLE) {
if (OverridingUtil.isVisibleForOverride(declared, fromSuper)) {
if (OverridingUtil.isVisibleForOverride(declared, fromSuper, languageVersionSettings.useSpecialRulesForPrivateSealedConstructors)) {
throw IllegalStateException(
"Descriptor " + fromSuper + " is overridable by " + declared +
" and visible but does not appear in its getOverriddenDescriptors()"
@@ -336,6 +336,7 @@ class QualifiedExpressionResolver(val languageVersionSettings: LanguageVersionSe
(resolvedDescriptor as? TypeAliasDescriptor)?.let { it.classDescriptor ?: return null } ?: resolvedDescriptor
return LazyExplicitImportScope(
languageVersionSettings,
packageOrClassDescriptor,
packageFragmentForVisibilityCheck,
lastPart.name,
@@ -739,7 +740,7 @@ class QualifiedExpressionResolver(val languageVersionSettings: LanguageVersionSe
) {
referenceExpression ?: return
if (descriptors.size > 1) {
val visibleDescriptors = descriptors.filter { isVisible(it, shouldBeVisibleFrom, position) }
val visibleDescriptors = descriptors.filter { isVisible(it, shouldBeVisibleFrom, position, languageVersionSettings) }
when {
visibleDescriptors.isEmpty() -> {
val descriptor = descriptors.first() as DeclarationDescriptorWithVisibility
@@ -782,7 +783,7 @@ class QualifiedExpressionResolver(val languageVersionSettings: LanguageVersionSe
} else {
shouldBeVisibleFrom
}
if (!isVisible(descriptor, fromToCheck, position)) {
if (!isVisible(descriptor, fromToCheck, position, languageVersionSettings)) {
trace.report(Errors.INVISIBLE_REFERENCE.on(referenceExpression, descriptor, descriptor.visibility, descriptor))
}
}
@@ -836,7 +837,8 @@ class QualifiedExpressionResolver(val languageVersionSettings: LanguageVersionSe
internal fun isVisible(
descriptor: DeclarationDescriptor,
shouldBeVisibleFrom: DeclarationDescriptor?,
position: QualifierPosition
position: QualifierPosition,
languageVersionSettings: LanguageVersionSettings
): Boolean {
if (descriptor !is DeclarationDescriptorWithVisibility || shouldBeVisibleFrom == null) return true
@@ -845,7 +847,7 @@ internal fun isVisible(
if (DescriptorVisibilities.isPrivate(visibility)) return DescriptorVisibilities.inSameFile(descriptor, shouldBeVisibleFrom)
if (!visibility.mustCheckInImports()) return true
}
return DescriptorVisibilities.isVisibleIgnoringReceiver(descriptor, shouldBeVisibleFrom)
return DescriptorVisibilityUtils.isVisibleIgnoringReceiver(descriptor, shouldBeVisibleFrom, languageVersionSettings)
}
internal enum class QualifierPosition {
@@ -12,17 +12,12 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.diagnostics.Errors.EXPANDED_TYPE_CANNOT_BE_CONSTRUCTED
import org.jetbrains.kotlin.diagnostics.Errors.SUPER_CANT_BE_EXTENSION_RECEIVER
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.calls.CallTransformer.CallForImplicitInvoke
import org.jetbrains.kotlin.resolve.calls.util.ResolveArgumentsMode
import org.jetbrains.kotlin.resolve.calls.util.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS
import org.jetbrains.kotlin.resolve.calls.util.getEffectiveExpectedType
import org.jetbrains.kotlin.resolve.calls.util.getErasedReceiverType
import org.jetbrains.kotlin.resolve.calls.util.isInvokeCallOnExpressionWithBothReceivers
import org.jetbrains.kotlin.resolve.calls.util.isSafeCall
import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker
import org.jetbrains.kotlin.resolve.calls.context.*
import org.jetbrains.kotlin.resolve.calls.inference.SubstitutionFilteringInternalResolveAnnotations
@@ -33,7 +28,8 @@ import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.*
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.calls.util.*
import org.jetbrains.kotlin.resolve.calls.util.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
@@ -44,7 +40,6 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
import org.jetbrains.kotlin.types.typeUtil.containsTypeProjectionsInTopLevelArguments
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import java.util.*
import kotlin.math.min
class CandidateResolver(
@@ -185,8 +180,11 @@ class CandidateResolver(
receiverArgument: ReceiverValue?,
smartCastType: KotlinType?
): ResolutionStatus {
val invisibleMember = DescriptorVisibilities.findInvisibleMember(
getReceiverValueWithSmartCast(receiverArgument, smartCastType), candidateDescriptor, scope.ownerDescriptor
val invisibleMember = DescriptorVisibilityUtils.findInvisibleMember(
getReceiverValueWithSmartCast(receiverArgument, smartCastType),
candidateDescriptor,
scope.ownerDescriptor,
languageVersionSettings
)
return if (invisibleMember != null) {
tracing.invisibleMember(trace, invisibleMember)
@@ -205,9 +203,10 @@ class CandidateResolver(
private fun CallCandidateResolutionContext<*>.isCandidateVisible(
receiverArgument: ReceiverValue?,
smartCastType: KotlinType?
) = DescriptorVisibilities.findInvisibleMember(
) = DescriptorVisibilityUtils.findInvisibleMember(
getReceiverValueWithSmartCast(receiverArgument, smartCastType),
candidateDescriptor, scope.ownerDescriptor
candidateDescriptor, scope.ownerDescriptor,
languageVersionSettings
) == null
private fun CallCandidateResolutionContext<*>.checkExtensionReceiver() = checkAndReport {
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibilityUtils
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtConstructorCalleeExpression
@@ -37,7 +38,7 @@ object ProtectedConstructorCallChecker : CallChecker {
if (actualConstructor.visibility.normalize() != DescriptorVisibilities.PROTECTED) return
// Error already reported
if (!DescriptorVisibilities.isVisibleWithAnyReceiver(descriptor, scopeOwner)) return
if (!DescriptorVisibilityUtils.isVisibleWithAnyReceiver(descriptor, scopeOwner, context.languageVersionSettings)) return
val calleeExpression = resolvedCall.call.calleeExpression
@@ -55,7 +56,13 @@ object ProtectedConstructorCallChecker : CallChecker {
// And without ProtectedConstructorCallChecker such calls would be allowed only because they are performed within subclass
// of constructor owner
@Suppress("DEPRECATION")
if (DescriptorVisibilities.findInvisibleMember(DescriptorVisibilities.FALSE_IF_PROTECTED, descriptor, scopeOwner) == actualConstructor.original) {
if (DescriptorVisibilityUtils.findInvisibleMember(
DescriptorVisibilities.FALSE_IF_PROTECTED,
descriptor,
scopeOwner,
context.languageVersionSettings
) == actualConstructor.original
) {
context.trace.report(Errors.PROTECTED_CONSTRUCTOR_NOT_IN_SUPER_CALL.on(reportOn, descriptor))
}
}
@@ -32,10 +32,6 @@ import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
import org.jetbrains.kotlin.resolve.calls.CallResolver
import org.jetbrains.kotlin.resolve.calls.CallTransformer
import org.jetbrains.kotlin.resolve.calls.CandidateResolver
import org.jetbrains.kotlin.resolve.calls.util.isBinaryRemOperator
import org.jetbrains.kotlin.resolve.calls.util.isConventionCall
import org.jetbrains.kotlin.resolve.calls.util.isInfixCall
import org.jetbrains.kotlin.resolve.calls.util.createLookupLocation
import org.jetbrains.kotlin.resolve.calls.context.*
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSupport
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
@@ -48,7 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.calls.tasks.*
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.calls.util.*
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDynamicExtensionAnnotation
import org.jetbrains.kotlin.resolve.scopes.*
@@ -381,6 +377,8 @@ class NewResolutionOldInference(
override val isNewInferenceEnabled: Boolean
get() = resolutionContext.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
override val languageVersionSettings: LanguageVersionSettings
get() = resolutionContext.languageVersionSettings
override fun interceptFunctionCandidates(
resolutionScope: ResolutionScope,
@@ -50,7 +50,6 @@ import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
import org.jetbrains.kotlin.utils.addToStdlib.compactIfPossible
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.util.*
class PSICallResolver(
private val typeResolver: TypeResolver,
@@ -395,6 +394,7 @@ class PSICallResolver(
override val syntheticScopes: SyntheticScopes get() = this@PSICallResolver.syntheticScopes
override val isDebuggerContext: Boolean get() = context.isDebuggerContext
override val isNewInferenceEnabled: Boolean get() = context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
override val languageVersionSettings: LanguageVersionSettings get() = context.languageVersionSettings
override val lexicalScope: LexicalScope get() = context.scope
override val typeApproximator: TypeApproximator get() = this@PSICallResolver.typeApproximator
override val implicitsResolutionFilter: ImplicitsExtensionsResolutionFilter get() = this@PSICallResolver.implicitsResolutionFilter
@@ -269,7 +269,11 @@ class FileScopeFactory(
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
if (name in excludedNames) return null
val classifier = scope.getContributedClassifier(name, location) ?: return null
val visible = DescriptorVisibilities.isVisibleIgnoringReceiver(classifier as DeclarationDescriptorWithVisibility, fromDescriptor)
val visible = DescriptorVisibilityUtils.isVisibleIgnoringReceiver(
classifier as DeclarationDescriptorWithVisibility,
fromDescriptor,
components.languageVersionSettings
)
return classifier.takeIf { filteringKind == if (visible) FilteringKind.VISIBLE_CLASSES else FilteringKind.INVISIBLE_CLASSES }
}
@@ -23,6 +23,7 @@ import gnu.trove.THashSet
import org.jetbrains.kotlin.builtins.PlatformToKotlinClassMapper
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.DescriptorVisibilityUtils.isVisibleIgnoringReceiver
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
import org.jetbrains.kotlin.incremental.components.LookupLocation
@@ -240,7 +241,7 @@ class LazyImportScope(
val visibility = (descriptor as DeclarationDescriptorWithVisibility).visibility
val includeVisible = filteringKind == FilteringKind.VISIBLE_CLASSES
if (!visibility.mustCheckInImports()) return includeVisible
return DescriptorVisibilities.isVisibleIgnoringReceiver(descriptor, components.moduleDescriptor) == includeVisible
return isVisibleIgnoringReceiver(descriptor, components.moduleDescriptor, components.languageVersionSettings) == includeVisible
}
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
@@ -25,9 +25,6 @@ import org.jetbrains.kotlin.psi.psiUtil.checkReservedYield
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.calls.CallResolver
import org.jetbrains.kotlin.resolve.calls.util.ResolveArgumentsMode
import org.jetbrains.kotlin.resolve.calls.util.getCalleeExpressionIfAny
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.checkers.isBuiltInCoroutineContext
import org.jetbrains.kotlin.resolve.calls.context.*
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSession
@@ -35,9 +32,7 @@ import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsUtil
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.calls.util.createValueParametersForInvokeInFunctionType
import org.jetbrains.kotlin.resolve.calls.util.*
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
@@ -50,7 +45,6 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.types.expressions.FunctionWithBigAritySupport.LanguageVersionDependent
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.noTypeInfo
import org.jetbrains.kotlin.types.TypeRefinement
import org.jetbrains.kotlin.types.typeUtil.*
import org.jetbrains.kotlin.utils.yieldIfNotNull
import java.util.*
@@ -846,7 +840,7 @@ class DoubleColonExpressionResolver(
): Boolean {
val receiver = receiverTypeFor(descriptor, lhs)?.let(::TransientReceiver)
val setter = descriptor.setter
return descriptor.isVar && (setter == null || DescriptorVisibilities.isVisible(receiver, setter, scopeOwnerDescriptor))
return descriptor.isVar && (setter == null || DescriptorVisibilities.isVisible(receiver, setter, scopeOwnerDescriptor, false))
}
fun createKCallableTypeForReference(