From 371b1eb3d5408aaf988a501b77e985f8dab720dc Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Fri, 5 Jan 2024 15:14:29 +0100 Subject: [PATCH] [FIR] Don't lose error level enhancements in warning-level-enhanced arguments The error-level enhancement is kept as warning-level and a new LanguageFeature is introduced to turn the warning into an error. #KT-63208 Fixed #KT-63209 --- .../diagnostics/KtFirDataClassConverters.kt | 2 + .../api/fir/diagnostics/KtFirDiagnostics.kt | 2 + .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 2 + ...nAnnotationsCompiledJavaTestGenerated.java | 12 ++++ ...dJavaWithPsiClassReadingTestGenerated.java | 12 ++++ ...ignAnnotationsSourceJavaTestGenerated.java | 12 ++++ .../diagnostics/FirJvmDiagnosticsList.kt | 2 + .../analysis/diagnostics/jvm/FirJvmErrors.kt | 5 +- .../jvm/FirJvmErrorsDefaultMessages.kt | 11 +-- ...xpressionJavaNullabilityWarningCheckers.kt | 16 +++-- .../EnhancedTypeForWarningAttribute.kt | 8 ++- .../fir/java/enhancement/javaTypeUtils.kt | 56 +++++++++------ .../java8Tests/warningModeForHeadType.fir.kt | 39 ++++++++++ .../java8Tests/warningModeForHeadType.kt | 3 +- .../tests/errorArgumentOfWarningAfter.fir.kt | 71 +++++++++++++++++++ .../tests/errorArgumentOfWarningAfter.kt | 71 +++++++++++++++++++ .../tests/errorArgumentOfWarningBefore.fir.kt | 71 +++++++++++++++++++ .../tests/errorArgumentOfWarningBefore.kt | 71 +++++++++++++++++++ ...nAnnotationsCompiledJavaTestGenerated.java | 12 ++++ ...dJavaWithPsiClassReadingTestGenerated.java | 12 ++++ ...ignAnnotationsSourceJavaTestGenerated.java | 12 ++++ .../kotlin/config/LanguageVersionSettings.kt | 1 + 22 files changed, 470 insertions(+), 33 deletions(-) create mode 100644 compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/warningModeForHeadType.fir.kt create mode 100644 compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.fir.kt create mode 100644 compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.kt create mode 100644 compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.fir.kt create mode 100644 compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.kt diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index 3a973296ccd..040b4e3b29d 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -5091,6 +5091,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert ReceiverNullabilityMismatchBasedOnJavaAnnotationsImpl( firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a), firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b), + firDiagnostic.c, firDiagnostic as KtPsiDiagnostic, token, ) @@ -5099,6 +5100,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert NullabilityMismatchBasedOnJavaAnnotationsImpl( firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a), firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b), + firDiagnostic.c, firDiagnostic as KtPsiDiagnostic, token, ) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 0be47a7c7e2..bd146e88235 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -3544,12 +3544,14 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = ReceiverNullabilityMismatchBasedOnJavaAnnotations::class val actualType: KtType val expectedType: KtType + val messageSuffix: String } interface NullabilityMismatchBasedOnJavaAnnotations : KtFirDiagnostic { override val diagnosticClass get() = NullabilityMismatchBasedOnJavaAnnotations::class val actualType: KtType val expectedType: KtType + val messageSuffix: String } interface UpperBoundCannotBeArray : KtFirDiagnostic { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 1da6b1d3381..b749ed0e5ad 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -4274,6 +4274,7 @@ internal class JavaTypeMismatchImpl( internal class ReceiverNullabilityMismatchBasedOnJavaAnnotationsImpl( override val actualType: KtType, override val expectedType: KtType, + override val messageSuffix: String, firDiagnostic: KtPsiDiagnostic, token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.ReceiverNullabilityMismatchBasedOnJavaAnnotations @@ -4281,6 +4282,7 @@ internal class ReceiverNullabilityMismatchBasedOnJavaAnnotationsImpl( internal class NullabilityMismatchBasedOnJavaAnnotationsImpl( override val actualType: KtType, override val expectedType: KtType, + override val messageSuffix: String, firDiagnostic: KtPsiDiagnostic, token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.NullabilityMismatchBasedOnJavaAnnotations diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendForeignAnnotationsCompiledJavaTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendForeignAnnotationsCompiledJavaTestGenerated.java index 8780ca5d656..a3ba848561b 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendForeignAnnotationsCompiledJavaTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendForeignAnnotationsCompiledJavaTestGenerated.java @@ -68,6 +68,18 @@ public class FirPsiOldFrontendForeignAnnotationsCompiledJavaTestGenerated extend runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/eclipse.kt"); } + @Test + @TestMetadata("errorArgumentOfWarningAfter.kt") + public void testErrorArgumentOfWarningAfter() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.kt"); + } + + @Test + @TestMetadata("errorArgumentOfWarningBefore.kt") + public void testErrorArgumentOfWarningBefore() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.kt"); + } + @Test @TestMetadata("findBugsSimple.kt") public void testFindBugsSimple() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java index 63b97385038..371930d46b0 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java @@ -68,6 +68,18 @@ public class FirPsiOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingT runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/eclipse.kt"); } + @Test + @TestMetadata("errorArgumentOfWarningAfter.kt") + public void testErrorArgumentOfWarningAfter() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.kt"); + } + + @Test + @TestMetadata("errorArgumentOfWarningBefore.kt") + public void testErrorArgumentOfWarningBefore() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.kt"); + } + @Test @TestMetadata("findBugsSimple.kt") public void testFindBugsSimple() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendForeignAnnotationsSourceJavaTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendForeignAnnotationsSourceJavaTestGenerated.java index 07bf62bd751..3fd3594d1a8 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendForeignAnnotationsSourceJavaTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendForeignAnnotationsSourceJavaTestGenerated.java @@ -68,6 +68,18 @@ public class FirPsiOldFrontendForeignAnnotationsSourceJavaTestGenerated extends runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/eclipse.kt"); } + @Test + @TestMetadata("errorArgumentOfWarningAfter.kt") + public void testErrorArgumentOfWarningAfter() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.kt"); + } + + @Test + @TestMetadata("errorArgumentOfWarningBefore.kt") + public void testErrorArgumentOfWarningBefore() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.kt"); + } + @Test @TestMetadata("findBugsSimple.kt") public void testFindBugsSimple() throws Exception { diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt index 08798ec1a7c..85b010e131b 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt @@ -56,10 +56,12 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") { val RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS by warning { parameter("actualType") parameter("expectedType") + parameter("messageSuffix") } val NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS by warning { parameter("actualType") parameter("expectedType") + parameter("messageSuffix") } } diff --git a/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt b/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt index f1cfb2450a2..1fd9745d398 100644 --- a/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt +++ b/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.diagnostics.* import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory0 import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory1 import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory2 +import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory3 import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryForDeprecation0 import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryForDeprecation2 import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryForDeprecation4 @@ -52,8 +53,8 @@ object FirJvmErrors { // Types val JAVA_TYPE_MISMATCH: KtDiagnosticFactory2 by error2() - val RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS: KtDiagnosticFactory2 by warning2() - val NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS: KtDiagnosticFactory2 by warning2() + val RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS: KtDiagnosticFactory3 by warning3() + val NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS: KtDiagnosticFactory3 by warning3() // Type parameters val UPPER_BOUND_CANNOT_BE_ARRAY: KtDiagnosticFactory0 by error0() diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt index 44476358229..0bcad30ea3c 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.NAME import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.STRING import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.OPTIONAL_SENTENCE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.CONCURRENT_HASH_MAP_CONTAINS_OPERATOR @@ -94,15 +95,17 @@ object FirJvmErrorsDefaultMessages : BaseDiagnosticRendererFactory() { map.put( NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS, - "Java type mismatch: inferred type is ''{1}'', but ''{0}'' was expected.", + "Java type mismatch: inferred type is ''{1}'', but ''{0}'' was expected.{2}", RENDER_TYPE, - RENDER_TYPE + RENDER_TYPE, + OPTIONAL_SENTENCE, ) map.put( RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS, - "Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type ''{0}''.", + "Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type ''{0}''.{2}", RENDER_TYPE, - NOT_RENDERED + NOT_RENDERED, + OPTIONAL_SENTENCE, ) map.put( diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirExpressionJavaNullabilityWarningCheckers.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirExpressionJavaNullabilityWarningCheckers.kt index 9b8bdc9869f..5380032a382 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirExpressionJavaNullabilityWarningCheckers.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirExpressionJavaNullabilityWarningCheckers.kt @@ -5,8 +5,9 @@ package org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory2 +import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory3 import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext @@ -15,11 +16,11 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition import org.jetbrains.kotlin.fir.java.enhancement.EnhancedForWarningConeSubstitutor +import org.jetbrains.kotlin.fir.java.enhancement.isEnhancedTypeForWarningDeprecation import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.types.* -import java.util.* // TODO reimplement using AdditionalTypeChecker KT-62864 object FirQualifiedAccessJavaNullabilityWarningChecker : FirQualifiedAccessExpressionChecker() { @@ -142,7 +143,7 @@ internal fun FirExpression.checkExpressionForEnhancedTypeMismatch( expectedType: ConeKotlinType?, reporter: DiagnosticReporter, context: CheckerContext, - factory: KtDiagnosticFactory2, + factory: KtDiagnosticFactory3, ) { if (expectedType == null) return val actualType = resolvedType @@ -154,7 +155,14 @@ internal fun FirExpression.checkExpressionForEnhancedTypeMismatch( // Don't report anything if the original types didn't match. actualType.isSubtypeOf(context.session.typeContext, expectedType) ) { - reporter.reportOn(source, factory, actualTypeForComparison, expectedTypeForComparison, context) + val suffix = + if (actualType.isEnhancedTypeForWarningDeprecation || expectedType.isEnhancedTypeForWarningDeprecation) { + val versionString = LanguageFeature.SupportJavaErrorEnhancementOfArgumentsOfWarningLevelEnhanced.sinceVersion?.versionString + "This will become an error in Kotlin $versionString. See https://youtrack.jetbrains.com/issue/KT-63209" + } else { + "" + } + reporter.reportOn(source, factory, actualTypeForComparison, expectedTypeForComparison, suffix, context) } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/EnhancedTypeForWarningAttribute.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/EnhancedTypeForWarningAttribute.kt index ad0c8814c51..baff229ffdc 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/EnhancedTypeForWarningAttribute.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/EnhancedTypeForWarningAttribute.kt @@ -12,13 +12,14 @@ import kotlin.reflect.KClass class EnhancedTypeForWarningAttribute( override val coneType: ConeKotlinType, + val isDeprecation: Boolean, ) : ConeAttributeWithConeType() { override fun union(other: EnhancedTypeForWarningAttribute?): EnhancedTypeForWarningAttribute? = null override fun intersect(other: EnhancedTypeForWarningAttribute?): EnhancedTypeForWarningAttribute? = null override fun add(other: EnhancedTypeForWarningAttribute?): EnhancedTypeForWarningAttribute = other ?: this override fun isSubtypeOf(other: EnhancedTypeForWarningAttribute?): Boolean = true override fun toString(): String = "Enhanced for warning(${coneType.renderForDebugging()})" - override fun copyWith(newType: ConeKotlinType): EnhancedTypeForWarningAttribute = EnhancedTypeForWarningAttribute(newType) + override fun copyWith(newType: ConeKotlinType): EnhancedTypeForWarningAttribute = EnhancedTypeForWarningAttribute(newType, isDeprecation) override val key: KClass get() = EnhancedTypeForWarningAttribute::class @@ -36,12 +37,14 @@ class EnhancedTypeForWarningAttribute( other as EnhancedTypeForWarningAttribute if (coneType != other.coneType) return false + if (isDeprecation != other.isDeprecation) return false return true } override fun hashCode(): Int { var result = coneType.hashCode() + result = 31 * result + isDeprecation.hashCode() return result } } @@ -51,6 +54,9 @@ val ConeAttributes.enhancedTypeForWarning: EnhancedTypeForWarningAttribute? by C val ConeKotlinType.enhancedTypeForWarning: ConeKotlinType? get() = attributes.enhancedTypeForWarning?.coneType +val ConeKotlinType.isEnhancedTypeForWarningDeprecation: Boolean + get() = attributes.enhancedTypeForWarning?.isDeprecation == true + /** * Substitutor that substitutes types with their [ConeKotlinType.enhancedTypeForWarning] recursively. */ diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt index 6cdc3cc24c0..7d030a91752 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt @@ -6,7 +6,9 @@ package org.jetbrains.kotlin.fir.java.enhancement import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag import org.jetbrains.kotlin.fir.types.* @@ -15,7 +17,7 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.utils.addToStdlib.applyIf internal fun ConeKotlinType.enhance(session: FirSession, qualifiers: IndexedJavaTypeQualifiers): ConeKotlinType? = - enhanceConeKotlinType(session, qualifiers, 0, mutableListOf().apply { computeSubtreeSizes(this) }) + enhanceConeKotlinType(session, qualifiers, 0, mutableListOf().apply { computeSubtreeSizes(this) }, convertErrorsToWarnings = false) // The index in the lambda is the position of the type component in a depth-first walk of the tree. // Example: A, E> - 0<1<2, 3>, 4<5>>. For flexible types, some arguments in the lower bound @@ -37,7 +39,8 @@ private fun ConeKotlinType.enhanceConeKotlinType( session: FirSession, qualifiers: IndexedJavaTypeQualifiers, index: Int, - subtreeSizes: List + subtreeSizes: List, + convertErrorsToWarnings: Boolean, ): ConeKotlinType? { return when (this) { is ConeFlexibleType -> { @@ -46,10 +49,12 @@ private fun ConeKotlinType.enhanceConeKotlinType( // It's not totally correct, but tolerable since we would like to avoid excessive breaking changes and the warnings should be // anyway reported. val lowerResult = lowerBound.enhanceInflexibleType( - session, TypeComponentPosition.FLEXIBLE_LOWER, qualifiers, index, subtreeSizes + session, TypeComponentPosition.FLEXIBLE_LOWER, qualifiers, index, subtreeSizes, + isFromDefinitelyNotNullType = false, convertErrorToWarning = convertErrorsToWarnings, ) val upperResult = upperBound.enhanceInflexibleType( - session, TypeComponentPosition.FLEXIBLE_UPPER, qualifiers, index, subtreeSizes + session, TypeComponentPosition.FLEXIBLE_UPPER, qualifiers, index, subtreeSizes, + isFromDefinitelyNotNullType = false, convertErrorToWarning = convertErrorsToWarnings, ) when { @@ -59,7 +64,8 @@ private fun ConeKotlinType.enhanceConeKotlinType( } } is ConeSimpleKotlinType -> enhanceInflexibleType( - session, TypeComponentPosition.INFLEXIBLE, qualifiers, index, subtreeSizes + session, TypeComponentPosition.INFLEXIBLE, qualifiers, index, subtreeSizes, + isFromDefinitelyNotNullType = false, convertErrorToWarning = convertErrorsToWarnings, ) else -> null } @@ -79,10 +85,11 @@ private fun ConeSimpleKotlinType.enhanceInflexibleType( qualifiers: IndexedJavaTypeQualifiers, index: Int, subtreeSizes: List, - isFromDefinitelyNotNullType: Boolean = false, + isFromDefinitelyNotNullType: Boolean, + convertErrorToWarning: Boolean, ): ConeSimpleKotlinType? { if (this is ConeDefinitelyNotNullType) { - return original.enhanceInflexibleType(session, position, qualifiers, index, subtreeSizes, isFromDefinitelyNotNullType = true) + return original.enhanceInflexibleType(session, position, qualifiers, index, subtreeSizes, isFromDefinitelyNotNullType = true, convertErrorToWarning) } val shouldEnhance = position.shouldEnhance() @@ -103,19 +110,20 @@ private fun ConeSimpleKotlinType.enhanceInflexibleType( isFromDefinitelyNotNullType, effectiveQualifiers.definitelyNotNull, nullabilityFromQualifiers, - enhancedTag + enhancedTag, + convertNestedErrorsToWarnings = convertErrorToWarning || + effectiveQualifiers.isNullabilityQualifierForWarning && + !session.languageVersionSettings.supportsFeature(LanguageFeature.SupportJavaErrorEnhancementOfArgumentsOfWarningLevelEnhanced), ) - return if (effectiveQualifiers.isNullabilityQualifierForWarning && enhanced != null) { - val newAttributes = attributes.plus(EnhancedTypeForWarningAttribute(enhanced)) + return if (enhanced != null && (effectiveQualifiers.isNullabilityQualifierForWarning || convertErrorToWarning)) { + val newAttributes = attributes.plus(EnhancedTypeForWarningAttribute(enhanced, isDeprecation = convertErrorToWarning && effectiveQualifiers.enhancesSomethingForError())) - // TODO if the arguments of `enhanced` are error-level annotated, we're losing them here for compatibility with K1, - // a fix requires a deprecation cycle, see KT-63208 if (enhancedTag != lookupTag) { // Handle case when mutability was enhanced and nullability was enhanced for warning. - enhancedTag.constructType(typeArguments, isNullable, newAttributes) + enhancedTag.constructType(enhanced.typeArguments, isNullable, newAttributes) } else { - this.withAttributes(newAttributes) + this.withAttributes(newAttributes).withArguments(enhanced.typeArguments) }.applyIf(isFromDefinitelyNotNullType) { // If the original type was DNN, we need to wrap the result in a DNN type because `this` is the non-DNN part of the original. // In the non-warning case, this happens in the nested call and so `enhanced` is already DNN. @@ -126,6 +134,10 @@ private fun ConeSimpleKotlinType.enhanceInflexibleType( } } +private fun JavaTypeQualifiers.enhancesSomethingForError(): Boolean { + return !isNullabilityQualifierForWarning && (nullability != null || mutability != null || definitelyNotNull) +} + private fun ConeLookupTagBasedType.enhanceInflexibleType( session: FirSession, qualifiers: IndexedJavaTypeQualifiers, @@ -135,6 +147,7 @@ private fun ConeLookupTagBasedType.enhanceInflexibleType( isDefinitelyNotNull: Boolean, nullabilityFromQualifiers: NullabilityQualifier?, enhancedTag: ConeClassifierLookupTag, + convertNestedErrorsToWarnings: Boolean, ): ConeSimpleKotlinType? { val enhancedIsNullable = when (nullabilityFromQualifiers) { NullabilityQualifier.NULLABLE -> true @@ -145,14 +158,15 @@ private fun ConeLookupTagBasedType.enhanceInflexibleType( var globalArgIndex = index + 1 val enhancedArguments = typeArguments.map { arg -> val argIndex = globalArgIndex.also { globalArgIndex += subtreeSizes[it] } - arg.type?.enhanceConeKotlinType(session, qualifiers, argIndex, subtreeSizes)?.let { - when (arg.kind) { - ProjectionKind.IN -> ConeKotlinTypeProjectionIn(it) - ProjectionKind.OUT -> ConeKotlinTypeProjectionOut(it) - ProjectionKind.STAR -> ConeStarProjection - ProjectionKind.INVARIANT -> it + arg.type?.enhanceConeKotlinType(session, qualifiers, argIndex, subtreeSizes, convertErrorsToWarnings = convertNestedErrorsToWarnings) + ?.let { + when (arg.kind) { + ProjectionKind.IN -> ConeKotlinTypeProjectionIn(it) + ProjectionKind.OUT -> ConeKotlinTypeProjectionOut(it) + ProjectionKind.STAR -> ConeStarProjection + ProjectionKind.INVARIANT -> it + } } - } } val shouldAddAttribute = nullabilityFromQualifiers == NullabilityQualifier.NOT_NULL && !hasEnhancedNullability diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/warningModeForHeadType.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/warningModeForHeadType.fir.kt new file mode 100644 index 00000000000..87a0295cfa8 --- /dev/null +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/warningModeForHeadType.fir.kt @@ -0,0 +1,39 @@ +// FULL_JDK +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER +// LANGUAGE: -SupportJavaErrorEnhancementOfArgumentsOfWarningLevelEnhanced + +// FILE: ElementTypesAreNonnullByDefault.java +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.annotation.Nonnull; +import javax.annotation.meta.TypeQualifierDefault; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +@TypeQualifierDefault({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@Nonnull +@interface ElementTypesAreNonnullByDefault { +} + +// FILE: Maps.java +import org.checkerframework.checker.nullness.qual.Nullable; +// Here it's important that @ElementTypesAreNonnullByDefault is a JSR-305 default qualifier and disabled by default (resulting in warnings-only) +// Thus return type (head type) is considered as warningly-annotated as not-nullable and that makes annotations on bounds for K and V +// be effectively ignored on non-warnings level. +// Behavior was changed in K2, see KT-63209. +@ElementTypesAreNonnullByDefault +public final class Maps { + public static java.util.HashMap newHashMap() { return null; } +} + +// FILE: main.kt + +fun foo() { + val x = Maps.newHashMap() + x.put("", 1) + // If there were no @ElementTypesAreNonnullByDefault on the Maps class, there would be an error on `null` argument because the type of `x` + // would be `HashMap!`, i.e. with non-flexible type arguments, thus not allowing nulls. + x.put("", null) +} diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/warningModeForHeadType.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/warningModeForHeadType.kt index f124cb567db..7980ce00f37 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/warningModeForHeadType.kt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/warningModeForHeadType.kt @@ -1,6 +1,6 @@ -// FIR_IDENTICAL // FULL_JDK // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER +// LANGUAGE: -SupportJavaErrorEnhancementOfArgumentsOfWarningLevelEnhanced // FILE: ElementTypesAreNonnullByDefault.java import java.lang.annotation.ElementType; @@ -22,6 +22,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; // Here it's important that @ElementTypesAreNonnullByDefault is a JSR-305 default qualifier and disabled by default (resulting in warnings-only) // Thus return type (head type) is considered as warningly-annotated as not-nullable and that makes annotations on bounds for K and V // be effectively ignored on non-warnings level. +// Behavior was changed in K2, see KT-63209. @ElementTypesAreNonnullByDefault public final class Maps { public static java.util.HashMap newHashMap() { return null; } diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.fir.kt new file mode 100644 index 00000000000..3c027811bd5 --- /dev/null +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.fir.kt @@ -0,0 +1,71 @@ +// NULLABILITY_ANNOTATIONS: @io.reactivex.rxjava3.annotations:strict, @org.eclipse.jdt.annotation:warn +// LANGUAGE: +SupportJavaErrorEnhancementOfArgumentsOfWarningLevelEnhanced +// SOURCE_RETENTION_ANNOTATIONS +// MUTE_FOR_PSI_CLASS_FILES_READING +// ^because annotations don't allow type parameter use. +// ISSUE: KT-63209 + +// FILE: A1.java +import java.util.List; + +public class A1 { + @org.eclipse.jdt.annotation.Nullable + public static List<@io.reactivex.rxjava3.annotations.Nullable String> warningError() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List<@io.reactivex.rxjava3.annotations.Nullable List<@io.reactivex.rxjava3.annotations.Nullable String>> warningErrorError() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List<@org.eclipse.jdt.annotation.Nullable List<@io.reactivex.rxjava3.annotations.Nullable String>> warningWarningError() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List<@io.reactivex.rxjava3.annotations.Nullable List<@org.eclipse.jdt.annotation.Nullable String>> warningErrorWarning() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List> warningPlatformError() { + return null; + } +} + +// FILE: main.kt +fun main1() { + val list = A1.warningError() + val element = list.get(0) + element.length +} + +fun main2() { + val list = A1.warningErrorError() + val element = list.get(0) + element.get(0) + element!!.get(0).length +} + +fun main3() { + val list = A1.warningWarningError() + val element = list.get(0) + element.get(0) + element!!.get(0).length +} + +fun main4() { + val list = A1.warningErrorWarning() + val element = list.get(0) + element.get(0) + element!!.get(0).length +} + +fun main5() { + val list = A1.warningPlatformError() + val element = list.get(0) + element.get(0) + element!!.get(0).length +} diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.kt new file mode 100644 index 00000000000..49d5a968d9f --- /dev/null +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.kt @@ -0,0 +1,71 @@ +// NULLABILITY_ANNOTATIONS: @io.reactivex.rxjava3.annotations:strict, @org.eclipse.jdt.annotation:warn +// LANGUAGE: +SupportJavaErrorEnhancementOfArgumentsOfWarningLevelEnhanced +// SOURCE_RETENTION_ANNOTATIONS +// MUTE_FOR_PSI_CLASS_FILES_READING +// ^because annotations don't allow type parameter use. +// ISSUE: KT-63209 + +// FILE: A1.java +import java.util.List; + +public class A1 { + @org.eclipse.jdt.annotation.Nullable + public static List<@io.reactivex.rxjava3.annotations.Nullable String> warningError() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List<@io.reactivex.rxjava3.annotations.Nullable List<@io.reactivex.rxjava3.annotations.Nullable String>> warningErrorError() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List<@org.eclipse.jdt.annotation.Nullable List<@io.reactivex.rxjava3.annotations.Nullable String>> warningWarningError() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List<@io.reactivex.rxjava3.annotations.Nullable List<@org.eclipse.jdt.annotation.Nullable String>> warningErrorWarning() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List> warningPlatformError() { + return null; + } +} + +// FILE: main.kt +fun main1() { + val list = A1.warningError() + val element = list.get(0) + element.length +} + +fun main2() { + val list = A1.warningErrorError() + val element = list.get(0) + element.get(0) + element!!.get(0).length +} + +fun main3() { + val list = A1.warningWarningError() + val element = list.get(0) + element.get(0) + element!!.get(0).length +} + +fun main4() { + val list = A1.warningErrorWarning() + val element = list.get(0) + element.get(0) + element!!.get(0).length +} + +fun main5() { + val list = A1.warningPlatformError() + val element = list.get(0) + element.get(0) + element!!.get(0).length +} diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.fir.kt new file mode 100644 index 00000000000..a505059bacf --- /dev/null +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.fir.kt @@ -0,0 +1,71 @@ +// NULLABILITY_ANNOTATIONS: @io.reactivex.rxjava3.annotations:strict, @org.eclipse.jdt.annotation:warn +// LANGUAGE: -SupportJavaErrorEnhancementOfArgumentsOfWarningLevelEnhanced +// SOURCE_RETENTION_ANNOTATIONS +// MUTE_FOR_PSI_CLASS_FILES_READING +// ^because annotations don't allow type parameter use. +// ISSUE: KT-63209 + +// FILE: A1.java +import java.util.List; + +public class A1 { + @org.eclipse.jdt.annotation.Nullable + public static List<@io.reactivex.rxjava3.annotations.Nullable String> warningError() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List<@io.reactivex.rxjava3.annotations.Nullable List<@io.reactivex.rxjava3.annotations.Nullable String>> warningErrorError() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List<@org.eclipse.jdt.annotation.Nullable List<@io.reactivex.rxjava3.annotations.Nullable String>> warningWarningError() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List<@io.reactivex.rxjava3.annotations.Nullable List<@org.eclipse.jdt.annotation.Nullable String>> warningErrorWarning() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List> warningPlatformError() { + return null; + } +} + +// FILE: main.kt +fun main1() { + val list = A1.warningError() + val element = ?")!>list.get(0) + element.length +} + +fun main2() { + val list = A1.warningErrorError() + val element = ?..@Nullable() kotlin.collections.List<@Nullable() kotlin.String?>?)>?")!>list.get(0) + ?..@Nullable() kotlin.collections.List<@Nullable() kotlin.String?>?); This will become an error in Kotlin 2.1. See https://youtrack.jetbrains.com/issue/KT-63209.")!>element.get(0) + element!!.get(0).length +} + +fun main3() { + val list = A1.warningWarningError() + val element = ?..@Nullable() kotlin.collections.List<@Nullable() kotlin.String?>?)>?")!>list.get(0) + ?..@Nullable() kotlin.collections.List<@Nullable() kotlin.String?>?)")!>element.get(0) + element!!.get(0).length +} + +fun main4() { + val list = A1.warningErrorWarning() + val element = ?..@Nullable() kotlin.collections.List<@Nullable() kotlin.String?>?)>?")!>list.get(0) + ?..@Nullable() kotlin.collections.List<@Nullable() kotlin.String?>?); This will become an error in Kotlin 2.1. See https://youtrack.jetbrains.com/issue/KT-63209.")!>element.get(0) + element!!.get(0).length +} + +fun main5() { + val list = A1.warningPlatformError() + val element = !>?")!>list.get(0) + element.get(0) + element!!.get(0).length +} diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.kt new file mode 100644 index 00000000000..b1b64de7341 --- /dev/null +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.kt @@ -0,0 +1,71 @@ +// NULLABILITY_ANNOTATIONS: @io.reactivex.rxjava3.annotations:strict, @org.eclipse.jdt.annotation:warn +// LANGUAGE: -SupportJavaErrorEnhancementOfArgumentsOfWarningLevelEnhanced +// SOURCE_RETENTION_ANNOTATIONS +// MUTE_FOR_PSI_CLASS_FILES_READING +// ^because annotations don't allow type parameter use. +// ISSUE: KT-63209 + +// FILE: A1.java +import java.util.List; + +public class A1 { + @org.eclipse.jdt.annotation.Nullable + public static List<@io.reactivex.rxjava3.annotations.Nullable String> warningError() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List<@io.reactivex.rxjava3.annotations.Nullable List<@io.reactivex.rxjava3.annotations.Nullable String>> warningErrorError() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List<@org.eclipse.jdt.annotation.Nullable List<@io.reactivex.rxjava3.annotations.Nullable String>> warningWarningError() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List<@io.reactivex.rxjava3.annotations.Nullable List<@org.eclipse.jdt.annotation.Nullable String>> warningErrorWarning() { + return null; + } + + @org.eclipse.jdt.annotation.Nullable + public static List> warningPlatformError() { + return null; + } +} + +// FILE: main.kt +fun main1() { + val list = A1.warningError() + val element = list.get(0) + element.length +} + +fun main2() { + val list = A1.warningErrorError() + val element = list.get(0) + element.get(0) + element!!.get(0).length +} + +fun main3() { + val list = A1.warningWarningError() + val element = list.get(0) + element.get(0) + element!!.get(0).length +} + +fun main4() { + val list = A1.warningErrorWarning() + val element = list.get(0) + element.get(0) + element!!.get(0).length +} + +fun main5() { + val list = A1.warningPlatformError() + val element = list.get(0) + element.get(0) + element!!.get(0).length +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaTestGenerated.java index 8525dfb3ad1..51826c6f001 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaTestGenerated.java @@ -68,6 +68,18 @@ public class ForeignAnnotationsCompiledJavaTestGenerated extends AbstractForeign runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/eclipse.kt"); } + @Test + @TestMetadata("errorArgumentOfWarningAfter.kt") + public void testErrorArgumentOfWarningAfter() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.kt"); + } + + @Test + @TestMetadata("errorArgumentOfWarningBefore.kt") + public void testErrorArgumentOfWarningBefore() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.kt"); + } + @Test @TestMetadata("findBugsSimple.kt") public void testFindBugsSimple() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java index 13b72e07a9f..995d59bdb21 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated.java @@ -68,6 +68,18 @@ public class ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated exte runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/eclipse.kt"); } + @Test + @TestMetadata("errorArgumentOfWarningAfter.kt") + public void testErrorArgumentOfWarningAfter() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.kt"); + } + + @Test + @TestMetadata("errorArgumentOfWarningBefore.kt") + public void testErrorArgumentOfWarningBefore() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.kt"); + } + @Test @TestMetadata("findBugsSimple.kt") public void testFindBugsSimple() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsSourceJavaTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsSourceJavaTestGenerated.java index ed0d96d42ec..ac29e557525 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsSourceJavaTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ForeignAnnotationsSourceJavaTestGenerated.java @@ -68,6 +68,18 @@ public class ForeignAnnotationsSourceJavaTestGenerated extends AbstractForeignAn runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/eclipse.kt"); } + @Test + @TestMetadata("errorArgumentOfWarningAfter.kt") + public void testErrorArgumentOfWarningAfter() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningAfter.kt"); + } + + @Test + @TestMetadata("errorArgumentOfWarningBefore.kt") + public void testErrorArgumentOfWarningBefore() throws Exception { + runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/errorArgumentOfWarningBefore.kt"); + } + @Test @TestMetadata("findBugsSimple.kt") public void testFindBugsSimple() throws Exception { diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 81be54d061e..6cf77803bdd 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -318,6 +318,7 @@ enum class LanguageFeature( ProhibitSingleNamedFunctionAsExpression(KOTLIN_2_1, kind = BUG_FIX), // KT-62573 ForbidLambdaParameterWithMissingDependencyType(KOTLIN_2_1, kind = BUG_FIX), // KT-64266 JsAllowInvalidCharsIdentifiersEscaping(KOTLIN_2_1, kind = OTHER), // KT-31799 + SupportJavaErrorEnhancementOfArgumentsOfWarningLevelEnhanced(KOTLIN_2_1, kind = BUG_FIX), // KT-63209 // End of 2.* language features --------------------------------------------------