diff --git a/compiler/build.gradle.kts b/compiler/build.gradle.kts index 5b5b6b94aae..668cf867fa6 100644 --- a/compiler/build.gradle.kts +++ b/compiler/build.gradle.kts @@ -32,7 +32,8 @@ val testDistProjects = listOf( ":kotlin-daemon-client", ":kotlin-preloader", ":plugins:android-extensions-compiler", - ":kotlin-ant") + ":kotlin-ant", + ":kotlin-annotations-jvm") dependencies { depDistProjects.forEach { diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt index e5cdd88c0dc..2eedb6dc2d5 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.config.AnalysisFlag import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.utils.Jsr305State +import org.jetbrains.kotlin.utils.ReportLevel class K2JVMCompilerArguments : CommonCompilerArguments() { companion object { @@ -165,10 +166,15 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { @Argument( value = "-Xjsr305", deprecatedName = "-Xjsr305-annotations", - valueDescription = "{ignore|strict|warn}", - description = "Specify global behavior for JSR-305 nullability annotations: ignore, treat as other supported nullability annotations, or report a warning" + valueDescription = "{ignore|strict|warn}" + + "|under-migration:{ignore-strict-warn}" + + "|@:{ignore|strict|warn}", + description = "Specify behaviors for JSR-305 nullability annotations for: " + + "global, annotated with @UnderMigration or custom annotation " + + "with specific value: ignore, treat as other supported nullability annotations, or report a warning. " + + "Note that strict value is experimental yet" ) - var jsr305: String? by FreezableVar(Jsr305State.DEFAULT.description) + var jsr305: Array? by FreezableVar(null) @Argument( value = "-Xno-exception-on-explicit-equals-for-boxed-null", @@ -181,20 +187,54 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { override fun configureAnalysisFlags(collector: MessageCollector): MutableMap, Any> { val result = super.configureAnalysisFlags(collector) + result[AnalysisFlag.jsr305] = parseJsr305(collector) + return result + } - if (jsr305 == "enable") { - collector.report( - CompilerMessageSeverity.STRONG_WARNING, - "Option 'enable' for -Xjsr305 flag is deprecated. Please use 'strict' instead" - ) - result.put(AnalysisFlag.jsr305, Jsr305State.STRICT) + fun parseJsr305(collector: MessageCollector): Jsr305State { + var global: ReportLevel? = null + var migration: ReportLevel? = null + val userDefined = mutableMapOf() + + fun parseJsr305UnderMigration(collector: MessageCollector, item: String): ReportLevel? { + val rawState = item.split(":").takeIf { it.size == 2 }?.get(1) + return ReportLevel.findByDescription(rawState) } - else { - Jsr305State.findByDescription(jsr305)?.let { - result.put(AnalysisFlag.jsr305, it) + + jsr305?.forEach { item -> + when { + item.startsWith("@") -> { + val (name, state) = parseJsr305UserDefined(collector, item) ?: return@forEach + val current = userDefined[name] + current?.let { return@forEach } + userDefined[name] = state + } + item.startsWith("under-migration") -> { + migration?.let { return@forEach } + migration = parseJsr305UnderMigration(collector, item) + } + item == "enable" -> { + collector.report( + CompilerMessageSeverity.STRONG_WARNING, + "Option 'enable' for -Xjsr305 flag is deprecated. Please use 'strict' instead" + ) + global?.let { return@forEach } + global = ReportLevel.STRICT + } + else -> { + global?.let { return@forEach } + global = ReportLevel.findByDescription(item) + } } } - return result + val state = Jsr305State(global ?: ReportLevel.WARN, migration, userDefined) + return if (state == Jsr305State.DISABLED) Jsr305State.DISABLED else state + } + + private fun parseJsr305UserDefined(collector: MessageCollector, item: String): Pair? { + val (name, rawState) = item.substring(1).split(":").takeIf { it.size == 2 } ?: return null + val state = ReportLevel.findByDescription(rawState) ?: return null + return name to state } } diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index e8a58b632fa..e2842d9644a 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -9,7 +9,8 @@ where advanced options include: -Xmultifile-parts-inherit Compile multifile classes as a hierarchy of parts and facade -Xmodule-path= Paths where to find Java 9+ modules -Xjavac-arguments= Java compiler arguments - -Xjsr305={ignore|strict|warn} Specify global behavior for JSR-305 nullability annotations: ignore, treat as other supported nullability annotations, or report a warning + -Xjsr305={ignore|strict|warn}|under-migration:{ignore-strict-warn}|@:{ignore|strict|warn} + Specify behaviors for JSR-305 nullability annotations for: global, annotated with @UnderMigration or custom annotation with specific value: ignore, treat as other supported nullability annotations, or report a warning. Note that strict value is experimental yet -Xload-builtins-from-dependencies Load definitions of built-in declarations from module dependencies, instead of from the compiler -Xno-call-assertions Don't generate not-null assertions for arguments of platform types diff --git a/compiler/testData/foreignAnnotations/testAnnotations/MyMigrationNonnull.java b/compiler/testData/foreignAnnotations/testAnnotations/MyMigrationNonnull.java new file mode 100644 index 00000000000..a328b21f353 --- /dev/null +++ b/compiler/testData/foreignAnnotations/testAnnotations/MyMigrationNonnull.java @@ -0,0 +1,18 @@ +import javax.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifierNickname; +import javax.annotation.meta.When; + +import kotlin.annotations.jvm.*; + +@Documented +@TypeQualifierNickname +@Nonnull(when = When.ALWAYS) +@Retention(RetentionPolicy.RUNTIME) +@UnderMigration(status = MigrationStatus.WARN) +public @interface MyMigrationNonnull { + +} diff --git a/compiler/testData/foreignAnnotations/testAnnotations/MyMigrationNullable.java b/compiler/testData/foreignAnnotations/testAnnotations/MyMigrationNullable.java new file mode 100644 index 00000000000..421896ba05a --- /dev/null +++ b/compiler/testData/foreignAnnotations/testAnnotations/MyMigrationNullable.java @@ -0,0 +1,18 @@ +import javax.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifierNickname; +import javax.annotation.meta.When; + +import kotlin.annotations.jvm.*; + +@Documented +@TypeQualifierNickname +@Nonnull(when = When.MAYBE) +@Retention(RetentionPolicy.RUNTIME) +@UnderMigration(status = MigrationStatus.WARN) +public @interface MyMigrationNullable { + +} \ No newline at end of file diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/ignore/parametersAreNonnullByDefault.kt b/compiler/testData/foreignAnnotations/tests/jsr305/ignore/parametersAreNonnullByDefault.kt index 177944fe363..88e688729da 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/ignore/parametersAreNonnullByDefault.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/ignore/parametersAreNonnullByDefault.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -// JSR305_ANNOTATIONS_IGNORE +// JSR305_GLOBAL_REPORT ignore // FILE: A.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/arithmetic.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/arithmetic.kt index 041b909cdb9..2d459415d0c 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/arithmetic.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/arithmetic.kt @@ -1,4 +1,4 @@ -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/array.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/array.kt index 1d3361208c6..2b6861b617f 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/array.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/array.kt @@ -1,4 +1,4 @@ -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/assignToVar.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/assignToVar.kt index 26c91535bb9..ac2604e3d0a 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/assignToVar.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/assignToVar.kt @@ -1,4 +1,4 @@ -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/conditions.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/conditions.kt index 9ee6fa645c1..81ba1f1f6a7 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/conditions.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/conditions.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_EXPRESSION -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/dataFlowInfo.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/dataFlowInfo.kt index 374049db81c..e605d9401e2 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/dataFlowInfo.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/dataFlowInfo.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/defaultParameters.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/defaultParameters.kt index 37b66ea2d42..ae0230cd4fe 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/defaultParameters.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/defaultParameters.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/delegatedProperties.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/delegatedProperties.kt index f37c6ed2e3e..0858a0ea375 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/delegatedProperties.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/delegatedProperties.kt @@ -1,4 +1,4 @@ -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/delegation.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/delegation.kt index 6d3dbab8f44..d530aaa8e1f 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/delegation.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/delegation.kt @@ -1,4 +1,4 @@ -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/derefenceExtension.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/derefenceExtension.kt index 50bdaf91f28..9fdfd52376b 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/derefenceExtension.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/derefenceExtension.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/derefenceMember.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/derefenceMember.kt index 1ab42f14d16..67d082641fa 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/derefenceMember.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/derefenceMember.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/expectedType.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/expectedType.kt index f1bb7fd09a4..fe78c4c18d6 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/expectedType.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/expectedType.kt @@ -1,5 +1,5 @@ // !CHECK_TYPE -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/for.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/for.kt index 21ca16afebe..622494e0f05 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/for.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/for.kt @@ -1,4 +1,4 @@ -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/functionArguments.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/functionArguments.kt index 00c4f82f7cf..3b88e1a4faa 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/functionArguments.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/functionArguments.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/invoke.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/invoke.kt index 914ab0171b4..2386c379e53 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/invoke.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/invoke.kt @@ -1,4 +1,4 @@ -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/kt6829.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/kt6829.kt index 35bc895674e..665a2b7add2 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/kt6829.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/kt6829.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // KT-6829 False warning on map to @Nullable diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/multiDeclaration.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/multiDeclaration.kt index c643824a033..e68c2d6dcca 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/multiDeclaration.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/multiDeclaration.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/passToJava.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/passToJava.kt index 2003f670f16..1be98d46514 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/passToJava.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/passToJava.kt @@ -1,4 +1,4 @@ -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/primitiveArray.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/primitiveArray.kt index 6de9449f8e0..bf1d07fc73c 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/primitiveArray.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/primitiveArray.kt @@ -1,4 +1,4 @@ -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/throw.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/throw.kt index cc60fb811b1..063d5a8040a 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/throw.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/throw.kt @@ -1,4 +1,4 @@ -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/uselessElvisRightIsNull.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/uselessElvisRightIsNull.kt index 8faa1bfb467..6f14996b996 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/uselessElvisRightIsNull.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/uselessElvisRightIsNull.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: J.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/nullabilityGenerics.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/nullabilityGenerics.kt index a59375b2c0f..1833cedee0b 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/nullabilityGenerics.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/nullabilityGenerics.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: A.java public class A { diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/nullabilityNicknames.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/nullabilityNicknames.kt index 5d6b9b4f5b8..0f9894dc652 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/nullabilityNicknames.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/nullabilityNicknames.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: MyNullable.java import javax.annotation.*; diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/simple.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/simple.kt index c3cc81520f1..08ad56c2509 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/simple.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/simple.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: A.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/strange.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/strange.kt index 23065ff7876..4d523713f40 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/strange.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/strange.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: A.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/fieldsAreNullable.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/fieldsAreNullable.kt index a8c2968b543..e23b1adc3ff 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/fieldsAreNullable.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/fieldsAreNullable.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: FieldsAreNullable.java import java.lang.annotation.Documented; diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/nullabilityFromOverridden.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/nullabilityFromOverridden.kt index a35ab08afe4..68e1be1e1bd 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/nullabilityFromOverridden.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/nullabilityFromOverridden.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: NonNullApi.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/overridingDefaultQualifier.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/overridingDefaultQualifier.kt index 2ffba618cda..0783c21b5a9 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/overridingDefaultQualifier.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/overridingDefaultQualifier.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: NonNullApi.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/parametersAreNonnullByDefault.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/parametersAreNonnullByDefault.kt index 759c1c721ce..e84522ab81f 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/parametersAreNonnullByDefault.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/parametersAreNonnullByDefault.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: A.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/parametersAreNonnullByDefaultPackage.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/parametersAreNonnullByDefaultPackage.kt index 5288a594012..82bdb9efe2f 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/parametersAreNonnullByDefaultPackage.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/parametersAreNonnullByDefaultPackage.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: test/package-info.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/springNullable.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/springNullable.kt index 15b11bd142e..215943844f7 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/springNullable.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/springNullable.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: spr/Nullable.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/springNullablePackage.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/springNullablePackage.kt index 425d0aa7d9b..08aca8a3b15 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/springNullablePackage.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/springNullablePackage.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -// WARNING_FOR_JSR305_ANNOTATIONS +// JSR305_GLOBAL_REPORT warn // FILE: spr/Nullable.java diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/customMigration.kt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/customMigration.kt new file mode 100644 index 00000000000..901f060308d --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/customMigration.kt @@ -0,0 +1,84 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER +// JSR305_GLOBAL_REPORT ignore + +// FILE: MyErrorNonnull.java +import javax.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifierNickname; +import javax.annotation.meta.When; + +import kotlin.annotations.jvm.*; + +@Documented +@TypeQualifierNickname +@Nonnull(when = When.ALWAYS) +@Retention(RetentionPolicy.RUNTIME) +@UnderMigration(status = MigrationStatus.STRICT) +public @interface MyErrorNonnull { +} + +// FILE: MyWarnNonnull.java +import javax.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifierNickname; +import javax.annotation.meta.When; + +import kotlin.annotations.jvm.*; + +@Documented +@TypeQualifierNickname +@Nonnull(when = When.ALWAYS) +@Retention(RetentionPolicy.RUNTIME) +@UnderMigration(status = MigrationStatus.WARN) +public @interface MyWarnNonnull { +} + +// FILE: MyIgnoreNonnull.java +import javax.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifierNickname; +import javax.annotation.meta.When; + +import kotlin.annotations.jvm.*; + +@Documented +@TypeQualifierNickname +@Nonnull(when = When.ALWAYS) +@Retention(RetentionPolicy.RUNTIME) +@UnderMigration(status = MigrationStatus.IGNORE) +public @interface MyIgnoreNonnull { +} + +// FILE: A.java + +public class A { + public void foo(@MyErrorNonnull String bar) {} + public void foo2(@MyWarnNonnull String bar) {} + public void foo3(@MyIgnoreNonnull String bar) {} + public void foo4(@MyMigrationNonnull String bar) {} +} + +// FILE: main.kt + +fun main(a: A) { + a.foo("") + a.foo(null) + + a.foo2("") + a.foo2(null) + + a.foo3("") + a.foo3(null) + + a.foo4("") + a.foo4(null) +} \ No newline at end of file diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/customMigration.txt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/customMigration.txt new file mode 100644 index 00000000000..83842aaa6d0 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/customMigration.txt @@ -0,0 +1,35 @@ +package + +public fun main(/*0*/ a: A): kotlin.Unit + +public open class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun foo(/*0*/ @MyErrorNonnull bar: kotlin.String): kotlin.Unit + public open fun foo2(/*0*/ @MyWarnNonnull bar: kotlin.String!): kotlin.Unit + public open fun foo3(/*0*/ @MyIgnoreNonnull bar: kotlin.String!): kotlin.Unit + public open fun foo4(/*0*/ @MyMigrationNonnull bar: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.annotation.MustBeDocumented @javax.annotation.meta.TypeQualifierNickname @javax.annotation.Nonnull(when = When.ALWAYS) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotations.jvm.UnderMigration(status = MigrationStatus.STRICT) public final annotation class MyErrorNonnull : kotlin.Annotation { + public constructor MyErrorNonnull() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.annotation.MustBeDocumented @javax.annotation.meta.TypeQualifierNickname @javax.annotation.Nonnull(when = When.ALWAYS) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotations.jvm.UnderMigration(status = MigrationStatus.IGNORE) public final annotation class MyIgnoreNonnull : kotlin.Annotation { + public constructor MyIgnoreNonnull() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.annotation.MustBeDocumented @javax.annotation.meta.TypeQualifierNickname @javax.annotation.Nonnull(when = When.ALWAYS) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotations.jvm.UnderMigration(status = MigrationStatus.WARN) public final annotation class MyWarnNonnull : kotlin.Annotation { + public constructor MyWarnNonnull() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalIgnore.kt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalIgnore.kt new file mode 100644 index 00000000000..72245c8be03 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalIgnore.kt @@ -0,0 +1,57 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER +// JSR305_GLOBAL_REPORT ignore +// JSR305_MIGRATION_REPORT strict +// JSR305_SPECIAL_REPORT MyNonnull:warn + +// FILE: A.java + +import javax.annotation.*; + +public class A { + @MyMigrationNullable public String field = null; + + @MyMigrationNullable + public String foo(@MyMigrationNonnull String x, CharSequence y) { + return ""; + } + + @MyMigrationNonnull + public String bar() { + return ""; + } + + @MyNullable public String field2 = null; + @MyNullable + public String foo2(@MyNonnull String x, CharSequence y) { + return ""; + } + + @MyNonnull + public String bar2() { + return ""; + } +} + +// FILE: main.kt + +fun main(a: A) { + a.foo("", null)?.length + a.foo("", null).length + a.foo(null, "").length + + a.bar().length + a.bar()!!.length + + a.field?.length + a.field.length + + a.foo2("", null)?.length + a.foo2("", null).length + a.foo2(null, "").length + + a.bar2().length + a.bar2()!!.length + + a.field2?.length + a.field2.length +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalIgnore.txt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalIgnore.txt new file mode 100644 index 00000000000..243af6b409b --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalIgnore.txt @@ -0,0 +1,16 @@ +package + +public fun main(/*0*/ a: A): kotlin.Unit + +public open class A { + public constructor A() + @MyMigrationNullable public final var field: kotlin.String? + @MyNullable public final var field2: kotlin.String! + @MyMigrationNonnull public open fun bar(): kotlin.String + @MyNonnull public open fun bar2(): kotlin.String! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyMigrationNullable public open fun foo(/*0*/ @MyMigrationNonnull x: kotlin.String, /*1*/ y: kotlin.CharSequence!): kotlin.String? + @MyNullable public open fun foo2(/*0*/ @MyNonnull x: kotlin.String!, /*1*/ y: kotlin.CharSequence!): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalWarningMigrationIgnore.kt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalWarningMigrationIgnore.kt new file mode 100644 index 00000000000..571c247ac0a --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalWarningMigrationIgnore.kt @@ -0,0 +1,57 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER +// JSR305_GLOBAL_REPORT warn +// JSR305_MIGRATION_REPORT ignore +// JSR305_SPECIAL_REPORT MyNullable:strict, MyMigrationNonnull:strict + +// FILE: A.java + +import javax.annotation.*; + +public class A { + @MyMigrationNullable public String field = null; + + @MyMigrationNullable + public String foo(@MyMigrationNonnull String x, CharSequence y) { + return ""; + } + + @MyMigrationNonnull + public String bar() { + return ""; + } + + @MyNullable public String field2 = null; + @MyNullable + public String foo2(@MyNonnull String x, CharSequence y) { + return ""; + } + + @MyNonnull + public String bar2() { + return ""; + } +} + +// FILE: main.kt + +fun main(a: A) { + a.foo("", null)?.length + a.foo("", null).length + a.foo(null, "").length + + a.bar().length + a.bar()!!.length + + a.field?.length + a.field.length + + a.foo2("", null)?.length + a.foo2("", null).length + a.foo2(null, "").length + + a.bar2().length + a.bar2()!!.length + + a.field2?.length + a.field2.length +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalWarningMigrationIgnore.txt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalWarningMigrationIgnore.txt new file mode 100644 index 00000000000..83343a807b1 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalWarningMigrationIgnore.txt @@ -0,0 +1,16 @@ +package + +public fun main(/*0*/ a: A): kotlin.Unit + +public open class A { + public constructor A() + @MyMigrationNullable public final var field: kotlin.String! + @MyNullable public final var field2: kotlin.String? + @MyMigrationNonnull public open fun bar(): kotlin.String + @MyNonnull public open fun bar2(): kotlin.String! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyMigrationNullable public open fun foo(/*0*/ @MyMigrationNonnull x: kotlin.String, /*1*/ y: kotlin.CharSequence!): kotlin.String! + @MyNullable public open fun foo2(/*0*/ @MyNonnull x: kotlin.String!, /*1*/ y: kotlin.CharSequence!): kotlin.String? + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationError.kt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationError.kt new file mode 100644 index 00000000000..8e2c6cf5260 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationError.kt @@ -0,0 +1,78 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER +// JSR305_GLOBAL_REPORT warn +// JSR305_MIGRATION_REPORT strict +// JSR305_SPECIAL_REPORT MyNonnull:ignore, MySuperNull:strict + +// FILE: MySuperNull.java +import javax.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifierNickname; +import javax.annotation.meta.When; + +@Documented +@TypeQualifierNickname +@Nonnull(when = When.MAYBE) +@Retention(RetentionPolicy.RUNTIME) +public @interface MySuperNull { +} + +// FILE: A.java + +import javax.annotation.*; + +public class A { + @MyMigrationNullable public String field = null; + + @MyMigrationNullable + public String foo(@MyMigrationNonnull String x, CharSequence y) { + return ""; + } + + @MyMigrationNonnull + public String bar() { + return ""; + } + + @MyNullable public String field2 = null; + @MyNullable + public String foo2(@MyNonnull String x, CharSequence y) { + return ""; + } + + @MyNonnull + public String bar2() { + return ""; + } + + @MySuperNull public String field3 = null; +} + +// FILE: main.kt + +fun main(a: A) { + a.foo("", null)?.length + a.foo("", null).length + a.foo(null, "").length + + a.bar().length + a.bar()!!.length + + a.field?.length + a.field.length + + a.foo2("", null)?.length + a.foo2("", null).length + a.foo2(null, "").length + + a.bar2().length + a.bar2()!!.length + + a.field2?.length + a.field2.length + + a.field3?.length + a.field3.length +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationError.txt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationError.txt new file mode 100644 index 00000000000..e7bf6899f3f --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationError.txt @@ -0,0 +1,24 @@ +package + +public fun main(/*0*/ a: A): kotlin.Unit + +public open class A { + public constructor A() + @MyMigrationNullable public final var field: kotlin.String? + @MyNullable public final var field2: kotlin.String! + @MySuperNull public final var field3: kotlin.String? + @MyMigrationNonnull public open fun bar(): kotlin.String + @MyNonnull public open fun bar2(): kotlin.String! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyMigrationNullable public open fun foo(/*0*/ @MyMigrationNonnull x: kotlin.String, /*1*/ y: kotlin.CharSequence!): kotlin.String? + @MyNullable public open fun foo2(/*0*/ @MyNonnull x: kotlin.String!, /*1*/ y: kotlin.CharSequence!): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.annotation.MustBeDocumented @javax.annotation.meta.TypeQualifierNickname @javax.annotation.Nonnull(when = When.MAYBE) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public final annotation class MySuperNull : kotlin.Annotation { + public constructor MySuperNull() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationIgnore.kt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationIgnore.kt new file mode 100644 index 00000000000..d3564fc12ea --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationIgnore.kt @@ -0,0 +1,57 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER +// JSR305_GLOBAL_REPORT strict +// JSR305_MIGRATION_REPORT ignore +// JSR305_SPECIAL_REPORT MyNullable:warn, MyMigrationNonnull:strict + +// FILE: A.java + +import javax.annotation.*; + +public class A { + @MyMigrationNullable public String field = null; + + @MyMigrationNullable + public String foo(@MyMigrationNonnull String x, CharSequence y) { + return ""; + } + + @MyMigrationNonnull + public String bar() { + return ""; + } + + @MyNullable public String field2 = null; + @MyNullable + public String foo2(@MyNonnull String x, CharSequence y) { + return ""; + } + + @MyNonnull + public String bar2() { + return ""; + } +} + +// FILE: main.kt + +fun main(a: A) { + a.foo("", null)?.length + a.foo("", null).length + a.foo(null, "").length + + a.bar().length + a.bar()!!.length + + a.field?.length + a.field.length + + a.foo2("", null)?.length + a.foo2("", null).length + a.foo2(null, "").length + + a.bar2().length + a.bar2()!!.length + + a.field2?.length + a.field2.length +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationIgnore.txt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationIgnore.txt new file mode 100644 index 00000000000..7bb17583fea --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationIgnore.txt @@ -0,0 +1,16 @@ +package + +public fun main(/*0*/ a: A): kotlin.Unit + +public open class A { + public constructor A() + @MyMigrationNullable public final var field: kotlin.String! + @MyNullable public final var field2: kotlin.String! + @MyMigrationNonnull public open fun bar(): kotlin.String + @MyNonnull public open fun bar2(): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyMigrationNullable public open fun foo(/*0*/ @MyMigrationNonnull x: kotlin.String, /*1*/ y: kotlin.CharSequence!): kotlin.String! + @MyNullable public open fun foo2(/*0*/ @MyNonnull x: kotlin.String, /*1*/ y: kotlin.CharSequence!): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationWarning.kt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationWarning.kt new file mode 100644 index 00000000000..8c636fbbd5a --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationWarning.kt @@ -0,0 +1,57 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER +// JSR305_GLOBAL_REPORT strict +// JSR305_MIGRATION_REPORT warn +// JSR305_SPECIAL_REPORT MyNullable:ignore, MyMigrationNullable:strict + +// FILE: A.java + +import javax.annotation.*; + +public class A { + @MyMigrationNullable public String field = null; + + @MyMigrationNullable + public String foo(@MyMigrationNonnull String x, CharSequence y) { + return ""; + } + + @MyMigrationNonnull + public String bar() { + return ""; + } + + @MyNullable public String field2 = null; + @MyNullable + public String foo2(@MyNonnull String x, CharSequence y) { + return ""; + } + + @MyNonnull + public String bar2() { + return ""; + } +} + +// FILE: main.kt + +fun main(a: A) { + a.foo("", null)?.length + a.foo("", null).length + a.foo(null, "").length + + a.bar().length + a.bar()!!.length + + a.field?.length + a.field.length + + a.foo2("", null)?.length + a.foo2("", null).length + a.foo2(null, "").length + + a.bar2().length + a.bar2()!!.length + + a.field2?.length + a.field2.length +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationWarning.txt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationWarning.txt new file mode 100644 index 00000000000..f36e6bc8da6 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationWarning.txt @@ -0,0 +1,16 @@ +package + +public fun main(/*0*/ a: A): kotlin.Unit + +public open class A { + public constructor A() + @MyMigrationNullable public final var field: kotlin.String? + @MyNullable public final var field2: kotlin.String! + @MyMigrationNonnull public open fun bar(): kotlin.String! + @MyNonnull public open fun bar2(): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyMigrationNullable public open fun foo(/*0*/ @MyMigrationNonnull x: kotlin.String!, /*1*/ y: kotlin.CharSequence!): kotlin.String? + @MyNullable public open fun foo2(/*0*/ @MyNonnull x: kotlin.String, /*1*/ y: kotlin.CharSequence!): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/overrideConflicts.kt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/overrideConflicts.kt new file mode 100644 index 00000000000..ef21f56308d --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/overrideConflicts.kt @@ -0,0 +1,85 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER +// JSR305_GLOBAL_REPORT warn +// JSR305_MIGRATION_REPORT strict + +// FILE: A.java +import javax.annotation.Nullable; +import javax.annotation.Nonnull; + +public class A { + @MyNullable + public String foo() { return ""; } + + @MyMigrationNullable + public String foo2() { return ""; } + + @Nullable + public String foo3() { return ""; } + + public String foo4() { return ""; } + + public void bar(@MyNonnull String baz) { } + + public void bar2(@MyMigrationNonnull String baz) { } + + public void bar3(@Nonnull String baz) {} + + public void bar4(String baz) {} +} + +// FILE: B.java +public class B extends A { + @MyMigrationNullable + public String foo() { return ""; } + + @MyNullable + public String foo2() { return ""; } + + @MyNullable + public String foo3() { return ""; } + + @MyNullable + public String foo4() { return ""; } + + public void bar(@MyMigrationNonnull String baz) { } + + public void bar2(@MyNonnull String baz) { } + + public void bar3(@MyNonnull String baz) {} + + public void bar4(@MyNonnull String baz) {} +} + +// FILE: C.java +public class C extends A { + @MyMigrationNullable + public String foo4() { return ""; } + + public void bar4(@MyMigrationNonnull String baz) {} +} + +// FILE: main.kt +fun main(b: B, c: C) { + b.foo().length + b.foo()?.length + b.foo2().length + b.foo2()?.length + b.foo3().length + b.foo3()?.length + b.foo4().length + b.foo4()?.length + + b.bar(null) + b.bar("") + b.bar2(null) + b.bar2("") + b.bar3(null) + b.bar3("") + b.bar4(null) + b.bar4("") + + c.foo4().length + c.foo4()?.length + c.bar4(null) + c.bar4("") +} \ No newline at end of file diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/overrideConflicts.txt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/overrideConflicts.txt new file mode 100644 index 00000000000..548f62b39d5 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/overrideConflicts.txt @@ -0,0 +1,48 @@ +package + +public fun main(/*0*/ b: B, /*1*/ c: C): kotlin.Unit + +public open class A { + public constructor A() + public open fun bar(/*0*/ @MyNonnull baz: kotlin.String!): kotlin.Unit + public open fun bar2(/*0*/ @MyMigrationNonnull baz: kotlin.String): kotlin.Unit + public open fun bar3(/*0*/ @javax.annotation.Nonnull baz: kotlin.String): kotlin.Unit + public open fun bar4(/*0*/ baz: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyNullable public open fun foo(): kotlin.String! + @MyMigrationNullable public open fun foo2(): kotlin.String? + @javax.annotation.Nullable public open fun foo3(): kotlin.String? + public open fun foo4(): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class B : A { + public constructor B() + public open override /*1*/ fun bar(/*0*/ @MyMigrationNonnull baz: kotlin.String): kotlin.Unit + public open override /*1*/ fun bar2(/*0*/ @MyNonnull baz: kotlin.String): kotlin.Unit + public open override /*1*/ fun bar3(/*0*/ @MyNonnull baz: kotlin.String): kotlin.Unit + public open override /*1*/ fun bar4(/*0*/ @MyNonnull baz: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyMigrationNullable public open override /*1*/ fun foo(): kotlin.String? + @MyNullable public open override /*1*/ fun foo2(): kotlin.String? + @MyNullable public open override /*1*/ fun foo3(): kotlin.String? + @MyNullable public open override /*1*/ fun foo4(): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class C : A { + public constructor C() + public open override /*1*/ /*fake_override*/ fun bar(/*0*/ @MyNonnull baz: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun bar2(/*0*/ @MyMigrationNonnull baz: kotlin.String): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun bar3(/*0*/ @javax.annotation.Nonnull baz: kotlin.String): kotlin.Unit + public open override /*1*/ fun bar4(/*0*/ @MyMigrationNonnull baz: kotlin.String): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyNullable public open override /*1*/ /*fake_override*/ fun foo(): kotlin.String! + @MyMigrationNullable public open override /*1*/ /*fake_override*/ fun foo2(): kotlin.String? + @javax.annotation.Nullable public open override /*1*/ /*fake_override*/ fun foo3(): kotlin.String? + @MyMigrationNullable public open override /*1*/ fun foo4(): kotlin.String? + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/specialCollision.kt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/specialCollision.kt new file mode 100644 index 00000000000..adb449454cb --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/specialCollision.kt @@ -0,0 +1,37 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER +// JSR305_GLOBAL_REPORT ignore +// JSR305_MIGRATION_REPORT ignore +// JSR305_SPECIAL_REPORT MyNonnull:warn, MyMigrationNonnull:strict + +// FILE: A.java + +import javax.annotation.*; + +public class A { + @MyMigrationNullable public String field = null; + + @MyMigrationNullable + public String foo(@MyMigrationNonnull String x, CharSequence y) { + return ""; + } + + @MyNonnull + @MyMigrationNonnull + public String bar() { + return ""; + } +} + +// FILE: main.kt + +fun main(a: A) { + a.foo("", null)?.length + a.foo("", null).length + a.foo(null, "").length + + a.bar().length + a.bar()!!.length + + a.field?.length + a.field.length +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/specialCollision.txt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/specialCollision.txt new file mode 100644 index 00000000000..9835fbefeee --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/specialCollision.txt @@ -0,0 +1,13 @@ +package + +public fun main(/*0*/ a: A): kotlin.Unit + +public open class A { + public constructor A() + @MyMigrationNullable public final var field: kotlin.String! + @MyNonnull @MyMigrationNonnull public open fun bar(): kotlin.String! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyMigrationNullable public open fun foo(/*0*/ @MyMigrationNonnull x: kotlin.String, /*1*/ y: kotlin.CharSequence!): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/stateRefinement.kt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/stateRefinement.kt new file mode 100644 index 00000000000..284ae7f9ce4 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/stateRefinement.kt @@ -0,0 +1,57 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER +// JSR305_GLOBAL_REPORT ignore +// JSR305_MIGRATION_REPORT warn +// JSR305_SPECIAL_REPORT MyNonnull:strict + +// FILE: A.java + +import javax.annotation.*; + +public class A { + @MyMigrationNullable public String field = null; + + @MyMigrationNullable + public String foo(@MyMigrationNonnull String x, CharSequence y) { + return ""; + } + + @MyMigrationNonnull + public String bar() { + return ""; + } + + @MyNullable public String field2 = null; + @MyNullable + public String foo2(@MyNonnull String x, CharSequence y) { + return ""; + } + + @MyNonnull + public String bar2() { + return ""; + } +} + +// FILE: main.kt + +fun main(a: A) { + a.foo("", null)?.length + a.foo("", null).length + a.foo(null, "").length + + a.bar().length + a.bar()!!.length + + a.field?.length + a.field.length + + a.foo2("", null)?.length + a.foo2("", null).length + a.foo2(null, "").length + + a.bar2().length + a.bar2()!!.length + + a.field2?.length + a.field2.length +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/stateRefinement.txt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/stateRefinement.txt new file mode 100644 index 00000000000..a5b37edfe14 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/stateRefinement.txt @@ -0,0 +1,16 @@ +package + +public fun main(/*0*/ a: A): kotlin.Unit + +public open class A { + public constructor A() + @MyMigrationNullable public final var field: kotlin.String! + @MyNullable public final var field2: kotlin.String! + @MyMigrationNonnull public open fun bar(): kotlin.String! + @MyNonnull public open fun bar2(): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyMigrationNullable public open fun foo(/*0*/ @MyMigrationNonnull x: kotlin.String!, /*1*/ y: kotlin.CharSequence!): kotlin.String! + @MyNullable public open fun foo2(/*0*/ @MyNonnull x: kotlin.String, /*1*/ y: kotlin.CharSequence!): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests-common/org/jetbrains/kotlin/codegen/forTestCompile/ForTestCompileRuntime.java b/compiler/tests-common/org/jetbrains/kotlin/codegen/forTestCompile/ForTestCompileRuntime.java index 9253f4ab78a..98e2e6f4d3e 100644 --- a/compiler/tests-common/org/jetbrains/kotlin/codegen/forTestCompile/ForTestCompileRuntime.java +++ b/compiler/tests-common/org/jetbrains/kotlin/codegen/forTestCompile/ForTestCompileRuntime.java @@ -71,6 +71,11 @@ public class ForTestCompileRuntime { return assertExists(new File("dist/kotlinc/lib/kotlin-stdlib-js.jar")); } + @NotNull + public static File jvmAnnotationsForTests() { + return assertExists(new File("dist/kotlinc/lib/kotlin-annotations-jvm.jar")); + } + // TODO: Do not use these classes, remove them after stdlib tests are merged in the same build as the compiler @NotNull @Deprecated diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/AbstractForeignAnnotationsNoAnnotationInClasspathTest.kt b/compiler/tests/org/jetbrains/kotlin/checkers/AbstractForeignAnnotationsNoAnnotationInClasspathTest.kt index 0328196f3e4..cbbc9e92e47 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/AbstractForeignAnnotationsNoAnnotationInClasspathTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/checkers/AbstractForeignAnnotationsNoAnnotationInClasspathTest.kt @@ -19,11 +19,11 @@ package org.jetbrains.kotlin.checkers import org.jetbrains.kotlin.codegen.CodegenTestUtil import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.KotlinTestUtils -import org.jetbrains.kotlin.test.MockLibraryUtil import java.io.File abstract class AbstractForeignAnnotationsNoAnnotationInClasspathTest : AbstractForeignAnnotationsTest() { private val compiledJavaPath = KotlinTestUtils.tmpDir("java-compiled-files") + override fun getExtraClasspath(): List { val foreignAnnotations = createJarWithForeignAnnotations() val testAnnotations = compileTestAnnotations(foreignAnnotations) @@ -45,7 +45,4 @@ abstract class AbstractForeignAnnotationsNoAnnotationInClasspathTest : AbstractF override fun isJavaSourceRootNeeded() = false override fun skipDescriptorsValidation() = true - - private fun createJarWithForeignAnnotations(): List = - listOf(MockLibraryUtil.compileJvmLibraryToJar(annotationsPath, "foreign-annotations")) } diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/AbstractForeignAnnotationsTest.kt b/compiler/tests/org/jetbrains/kotlin/checkers/AbstractForeignAnnotationsTest.kt index 8325ae758f7..702f757c01c 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/AbstractForeignAnnotationsTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/checkers/AbstractForeignAnnotationsTest.kt @@ -16,23 +16,26 @@ package org.jetbrains.kotlin.checkers +import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.MockLibraryUtil import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.utils.Jsr305State +import org.jetbrains.kotlin.utils.ReportLevel import java.io.File val FOREIGN_ANNOTATIONS_SOURCES_PATH = "third-party/annotations" val TEST_ANNOTATIONS_SOURCE_PATH = "compiler/testData/foreignAnnotations/testAnnotations" abstract class AbstractForeignAnnotationsTest : AbstractDiagnosticsTest() { - private val WARNING_FOR_JSR305_ANNOTATIONS_DIRECTIVE = "WARNING_FOR_JSR305_ANNOTATIONS" - private val JSR305_ANNOTATIONS_IGNORE_DIRECTIVE = "JSR305_ANNOTATIONS_IGNORE" + private val JSR305_GLOBAL_DIRECTIVE = "JSR305_GLOBAL_REPORT" + private val JSR305_MIGRATION_DIRECTIVE = "JSR305_MIGRATION_REPORT" + private val JSR305_SPECIAL_DIRECTIVE = "JSR305_SPECIAL_REPORT" override fun getExtraClasspath(): List { - val foreignAnnotations = listOf(MockLibraryUtil.compileJvmLibraryToJar(annotationsPath, "foreign-annotations")) + val foreignAnnotations = createJarWithForeignAnnotations() return foreignAnnotations + compileTestAnnotations(foreignAnnotations) } @@ -40,9 +43,15 @@ abstract class AbstractForeignAnnotationsTest : AbstractDiagnosticsTest() { listOf(MockLibraryUtil.compileJvmLibraryToJar( TEST_ANNOTATIONS_SOURCE_PATH, "test-foreign-annotations", + extraOptions = listOf("-Xallow-kotlin-package"), extraClasspath = extraClassPath.map { it.path } )) + protected fun createJarWithForeignAnnotations(): List = listOf( + MockLibraryUtil.compileJvmLibraryToJar(annotationsPath, "foreign-annotations"), + ForTestCompileRuntime.jvmAnnotationsForTests() + ) + override fun getConfigurationKind(): ConfigurationKind = ConfigurationKind.ALL override fun getTestJdkKind(file: File): TestJdkKind = TestJdkKind.FULL_JDK @@ -51,22 +60,27 @@ abstract class AbstractForeignAnnotationsTest : AbstractDiagnosticsTest() { get() = FOREIGN_ANNOTATIONS_SOURCES_PATH override fun loadLanguageVersionSettings(module: List): LanguageVersionSettings { - val hasWarningDirective = module.any { - InTextDirectivesUtils.isDirectiveDefined(it.expectedText, WARNING_FOR_JSR305_ANNOTATIONS_DIRECTIVE) - } - - val hasIgnoreDirective = module.any { - InTextDirectivesUtils.isDirectiveDefined(it.expectedText, JSR305_ANNOTATIONS_IGNORE_DIRECTIVE) - } - - val jsr305State = when { - hasIgnoreDirective -> Jsr305State.IGNORE - hasWarningDirective -> Jsr305State.WARN - else -> Jsr305State.STRICT - } - - return LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE, - mapOf(AnalysisFlag.jsr305 to jsr305State) - ) + val analysisFlags = loadAnalysisFlags(module) + return LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE, analysisFlags) } + + private fun loadAnalysisFlags(module: List): Map, Any?> { + val globalState = module.getDirectiveValue(JSR305_GLOBAL_DIRECTIVE) ?: ReportLevel.STRICT + val migrationState = module.getDirectiveValue(JSR305_MIGRATION_DIRECTIVE) + + val userAnnotationsState = module.flatMap { + InTextDirectivesUtils.findListWithPrefixes(it.expectedText, JSR305_SPECIAL_DIRECTIVE) + }.mapNotNull { + val (name, stateDescription) = it.split(":").takeIf { it.size == 2 } ?: return@mapNotNull null + val state = ReportLevel.findByDescription(stateDescription) ?: return@mapNotNull null + + name to state + }.toMap() + + return mapOf(AnalysisFlag.jsr305 to Jsr305State(globalState, migrationState, userAnnotationsState)) + } + + private fun List.getDirectiveValue(directive: String): ReportLevel? = mapNotNull { + InTextDirectivesUtils.findLinesWithPrefixesRemoved(it.expectedText, directive).firstOrNull() + }.firstOrNull().let { ReportLevel.findByDescription(it) } } diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathTestGenerated.java index cdbf5328d5b..c82e3f05bb5 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathTestGenerated.java @@ -401,4 +401,76 @@ public class ForeignAnnotationsNoAnnotationInClasspathTestGenerated extends Abst } } } + + @TestMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Jsr305NullabilityWarnings extends AbstractForeignAnnotationsNoAnnotationInClasspathTest { + public void testAllFilesPresentInJsr305NullabilityWarnings() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Migration extends AbstractForeignAnnotationsNoAnnotationInClasspathTest { + public void testAllFilesPresentInMigration() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("customMigration.kt") + public void testCustomMigration() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/customMigration.kt"); + doTest(fileName); + } + + @TestMetadata("globalIgnore.kt") + public void testGlobalIgnore() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalIgnore.kt"); + doTest(fileName); + } + + @TestMetadata("globalWarningMigrationIgnore.kt") + public void testGlobalWarningMigrationIgnore() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalWarningMigrationIgnore.kt"); + doTest(fileName); + } + + @TestMetadata("migrationError.kt") + public void testMigrationError() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationError.kt"); + doTest(fileName); + } + + @TestMetadata("migrationIgnore.kt") + public void testMigrationIgnore() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationIgnore.kt"); + doTest(fileName); + } + + @TestMetadata("migrationWarning.kt") + public void testMigrationWarning() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationWarning.kt"); + doTest(fileName); + } + + @TestMetadata("overrideConflicts.kt") + public void testOverrideConflicts() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/overrideConflicts.kt"); + doTest(fileName); + } + + @TestMetadata("specialCollision.kt") + public void testSpecialCollision() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/specialCollision.kt"); + doTest(fileName); + } + + @TestMetadata("stateRefinement.kt") + public void testStateRefinement() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/stateRefinement.kt"); + doTest(fileName); + } + } + } } diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGenerated.java index a89ea48a7ac..54a9edb29b3 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGenerated.java @@ -401,4 +401,76 @@ public class ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGe } } } + + @TestMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Jsr305NullabilityWarnings extends AbstractForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTest { + public void testAllFilesPresentInJsr305NullabilityWarnings() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Migration extends AbstractForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTest { + public void testAllFilesPresentInMigration() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("customMigration.kt") + public void testCustomMigration() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/customMigration.kt"); + doTest(fileName); + } + + @TestMetadata("globalIgnore.kt") + public void testGlobalIgnore() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalIgnore.kt"); + doTest(fileName); + } + + @TestMetadata("globalWarningMigrationIgnore.kt") + public void testGlobalWarningMigrationIgnore() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalWarningMigrationIgnore.kt"); + doTest(fileName); + } + + @TestMetadata("migrationError.kt") + public void testMigrationError() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationError.kt"); + doTest(fileName); + } + + @TestMetadata("migrationIgnore.kt") + public void testMigrationIgnore() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationIgnore.kt"); + doTest(fileName); + } + + @TestMetadata("migrationWarning.kt") + public void testMigrationWarning() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationWarning.kt"); + doTest(fileName); + } + + @TestMetadata("overrideConflicts.kt") + public void testOverrideConflicts() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/overrideConflicts.kt"); + doTest(fileName); + } + + @TestMetadata("specialCollision.kt") + public void testSpecialCollision() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/specialCollision.kt"); + doTest(fileName); + } + + @TestMetadata("stateRefinement.kt") + public void testStateRefinement() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/stateRefinement.kt"); + doTest(fileName); + } + } + } } diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsTestGenerated.java index 18b2d0630b5..fec653548ec 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsTestGenerated.java @@ -401,4 +401,76 @@ public class ForeignAnnotationsTestGenerated extends AbstractForeignAnnotationsT } } } + + @TestMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Jsr305NullabilityWarnings extends AbstractForeignAnnotationsTest { + public void testAllFilesPresentInJsr305NullabilityWarnings() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Migration extends AbstractForeignAnnotationsTest { + public void testAllFilesPresentInMigration() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("customMigration.kt") + public void testCustomMigration() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/customMigration.kt"); + doTest(fileName); + } + + @TestMetadata("globalIgnore.kt") + public void testGlobalIgnore() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalIgnore.kt"); + doTest(fileName); + } + + @TestMetadata("globalWarningMigrationIgnore.kt") + public void testGlobalWarningMigrationIgnore() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalWarningMigrationIgnore.kt"); + doTest(fileName); + } + + @TestMetadata("migrationError.kt") + public void testMigrationError() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationError.kt"); + doTest(fileName); + } + + @TestMetadata("migrationIgnore.kt") + public void testMigrationIgnore() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationIgnore.kt"); + doTest(fileName); + } + + @TestMetadata("migrationWarning.kt") + public void testMigrationWarning() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationWarning.kt"); + doTest(fileName); + } + + @TestMetadata("overrideConflicts.kt") + public void testOverrideConflicts() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/overrideConflicts.kt"); + doTest(fileName); + } + + @TestMetadata("specialCollision.kt") + public void testSpecialCollision() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/specialCollision.kt"); + doTest(fileName); + } + + @TestMetadata("stateRefinement.kt") + public void testStateRefinement() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/stateRefinement.kt"); + doTest(fileName); + } + } + } } diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignAnnotationsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignAnnotationsTestGenerated.java index ad4d2e87926..9709cc1d5ee 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignAnnotationsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignAnnotationsTestGenerated.java @@ -401,4 +401,76 @@ public class JavacForeignAnnotationsTestGenerated extends AbstractJavacForeignAn } } } + + @TestMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Jsr305NullabilityWarnings extends AbstractJavacForeignAnnotationsTest { + public void testAllFilesPresentInJsr305NullabilityWarnings() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Migration extends AbstractJavacForeignAnnotationsTest { + public void testAllFilesPresentInMigration() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("customMigration.kt") + public void testCustomMigration() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/customMigration.kt"); + doTest(fileName); + } + + @TestMetadata("globalIgnore.kt") + public void testGlobalIgnore() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalIgnore.kt"); + doTest(fileName); + } + + @TestMetadata("globalWarningMigrationIgnore.kt") + public void testGlobalWarningMigrationIgnore() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/globalWarningMigrationIgnore.kt"); + doTest(fileName); + } + + @TestMetadata("migrationError.kt") + public void testMigrationError() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationError.kt"); + doTest(fileName); + } + + @TestMetadata("migrationIgnore.kt") + public void testMigrationIgnore() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationIgnore.kt"); + doTest(fileName); + } + + @TestMetadata("migrationWarning.kt") + public void testMigrationWarning() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/migrationWarning.kt"); + doTest(fileName); + } + + @TestMetadata("overrideConflicts.kt") + public void testOverrideConflicts() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/overrideConflicts.kt"); + doTest(fileName); + } + + @TestMetadata("specialCollision.kt") + public void testSpecialCollision() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/specialCollision.kt"); + doTest(fileName); + } + + @TestMetadata("stateRefinement.kt") + public void testStateRefinement() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/stateRefinement.kt"); + doTest(fileName); + } + } + } } diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/TypeQualifierAnnotationResolverTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/TypeQualifierAnnotationResolverTest.kt index 90f47166f91..96533b34b09 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/TypeQualifierAnnotationResolverTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/TypeQualifierAnnotationResolverTest.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.container.get import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.resolveClassByFqName import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver @@ -128,7 +129,7 @@ class TypeQualifierAnnotationResolverTest : KtUsefulTestCase() { private fun ClassDescriptor.findSingleTypeQualifierAnnotationOnMethod( name: String, typeQualifierResolver: AnnotationTypeQualifierResolver - ) = unsubstitutedMemberScope + ): AnnotationDescriptor = unsubstitutedMemberScope .getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_TEST) .single() .annotations.single() diff --git a/core/builtins/src/kotlin/annotation/Annotations.kt b/core/builtins/src/kotlin/annotation/Annotations.kt index e466d0d198b..d6857da1fb7 100644 --- a/core/builtins/src/kotlin/annotation/Annotations.kt +++ b/core/builtins/src/kotlin/annotation/Annotations.kt @@ -98,4 +98,4 @@ public annotation class Repeatable * documentation for the element to which the annotation is applied. */ @Target(AnnotationTarget.ANNOTATION_CLASS) -public annotation class MustBeDocumented \ No newline at end of file +public annotation class MustBeDocumented diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt index db0150fb6e9..696213f4afc 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt @@ -19,21 +19,42 @@ package org.jetbrains.kotlin.load.java import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.kotlin.load.java.lazy.NullabilityQualifierWithApplicability +import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifier +import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifierWithMigrationStatus import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.constants.ArrayValue import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass +import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgumentValue import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.utils.Jsr305State +import org.jetbrains.kotlin.utils.ReportLevel import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult +import org.jetbrains.kotlin.utils.addToStdlib.safeAs private val TYPE_QUALIFIER_NICKNAME_FQNAME = FqName("javax.annotation.meta.TypeQualifierNickname") private val TYPE_QUALIFIER_FQNAME = FqName("javax.annotation.meta.TypeQualifier") private val TYPE_QUALIFIER_DEFAULT_FQNAME = FqName("javax.annotation.meta.TypeQualifierDefault") -class AnnotationTypeQualifierResolver(storageManager: StorageManager, val jsr305State: Jsr305State) { +private val MIGRATION_ANNOTATION_FQNAME = FqName("kotlin.annotations.jvm.UnderMigration") + +private val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf( + FqName("javax.annotation.ParametersAreNullableByDefault") to + NullabilityQualifierWithApplicability( + NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE), + listOf(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER) + ), + FqName("javax.annotation.ParametersAreNonnullByDefault") to + NullabilityQualifierWithApplicability( + NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL), + listOf(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER) + ) +) + +class AnnotationTypeQualifierResolver(storageManager: StorageManager, private val jsr305State: Jsr305State) { enum class QualifierApplicabilityType { METHOD_RETURN_TYPE, VALUE_PARAMETER, FIELD, TYPE_USE } @@ -68,7 +89,7 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, val jsr305 } fun resolveTypeQualifierAnnotation(annotationDescriptor: AnnotationDescriptor): AnnotationDescriptor? { - if (jsr305State.isIgnored()) { + if (jsr305State.disabled) { return null } @@ -78,8 +99,19 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, val jsr305 return resolveTypeQualifierNickname(annotationClass) } + fun resolveQualifierBuiltInDefaultAnnotation(annotationDescriptor: AnnotationDescriptor): NullabilityQualifierWithApplicability? { + if (jsr305State.disabled) { + return null + } + + return BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS[annotationDescriptor.fqName]?.let { (qualifier, applicability) -> + val state = resolveJsr305AnnotationState(annotationDescriptor).takeIf { it != ReportLevel.IGNORE } ?: return null + return NullabilityQualifierWithApplicability(qualifier.copy(isForWarningOnly = state.isWarning), applicability) + } + } + fun resolveTypeQualifierDefaultAnnotation(annotationDescriptor: AnnotationDescriptor): TypeQualifierWithApplicability? { - if (jsr305State.isIgnored()) { + if (jsr305State.disabled) { return null } @@ -99,12 +131,34 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, val jsr305 } .fold(0) { acc: Int, applicabilityType -> acc or (1 shl applicabilityType.ordinal) } - val typeQualifier = - typeQualifierDefaultAnnotatedClass.annotations.firstNotNullResult(this::resolveTypeQualifierAnnotation) - ?: return null + val typeQualifier = typeQualifierDefaultAnnotatedClass.annotations.firstOrNull { resolveTypeQualifierAnnotation(it) != null } + ?: return null + return TypeQualifierWithApplicability(typeQualifier, elementTypesMask) } + fun resolveJsr305AnnotationState(annotationDescriptor: AnnotationDescriptor): ReportLevel { + jsr305State.user[annotationDescriptor.fqName?.asString()]?.let { return it } + + annotationDescriptor.annotationClass?.migrationAnnotationStatus()?.let { return it } + + return jsr305State.global + } + + private fun ClassDescriptor.migrationAnnotationStatus(): ReportLevel? { + val stateDescriptor = annotations.findAnnotation(MIGRATION_ANNOTATION_FQNAME)?.firstArgumentValue()?.safeAs() + ?: return null + + jsr305State.migration?.let { return jsr305State.migration } + + return when (stateDescriptor.name.asString()) { + "STRICT" -> ReportLevel.STRICT + "WARN" -> ReportLevel.WARN + "IGNORE" -> ReportLevel.IGNORE + else -> null + } + } + private fun ConstantValue<*>.mapConstantToQualifierApplicabilityTypes(): List = when (this) { is ArrayValue -> value.flatMap { it.mapConstantToQualifierApplicabilityTypes() } @@ -119,6 +173,8 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, val jsr305 ) else -> emptyList() } + + val disabled: Boolean = jsr305State.disabled } val BUILT_IN_TYPE_QUALIFIER_FQ_NAMES = setOf(JAVAX_NONNULL_ANNOTATION, JAVAX_CHECKFORNULL_ANNOTATION) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt index 4fa7f711b58..4534495c9e7 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt @@ -28,14 +28,13 @@ import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver import org.jetbrains.kotlin.load.java.sources.JavaSourceElementFactory import org.jetbrains.kotlin.load.java.structure.JavaTypeParameterListOwner import org.jetbrains.kotlin.load.java.typeEnhancement.JavaTypeQualifiers -import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifier import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifierWithMigrationStatus import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.utils.ReportLevel import java.util.* class JavaResolverComponents( @@ -116,7 +115,7 @@ fun LazyJavaResolverContext.child( fun LazyJavaResolverContext.computeNewDefaultTypeQualifiers( additionalAnnotations: Annotations ): JavaTypeQualifiersByElementType? { - if (components.annotationTypeQualifierResolver.jsr305State.isIgnored()) return defaultTypeQualifiers + if (components.annotationTypeQualifierResolver.disabled) return defaultTypeQualifiers val nullabilityQualifiersWithApplicability = additionalAnnotations.mapNotNull(this::extractDefaultNullabilityQualifier) @@ -128,10 +127,9 @@ fun LazyJavaResolverContext.computeNewDefaultTypeQualifiers( ?: QualifierByApplicabilityType(AnnotationTypeQualifierResolver.QualifierApplicabilityType::class.java) var wasUpdate = false - val isForWarning = components.annotationTypeQualifierResolver.jsr305State.isWarning() for ((nullability, applicableTo) in nullabilityQualifiersWithApplicability) { for (applicabilityType in applicableTo) { - nullabilityQualifiersByType[applicabilityType] = NullabilityQualifierWithMigrationStatus(nullability, isForWarning) + nullabilityQualifiersByType[applicabilityType] = nullability wasUpdate = true } } @@ -142,35 +140,30 @@ fun LazyJavaResolverContext.computeNewDefaultTypeQualifiers( private fun LazyJavaResolverContext.extractDefaultNullabilityQualifier( annotationDescriptor: AnnotationDescriptor ): NullabilityQualifierWithApplicability? { - BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS[annotationDescriptor.fqName]?.let { return it } + val typeQualifierResolver = components.annotationTypeQualifierResolver + typeQualifierResolver.resolveQualifierBuiltInDefaultAnnotation(annotationDescriptor)?.let { return it } val (typeQualifier, applicability) = - components.annotationTypeQualifierResolver.resolveTypeQualifierDefaultAnnotation(annotationDescriptor) + typeQualifierResolver.resolveTypeQualifierDefaultAnnotation(annotationDescriptor) ?: return null - val nullabilityQualifier = components.signatureEnhancement.extractNullability(typeQualifier)?.qualifier ?: return null + val jsr305State = typeQualifierResolver.resolveJsr305AnnotationState(typeQualifier).takeIf { it != ReportLevel.IGNORE } ?: return null + + val nullabilityQualifier = + components + .signatureEnhancement + .extractNullability(typeQualifier) + ?.copy(isForWarningOnly = jsr305State.isWarning) + ?: return null return NullabilityQualifierWithApplicability(nullabilityQualifier, applicability) } data class NullabilityQualifierWithApplicability( - val nullabilityQualifier: NullabilityQualifier, + val nullabilityQualifier: NullabilityQualifierWithMigrationStatus, val qualifierApplicabilityTypes: Collection ) -private val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf( - FqName("javax.annotation.ParametersAreNullableByDefault") to - NullabilityQualifierWithApplicability( - NullabilityQualifier.NULLABLE, - listOf(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER) - ), - FqName("javax.annotation.ParametersAreNonnullByDefault") to - NullabilityQualifierWithApplicability( - NullabilityQualifier.NOT_NULL, - listOf(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER) - ) -) - fun LazyJavaResolverContext.replaceComponents( components: JavaResolverComponents ) = LazyJavaResolverContext(components, typeParameterResolver, delegateForDefaultTypeQualifiers) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt index cca0e342fe7..d62b2dfb8c4 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt @@ -55,7 +55,7 @@ class LazyJavaPackageFragment( override val annotations = // Do not resolve package annotations if JSR-305 is disabled - if (c.components.annotationTypeQualifierResolver.jsr305State.isIgnored()) Annotations.EMPTY + if (c.components.annotationTypeQualifierResolver.disabled) Annotations.EMPTY else c.resolveAnnotations(jPackage) internal fun getSubPackageFqNames(): List = subPackages() diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt index 84c15b7b4fd..d822949db78 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt @@ -52,8 +52,8 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati private fun AnnotationDescriptor.extractNullabilityTypeFromArgument(): NullabilityQualifierWithMigrationStatus? { val enumEntryDescriptor = firstArgumentValue() - // if no argument is specified, use default value: NOT_NULL - ?: return NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL) + // if no argument is specified, use default value: NOT_NULL + ?: return NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL) if (enumEntryDescriptor !is ClassDescriptor) return null @@ -72,9 +72,10 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati annotationTypeQualifierResolver.resolveTypeQualifierAnnotation(annotationDescriptor) ?: return null - val forWarning = annotationTypeQualifierResolver.jsr305State.isWarning() + val jsr305State = annotationTypeQualifierResolver.resolveJsr305AnnotationState(annotationDescriptor) + if (jsr305State.isIgnore) return null - return extractNullabilityFromKnownAnnotations(typeQualifierAnnotation)?.copy(isForWarningOnly = forWarning) + return extractNullabilityFromKnownAnnotations(typeQualifierAnnotation)?.copy(isForWarningOnly = jsr305State.isWarning) } private fun extractNullabilityFromKnownAnnotations( @@ -119,7 +120,7 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati if (extensionReceiverParameter != null) partsForValueParameter( parameterDescriptor = - annotationOwnerForMember.safeAs() + annotationOwnerForMember.safeAs() ?.getUserData(JavaMethodDescriptor.ORIGINAL_VALUE_PARAMETER_FOR_EXTENSION_RECEIVER), methodContext = memberContext ) { it.extensionReceiverParameter!!.type }.enhance() @@ -138,10 +139,9 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati } } - val valueParameterEnhancements = annotationOwnerForMember.valueParameters.map { - p -> - partsForValueParameter(p, memberContext) { it.valueParameters[p.index].type } - .enhance(predefinedEnhancementInfo?.parametersInfo?.getOrNull(p.index)) + val valueParameterEnhancements = annotationOwnerForMember.valueParameters.map { p -> + partsForValueParameter(p, memberContext) { it.valueParameters[p.index].type } + .enhance(predefinedEnhancementInfo?.parametersInfo?.getOrNull(p.index)) } val returnTypeEnhancement = @@ -149,10 +149,10 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati typeContainer = annotationOwnerForMember, isCovariant = true, containerContext = memberContext, containerApplicabilityType = - if (this.safeAs()?.isJavaField == true) - AnnotationTypeQualifierResolver.QualifierApplicabilityType.FIELD - else - AnnotationTypeQualifierResolver.QualifierApplicabilityType.METHOD_RETURN_TYPE + if (this.safeAs()?.isJavaField == true) + AnnotationTypeQualifierResolver.QualifierApplicabilityType.FIELD + else + AnnotationTypeQualifierResolver.QualifierApplicabilityType.METHOD_RETURN_TYPE ) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo) if ((receiverTypeEnhancement?.wereChanges ?: false) @@ -176,14 +176,12 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati val qualifiers = computeIndexedQualifiersForOverride() val qualifiersWithPredefined: ((Int) -> JavaTypeQualifiers)? = predefined?.let { - { - index -> + { index -> predefined.map[index] ?: qualifiers(index) } } - return fromOverride.enhance(qualifiersWithPredefined ?: qualifiers)?.let { - enhanced -> + return fromOverride.enhance(qualifiersWithPredefined ?: qualifiers)?.let { enhanced -> PartEnhancementResult(enhanced, wereChanges = true) } ?: PartEnhancementResult(fromOverride, wereChanges = false) } @@ -219,10 +217,10 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati else annotations - fun List.ifPresent(qualifier: T) = + fun List.ifPresent(qualifier: T) = if (any { composedAnnotation.findAnnotation(it) != null }) qualifier else null - fun uniqueNotNull(x: T?, y: T?) = if (x == null || y == null || x == y) x ?: y else null + fun uniqueNotNull(x: T?, y: T?) = if (x == null || y == null || x == y) x ?: y else null val defaultTypeQualifier = if (isHeadTypeConstructor) @@ -270,8 +268,7 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati val onlyHeadTypeConstructor = isCovariant && fromOverridden.any { !KotlinTypeChecker.DEFAULT.equalTypes(it, fromOverride) } val treeSize = if (onlyHeadTypeConstructor) 1 else indexedThisType.size - val computedResult = Array(treeSize) { - index -> + val computedResult = Array(treeSize) { index -> val isHeadTypeConstructor = index == 0 assert(isHeadTypeConstructor || !onlyHeadTypeConstructor) { "Only head type constructors should be computed" } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt index 91f099bc17d..5b226d431d7 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt @@ -59,7 +59,7 @@ class RuntimeModuleData private constructor( val runtimePackagePartProvider = RuntimePackagePartProvider(classLoader) val javaResolverCache = JavaResolverCache.EMPTY val notFoundClasses = NotFoundClasses(storageManager, module) - val annotationTypeQualifierResolver = AnnotationTypeQualifierResolver(storageManager, Jsr305State.IGNORE) + val annotationTypeQualifierResolver = AnnotationTypeQualifierResolver(storageManager, Jsr305State.DISABLED) val globalJavaResolverContext = JavaResolverComponents( storageManager, ReflectJavaClassFinder(classLoader), reflectKotlinClassFinder, deserializedDescriptorResolver, ExternalAnnotationResolver.EMPTY, SignaturePropagator.DO_NOTHING, RuntimeErrorReporter, javaResolverCache, diff --git a/core/util.runtime/src/org/jetbrains/kotlin/utils/Jsr305State.kt b/core/util.runtime/src/org/jetbrains/kotlin/utils/Jsr305State.kt index 23314787efa..0f9885a2e7d 100644 --- a/core/util.runtime/src/org/jetbrains/kotlin/utils/Jsr305State.kt +++ b/core/util.runtime/src/org/jetbrains/kotlin/utils/Jsr305State.kt @@ -16,21 +16,48 @@ package org.jetbrains.kotlin.utils -enum class Jsr305State( - val description: String -) { +enum class ReportLevel(val description: String) { IGNORE("ignore"), WARN("warn"), STRICT("strict"), ; companion object { - @JvmField - val DEFAULT: Jsr305State = WARN - - fun findByDescription(description: String?) = values().firstOrNull { it.description == description } + fun findByDescription(description: String?): ReportLevel? = values().firstOrNull { it.description == description } } - fun isIgnored(): Boolean = this == IGNORE - fun isWarning(): Boolean = this == WARN + val isWarning: Boolean get() = this == ReportLevel.WARN + val isIgnore: Boolean get() = this == ReportLevel.IGNORE +} + +data class Jsr305State( + val global: ReportLevel, + val migration: ReportLevel?, + val user: Map +) { + val description: Array by lazy { + val result = mutableListOf() + result.add(global.description) + + migration?.let { result.add("under-migration:${it.description}") } + + user.forEach { + result.add("@${it.key}:${it.value.description}") + } + + result.toTypedArray() + } + + val disabled: Boolean get() = this === DISABLED + + companion object { + @JvmField + val DEFAULT: Jsr305State = Jsr305State(ReportLevel.WARN, null, emptyMap()) + + @JvmField + val DISABLED: Jsr305State = Jsr305State(ReportLevel.IGNORE, ReportLevel.IGNORE, emptyMap()) + + @JvmField + val STRICT: Jsr305State = Jsr305State(ReportLevel.STRICT, ReportLevel.STRICT, emptyMap()) + } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt index 536c625547b..8706ba0493a 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt @@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project import org.jetbrains.kotlin.analyzer.LanguageSettingsProvider import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.idea.caches.resolve.LibraryInfo import org.jetbrains.kotlin.idea.caches.resolve.ModuleSourceInfo @@ -43,11 +44,8 @@ object IDELanguageSettingsProvider : LanguageSettingsProvider { val settings = KotlinFacetSettingsProvider.getInstance(project).getSettings(module) ?: continue val compilerArguments = settings.mergedCompilerArguments as? K2JVMCompilerArguments ?: continue - val jsr305state = Jsr305State.findByDescription(compilerArguments.jsr305) - if (jsr305state != null && jsr305state != Jsr305State.DEFAULT) { - map.put(AnalysisFlag.jsr305, jsr305state) - break - } + val jsr305State = compilerArguments.parseJsr305(MessageCollector.NONE) + map.put(AnalysisFlag.jsr305, jsr305State) } return map } diff --git a/idea/tests/org/jetbrains/kotlin/idea/highlighter/Jsr305HighlightingTest.kt b/idea/tests/org/jetbrains/kotlin/idea/highlighter/Jsr305HighlightingTest.kt index ca57f15b242..64ab3ef37d6 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/highlighter/Jsr305HighlightingTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/highlighter/Jsr305HighlightingTest.kt @@ -28,6 +28,8 @@ import org.jetbrains.kotlin.idea.test.KotlinJdkAndLibraryProjectDescriptor import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.test.MockLibraryUtil import org.jetbrains.kotlin.utils.Jsr305State +import org.jetbrains.kotlin.utils.ReportLevel +import org.jetbrains.kotlin.utils.ReportLevel.Companion.findByDescription class Jsr305HighlightingTest : KotlinLightCodeInsightFixtureTestCase() { override fun getProjectDescriptor(): LightProjectDescriptor { @@ -48,7 +50,7 @@ class Jsr305HighlightingTest : KotlinLightCodeInsightFixtureTestCase() { facetSettings.apply { val jsrStateByTestName = - Jsr305State.findByDescription(getTestName(true)) ?: return@apply + ReportLevel.findByDescription(getTestName(true)) ?: return@apply compilerSettings!!.additionalArguments += " -Xjsr305=${jsrStateByTestName.description}" updateMergedArguments() diff --git a/libraries/tools/kotlin-annotations-jvm/build.gradle b/libraries/tools/kotlin-annotations-jvm/build.gradle new file mode 100644 index 00000000000..f9d929951bd --- /dev/null +++ b/libraries/tools/kotlin-annotations-jvm/build.gradle @@ -0,0 +1,36 @@ +description = 'Kotlin annotations for JVM' + +apply plugin: 'kotlin' + +configureJvm6Project(project) +configurePublishing(project) + +sourceSets { + main { + kotlin { + srcDir 'src' + } + } +} + +artifacts { + archives sourcesJar + archives javadocJar +} + +dist { + from (jar, sourcesJar) +} + +tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) { + kotlinOptions.jdkHome = JDK_16 + kotlinOptions.jvmTarget = 1.6 +} + +compileKotlin { + kotlinOptions.freeCompilerArgs = [ + "-Xallow-kotlin-package", + "-module-name", project.name + ] +} + diff --git a/libraries/tools/kotlin-annotations-jvm/src/kotlin/annotations/jvm/Annotations.kt b/libraries/tools/kotlin-annotations-jvm/src/kotlin/annotations/jvm/Annotations.kt new file mode 100644 index 00000000000..00d67daae8d --- /dev/null +++ b/libraries/tools/kotlin-annotations-jvm/src/kotlin/annotations/jvm/Annotations.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package kotlin.annotations.jvm + +/** + * Contains the list of possible migration statuses. + */ +public enum class MigrationStatus { + IGNORE, + WARN, + @Deprecated("experimental feature") + STRICT +} + +/** + * This meta-annotation is intended for user nullability annotations with JSR-305 type qualifiers. Behaviour of meta-annotated + * nullability annotations can be controlled via compilation flag. + */ +@Target(AnnotationTarget.ANNOTATION_CLASS) +public annotation class UnderMigration(val status: MigrationStatus) diff --git a/settings.gradle b/settings.gradle index 492db255b21..f91b6cd22a5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -131,6 +131,7 @@ include ":kotlin-build-common", ":examples:kotlin-jsr223-daemon-local-eval-example", ":ultimate", ":ultimate:ultimate-runner", + ":kotlin-annotations-jvm", // plugin markers: ':kotlin-gradle-plugin:plugin-marker', @@ -199,6 +200,7 @@ project(':kotlin-annotation-processing-gradle').projectDir = "$rootDir/libraries project(':kotlin-annotation-processing').projectDir = "$rootDir/plugins/kapt3" as File project(':examples:kotlin-jsr223-local-example').projectDir = "$rootDir/libraries/examples/kotlin-jsr223-local-example" as File project(':examples:kotlin-jsr223-daemon-local-eval-example').projectDir = "$rootDir/libraries/examples/kotlin-jsr223-daemon-local-eval-example" as File +project(':kotlin-annotations-jvm').projectDir = "$rootDir/libraries/tools/kotlin-annotations-jvm" as File // plugin markers: project(':kotlin-gradle-plugin:plugin-marker').projectDir = file("$rootDir/libraries/tools/kotlin-gradle-plugin/plugin-marker")