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");
|
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")
|
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jsr305")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+18
@@ -43,6 +43,24 @@ public class ForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTe
|
|||||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/typeUseOnObject.kt");
|
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")
|
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jsr305")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Generated
+18
@@ -43,6 +43,24 @@ public class ForeignJava8AnnotationsTestGenerated extends AbstractForeignJava8An
|
|||||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/typeUseOnObject.kt");
|
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")
|
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jsr305")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+18
@@ -43,6 +43,24 @@ public class JavacForeignJava8AnnotationsTestGenerated extends AbstractJavacFore
|
|||||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/typeUseOnObject.kt");
|
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")
|
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jsr305")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
@@ -18,7 +18,15 @@ package org.jetbrains.kotlin.load.java
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
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,
|
JvmAnnotationNames.JETBRAINS_NULLABLE_ANNOTATION,
|
||||||
FqName("androidx.annotation.Nullable"),
|
FqName("androidx.annotation.Nullable"),
|
||||||
FqName("android.support.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.CheckForNull"),
|
||||||
FqName("edu.umd.cs.findbugs.annotations.Nullable"),
|
FqName("edu.umd.cs.findbugs.annotations.Nullable"),
|
||||||
FqName("edu.umd.cs.findbugs.annotations.PossiblyNull"),
|
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_NONNULL_ANNOTATION = FqName("javax.annotation.Nonnull")
|
||||||
val JAVAX_CHECKFORNULL_ANNOTATION: FqName = FqName("javax.annotation.CheckForNull")
|
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,
|
JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION,
|
||||||
FqName("edu.umd.cs.findbugs.annotations.NonNull"),
|
FqName("edu.umd.cs.findbugs.annotations.NonNull"),
|
||||||
FqName("androidx.annotation.NonNull"),
|
FqName("androidx.annotation.NonNull"),
|
||||||
@@ -47,30 +56,37 @@ val NOT_NULL_ANNOTATIONS: List<FqName> = listOf(
|
|||||||
FqName("org.eclipse.jdt.annotation.NonNull"),
|
FqName("org.eclipse.jdt.annotation.NonNull"),
|
||||||
FqName("org.checkerframework.checker.nullness.qual.NonNull"),
|
FqName("org.checkerframework.checker.nullness.qual.NonNull"),
|
||||||
FqName("lombok.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_NULLABLE_ANNOTATION = FqName("org.checkerframework.checker.nullness.compatqual.NullableDecl")
|
||||||
val COMPATQUAL_NONNULL_ANNOTATION: FqName = FqName("org.checkerframework.checker.nullness.compatqual.NonNullDecl")
|
val COMPATQUAL_NONNULL_ANNOTATION = FqName("org.checkerframework.checker.nullness.compatqual.NonNullDecl")
|
||||||
|
|
||||||
val ANDROIDX_RECENTLY_NULLABLE_ANNOTATION: FqName = FqName("androidx.annotation.RecentlyNullable")
|
val ANDROIDX_RECENTLY_NULLABLE_ANNOTATION = FqName("androidx.annotation.RecentlyNullable")
|
||||||
val ANDROIDX_RECENTLY_NON_NULL_ANNOTATION: FqName = FqName("androidx.annotation.RecentlyNonNull")
|
val ANDROIDX_RECENTLY_NON_NULL_ANNOTATION = FqName("androidx.annotation.RecentlyNonNull")
|
||||||
|
|
||||||
val NULLABILITY_ANNOTATIONS: Set<FqName> = mutableSetOf<FqName>() +
|
val NULLABILITY_ANNOTATIONS = mutableSetOf<FqName>() +
|
||||||
NULLABLE_ANNOTATIONS +
|
NULLABLE_ANNOTATIONS +
|
||||||
JAVAX_NONNULL_ANNOTATION +
|
JAVAX_NONNULL_ANNOTATION +
|
||||||
NOT_NULL_ANNOTATIONS +
|
NOT_NULL_ANNOTATIONS +
|
||||||
COMPATQUAL_NULLABLE_ANNOTATION +
|
COMPATQUAL_NULLABLE_ANNOTATION +
|
||||||
COMPATQUAL_NONNULL_ANNOTATION +
|
COMPATQUAL_NONNULL_ANNOTATION +
|
||||||
ANDROIDX_RECENTLY_NULLABLE_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.JETBRAINS_READONLY_ANNOTATION,
|
||||||
JvmAnnotationNames.READONLY_ANNOTATION
|
JvmAnnotationNames.READONLY_ANNOTATION
|
||||||
)
|
)
|
||||||
|
|
||||||
val MUTABLE_ANNOTATIONS: List<FqName> = listOf(
|
val MUTABLE_ANNOTATIONS = listOf(
|
||||||
JvmAnnotationNames.JETBRAINS_MUTABLE_ANNOTATION,
|
JvmAnnotationNames.JETBRAINS_MUTABLE_ANNOTATION,
|
||||||
JvmAnnotationNames.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