Add reporting of the warnings based on Java annotations for expanded type aliases

Before that, such warnings weren't reported as the corresponding errors were reported during type inference (only original types took part there)
This commit is contained in:
Victor Petukhov
2021-02-04 11:42:52 +03:00
parent d783d99443
commit 0d40022d6d
22 changed files with 186 additions and 114 deletions
@@ -21,11 +21,9 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtPostfixExpression
import org.jetbrains.kotlin.psi.KtWhenExpression
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.UpperBoundChecker
import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker
import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
@@ -43,14 +41,17 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.typeUtil.contains
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
class JavaNullabilityChecker : AdditionalTypeChecker {
class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : AdditionalTypeChecker {
override fun checkType(
expression: KtExpression,
expressionType: KotlinType,
expressionTypeWithSmartCast: KotlinType,
c: ResolutionContext<*>
) {
if (expressionType is AbbreviatedType) {
upperBoundChecker.checkBoundsOfExpandedTypeAlias(expressionType.expandedType, expression, c.trace)
}
val dataFlowValue by lazy(LazyThreadSafetyMode.NONE) {
c.dataFlowValueFactory.createDataFlowValue(expression, expressionType, c)
}
@@ -5,10 +5,9 @@
package org.jetbrains.kotlin.resolve.jvm.checkers
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.UpperBoundChecker
@@ -18,8 +17,17 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.UPPER_BOUND_VIOLAT
import org.jetbrains.kotlin.types.*
// TODO: remove this checker after removing support LV < 1.6
class EnhancedUpperBoundChecker(languageVersionSettings: LanguageVersionSettings) : UpperBoundChecker(languageVersionSettings) {
val isTypeEnhancementImprovementsEnabled = languageVersionSettings.supportsFeature(LanguageFeature.ImprovementsAroundTypeEnhancement)
class WarningAwareUpperBoundChecker : UpperBoundChecker() {
override fun checkBoundsOfExpandedTypeAlias(type: KotlinType, expression: KtExpression, trace: BindingTrace) {
val typeParameters = type.constructor.parameters
for ((index, arg) in type.arguments.withIndex()) {
checkBounds(
null, arg.type, typeParameters[index], TypeSubstitutor.create(type), trace, expression,
withOnlyCheckForWarning = true
)
}
}
override fun checkBounds(
argumentReference: KtTypeReference?,
@@ -28,6 +36,21 @@ class EnhancedUpperBoundChecker(languageVersionSettings: LanguageVersionSettings
substitutor: TypeSubstitutor,
trace: BindingTrace,
typeAliasUsageElement: KtElement?
) {
checkBounds(
argumentReference, argumentType, typeParameterDescriptor, substitutor, trace, typeAliasUsageElement,
withOnlyCheckForWarning = false
)
}
fun checkBounds(
argumentReference: KtTypeReference?,
argumentType: KotlinType,
typeParameterDescriptor: TypeParameterDescriptor,
substitutor: TypeSubstitutor,
trace: BindingTrace,
typeAliasUsageElement: KtElement?,
withOnlyCheckForWarning: Boolean = false
) {
if (typeParameterDescriptor.upperBounds.isEmpty()) return
@@ -39,13 +62,13 @@ class EnhancedUpperBoundChecker(languageVersionSettings: LanguageVersionSettings
)
for (bound in typeParameterDescriptor.upperBounds) {
val isCheckPassed = checkBound(bound, argumentType, argumentReference, substitutor, typeAliasUsageElement, diagnosticsReporter)
if (!withOnlyCheckForWarning) {
val isBaseCheckPassed =
checkBound(bound, argumentType, argumentReference, substitutor, typeAliasUsageElement, diagnosticsReporter)
// The error is already reported, it's unnecessary to do more checks
if (!isCheckPassed) continue
// If improvements are enabled, then type parameter's upper bounds will already enhanced, and the error will reported inside the first check
if (isTypeEnhancementImprovementsEnabled) continue
// The error is already reported, it's unnecessary to do more checks
if (!isBaseCheckPassed) continue
}
val enhancedBound = bound.getEnhancementDeeply() ?: continue
@@ -6,10 +6,9 @@
package org.jetbrains.kotlin.resolve.jvm.platform
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMapper
import org.jetbrains.kotlin.container.PlatformExtensionsClashResolver
import org.jetbrains.kotlin.container.StorageComponentContainer
import org.jetbrains.kotlin.container.useImpl
import org.jetbrains.kotlin.container.useInstance
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.container.*
import org.jetbrains.kotlin.load.java.sam.JvmSamConversionOracle
import org.jetbrains.kotlin.resolve.PlatformConfiguratorBase
import org.jetbrains.kotlin.resolve.checkers.BigFunctionTypeAvailabilityChecker
@@ -61,7 +60,6 @@ object JvmPlatformConfigurator : PlatformConfiguratorBase(
),
additionalTypeCheckers = listOf(
JavaNullabilityChecker(),
RuntimeAssertionsTypeChecker,
JavaGenericVarianceViolationTypeChecker,
JavaTypeAccessibilityChecker(),
@@ -95,9 +93,13 @@ object JvmPlatformConfigurator : PlatformConfiguratorBase(
declarationReturnTypeSanitizer = JvmDeclarationReturnTypeSanitizer
) {
override fun configureModuleComponents(container: StorageComponentContainer) {
override fun configureModuleComponents(container: StorageComponentContainer, languageVersionSettings: LanguageVersionSettings) {
container.useImplIf<WarningAwareUpperBoundChecker>(
!languageVersionSettings.supportsFeature(LanguageFeature.ImprovementsAroundTypeEnhancement)
)
container.useImpl<JavaNullabilityChecker>()
container.useImpl<JvmStaticChecker>()
container.useImpl<EnhancedUpperBoundChecker>()
container.useImpl<JvmReflectionAPICallChecker>()
container.useImpl<JavaSyntheticScopes>()
container.useImpl<SamConversionResolverImpl>()
@@ -112,6 +114,7 @@ object JvmPlatformConfigurator : PlatformConfiguratorBase(
container.useImpl<JvmSamConversionOracle>()
container.useImpl<JvmAdditionalClassPartsProvider>()
container.useImpl<JvmRecordApplicabilityChecker>()
container.useInstance(FunctionWithBigAritySupport.LanguageVersionDependent)
container.useInstance(GenericArrayClassLiteralSupport.Enabled)
container.useInstance(JavaActualAnnotationArgumentExtractor())