Add @UnderMigration annotation and options for report level
This commit is contained in:
@@ -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 {
|
||||
|
||||
+53
-13
@@ -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}" +
|
||||
"|@<fully qualified class name>:{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<String>? 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<AnalysisFlag<*>, 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<String, ReportLevel>()
|
||||
|
||||
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<String, ReportLevel>? {
|
||||
val (name, rawState) = item.substring(1).split(":").takeIf { it.size == 2 } ?: return null
|
||||
val state = ReportLevel.findByDescription(rawState) ?: return null
|
||||
return name to state
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -9,7 +9,8 @@ where advanced options include:
|
||||
-Xmultifile-parts-inherit Compile multifile classes as a hierarchy of parts and facade
|
||||
-Xmodule-path=<path> Paths where to find Java 9+ modules
|
||||
-Xjavac-arguments=<option[,]> 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}|@<fully qualified class name>:{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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
+18
@@ -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 {
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// JSR305_ANNOTATIONS_IGNORE
|
||||
// JSR305_GLOBAL_REPORT ignore
|
||||
|
||||
// FILE: A.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !CHECK_TYPE
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// KT-6829 False warning on map to @Nullable
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: A.java
|
||||
public class A<T> {
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: MyNullable.java
|
||||
import javax.annotation.*;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: A.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: A.java
|
||||
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: NonNullApi.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: NonNullApi.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: A.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: test/package-info.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: spr/Nullable.java
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// WARNING_FOR_JSR305_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: spr/Nullable.java
|
||||
|
||||
|
||||
Vendored
+84
@@ -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_FOR_NONNULL_TYPE!>null<!>)
|
||||
|
||||
a.foo2("")
|
||||
a.foo2(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||
|
||||
a.foo3("")
|
||||
a.foo3(null)
|
||||
|
||||
a.foo4("")
|
||||
a.foo4(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||
}
|
||||
Vendored
+35
@@ -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
|
||||
}
|
||||
Vendored
+57
@@ -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)<!UNSAFE_CALL!>.<!>length
|
||||
a.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, "")<!UNSAFE_CALL!>.<!>length
|
||||
|
||||
a.bar().length
|
||||
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
a.field?.length
|
||||
a.field<!UNSAFE_CALL!>.<!>length
|
||||
|
||||
a.foo2("", null)?.length
|
||||
a.foo2("", null).length
|
||||
a.foo2(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>, "").length
|
||||
|
||||
a.bar2().length
|
||||
a.bar2()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
a.field2?.length
|
||||
a.field2.length
|
||||
}
|
||||
Vendored
+16
@@ -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
|
||||
}
|
||||
+57
@@ -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_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||
|
||||
a.bar().length
|
||||
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
a.field?.length
|
||||
a.field.length
|
||||
|
||||
a.foo2("", null)?.length
|
||||
a.foo2("", null)<!UNSAFE_CALL!>.<!>length
|
||||
a.foo2(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>, "")<!UNSAFE_CALL!>.<!>length
|
||||
|
||||
a.bar2().length
|
||||
a.bar2()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
a.field2?.length
|
||||
a.field2<!UNSAFE_CALL!>.<!>length
|
||||
}
|
||||
+16
@@ -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
|
||||
}
|
||||
Vendored
+78
@@ -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)<!UNSAFE_CALL!>.<!>length
|
||||
a.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, "")<!UNSAFE_CALL!>.<!>length
|
||||
|
||||
a.bar().length
|
||||
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
a.field?.length
|
||||
a.field<!UNSAFE_CALL!>.<!>length
|
||||
|
||||
a.foo2("", null)?.length
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.foo2("", null)<!>.length
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.foo2(null, "")<!>.length
|
||||
|
||||
a.bar2().length
|
||||
a.bar2()!!.length
|
||||
|
||||
a.field2?.length
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.field2<!>.length
|
||||
|
||||
a.field3?.length
|
||||
a.field3<!UNSAFE_CALL!>.<!>length
|
||||
}
|
||||
Vendored
+24
@@ -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
|
||||
}
|
||||
Vendored
+57
@@ -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_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||
|
||||
a.bar().length
|
||||
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
a.field?.length
|
||||
a.field.length
|
||||
|
||||
a.foo2("", null)?.length
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.foo2("", null)<!>.length
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.foo2(<!NULL_FOR_NONNULL_TYPE!>null<!>, "")<!>.length
|
||||
|
||||
a.bar2().length
|
||||
a.bar2()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
a.field2?.length
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.field2<!>.length
|
||||
}
|
||||
Vendored
+16
@@ -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
|
||||
}
|
||||
Vendored
+57
@@ -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)<!UNSAFE_CALL!>.<!>length
|
||||
a.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>, "")<!UNSAFE_CALL!>.<!>length
|
||||
|
||||
a.bar().length
|
||||
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
a.field?.length
|
||||
a.field<!UNSAFE_CALL!>.<!>length
|
||||
|
||||
a.foo2("", null)?.length
|
||||
a.foo2("", null).length
|
||||
a.foo2(<!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||
|
||||
a.bar2().length
|
||||
a.bar2()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
a.field2?.length
|
||||
a.field2.length
|
||||
}
|
||||
Vendored
+16
@@ -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
|
||||
}
|
||||
Vendored
+85
@@ -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()<!UNSAFE_CALL!>.<!>length
|
||||
b.foo()?.length
|
||||
b.foo2()<!UNSAFE_CALL!>.<!>length
|
||||
b.foo2()?.length
|
||||
b.foo3()<!UNSAFE_CALL!>.<!>length
|
||||
b.foo3()?.length
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>b.foo4()<!>.length
|
||||
b.foo4()?.length
|
||||
|
||||
b.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
b.bar("")
|
||||
b.bar2(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
b.bar2("")
|
||||
b.bar3(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
b.bar3("")
|
||||
b.bar4(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||
b.bar4("")
|
||||
|
||||
c.foo4()<!UNSAFE_CALL!>.<!>length
|
||||
c.foo4()?.length
|
||||
c.bar4(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
c.bar4("")
|
||||
}
|
||||
compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/migration/overrideConflicts.txt
Vendored
+48
@@ -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
|
||||
}
|
||||
Vendored
+37
@@ -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_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||
|
||||
a.bar().length
|
||||
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
a.field?.length
|
||||
a.field.length
|
||||
}
|
||||
Vendored
+13
@@ -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
|
||||
}
|
||||
Vendored
+57
@@ -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
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.foo("", null)<!>.length
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>, "")<!>.length
|
||||
|
||||
a.bar().length
|
||||
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
a.field?.length
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.field<!>.length
|
||||
|
||||
a.foo2("", null)?.length
|
||||
a.foo2("", null).length
|
||||
a.foo2(<!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||
|
||||
a.bar2().length
|
||||
a.bar2()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
a.field2?.length
|
||||
a.field2.length
|
||||
}
|
||||
Vendored
+16
@@ -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
|
||||
}
|
||||
+5
@@ -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
|
||||
|
||||
+1
-4
@@ -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<File> {
|
||||
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<File> =
|
||||
listOf(MockLibraryUtil.compileJvmLibraryToJar(annotationsPath, "foreign-annotations"))
|
||||
}
|
||||
|
||||
@@ -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<File> {
|
||||
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<File> = 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<TestFile>): 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<TestFile>): Map<AnalysisFlag<*>, 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<TestFile>.getDirectiveValue(directive: String): ReportLevel? = mapNotNull {
|
||||
InTextDirectivesUtils.findLinesWithPrefixesRemoved(it.expectedText, directive).firstOrNull()
|
||||
}.firstOrNull().let { ReportLevel.findByDescription(it) }
|
||||
}
|
||||
|
||||
+72
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+72
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+72
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -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()
|
||||
|
||||
@@ -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
|
||||
public annotation class MustBeDocumented
|
||||
|
||||
+62
-6
@@ -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<ClassDescriptor>()
|
||||
?: 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<QualifierApplicabilityType> =
|
||||
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)
|
||||
|
||||
@@ -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<AnnotationTypeQualifierResolver.QualifierApplicabilityType>
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
+1
-1
@@ -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<FqName> = subPackages()
|
||||
|
||||
+18
-21
@@ -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<FunctionDescriptor>()
|
||||
annotationOwnerForMember.safeAs<FunctionDescriptor>()
|
||||
?.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<PropertyDescriptor>()?.isJavaField == true)
|
||||
AnnotationTypeQualifierResolver.QualifierApplicabilityType.FIELD
|
||||
else
|
||||
AnnotationTypeQualifierResolver.QualifierApplicabilityType.METHOD_RETURN_TYPE
|
||||
if (this.safeAs<PropertyDescriptor>()?.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 <T: Any> List<FqName>.ifPresent(qualifier: T) =
|
||||
fun <T : Any> List<FqName>.ifPresent(qualifier: T) =
|
||||
if (any { composedAnnotation.findAnnotation(it) != null }) qualifier else null
|
||||
|
||||
fun <T: Any> uniqueNotNull(x: T?, y: T?) = if (x == null || y == null || x == y) x ?: y else null
|
||||
fun <T : Any> 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" }
|
||||
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
@@ -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<String, ReportLevel>
|
||||
) {
|
||||
val description: Array<String> by lazy {
|
||||
val result = mutableListOf<String>()
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
+3
-5
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user