Disallow using optional annotations outside common module sources

#KT-25196 Fixed
This commit is contained in:
Alexander Udalov
2018-07-30 18:10:20 +02:00
parent 0f003802fe
commit e56374908e
8 changed files with 27 additions and 0 deletions
@@ -633,6 +633,7 @@ public interface Errors {
DiagnosticFactory0<PsiElement> OPTIONAL_EXPECTATION_NOT_ON_EXPECTED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE = DiagnosticFactory0.create(ERROR);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -289,6 +289,7 @@ public class DefaultErrorMessages {
MAP.put(OPTIONAL_EXPECTATION_NOT_ON_EXPECTED, "'@OptionalExpectation' can only be used on an expected annotation class");
MAP.put(OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY, "Declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry");
MAP.put(OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE, "Declaration annotated with '@OptionalExpectation' can only be used in common module sources");
MAP.put(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, "Projections are not allowed on type arguments of functions and properties");
MAP.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here");
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.resolve.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
class OptionalExpectationUsageChecker : ClassifierUsageChecker {
override fun check(targetDescriptor: ClassifierDescriptor, element: PsiElement, context: ClassifierUsageCheckerContext) {
@@ -16,5 +18,10 @@ class OptionalExpectationUsageChecker : ClassifierUsageChecker {
if (!element.isUsageAsAnnotationOrImport()) {
context.trace.report(Errors.OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY.on(element))
}
val ktFile = element.containingFile as KtFile
if (ktFile.isCommonSource != true) {
context.trace.report(Errors.OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE.on(element))
}
}
}
@@ -23,6 +23,8 @@ actual annotation class A(actual val x: Int)
// MODULE: main(library)
// FILE: main.kt
@file:Suppress("OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE") // TODO: support common sources in the test infrastructure
package usage
import a.A
@@ -9,6 +9,8 @@ expect annotation class Anno(val s: String)
// FILE: jvm.kt
@file:Suppress("OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE") // TODO: support common sources in the test infrastructure
import java.lang.reflect.AnnotatedElement
@Anno("Foo")
@@ -3,6 +3,8 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
@file:Suppress("OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE") // TODO: support common sources in the test infrastructure
@OptionalExpectation
expect annotation class Anno(val s: String)
@@ -14,6 +14,9 @@ expect annotation class B(val s: String)
actual annotation class A(actual val x: Int)
// FILE: B.kt
@file:Suppress("OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE") // TODO: support common sources in the test infrastructure
import a.A
import a.B
import java.lang.reflect.Modifier
@@ -39,11 +39,20 @@ compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:19:20:
@InOtherAnnotation(A())
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/jvm.kt:1:24: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
fun useInReturnType(): A? = null
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/jvm.kt:1:24: error: declaration annotated with '@OptionalExpectation' can only be used in common module sources
fun useInReturnType(): A? = null
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/jvm.kt:3:43: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
annotation class AnotherAnnotation(val a: A)
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/jvm.kt:3:43: error: declaration annotated with '@OptionalExpectation' can only be used in common module sources
annotation class AnotherAnnotation(val a: A)
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/jvm.kt:5:20: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
@AnotherAnnotation(A())
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/jvm.kt:5:20: error: declaration annotated with '@OptionalExpectation' can only be used in common module sources
@AnotherAnnotation(A())
^