diff --git a/compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/defaults.kt b/compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/defaults.kt new file mode 100644 index 00000000000..531531700ce --- /dev/null +++ b/compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/defaults.kt @@ -0,0 +1,45 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER +// 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(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 + + a.mixed(null).length + a.mixed(null)?.length + a.mixed("")?.length + + a.defaultField?.length + a.defaultField.length + + a.field?.length + a.field.length +} diff --git a/compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/defaults.txt b/compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/defaults.txt new file mode 100644 index 00000000000..4ba717fb9de --- /dev/null +++ b/compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/defaults.txt @@ -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 +} diff --git a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/ForeignJava8AnnotationsNoAnnotationInClasspathTestGenerated.java b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/ForeignJava8AnnotationsNoAnnotationInClasspathTestGenerated.java index 2c8247ab74c..6ae8de9b296 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/ForeignJava8AnnotationsNoAnnotationInClasspathTestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/ForeignJava8AnnotationsNoAnnotationInClasspathTestGenerated.java @@ -43,6 +43,24 @@ public class ForeignJava8AnnotationsNoAnnotationInClasspathTestGenerated extends runTest("compiler/testData/foreignAnnotationsJava8/tests/typeUseOnObject.kt"); } + @TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Codeanalysis extends AbstractForeignJava8AnnotationsNoAnnotationInClasspathTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInCodeanalysis() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("defaults.kt") + public void testDefaults() throws Exception { + runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/defaults.kt"); + } + } + @TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jspecify") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/ForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTestGenerated.java b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/ForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTestGenerated.java index b6d85dbb4cb..30e8186de7d 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/ForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/ForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTestGenerated.java @@ -43,6 +43,24 @@ public class ForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTe runTest("compiler/testData/foreignAnnotationsJava8/tests/typeUseOnObject.kt"); } + @TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Codeanalysis extends AbstractForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInCodeanalysis() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("defaults.kt") + public void testDefaults() throws Exception { + runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/defaults.kt"); + } + } + @TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jspecify") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/ForeignJava8AnnotationsTestGenerated.java b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/ForeignJava8AnnotationsTestGenerated.java index 2c0a8de967c..67cf2f3dbdd 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/ForeignJava8AnnotationsTestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/ForeignJava8AnnotationsTestGenerated.java @@ -43,6 +43,24 @@ public class ForeignJava8AnnotationsTestGenerated extends AbstractForeignJava8An runTest("compiler/testData/foreignAnnotationsJava8/tests/typeUseOnObject.kt"); } + @TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Codeanalysis extends AbstractForeignJava8AnnotationsTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInCodeanalysis() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("defaults.kt") + public void testDefaults() throws Exception { + runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/defaults.kt"); + } + } + @TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jspecify") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignJava8AnnotationsTestGenerated.java b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignJava8AnnotationsTestGenerated.java index 4241e260506..d421c68e288 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignJava8AnnotationsTestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignJava8AnnotationsTestGenerated.java @@ -43,6 +43,24 @@ public class JavacForeignJava8AnnotationsTestGenerated extends AbstractJavacFore runTest("compiler/testData/foreignAnnotationsJava8/tests/typeUseOnObject.kt"); } + @TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Codeanalysis extends AbstractJavacForeignJava8AnnotationsTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInCodeanalysis() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("defaults.kt") + public void testDefaults() throws Exception { + runTest("compiler/testData/foreignAnnotationsJava8/tests/codeanalysis/defaults.kt"); + } + } + @TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/jspecify") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/AnnotationQualifiersFqNames.kt b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/AnnotationQualifiersFqNames.kt index 1afbaf04eca..a00526d2d36 100644 --- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/AnnotationQualifiersFqNames.kt +++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/AnnotationQualifiersFqNames.kt @@ -15,6 +15,12 @@ val TYPE_QUALIFIER_DEFAULT_FQNAME = FqName("javax.annotation.meta.TypeQualifierD val MIGRATION_ANNOTATION_FQNAME = FqName("kotlin.annotations.jvm.UnderMigration") +val DEFAULT_JSPECIFY_APPLICABILITY = listOf( + AnnotationQualifierApplicabilityType.FIELD, + AnnotationQualifierApplicabilityType.METHOD_RETURN_TYPE, + AnnotationQualifierApplicabilityType.VALUE_PARAMETER +) + val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf( FqName("javax.annotation.ParametersAreNullableByDefault") to NullabilityQualifierWithApplicability( @@ -25,7 +31,20 @@ val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf( NullabilityQualifierWithApplicability( NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL), listOf(AnnotationQualifierApplicabilityType.VALUE_PARAMETER) - ) + ), + + JSPECIFY_DEFAULT_NULLABLE to NullabilityQualifierWithApplicability( + NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE), + DEFAULT_JSPECIFY_APPLICABILITY + ), + JSPECIFY_DEFAULT_NOT_NULL to NullabilityQualifierWithApplicability( + NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL), + DEFAULT_JSPECIFY_APPLICABILITY + ), + JSPECIFY_DEFAULT_NULLNESS_UNKNOWN to NullabilityQualifierWithApplicability( + NullabilityQualifierWithMigrationStatus(NullabilityQualifier.FORCE_FLEXIBILITY), + DEFAULT_JSPECIFY_APPLICABILITY + ) ) val BUILT_IN_TYPE_QUALIFIER_FQ_NAMES = setOf(JAVAX_NONNULL_ANNOTATION, JAVAX_CHECKFORNULL_ANNOTATION)