Add initial support for codeanalysis annotations

This commit is contained in:
Denis Zharkov
2019-08-06 16:11:21 +03:00
committed by Victor Petukhov
parent 165a147dd8
commit 517cc84f4d
13 changed files with 234 additions and 14 deletions
@@ -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
}
@@ -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)
@@ -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)
@@ -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)
@@ -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 {
}
@@ -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 {
}