Add initial support for codeanalysis annotations
This commit is contained in:
committed by
Victor Petukhov
parent
165a147dd8
commit
517cc84f4d
@@ -0,0 +1,33 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// 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
|
||||
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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
+18
@@ -43,6 +43,24 @@ public class ForeignJava8AnnotationsNoAnnotationInClasspathTestGenerated extends
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/typeUseOnObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jspecify")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Jspecify extends AbstractForeignJava8AnnotationsNoAnnotationInClasspathTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInJspecify() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotationsJava8/tests/jspecify"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/simple.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jsr305")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+18
@@ -43,6 +43,24 @@ public class ForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTe
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/typeUseOnObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jspecify")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Jspecify extends AbstractForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInJspecify() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotationsJava8/tests/jspecify"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/simple.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jsr305")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Generated
+18
@@ -43,6 +43,24 @@ public class ForeignJava8AnnotationsTestGenerated extends AbstractForeignJava8An
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/typeUseOnObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jspecify")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Jspecify extends AbstractForeignJava8AnnotationsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInJspecify() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotationsJava8/tests/jspecify"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/simple.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jsr305")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+18
@@ -43,6 +43,24 @@ public class JavacForeignJava8AnnotationsTestGenerated extends AbstractJavacFore
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/typeUseOnObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jspecify")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Jspecify extends AbstractJavacForeignJava8AnnotationsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInJspecify() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotationsJava8/tests/jspecify"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/simple.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jsr305")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -18,7 +18,15 @@ package org.jetbrains.kotlin.load.java
|
||||
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
val NULLABLE_ANNOTATIONS: List<FqName> = listOf(
|
||||
val JSPECIFY_NULLABLE = FqName("jspecify.annotations.Nullable")
|
||||
val JSPECIFY_NOT_NULL = FqName("jspecify.annotations.NotNull")
|
||||
val JSPECIFY_NULLNESS_UNKNOWN = FqName("jspecify.annotations.NullnessUnknown")
|
||||
|
||||
val JSPECIFY_DEFAULT_NULLABLE = FqName("jspecify.annotations.DefaultNullable")
|
||||
val JSPECIFY_DEFAULT_NOT_NULL = FqName("jspecify.annotations.DefaultNotNull")
|
||||
val JSPECIFY_DEFAULT_NULLNESS_UNKNOWN = FqName("jspecify.annotations.DefaultNullnessUnknown")
|
||||
|
||||
val NULLABLE_ANNOTATIONS = listOf(
|
||||
JvmAnnotationNames.JETBRAINS_NULLABLE_ANNOTATION,
|
||||
FqName("androidx.annotation.Nullable"),
|
||||
FqName("android.support.annotation.Nullable"),
|
||||
@@ -31,13 +39,14 @@ val NULLABLE_ANNOTATIONS: List<FqName> = listOf(
|
||||
FqName("edu.umd.cs.findbugs.annotations.CheckForNull"),
|
||||
FqName("edu.umd.cs.findbugs.annotations.Nullable"),
|
||||
FqName("edu.umd.cs.findbugs.annotations.PossiblyNull"),
|
||||
FqName("io.reactivex.annotations.Nullable")
|
||||
FqName("io.reactivex.annotations.Nullable"),
|
||||
JSPECIFY_NULLABLE
|
||||
)
|
||||
|
||||
val JAVAX_NONNULL_ANNOTATION: FqName = FqName("javax.annotation.Nonnull")
|
||||
val JAVAX_CHECKFORNULL_ANNOTATION: FqName = FqName("javax.annotation.CheckForNull")
|
||||
val JAVAX_NONNULL_ANNOTATION = FqName("javax.annotation.Nonnull")
|
||||
val JAVAX_CHECKFORNULL_ANNOTATION = FqName("javax.annotation.CheckForNull")
|
||||
|
||||
val NOT_NULL_ANNOTATIONS: List<FqName> = listOf(
|
||||
val NOT_NULL_ANNOTATIONS = listOf(
|
||||
JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION,
|
||||
FqName("edu.umd.cs.findbugs.annotations.NonNull"),
|
||||
FqName("androidx.annotation.NonNull"),
|
||||
@@ -47,30 +56,37 @@ val NOT_NULL_ANNOTATIONS: List<FqName> = listOf(
|
||||
FqName("org.eclipse.jdt.annotation.NonNull"),
|
||||
FqName("org.checkerframework.checker.nullness.qual.NonNull"),
|
||||
FqName("lombok.NonNull"),
|
||||
FqName("io.reactivex.annotations.NonNull")
|
||||
FqName("io.reactivex.annotations.NonNull"),
|
||||
JSPECIFY_NOT_NULL
|
||||
)
|
||||
|
||||
val COMPATQUAL_NULLABLE_ANNOTATION: FqName = FqName("org.checkerframework.checker.nullness.compatqual.NullableDecl")
|
||||
val COMPATQUAL_NONNULL_ANNOTATION: FqName = FqName("org.checkerframework.checker.nullness.compatqual.NonNullDecl")
|
||||
val COMPATQUAL_NULLABLE_ANNOTATION = FqName("org.checkerframework.checker.nullness.compatqual.NullableDecl")
|
||||
val COMPATQUAL_NONNULL_ANNOTATION = FqName("org.checkerframework.checker.nullness.compatqual.NonNullDecl")
|
||||
|
||||
val ANDROIDX_RECENTLY_NULLABLE_ANNOTATION: FqName = FqName("androidx.annotation.RecentlyNullable")
|
||||
val ANDROIDX_RECENTLY_NON_NULL_ANNOTATION: FqName = FqName("androidx.annotation.RecentlyNonNull")
|
||||
val ANDROIDX_RECENTLY_NULLABLE_ANNOTATION = FqName("androidx.annotation.RecentlyNullable")
|
||||
val ANDROIDX_RECENTLY_NON_NULL_ANNOTATION = FqName("androidx.annotation.RecentlyNonNull")
|
||||
|
||||
val NULLABILITY_ANNOTATIONS: Set<FqName> = mutableSetOf<FqName>() +
|
||||
val NULLABILITY_ANNOTATIONS = mutableSetOf<FqName>() +
|
||||
NULLABLE_ANNOTATIONS +
|
||||
JAVAX_NONNULL_ANNOTATION +
|
||||
NOT_NULL_ANNOTATIONS +
|
||||
COMPATQUAL_NULLABLE_ANNOTATION +
|
||||
COMPATQUAL_NONNULL_ANNOTATION +
|
||||
ANDROIDX_RECENTLY_NULLABLE_ANNOTATION +
|
||||
ANDROIDX_RECENTLY_NON_NULL_ANNOTATION
|
||||
ANDROIDX_RECENTLY_NON_NULL_ANNOTATION +
|
||||
JSPECIFY_NULLABLE +
|
||||
JSPECIFY_NOT_NULL +
|
||||
JSPECIFY_NULLNESS_UNKNOWN +
|
||||
JSPECIFY_DEFAULT_NULLABLE +
|
||||
JSPECIFY_DEFAULT_NOT_NULL +
|
||||
JSPECIFY_DEFAULT_NULLNESS_UNKNOWN
|
||||
|
||||
val READ_ONLY_ANNOTATIONS: List<FqName> = listOf(
|
||||
val READ_ONLY_ANNOTATIONS = listOf(
|
||||
JvmAnnotationNames.JETBRAINS_READONLY_ANNOTATION,
|
||||
JvmAnnotationNames.READONLY_ANNOTATION
|
||||
)
|
||||
|
||||
val MUTABLE_ANNOTATIONS: List<FqName> = listOf(
|
||||
val MUTABLE_ANNOTATIONS = listOf(
|
||||
JvmAnnotationNames.JETBRAINS_MUTABLE_ANNOTATION,
|
||||
JvmAnnotationNames.MUTABLE_ANNOTATION
|
||||
)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package jspecify.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DefaultNotNull {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package jspecify.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DefaultNullable {
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package jspecify.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DefaultNullnessUnknown {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package jspecify.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface NotNull {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package jspecify.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Nullable {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package jspecify.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface UnknownNullness {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user