Support compiler flag -Xcodeanalysis-annotations
This commit is contained in:
committed by
Victor Petukhov
parent
c734bac676
commit
f3a490ee16
+23
-2
@@ -23,7 +23,9 @@ import org.jetbrains.kotlin.utils.ReportLevel
|
||||
|
||||
class JavaTypeEnhancementStateParser(private val collector: MessageCollector) {
|
||||
fun parse(
|
||||
jsr305Args: Array<String>?, supportCompatqualCheckerFrameworkAnnotations: String?
|
||||
jsr305Args: Array<String>?,
|
||||
supportCompatqualCheckerFrameworkAnnotations: String?,
|
||||
codeAnalysisState: String?
|
||||
): JavaTypeEnhancementState {
|
||||
val jsr305State = parseJsr305State(jsr305Args)
|
||||
|
||||
@@ -40,15 +42,34 @@ class JavaTypeEnhancementStateParser(private val collector: MessageCollector) {
|
||||
}
|
||||
}
|
||||
|
||||
val codeAnalysisReportLevel = parseCodeAnalysisReportLevel(codeAnalysisState)
|
||||
|
||||
val state = JavaTypeEnhancementState(
|
||||
jsr305State.global ?: ReportLevel.WARN, jsr305State.migration, jsr305State.usedDefined,
|
||||
enableCompatqualCheckerFrameworkAnnotations =
|
||||
enableCompatqualCheckerFrameworkAnnotations
|
||||
?: JavaTypeEnhancementState.COMPATQUAL_CHECKER_FRAMEWORK_ANNOTATIONS_SUPPORT_DEFAULT_VALUE
|
||||
?: JavaTypeEnhancementState.COMPATQUAL_CHECKER_FRAMEWORK_ANNOTATIONS_SUPPORT_DEFAULT_VALUE,
|
||||
jspecifyReportLevel = codeAnalysisReportLevel
|
||||
)
|
||||
return if (state == JavaTypeEnhancementState.DISABLED_JSR_305) JavaTypeEnhancementState.DISABLED_JSR_305 else state
|
||||
}
|
||||
|
||||
|
||||
private fun parseCodeAnalysisReportLevel(codeAnalysisState: String?): ReportLevel {
|
||||
if (codeAnalysisState == null) return JavaTypeEnhancementState.DEFAULT_REPORT_LEVEL_FOR_CODE_ANALYSIS
|
||||
val reportLevel = ReportLevel.findByDescription(codeAnalysisState)
|
||||
|
||||
if (reportLevel == null) {
|
||||
collector.report(
|
||||
CompilerMessageSeverity.ERROR,
|
||||
"Unrecognized -Xcodeanalysis-annotations option: $codeAnalysisState. Possible values are 'disable'/'warn'/'strict'"
|
||||
)
|
||||
return JavaTypeEnhancementState.DEFAULT_REPORT_LEVEL_FOR_CODE_ANALYSIS
|
||||
}
|
||||
|
||||
return reportLevel
|
||||
}
|
||||
|
||||
private data class Jsr305State(
|
||||
val global: ReportLevel?,
|
||||
val migration: ReportLevel?,
|
||||
|
||||
+10
-1
@@ -263,6 +263,14 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
)
|
||||
var supportCompatqualCheckerFrameworkAnnotations: String? by NullableStringFreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-Xjspecify-annotations",
|
||||
valueDescription = "ignore|strict|warn",
|
||||
description = "Specify behavior for jspecify annotations.\n" +
|
||||
"Default value is 'warn'"
|
||||
)
|
||||
var jspecifyAnnotations: String? by FreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-Xno-exception-on-explicit-equals-for-boxed-null",
|
||||
description = "Do not throw NPE on explicit 'equals' call for null receiver of platform boxed primitive type"
|
||||
@@ -397,7 +405,8 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics
|
||||
result[JvmAnalysisFlags.javaTypeEnhancementState] = JavaTypeEnhancementStateParser(collector).parse(
|
||||
jsr305,
|
||||
supportCompatqualCheckerFrameworkAnnotations
|
||||
supportCompatqualCheckerFrameworkAnnotations,
|
||||
jspecifyAnnotations
|
||||
)
|
||||
result[AnalysisFlags.ignoreDataFlowInAssert] = JVMAssertionsMode.fromString(assertionsMode) != JVMAssertionsMode.LEGACY
|
||||
JvmDefaultMode.fromStringOrNull(jvmDefault)?.let {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
@codeanalysis.experimental.annotations.DefaultNotNull
|
||||
public class A {
|
||||
public void foo(String x) {}
|
||||
|
||||
@codeanalysis.experimental.annotations.Nullable
|
||||
public String bar() { return null; }
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
$TESTDATA_DIR$/jspecifyUsage.kt
|
||||
$TESTDATA_DIR$/jspecify
|
||||
$FOREIGN_ANNOTATIONS_DIR$
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
@@ -0,0 +1,7 @@
|
||||
compiler/testData/cli/jvm/codeanalysisUsage.kt:2:11: warning: type mismatch: inferred type is Nothing? but String was expected
|
||||
a.foo(null)
|
||||
^
|
||||
compiler/testData/cli/jvm/codeanalysisUsage.kt:3:5: warning: unsafe use of a nullable receiver of type String?
|
||||
a.bar().hashCode()
|
||||
^
|
||||
OK
|
||||
@@ -0,0 +1,6 @@
|
||||
-Xcodeanalysis-annotations=ignore
|
||||
$TESTDATA_DIR$/codeanalysisUsage.kt
|
||||
$TESTDATA_DIR$/codeanalysis
|
||||
$FOREIGN_ANNOTATIONS_DIR$
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
@@ -0,0 +1 @@
|
||||
OK
|
||||
@@ -0,0 +1,6 @@
|
||||
-Xcodeanalysis-annotations=strict
|
||||
$TESTDATA_DIR$/codeanalysisUsage.kt
|
||||
$TESTDATA_DIR$/codeanalysis
|
||||
$FOREIGN_ANNOTATIONS_DIR$
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
@@ -0,0 +1,4 @@
|
||||
compiler/testData/cli/jvm/jspecifyUsage.kt:2:11: error: null can not be a value of a non-null type String
|
||||
a.foo(null)
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
@@ -0,0 +1,4 @@
|
||||
fun bar(a: A) {
|
||||
a.foo(null)
|
||||
a.bar().hashCode()
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
-Xjspecify-annotations=warn
|
||||
$TESTDATA_DIR$/codeanalysisUsage.kt
|
||||
$TESTDATA_DIR$/codeanalysis
|
||||
$FOREIGN_ANNOTATIONS_DIR$
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
@@ -0,0 +1,7 @@
|
||||
compiler/testData/cli/jvm/jspecifyUsage.kt:2:11: warning: type mismatch: inferred type is Nothing? but String was expected
|
||||
a.foo(null)
|
||||
^
|
||||
compiler/testData/cli/jvm/jspecifyUsage.kt:3:5: warning: unsafe use of a nullable receiver of type String?
|
||||
a.bar().hashCode()
|
||||
^
|
||||
OK
|
||||
+3
@@ -12,6 +12,9 @@ where advanced options include:
|
||||
-Xassertions=legacy: calculate condition on each call, check depends on jvm assertion settings in the kotlin package;
|
||||
default: legacy
|
||||
-Xbuild-file=<path> Path to the .xml build file to compile
|
||||
-Xcodeanalysis-annotations=ignore|strict|warn
|
||||
Specify behavior for Codeanalysis annotations.
|
||||
Default value is 'warn'
|
||||
-Xcompile-java Reuse javac analysis and compile Java source files
|
||||
-Xnormalize-constructor-calls={disable|enable}
|
||||
Normalize constructor calls (disable: don't normalize; enable: normalize),
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// CODE_ANALYSIS_STATE ignore
|
||||
// FILE: A.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
public class A {
|
||||
@Nullable public String field = null;
|
||||
|
||||
@Nullable
|
||||
public String foo(@NotNull String x, @UnknownNullness CharSequence y) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String bar() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@DefaultNotNull
|
||||
public String everythingNotNullable(String x) { return ""; }
|
||||
|
||||
@DefaultNullable
|
||||
public String everythingNullable(String x) { return ""; }
|
||||
|
||||
@DefaultNullnessUnknown
|
||||
public String everythingUnknown(String x) { 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.everythingNotNullable(null)?.length
|
||||
a.everythingNotNullable(null).length
|
||||
a.everythingNotNullable("").length
|
||||
|
||||
a.everythingNullable(null).length
|
||||
a.everythingNullable(null)?.length
|
||||
|
||||
a.everythingUnknown(null).length
|
||||
a.everythingUnknown(null)?.length
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package
|
||||
|
||||
public fun main(/*0*/ a: A): kotlin.Unit
|
||||
|
||||
public open class A {
|
||||
public constructor A()
|
||||
@jspecify.annotations.Nullable public final var field: kotlin.String!
|
||||
@jspecify.annotations.NotNull public open fun bar(): kotlin.String!
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@jspecify.annotations.DefaultNotNull public open fun everythingNotNullable(/*0*/ x: kotlin.String!): kotlin.String!
|
||||
@jspecify.annotations.DefaultNullable public open fun everythingNullable(/*0*/ x: kotlin.String!): kotlin.String!
|
||||
@jspecify.annotations.DefaultNullnessUnknown public open fun everythingUnknown(/*0*/ x: kotlin.String!): kotlin.String!
|
||||
@jspecify.annotations.Nullable public open fun foo(/*0*/ @jspecify.annotations.NotNull x: kotlin.String!, /*1*/ @jspecify.annotations.UnknownNullness 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
+81
@@ -0,0 +1,81 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// CODE_ANALYSIS_STATE warn
|
||||
// FILE: A.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
public class A<T extends @NotNull Object, E extends @Nullable Object, F extends @UnknownNullness Object> {
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
public class B {
|
||||
public void superAsIs(A<? super CharSequence, ? super CharSequence, ? super CharSequence> a) {}
|
||||
public void superNotNull(A<? super @NotNull CharSequence, ? super @NotNull CharSequence, ? super @NotNull CharSequence> a) {}
|
||||
public void superNullable(A<? super @Nullable CharSequence, ? super @Nullable CharSequence, ? super @Nullable CharSequence> a) {}
|
||||
|
||||
public void extendsAsIs(A<? extends CharSequence, ? extends CharSequence, ? extends CharSequence> a) {}
|
||||
public void extendsNotNull(A<? extends @NotNull CharSequence, ? extends @NotNull CharSequence, ? extends @NotNull CharSequence> a) {}
|
||||
public void extendsNullable(A<? extends @Nullable CharSequence, ? extends @Nullable CharSequence, ? extends @Nullable CharSequence> a) {}
|
||||
|
||||
public void noBounds(A<?, ?, ?> a) {}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun main(
|
||||
aNotNullNotNullNotNull: A<String, String, String>,
|
||||
aNotNullNotNullNull: A<String, String, String?>,
|
||||
aNotNullNullNotNull: A<String, String?, String>,
|
||||
aNotNullNullNull: A<String, String?, String?>,
|
||||
|
||||
aAnyNotNullNotNullNotNull: A<Any, Any, Any>,
|
||||
aAnyNotNullNotNullNull: A<Any, Any, Any?>,
|
||||
aAnyNotNullNullNotNull: A<Any, Any?, Any>,
|
||||
aAnyNotNullNullNull: A<Any, Any?, Any?>,
|
||||
b: B
|
||||
) {
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b.superAsIs(aAnyNotNullNotNullNotNull)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b.superAsIs(aAnyNotNullNotNullNull)
|
||||
b.superAsIs(aAnyNotNullNullNotNull)
|
||||
b.superAsIs(aAnyNotNullNullNull)
|
||||
|
||||
b.superNotNull(aAnyNotNullNotNullNotNull)
|
||||
b.superNotNull(aAnyNotNullNotNullNull)
|
||||
b.superNotNull(aAnyNotNullNullNotNull)
|
||||
b.superNotNull(aAnyNotNullNullNull)
|
||||
|
||||
// TODO: Bound for the first argument in "superNullable" contradicts to declared nullability of the parameter
|
||||
// Do we need to ignore such arguments' nullability?
|
||||
b.superNullable(aAnyNotNullNotNullNotNull)
|
||||
b.superNullable(aAnyNotNullNotNullNull)
|
||||
b.superNullable(aAnyNotNullNullNotNull)
|
||||
b.superNullable(aAnyNotNullNullNull)
|
||||
|
||||
b.extendsAsIs(aNotNullNotNullNotNull)
|
||||
b.extendsAsIs(aNotNullNotNullNull)
|
||||
b.extendsAsIs(aNotNullNullNotNull)
|
||||
b.extendsAsIs(aNotNullNullNull)
|
||||
|
||||
b.extendsNotNull(aNotNullNotNullNotNull)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b.extendsNotNull(aNotNullNotNullNull)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b.extendsNotNull(aNotNullNullNotNull)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b.extendsNotNull(aNotNullNullNull)
|
||||
|
||||
b.extendsNullable(aNotNullNotNullNotNull)
|
||||
b.extendsNullable(aNotNullNotNullNull)
|
||||
b.extendsNullable(aNotNullNullNotNull)
|
||||
b.extendsNullable(aNotNullNullNull)
|
||||
|
||||
b.noBounds(aNotNullNotNullNotNull)
|
||||
b.noBounds(aNotNullNotNullNull)
|
||||
b.noBounds(aNotNullNullNotNull)
|
||||
b.noBounds(aNotNullNullNull)
|
||||
}
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
package
|
||||
|
||||
public fun main(/*0*/ aNotNullNotNullNotNull: A<kotlin.String, kotlin.String, kotlin.String>, /*1*/ aNotNullNotNullNull: A<kotlin.String, kotlin.String, kotlin.String?>, /*2*/ aNotNullNullNotNull: A<kotlin.String, kotlin.String?, kotlin.String>, /*3*/ aNotNullNullNull: A<kotlin.String, kotlin.String?, kotlin.String?>, /*4*/ aAnyNotNullNotNullNotNull: A<kotlin.Any, kotlin.Any, kotlin.Any>, /*5*/ aAnyNotNullNotNullNull: A<kotlin.Any, kotlin.Any, kotlin.Any?>, /*6*/ aAnyNotNullNullNotNull: A<kotlin.Any, kotlin.Any?, kotlin.Any>, /*7*/ aAnyNotNullNullNull: A<kotlin.Any, kotlin.Any?, kotlin.Any?>, /*8*/ b: B): kotlin.Unit
|
||||
|
||||
public open class A</*0*/ T : @jspecify.annotations.NotNull kotlin.Any!, /*1*/ E : @jspecify.annotations.Nullable kotlin.Any!, /*2*/ F : @jspecify.annotations.UnknownNullness kotlin.Any!> {
|
||||
public constructor A</*0*/ T : @jspecify.annotations.NotNull kotlin.Any!, /*1*/ E : @jspecify.annotations.Nullable kotlin.Any!, /*2*/ F : @jspecify.annotations.UnknownNullness kotlin.Any!>()
|
||||
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
|
||||
}
|
||||
|
||||
public open class B {
|
||||
public constructor B()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun extendsAsIs(/*0*/ a: A<out kotlin.CharSequence!, out kotlin.CharSequence!, out kotlin.CharSequence!>!): kotlin.Unit
|
||||
public open fun extendsNotNull(/*0*/ a: A<out @jspecify.annotations.NotNull kotlin.CharSequence!, out @jspecify.annotations.NotNull kotlin.CharSequence!, out @jspecify.annotations.NotNull kotlin.CharSequence!>!): kotlin.Unit
|
||||
public open fun extendsNullable(/*0*/ a: A<out @jspecify.annotations.Nullable kotlin.CharSequence!, out @jspecify.annotations.Nullable kotlin.CharSequence!, out @jspecify.annotations.Nullable kotlin.CharSequence!>!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open fun noBounds(/*0*/ a: A<*, *, *>!): kotlin.Unit
|
||||
public open fun superAsIs(/*0*/ a: A<in kotlin.CharSequence!, in kotlin.CharSequence!, in kotlin.CharSequence!>!): kotlin.Unit
|
||||
public open fun superNotNull(/*0*/ a: A<in @jspecify.annotations.NotNull kotlin.CharSequence!, in @jspecify.annotations.NotNull kotlin.CharSequence!, in @jspecify.annotations.NotNull kotlin.CharSequence!>!): kotlin.Unit
|
||||
public open fun superNullable(/*0*/ a: A<in @jspecify.annotations.Nullable kotlin.CharSequence!, in @jspecify.annotations.Nullable kotlin.CharSequence!, in @jspecify.annotations.Nullable kotlin.CharSequence!>!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// CODE_ANALYSIS_STATE warn
|
||||
// FILE: A.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
@DefaultNotNull
|
||||
public class A {
|
||||
public String defaultField = "";
|
||||
@Nullable public String field = null;
|
||||
|
||||
public String everythingNotNullable(String x) { return ""; }
|
||||
|
||||
@DefaultNullable
|
||||
public String everythingNullable(String x) { return ""; }
|
||||
|
||||
@DefaultNullnessUnknown
|
||||
public String everythingUnknown(String x) { return ""; }
|
||||
|
||||
@DefaultNullable
|
||||
public String mixed(@NotNull String x) { return ""; }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun main(a: A) {
|
||||
a.everythingNotNullable(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||
a.everythingNotNullable(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>).length
|
||||
a.everythingNotNullable("").length
|
||||
|
||||
<!RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.everythingNullable(null)<!>.length
|
||||
a.everythingNullable(null)?.length
|
||||
|
||||
a.everythingUnknown(null).length
|
||||
a.everythingUnknown(null)?.length
|
||||
|
||||
<!RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.mixed(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)<!>.length
|
||||
a.mixed(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)?.length
|
||||
a.mixed("")?.length
|
||||
|
||||
a.defaultField<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||
a.defaultField.length
|
||||
|
||||
a.field?.length
|
||||
<!RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.field<!>.length
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package
|
||||
|
||||
public fun main(/*0*/ a: A): kotlin.Unit
|
||||
|
||||
@jspecify.annotations.DefaultNotNull public open class A {
|
||||
public constructor A()
|
||||
public final var defaultField: kotlin.String!
|
||||
@jspecify.annotations.Nullable public final var field: kotlin.String!
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun everythingNotNullable(/*0*/ x: kotlin.String!): kotlin.String!
|
||||
@jspecify.annotations.DefaultNullable public open fun everythingNullable(/*0*/ x: kotlin.String!): kotlin.String!
|
||||
@jspecify.annotations.DefaultNullnessUnknown public open fun everythingUnknown(/*0*/ x: kotlin.String!): kotlin.String!
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
@jspecify.annotations.DefaultNullable public open fun mixed(/*0*/ @jspecify.annotations.NotNull x: kotlin.String!): kotlin.String!
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
Vendored
+50
@@ -0,0 +1,50 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// CODE_ANALYSIS_STATE warn
|
||||
// FILE: A.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
public class A<T extends @Nullable Object> {
|
||||
public void foo(T t) {}
|
||||
public <E extends @Nullable Object> void bar(E e) {}
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
@DefaultNullable
|
||||
public class B<T> {
|
||||
public void foo(T t) {}
|
||||
public <E> void bar(E e) {}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun main(a1: A<Any?>, a2: A<String>, b1: B<Any?>, b2: B<String>) {
|
||||
a1.foo(null)
|
||||
a1.bar<String?>(null)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
a1.bar<String>(null)
|
||||
a1.bar<String>("")
|
||||
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
a2.foo(null)
|
||||
a2.bar<String?>(null)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
a2.bar<String>(null)
|
||||
a2.bar<String>("")
|
||||
|
||||
b1.foo(null)
|
||||
b1.bar<String?>(null)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b1.bar<String>(null)
|
||||
b1.bar<String>("")
|
||||
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b2.foo(null)
|
||||
b2.bar<String?>(null)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b2.bar<String>(null)
|
||||
b2.bar<String>("")
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
package
|
||||
|
||||
public fun main(/*0*/ a1: A<kotlin.Any?>, /*1*/ a2: A<kotlin.String>, /*2*/ b1: B<kotlin.Any?>, /*3*/ b2: B<kotlin.String>): kotlin.Unit
|
||||
|
||||
public open class A</*0*/ T : @jspecify.annotations.Nullable kotlin.Any!> {
|
||||
public constructor A</*0*/ T : @jspecify.annotations.Nullable kotlin.Any!>()
|
||||
public open fun </*0*/ E : @jspecify.annotations.Nullable kotlin.Any!> bar(/*0*/ e: E!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun foo(/*0*/ t: T!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@jspecify.annotations.DefaultNullable public open class B</*0*/ T : kotlin.Any!> {
|
||||
public constructor B</*0*/ T : kotlin.Any!>()
|
||||
public open fun </*0*/ E : kotlin.Any!> bar(/*0*/ e: E!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun foo(/*0*/ t: T!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// CODE_ANALYSIS_STATE warn
|
||||
// FILE: A.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
public class A {
|
||||
@Nullable public String field = null;
|
||||
|
||||
@Nullable
|
||||
public String foo(@NotNull String x, @UnknownNullness CharSequence y) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String bar() {
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun main(a: A) {
|
||||
a.foo("", null)?.length
|
||||
<!RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.foo("", null)<!>.length
|
||||
<!RECEIVER_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
|
||||
<!RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.field<!>.length
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package
|
||||
|
||||
public fun main(/*0*/ a: A): kotlin.Unit
|
||||
|
||||
public open class A {
|
||||
public constructor A()
|
||||
@jspecify.annotations.Nullable public final var field: kotlin.String!
|
||||
@jspecify.annotations.NotNull public open fun bar(): kotlin.String!
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@jspecify.annotations.Nullable public open fun foo(/*0*/ @jspecify.annotations.NotNull x: kotlin.String!, /*1*/ @jspecify.annotations.UnknownNullness 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
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// CODE_ANALYSIS_STATE warn
|
||||
// FILE: A.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
public class A<T extends @NotNull Object, E extends @Nullable Object, F extends @UnknownNullness Object> {
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
@DefaultNullable
|
||||
public class B {
|
||||
public void bar(A<String, String, String> a) {}
|
||||
}
|
||||
|
||||
// FILE: C.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
@DefaultNotNull
|
||||
public class C {
|
||||
public void bar(A<String, String, String> a) {}
|
||||
}
|
||||
|
||||
// FILE: D.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
@DefaultUnknownNullness
|
||||
public class D {
|
||||
public void bar(A<String, String, String> a) {}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun main(
|
||||
aNotNullNotNullNotNull: A<String, String, String>,
|
||||
aNotNullNotNullNull: A<String, String, String?>,
|
||||
aNotNullNullNotNull: A<String, String?, String>,
|
||||
aNotNullNullNull: A<String, String?, String?>,
|
||||
b: B, c: C, d: D
|
||||
) {
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b.bar(aNotNullNotNullNotNull)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b.bar(aNotNullNotNullNull)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b.bar(aNotNullNullNotNull)
|
||||
b.bar(aNotNullNullNull)
|
||||
|
||||
c.bar(aNotNullNotNullNotNull)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
c.bar(aNotNullNotNullNull)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
c.bar(aNotNullNullNotNull)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
c.bar(aNotNullNullNull)
|
||||
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
d.bar(aNotNullNotNullNotNull)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
d.bar(aNotNullNotNullNull)
|
||||
d.bar(aNotNullNullNotNull)
|
||||
d.bar(aNotNullNullNull)
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package
|
||||
|
||||
public fun main(/*0*/ aNotNullNotNullNotNull: A<kotlin.String, kotlin.String, kotlin.String>, /*1*/ aNotNullNotNullNull: A<kotlin.String, kotlin.String, kotlin.String?>, /*2*/ aNotNullNullNotNull: A<kotlin.String, kotlin.String?, kotlin.String>, /*3*/ aNotNullNullNull: A<kotlin.String, kotlin.String?, kotlin.String?>, /*4*/ b: B, /*5*/ c: C, /*6*/ d: D): kotlin.Unit
|
||||
|
||||
public open class A</*0*/ T : @jspecify.annotations.NotNull kotlin.Any!, /*1*/ E : @jspecify.annotations.Nullable kotlin.Any!, /*2*/ F : @jspecify.annotations.UnknownNullness kotlin.Any!> {
|
||||
public constructor A</*0*/ T : @jspecify.annotations.NotNull kotlin.Any!, /*1*/ E : @jspecify.annotations.Nullable kotlin.Any!, /*2*/ F : @jspecify.annotations.UnknownNullness kotlin.Any!>()
|
||||
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
|
||||
}
|
||||
|
||||
@jspecify.annotations.DefaultNullable public open class B {
|
||||
public constructor B()
|
||||
public open fun bar(/*0*/ a: A<kotlin.String!, kotlin.String!, kotlin.String!>!): kotlin.Unit
|
||||
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
|
||||
}
|
||||
|
||||
@jspecify.annotations.DefaultNotNull public open class C {
|
||||
public constructor C()
|
||||
public open fun bar(/*0*/ a: A<kotlin.String!, kotlin.String!, kotlin.String!>!): kotlin.Unit
|
||||
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
|
||||
}
|
||||
|
||||
@DefaultUnknownNullness /* annotation class not found */ public open class D {
|
||||
public constructor D()
|
||||
public open fun bar(/*0*/ a: A<kotlin.String!, kotlin.String!, kotlin.String!>!): kotlin.Unit
|
||||
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
+49
@@ -0,0 +1,49 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// CODE_ANALYSIS_STATE warn
|
||||
// FILE: A.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
public class A<T extends @NotNull Object> {
|
||||
public void foo(T t) {}
|
||||
public <E extends @NotNull Object> void bar(E e) {}
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
@DefaultNotNull
|
||||
public class B<T> {
|
||||
public void foo(T t) {}
|
||||
public <E> void bar(E e) {}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
// TODO: UPPER_BOUND_VIOLATED_WARNING should be reported
|
||||
fun main(a1: A<Any?>, a2: A<String>, b1: B<Any?>, b2: B<String>) {
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
a1.foo(null)
|
||||
// TODO: UPPER_BOUND_VIOLATED_WARNING should be reported
|
||||
a1.bar<String?>(null)
|
||||
a1.bar<String>("")
|
||||
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
a2.foo(null)
|
||||
// TODO: UPPER_BOUND_VIOLATED_WARNING should be reported
|
||||
a2.bar<String?>(null)
|
||||
a2.bar<String>("")
|
||||
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b1.foo(null)
|
||||
// TODO: UPPER_BOUND_VIOLATED_WARNING should be reported
|
||||
b1.bar<String?>(null)
|
||||
b1.bar<String>("")
|
||||
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b2.foo(null)
|
||||
// TODO: UPPER_BOUND_VIOLATED_WARNING should be reported
|
||||
b2.bar<String?>(null)
|
||||
b2.bar<String>("")
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
package
|
||||
|
||||
public fun main(/*0*/ a1: A<kotlin.Any?>, /*1*/ a2: A<kotlin.String>, /*2*/ b1: B<kotlin.Any?>, /*3*/ b2: B<kotlin.String>): kotlin.Unit
|
||||
|
||||
public open class A</*0*/ T : @jspecify.annotations.NotNull kotlin.Any!> {
|
||||
public constructor A</*0*/ T : @jspecify.annotations.NotNull kotlin.Any!>()
|
||||
public open fun </*0*/ E : @jspecify.annotations.NotNull kotlin.Any!> bar(/*0*/ e: E!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun foo(/*0*/ t: T!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@jspecify.annotations.DefaultNotNull public open class B</*0*/ T : kotlin.Any!> {
|
||||
public constructor B</*0*/ T : kotlin.Any!>()
|
||||
public open fun </*0*/ E : kotlin.Any!> bar(/*0*/ e: E!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun foo(/*0*/ t: T!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// CODE_ANALYSIS_STATE warn
|
||||
// FILE: A.java
|
||||
|
||||
import codeanalysis.annotations.*;
|
||||
|
||||
public class A<T> {
|
||||
public void foo(T t) {}
|
||||
|
||||
@DefaultNotNull
|
||||
public void bar(String s, T t) {} // t should not become not nullable
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun main(a1: A<Int>, a2: A<Int?>) {
|
||||
a1.foo(null)
|
||||
a1.foo(1)
|
||||
|
||||
a2.foo(null)
|
||||
a2.foo(1)
|
||||
|
||||
a1.bar(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>, null)
|
||||
a1.bar("", null)
|
||||
a1.bar("", 1)
|
||||
|
||||
a2.bar(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>, null)
|
||||
a2.bar("", null)
|
||||
a2.bar("", 1)
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package
|
||||
|
||||
public fun main(/*0*/ a1: A<kotlin.Int>, /*1*/ a2: A<kotlin.Int?>): kotlin.Unit
|
||||
|
||||
public open class A</*0*/ T : kotlin.Any!> {
|
||||
public constructor A</*0*/ T : kotlin.Any!>()
|
||||
@codeanalysis.annotations.DefaultNotNull public open fun bar(/*0*/ s: kotlin.String!, /*1*/ t: T!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun foo(/*0*/ t: T!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
Vendored
+42
@@ -0,0 +1,42 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// CODE_ANALYSIS_STATE warn
|
||||
// FILE: A.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
public class A<T extends @NotNull Object, E extends @Nullable Object, F extends @UnknownNullness Object> {
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
|
||||
import jspecify.annotations.*;
|
||||
|
||||
public class B {
|
||||
@DefaultNotNull
|
||||
public void noBoundsNotNull(A<?, ?, ?> a) {}
|
||||
@DefaultNullable
|
||||
public void noBoundsNullable(A<?, ?, ?> a) {}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun main(
|
||||
aNotNullNotNullNotNull: A<String, String, String>,
|
||||
aNotNullNotNullNull: A<String, String, String?>,
|
||||
aNotNullNullNotNull: A<String, String?, String>,
|
||||
aNotNullNullNull: A<String, String?, String?>,
|
||||
b: B
|
||||
) {
|
||||
b.noBoundsNotNull(aNotNullNotNullNotNull)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b.noBoundsNotNull(aNotNullNotNullNull)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b.noBoundsNotNull(aNotNullNullNotNull)
|
||||
// TODO: NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS should be reported
|
||||
b.noBoundsNotNull(aNotNullNullNull)
|
||||
|
||||
b.noBoundsNullable(aNotNullNotNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNotNullNull)
|
||||
b.noBoundsNullable(aNotNullNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNullNull)
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
package
|
||||
|
||||
public fun main(/*0*/ aNotNullNotNullNotNull: A<kotlin.String, kotlin.String, kotlin.String>, /*1*/ aNotNullNotNullNull: A<kotlin.String, kotlin.String, kotlin.String?>, /*2*/ aNotNullNullNotNull: A<kotlin.String, kotlin.String?, kotlin.String>, /*3*/ aNotNullNullNull: A<kotlin.String, kotlin.String?, kotlin.String?>, /*4*/ b: B): kotlin.Unit
|
||||
|
||||
public open class A</*0*/ T : @jspecify.annotations.NotNull kotlin.Any!, /*1*/ E : @jspecify.annotations.Nullable kotlin.Any!, /*2*/ F : @jspecify.annotations.UnknownNullness kotlin.Any!> {
|
||||
public constructor A</*0*/ T : @jspecify.annotations.NotNull kotlin.Any!, /*1*/ E : @jspecify.annotations.Nullable kotlin.Any!, /*2*/ F : @jspecify.annotations.UnknownNullness kotlin.Any!>()
|
||||
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
|
||||
}
|
||||
|
||||
public open class B {
|
||||
public constructor B()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
@jspecify.annotations.DefaultNotNull public open fun noBoundsNotNull(/*0*/ a: A<*, *, *>!): kotlin.Unit
|
||||
@jspecify.annotations.DefaultNullable public open fun noBoundsNullable(/*0*/ a: A<*, *, *>!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+5
-3
@@ -18,10 +18,8 @@ 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.JavaTypeEnhancementState
|
||||
import org.jetbrains.kotlin.utils.ReportLevel
|
||||
import java.io.File
|
||||
@@ -33,6 +31,7 @@ abstract class AbstractForeignAnnotationsTest : AbstractDiagnosticsTest() {
|
||||
private val JSR305_GLOBAL_DIRECTIVE = "JSR305_GLOBAL_REPORT"
|
||||
private val JSR305_MIGRATION_DIRECTIVE = "JSR305_MIGRATION_REPORT"
|
||||
private val JSR305_SPECIAL_DIRECTIVE = "JSR305_SPECIAL_REPORT"
|
||||
private val CODE_ANALYSIS_STATE_SPECIAL_DIRECTIVE = "CODE_ANALYSIS_STATE"
|
||||
|
||||
override fun getExtraClasspath(): List<File> {
|
||||
val foreignAnnotations = createJarWithForeignAnnotations()
|
||||
@@ -78,11 +77,14 @@ abstract class AbstractForeignAnnotationsTest : AbstractDiagnosticsTest() {
|
||||
name to state
|
||||
}.toMap()
|
||||
|
||||
val codeAnalysisReportLevel = module.getDirectiveValue(CODE_ANALYSIS_STATE_SPECIAL_DIRECTIVE) ?: ReportLevel.STRICT
|
||||
|
||||
return mapOf(
|
||||
JvmAnalysisFlags.javaTypeEnhancementState to JavaTypeEnhancementState(
|
||||
globalState,
|
||||
migrationState,
|
||||
userAnnotationsState
|
||||
userAnnotationsState,
|
||||
jspecifyReportLevel = codeAnalysisReportLevel
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
+58
@@ -60,10 +60,68 @@ public class ForeignJava8AnnotationsNoAnnotationInClasspathTestGenerated extends
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/annotatedWildcards.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ignoreAnnotations.kt")
|
||||
public void testIgnoreAnnotations() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/ignoreAnnotations.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("wildcardsWithDefault.kt")
|
||||
public void testWildcardsWithDefault() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/wildcardsWithDefault.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Warnings extends AbstractForeignJava8AnnotationsNoAnnotationInClasspathTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInWarnings() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotatedWildcards.kt")
|
||||
public void testAnnotatedWildcards() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/annotatedWildcards.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaults.kt")
|
||||
public void testDefaults() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/defaults.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonPlatformTypeParameter.kt")
|
||||
public void testNonPlatformTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/nonPlatformTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeArgumentsFromParameterBounds.kt")
|
||||
public void testTypeArgumentsFromParameterBounds() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/typeArgumentsFromParameterBounds.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeParameterBounds.kt")
|
||||
public void testTypeParameterBounds() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/typeParameterBounds.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unknownNullnessTypeParameter.kt")
|
||||
public void testUnknownNullnessTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/unknownNullnessTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("wildcardsWithDefault.kt")
|
||||
public void testWildcardsWithDefault() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/wildcardsWithDefault.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jspecify")
|
||||
|
||||
+58
@@ -60,10 +60,68 @@ public class ForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTe
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/annotatedWildcards.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ignoreAnnotations.kt")
|
||||
public void testIgnoreAnnotations() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/ignoreAnnotations.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("wildcardsWithDefault.kt")
|
||||
public void testWildcardsWithDefault() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/wildcardsWithDefault.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Warnings extends AbstractForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInWarnings() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotatedWildcards.kt")
|
||||
public void testAnnotatedWildcards() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/annotatedWildcards.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaults.kt")
|
||||
public void testDefaults() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/defaults.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonPlatformTypeParameter.kt")
|
||||
public void testNonPlatformTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/nonPlatformTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeArgumentsFromParameterBounds.kt")
|
||||
public void testTypeArgumentsFromParameterBounds() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/typeArgumentsFromParameterBounds.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeParameterBounds.kt")
|
||||
public void testTypeParameterBounds() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/typeParameterBounds.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unknownNullnessTypeParameter.kt")
|
||||
public void testUnknownNullnessTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/unknownNullnessTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("wildcardsWithDefault.kt")
|
||||
public void testWildcardsWithDefault() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/wildcardsWithDefault.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jspecify")
|
||||
|
||||
Generated
+58
@@ -60,10 +60,68 @@ public class ForeignJava8AnnotationsTestGenerated extends AbstractForeignJava8An
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/annotatedWildcards.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ignoreAnnotations.kt")
|
||||
public void testIgnoreAnnotations() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/ignoreAnnotations.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("wildcardsWithDefault.kt")
|
||||
public void testWildcardsWithDefault() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/wildcardsWithDefault.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Warnings extends AbstractForeignJava8AnnotationsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInWarnings() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotatedWildcards.kt")
|
||||
public void testAnnotatedWildcards() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/annotatedWildcards.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaults.kt")
|
||||
public void testDefaults() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/defaults.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonPlatformTypeParameter.kt")
|
||||
public void testNonPlatformTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/nonPlatformTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeArgumentsFromParameterBounds.kt")
|
||||
public void testTypeArgumentsFromParameterBounds() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/typeArgumentsFromParameterBounds.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeParameterBounds.kt")
|
||||
public void testTypeParameterBounds() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/typeParameterBounds.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unknownNullnessTypeParameter.kt")
|
||||
public void testUnknownNullnessTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/unknownNullnessTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("wildcardsWithDefault.kt")
|
||||
public void testWildcardsWithDefault() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/wildcardsWithDefault.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jspecify")
|
||||
|
||||
+58
@@ -60,10 +60,68 @@ public class JavacForeignJava8AnnotationsTestGenerated extends AbstractJavacFore
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/annotatedWildcards.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ignoreAnnotations.kt")
|
||||
public void testIgnoreAnnotations() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/ignoreAnnotations.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("wildcardsWithDefault.kt")
|
||||
public void testWildcardsWithDefault() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/wildcardsWithDefault.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Warnings extends AbstractJavacForeignJava8AnnotationsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInWarnings() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotatedWildcards.kt")
|
||||
public void testAnnotatedWildcards() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/annotatedWildcards.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaults.kt")
|
||||
public void testDefaults() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/defaults.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonPlatformTypeParameter.kt")
|
||||
public void testNonPlatformTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/nonPlatformTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeArgumentsFromParameterBounds.kt")
|
||||
public void testTypeArgumentsFromParameterBounds() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/typeArgumentsFromParameterBounds.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeParameterBounds.kt")
|
||||
public void testTypeParameterBounds() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/typeParameterBounds.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unknownNullnessTypeParameter.kt")
|
||||
public void testUnknownNullnessTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/unknownNullnessTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("wildcardsWithDefault.kt")
|
||||
public void testWildcardsWithDefault() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/warnings/wildcardsWithDefault.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jspecify")
|
||||
|
||||
@@ -115,6 +115,26 @@ public class CliTestGenerated extends AbstractCliTest {
|
||||
runTest("compiler/testData/cli/jvm/classpath.args");
|
||||
}
|
||||
|
||||
@TestMetadata("codeanalysisDefault.args")
|
||||
public void testCodeanalysisDefault() throws Exception {
|
||||
runTest("compiler/testData/cli/jvm/codeanalysisDefault.args");
|
||||
}
|
||||
|
||||
@TestMetadata("codeanalysisIgnore.args")
|
||||
public void testCodeanalysisIgnore() throws Exception {
|
||||
runTest("compiler/testData/cli/jvm/codeanalysisIgnore.args");
|
||||
}
|
||||
|
||||
@TestMetadata("codeanalysisStrict.args")
|
||||
public void testCodeanalysisStrict() throws Exception {
|
||||
runTest("compiler/testData/cli/jvm/codeanalysisStrict.args");
|
||||
}
|
||||
|
||||
@TestMetadata("codeanalysisWarn.args")
|
||||
public void testCodeanalysisWarn() throws Exception {
|
||||
runTest("compiler/testData/cli/jvm/codeanalysisWarn.args");
|
||||
}
|
||||
|
||||
@TestMetadata("compatqualDefault.args")
|
||||
public void testCompatqualDefault() throws Exception {
|
||||
runTest("compiler/testData/cli/jvm/compatqualDefault.args");
|
||||
|
||||
+14
-12
@@ -31,18 +31,7 @@ val DEFAULT_JSPECIFY_APPLICABILITY = listOf(
|
||||
AnnotationQualifierApplicabilityType.TYPE_USE
|
||||
)
|
||||
|
||||
val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf(
|
||||
FqName("javax.annotation.ParametersAreNullableByDefault") to
|
||||
JavaDefaultQualifiers(
|
||||
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE),
|
||||
listOf(AnnotationQualifierApplicabilityType.VALUE_PARAMETER)
|
||||
),
|
||||
FqName("javax.annotation.ParametersAreNonnullByDefault") to
|
||||
JavaDefaultQualifiers(
|
||||
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL),
|
||||
listOf(AnnotationQualifierApplicabilityType.VALUE_PARAMETER)
|
||||
),
|
||||
|
||||
val CODE_ANALYSIS_DEFAULT_ANNOTATIONS = mapOf(
|
||||
JSPECIFY_DEFAULT_NULLABLE to JavaDefaultQualifiers(
|
||||
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE),
|
||||
DEFAULT_JSPECIFY_APPLICABILITY
|
||||
@@ -58,4 +47,17 @@ val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf(
|
||||
)
|
||||
)
|
||||
|
||||
val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf(
|
||||
FqName("javax.annotation.ParametersAreNullableByDefault") to
|
||||
JavaDefaultQualifiers(
|
||||
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE),
|
||||
listOf(AnnotationQualifierApplicabilityType.VALUE_PARAMETER)
|
||||
),
|
||||
FqName("javax.annotation.ParametersAreNonnullByDefault") to
|
||||
JavaDefaultQualifiers(
|
||||
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL),
|
||||
listOf(AnnotationQualifierApplicabilityType.VALUE_PARAMETER)
|
||||
)
|
||||
) + CODE_ANALYSIS_DEFAULT_ANNOTATIONS
|
||||
|
||||
val BUILT_IN_TYPE_QUALIFIER_FQ_NAMES = setOf(JAVAX_NONNULL_ANNOTATION, JAVAX_CHECKFORNULL_ANNOTATION)
|
||||
|
||||
+10
-4
@@ -79,18 +79,26 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, private va
|
||||
}
|
||||
|
||||
fun resolveQualifierBuiltInDefaultAnnotation(annotationDescriptor: AnnotationDescriptor): JavaDefaultQualifiers? {
|
||||
if (javaTypeEnhancementState.disabledJsr305) {
|
||||
if (javaTypeEnhancementState.disabledDefaultAnnotations) {
|
||||
return null
|
||||
}
|
||||
|
||||
return BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS[annotationDescriptor.fqName]?.let { qualifierForDefaultingAnnotation ->
|
||||
val state = resolveJsr305AnnotationState(annotationDescriptor).takeIf { it != ReportLevel.IGNORE } ?: return null
|
||||
val state = resolveDefaultAnnotationState(annotationDescriptor).takeIf { it != ReportLevel.IGNORE } ?: return null
|
||||
return qualifierForDefaultingAnnotation.copy(
|
||||
nullabilityQualifier = qualifierForDefaultingAnnotation.nullabilityQualifier.copy(isForWarningOnly = state.isWarning)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveDefaultAnnotationState(annotationDescriptor: AnnotationDescriptor): ReportLevel {
|
||||
if (annotationDescriptor.fqName in CODE_ANALYSIS_DEFAULT_ANNOTATIONS) {
|
||||
return javaTypeEnhancementState.jspecifyReportLevel
|
||||
}
|
||||
|
||||
return resolveJsr305AnnotationState(annotationDescriptor)
|
||||
}
|
||||
|
||||
fun resolveTypeQualifierDefaultAnnotation(annotationDescriptor: AnnotationDescriptor): TypeQualifierWithApplicability? {
|
||||
if (javaTypeEnhancementState.disabledJsr305) {
|
||||
return null
|
||||
@@ -156,8 +164,6 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, private va
|
||||
)
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
val disabled: Boolean = javaTypeEnhancementState.disabledJsr305
|
||||
}
|
||||
|
||||
private val ClassDescriptor.isAnnotatedWithTypeQualifier: Boolean
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.resolve.sam.SamConversionResolver
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
|
||||
import org.jetbrains.kotlin.utils.JavaTypeEnhancementState
|
||||
import java.util.*
|
||||
|
||||
class JavaResolverComponents(
|
||||
@@ -64,7 +65,8 @@ class JavaResolverComponents(
|
||||
val signatureEnhancement: SignatureEnhancement,
|
||||
val javaClassesTracker: JavaClassesTracker,
|
||||
val settings: JavaResolverSettings,
|
||||
val kotlinTypeChecker: NewKotlinTypeChecker
|
||||
val kotlinTypeChecker: NewKotlinTypeChecker,
|
||||
val javaTypeEnhancementState: JavaTypeEnhancementState
|
||||
) {
|
||||
fun replace(
|
||||
javaResolverCache: JavaResolverCache = this.javaResolverCache
|
||||
@@ -74,7 +76,8 @@ class JavaResolverComponents(
|
||||
javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory,
|
||||
moduleClassResolver, packagePartProvider, supertypeLoopChecker, lookupTracker, module, reflectionTypes,
|
||||
annotationTypeQualifierResolver, signatureEnhancement, javaClassesTracker, settings,
|
||||
kotlinTypeChecker
|
||||
kotlinTypeChecker,
|
||||
javaTypeEnhancementState
|
||||
)
|
||||
}
|
||||
|
||||
@@ -130,7 +133,7 @@ fun LazyJavaResolverContext.child(
|
||||
fun LazyJavaResolverContext.computeNewDefaultTypeQualifiers(
|
||||
additionalAnnotations: Annotations
|
||||
): JavaTypeQualifiersByElementType? {
|
||||
if (components.annotationTypeQualifierResolver.disabled) return defaultTypeQualifiers
|
||||
if (components.javaTypeEnhancementState.disabledDefaultAnnotations) return defaultTypeQualifiers
|
||||
|
||||
val defaultQualifiers =
|
||||
additionalAnnotations.mapNotNull(this::extractDefaultNullabilityQualifier)
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ class LazyJavaPackageFragment(
|
||||
|
||||
override val annotations =
|
||||
// Do not resolve package annotations if JSR-305 is disabled
|
||||
if (c.components.annotationTypeQualifierResolver.disabled) Annotations.EMPTY
|
||||
if (c.components.javaTypeEnhancementState.disabledDefaultAnnotations) Annotations.EMPTY
|
||||
else c.resolveAnnotations(jPackage)
|
||||
|
||||
internal fun getSubPackageFqNames(): List<FqName> = subPackages()
|
||||
|
||||
+11
-5
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||
import org.jetbrains.kotlin.utils.JavaTypeEnhancementState
|
||||
import org.jetbrains.kotlin.utils.ReportLevel
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -102,11 +103,16 @@ class SignatureEnhancement(
|
||||
|
||||
private fun jspecifyMigrationStatus(
|
||||
annotationFqName: FqName
|
||||
): NullabilityQualifierWithMigrationStatus? = when (annotationFqName) {
|
||||
JSPECIFY_NOT_NULL -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL)
|
||||
JSPECIFY_NULLABLE -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE)
|
||||
JSPECIFY_NULLNESS_UNKNOWN -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.FORCE_FLEXIBILITY)
|
||||
else -> null
|
||||
): NullabilityQualifierWithMigrationStatus? {
|
||||
if (javaTypeEnhancementState.jspecifyReportLevel == ReportLevel.IGNORE) return null
|
||||
val isForWarningOnly = javaTypeEnhancementState.jspecifyReportLevel == ReportLevel.WARN
|
||||
return when (annotationFqName) {
|
||||
JSPECIFY_NOT_NULL -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL, isForWarningOnly)
|
||||
JSPECIFY_NULLABLE -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE, isForWarningOnly)
|
||||
JSPECIFY_NULLNESS_UNKNOWN ->
|
||||
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.FORCE_FLEXIBILITY, isForWarningOnly)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun commonMigrationStatus(
|
||||
|
||||
+2
-1
@@ -111,6 +111,7 @@ fun makeLazyJavaPackageFragmentFromClassLoaderProvider(
|
||||
packagePartProvider: PackagePartProvider = PackagePartProvider.Empty
|
||||
): LazyJavaPackageFragmentProvider {
|
||||
val annotationTypeQualifierResolver = AnnotationTypeQualifierResolver(storageManager, JavaTypeEnhancementState.DISABLED_JSR_305)
|
||||
val javaTypeEnhancementState = JavaTypeEnhancementState.DISABLED_JSR_305
|
||||
val javaResolverComponents = JavaResolverComponents(
|
||||
storageManager, ReflectJavaClassFinder(classLoader), reflectKotlinClassFinder, deserializedDescriptorResolver,
|
||||
SignaturePropagator.DO_NOTHING, RuntimeErrorReporter, JavaResolverCache.EMPTY,
|
||||
@@ -118,7 +119,7 @@ fun makeLazyJavaPackageFragmentFromClassLoaderProvider(
|
||||
singleModuleClassResolver, packagePartProvider, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module,
|
||||
ReflectionTypes(module, notFoundClasses), annotationTypeQualifierResolver,
|
||||
SignatureEnhancement(annotationTypeQualifierResolver, JavaTypeEnhancementState.DISABLED_JSR_305, JavaTypeEnhancement(JavaResolverSettings.Default)),
|
||||
JavaClassesTracker.Default, JavaResolverSettings.Default, NewKotlinTypeChecker.Default
|
||||
JavaClassesTracker.Default, JavaResolverSettings.Default, NewKotlinTypeChecker.Default, javaTypeEnhancementState
|
||||
)
|
||||
|
||||
return LazyJavaPackageFragmentProvider(javaResolverComponents)
|
||||
|
||||
@@ -34,7 +34,8 @@ class JavaTypeEnhancementState(
|
||||
val globalJsr305Level: ReportLevel,
|
||||
val migrationLevelForJsr305: ReportLevel?,
|
||||
val userDefinedLevelForSpecificJsr305Annotation: Map<String, ReportLevel>,
|
||||
val enableCompatqualCheckerFrameworkAnnotations: Boolean = COMPATQUAL_CHECKER_FRAMEWORK_ANNOTATIONS_SUPPORT_DEFAULT_VALUE
|
||||
val enableCompatqualCheckerFrameworkAnnotations: Boolean = COMPATQUAL_CHECKER_FRAMEWORK_ANNOTATIONS_SUPPORT_DEFAULT_VALUE,
|
||||
val jspecifyReportLevel: ReportLevel = DEFAULT_REPORT_LEVEL_FOR_CODE_ANALYSIS
|
||||
) {
|
||||
val description: Array<String> by lazy {
|
||||
val result = mutableListOf<String>()
|
||||
@@ -49,11 +50,19 @@ class JavaTypeEnhancementState(
|
||||
result.toTypedArray()
|
||||
}
|
||||
|
||||
val disabledJsr305: Boolean get() = this === DISABLED_JSR_305
|
||||
val disabledJsr305: Boolean =
|
||||
globalJsr305Level == ReportLevel.IGNORE &&
|
||||
migrationLevelForJsr305 == ReportLevel.IGNORE &&
|
||||
userDefinedLevelForSpecificJsr305Annotation.isEmpty()
|
||||
|
||||
val disabledDefaultAnnotations = disabledJsr305 || jspecifyReportLevel == ReportLevel.IGNORE
|
||||
|
||||
companion object {
|
||||
const val COMPATQUAL_CHECKER_FRAMEWORK_ANNOTATIONS_SUPPORT_DEFAULT_VALUE = true
|
||||
|
||||
@JvmField
|
||||
val DEFAULT_REPORT_LEVEL_FOR_CODE_ANALYSIS = ReportLevel.WARN
|
||||
|
||||
@JvmField
|
||||
val DEFAULT: JavaTypeEnhancementState = JavaTypeEnhancementState(ReportLevel.WARN, null, emptyMap())
|
||||
|
||||
|
||||
+2
-1
@@ -79,7 +79,8 @@ object IDELanguageSettingsProvider : LanguageSettingsProvider {
|
||||
|
||||
result = JavaTypeEnhancementStateParser(MessageCollector.NONE).parse(
|
||||
compilerArguments.jsr305,
|
||||
compilerArguments.supportCompatqualCheckerFrameworkAnnotations
|
||||
compilerArguments.supportCompatqualCheckerFrameworkAnnotations,
|
||||
compilerArguments.jspecifyAnnotations
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user