FIR: load type qualifiers from module, package, and parent classes

This commit is contained in:
pyos
2021-08-19 17:54:40 +02:00
committed by teamcityserver
parent 24210aacc8
commit 090b90f62e
49 changed files with 121 additions and 673 deletions
@@ -1,25 +0,0 @@
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
// FILE: sandbox/module-info.java
import org.jspecify.nullness.NullMarked;
@NullMarked
module sandbox {
requires java9_annotations;
exports test;
}
// FILE: sandbox/test/Test.java
package test;
public class Test {
public void foo(Integer x) {}
}
// FILE: main.kt
import test.Test
fun main(x: Test) {
x.foo(null)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
@@ -1,31 +0,0 @@
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
// FILE: sandbox/module-info.java
import org.jspecify.nullness.NullMarked;
@NullMarked
module sandbox {
requires java9_annotations;
exports test;
}
// FILE: sandbox/test/package-info.java
@NullMarked
package test;
import org.jspecify.nullness.NullMarked;
// FILE: sandbox/test/Test.java
package test;
public class Test {
public void foo(Integer x) {}
}
// FILE: main.kt
import test.Test
fun main(x: Test) {
x.foo(null)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
@@ -1,30 +0,0 @@
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
// MODULE: module1
// FILE: module1/module-info.java
module module1 {
}
// MODULE: module2(module1)
// FILE: module2/module-info.java
import org.jspecify.nullness.NullMarked;
@NullMarked
module module2 {
requires java9_annotations;
requires module1;
exports test2;
}
// FILE: module2/test2/Test.java
package test2;
public class Test {
public void foo(Integer x) {}
}
// FILE: main.kt
fun main(y: test2.Test) {
y.foo(null)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
@@ -1,25 +0,0 @@
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
// FILE: my.sand.box/module-info.java
import org.jspecify.nullness.NullMarked;
@NullMarked
open module my.sand.box {
requires java9_annotations;
exports my.test;
}
// FILE: my.sand.box/my/test/Test.java
package my.test;
public class Test {
public void foo(Integer x) {}
}
// FILE: main.kt
import my.test.Test
fun main(x: Test) {
x.foo(null)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
@@ -1,45 +0,0 @@
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
// MODULE: module1
// FILE: module1/module-info.java
import org.jspecify.nullness.NullMarked;
@NullMarked
module module1 {
requires java9_annotations;
exports test1;
}
// FILE: module1/test1/Test1.java
package test1;
public class Test1 {
public void foo(Integer x) {}
}
// MODULE: module2(module1)
// FILE: module2/module-info.java
module module2 {
requires module1;
exports test2;
}
// FILE: module2/test2/Test2.java
package test2;
import test1.Test1;
public class Test2 extends Test1 {
public void foo2(Integer x) {}
}
// FILE: main.kt
import test1.Test1
import test2.Test2
fun main(x: Test1, y: Test2) {
x.foo(null)
y.foo(null)
y.foo2(null)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
@@ -1,43 +0,0 @@
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
// FILE: sandbox/module-info.java
import org.jspecify.nullness.NullMarked;
@NullMarked
module sandbox {
requires java9_annotations;
exports test;
}
// FILE: sandbox/test/Test.java
package test;
public class Test {
public static class Test2 {
public Integer foo(Integer x) { return 1; }
public static class Test4 {
public Integer foo(Integer x) { return 1; }
}
public class Test5 {
public Integer foo(Integer x) { return 1; }
}
}
public class Test3 {
public Integer foo(Integer x) { return 1; }
public class Test5 {
public Integer foo(Integer x) { return 1; }
}
}
}
// FILE: main.kt
import test.Test
fun main(x: Test) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int..kotlin.Int?!")!>x.Test3().foo(null)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int..kotlin.Int?!")!>x.Test3().Test5().foo(null)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int..kotlin.Int?!")!>Test.Test2().foo(null)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int..kotlin.Int?!")!>Test.Test2().Test5().foo(null)<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
@@ -1,39 +0,0 @@
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
// MODULE: module1
// FILE: module1/module-info.java
import org.jspecify.nullness.NullMarked;
@NullMarked
module module1 {
requires java9_annotations;
exports test1;
}
// FILE: module1/test1/Test.java
package test1;
public class Test {
public void foo(Integer x) {}
}
// MODULE: module2(module1)
// FILE: module2/module-info.java
module module2 {
requires module1;
exports test2;
}
// FILE: module2/test2/Test.java
package test2;
public class Test {
public void foo(Integer x) {}
}
// FILE: main.kt
fun main(x: test1.Test, y: test2.Test) {
x.foo(null)
y.foo(null)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// ALLOW_KOTLIN_PACKAGE
// JSPECIFY_STATE: strict
@@ -21,5 +21,5 @@ public class Test {
import test.Test
fun main(x: Test) {
x.foo(null)
x.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
}
@@ -27,5 +27,5 @@ public class Test {
import test.Test
fun main(x: Test) {
x.foo(null)
x.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
}
@@ -26,5 +26,5 @@ public class Test {
// FILE: main.kt
fun main(y: test2.Test) {
y.foo(null)
y.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
}
@@ -21,5 +21,5 @@ public class Test {
import my.test.Test
fun main(x: Test) {
x.foo(null)
x.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
}
@@ -39,7 +39,7 @@ import test1.Test1
import test2.Test2
fun main(x: Test1, y: Test2) {
x.foo(null)
y.foo(null)
x.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
y.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
y.foo2(null)
}
@@ -35,9 +35,9 @@ public class Test {
import test.Test
fun main(x: Test) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int..kotlin.Int?!")!>x.Test3().foo(null)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int..kotlin.Int?!")!>x.Test3().Test5().foo(null)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>x.Test3().foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>x.Test3().Test5().foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int..kotlin.Int?!")!>Test.Test2().foo(null)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int..kotlin.Int?!")!>Test.Test2().Test5().foo(null)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>Test.Test2().foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>Test.Test2().Test5().foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)<!>
}
@@ -34,6 +34,6 @@ public class Test {
// FILE: main.kt
fun main(x: test1.Test, y: test2.Test) {
x.foo(null)
x.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
y.foo(null)
}
@@ -162,15 +162,15 @@ fun main(a: A, b: A.B, c: A.C) {
b.baz()!!.get(0)?.get(0)
// c
c.foo("", null)?.length
c.foo("", null)<!UNNECESSARY_SAFE_CALL!>?.<!>length
c.foo("", null).length
c.foo(null, "").length
c.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
c.foobar(null, "")<!UNSAFE_CALL!>.<!>length
c.foobar("", null)?.length
c.bar().length
c.bar()!!.length
c.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
c.field?.length
c.field<!UNSAFE_CALL!>.<!>length
@@ -48,7 +48,7 @@ import test2.A2
fun main(a: A, a2: A2) {
a.foo("", "", null)?.length
a.foo("", "", null).length
a.foo(null, <!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
a.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, <!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
a.bar().length
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
@@ -68,12 +68,12 @@ public class A {
// FILE: main.kt
fun main(a: test.A) {
a.foo("", null)?.length
a.foo("", null)<!UNNECESSARY_SAFE_CALL!>?.<!>length
a.foo("", null).length
a.foo(null, "").length
a.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
a.bar().length
a.bar()!!.length
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
a.field?.length
a.field.length
@@ -1,181 +0,0 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
// JSR305_GLOBAL_REPORT: strict
// FILE: NonNullApi.java
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Nonnull
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
public @interface NonNullApi {
}
// FILE: NullableApi.java
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.annotation.CheckForNull;
import javax.annotation.meta.TypeQualifierDefault;
@Retention(RetentionPolicy.RUNTIME)
@Documented
@CheckForNull
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
public @interface NullableApi {
}
// FILE: FieldsAreNullable.java
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.annotation.Nonnull;
import javax.annotation.CheckForNull;
import javax.annotation.meta.TypeQualifierDefault;
@Retention(RetentionPolicy.RUNTIME)
@Documented
@CheckForNull
@TypeQualifierDefault({ElementType.FIELD})
public @interface FieldsAreNullable {
}
// FILE: A.java
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.Nonnull;
@NonNullApi
public class A {
public String field = null;
public String foo(String x, @CheckForNull CharSequence y) {
return "";
}
@NullableApi
public String foobar(String x, @NonNullApi CharSequence y) {
return "";
}
public String bar() {
return "";
}
@Nullable
public java.util.List<String> baz() {
return null;
}
@NullableApi
public class B {
public String field = null;
public String foo(String x, @Nonnull CharSequence y) {
return "";
}
@NonNullApi
public String foobar(String x, @NullableApi CharSequence y) {
return "";
}
public String bar() {
return "";
}
@Nullable
public java.util.List<String> baz() {
return null;
}
}
@FieldsAreNullable
public class C {
public String field = null;
public String foo(String x, @Nullable CharSequence y) {
return "";
}
@NullableApi
public String foobar(String x, @Nullable CharSequence y) {
return "";
}
public String bar() {
return "";
}
@Nullable
public java.util.List<String> baz() {
return null;
}
}
}
// FILE: main.kt
fun main(a: A, b: A.B, c: A.C) {
a.foo("", null)<!UNNECESSARY_SAFE_CALL!>?.<!>length
a.foo("", null).length
a.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
a.foobar(null, "")<!UNSAFE_CALL!>.<!>length
a.foobar("", <!NULL_FOR_NONNULL_TYPE!>null<!>)?.length
a.bar().length
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
a.field<!UNNECESSARY_SAFE_CALL!>?.<!>length
a.field.length
a.baz()<!UNSAFE_CALL!>.<!>get(0)
a.baz()!!.get(0).get(0)
a.baz()!!.get(0)?.get(0)
// b
b.foo("", <!NULL_FOR_NONNULL_TYPE!>null<!>)?.length
b.foo("", <!NULL_FOR_NONNULL_TYPE!>null<!>)<!UNSAFE_CALL!>.<!>length
b.foo(null, "")<!UNSAFE_CALL!>.<!>length
b.foobar(<!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
b.foobar("", null)<!UNNECESSARY_SAFE_CALL!>?.<!>length
b.bar()<!UNSAFE_CALL!>.<!>length
b.bar()!!.length
b.field?.length
b.field<!UNSAFE_CALL!>.<!>length
b.baz()<!UNSAFE_CALL!>.<!>get(0)
b.baz()!!.get(0).get(0)
b.baz()!!.get(0)?.get(0)
// c
c.foo("", null)?.length
c.foo("", null).length
c.foo(null, "").length
c.foobar(null, "")<!UNSAFE_CALL!>.<!>length
c.foobar("", null)?.length
c.bar().length
c.bar()!!.length
c.field?.length
c.field<!UNSAFE_CALL!>.<!>length
c.baz()<!UNSAFE_CALL!>.<!>get(0)
c.baz()!!.get(0).get(0)
c.baz()!!.get(0)?.get(0)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
// JSR305_GLOBAL_REPORT: strict
@@ -1,70 +0,0 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
// JSR305_GLOBAL_REPORT: strict
// RENDER_PACKAGE: test, test2
// FILE: test/package-info.java
@javax.annotation.ParametersAreNonnullByDefault()
package test;
// FILE: test/A.java
package test;
import javax.annotation.*;
public class A {
@Nullable public String field = null;
public String foo(String q, @Nonnull String x, @CheckForNull CharSequence y) {
return "";
}
@Nonnull
public String bar() {
return "";
}
}
// FILE: test2/A2.java
package test2;
import javax.annotation.*;
public class A2 {
@Nullable public String field = null;
public String foo(String q, @Nonnull String x, @CheckForNull CharSequence y) {
return "";
}
@Nonnull
public String bar() {
return "";
}
}
// FILE: main.kt
import test.A
import test2.A2
fun main(a: A, a2: A2) {
a.foo("", "", null)?.length
a.foo("", "", null).length
a.foo(null, <!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
a.bar().length
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
a.field?.length
a.field<!UNSAFE_CALL!>.<!>length
a2.foo("", "", null)?.length
a2.foo("", "", null).length
a2.foo(null, <!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
a2.bar().length
a2.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
a2.field?.length
a2.field<!UNSAFE_CALL!>.<!>length
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
// JSR305_GLOBAL_REPORT: strict
@@ -1,85 +0,0 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
// JSR305_GLOBAL_REPORT: strict
// RENDER_PACKAGE: test
// FILE: spr/Nullable.java
package spr;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierNickname;
import javax.annotation.meta.When;
@Target({ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Nonnull(when = When.MAYBE)
@TypeQualifierNickname
public @interface Nullable {
}
// FILE: spr/NonNullApi.java
package spr;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;
@Target(ElementType.PACKAGE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Nonnull
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER})
public @interface NonNullApi {
}
// FILE: test/package-info.java
@spr.NonNullApi()
package test;
// FILE: test/A.java
package test;
import spr.*;
public class A {
public String field = null;
public String foo(String x, @Nullable CharSequence y) {
return "";
}
public String bar() {
return "";
}
@Nullable
public java.util.List<String> baz() {
return null;
}
}
// FILE: main.kt
fun main(a: test.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.baz()<!UNSAFE_CALL!>.<!>get(0)
a.baz()!!.get(0).get(0)
a.baz()!!.get(0)?.get(0)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
// JSR305_GLOBAL_REPORT: strict
// RENDER_PACKAGE: test