Prohibit OptionalExpectation on nested annotation classes
Because the new generation scheme based on module metadata does not support them, and we don't plan to have them in the standard library yet.
This commit is contained in:
@@ -681,6 +681,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtNamedDeclaration> ACTUAL_MISSING = DiagnosticFactory0.create(ERROR, ACTUAL_DECLARATION_NAME);
|
||||
|
||||
DiagnosticFactory0<PsiElement> OPTIONAL_EXPECTATION_NOT_ON_EXPECTED = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> NESTED_OPTIONAL_EXPECTATION = 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);
|
||||
|
||||
|
||||
+1
@@ -306,6 +306,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(ACTUAL_MISSING, "Declaration must be marked with 'actual'");
|
||||
|
||||
MAP.put(OPTIONAL_EXPECTATION_NOT_ON_EXPECTED, "'@OptionalExpectation' can only be used on an expected annotation class");
|
||||
MAP.put(NESTED_OPTIONAL_EXPECTATION, "'@OptionalExpectation' cannot be used on a nested 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");
|
||||
|
||||
|
||||
@@ -276,7 +276,7 @@ public class ModifiersChecker {
|
||||
}
|
||||
OperatorModifierChecker.INSTANCE.check(declaration, descriptor, trace, languageVersionSettings);
|
||||
PublishedApiUsageChecker.INSTANCE.check(declaration, descriptor, trace);
|
||||
OptionalExpectationTargetChecker.INSTANCE.check(declaration, descriptor, trace);
|
||||
OptionalExpectationChecker.INSTANCE.check(declaration, descriptor, trace);
|
||||
}
|
||||
|
||||
public void checkTypeParametersModifiers(@NotNull KtModifierListOwner modifierListOwner) {
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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 org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
object OptionalExpectationChecker {
|
||||
fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, trace: BindingTrace) {
|
||||
val isExpect = descriptor is MemberDescriptor && descriptor.isExpect
|
||||
if (isExpect) {
|
||||
if (DescriptorUtils.isAnnotationClass(descriptor) && descriptor.containingDeclaration !is PackageFragmentDescriptor) {
|
||||
getOptionalExpectationEntry(declaration, trace)?.let {
|
||||
trace.report(Errors.NESTED_OPTIONAL_EXPECTATION.on(it))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
getOptionalExpectationEntry(declaration, trace)?.let {
|
||||
trace.report(Errors.OPTIONAL_EXPECTATION_NOT_ON_EXPECTED.on(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getOptionalExpectationEntry(declaration: KtDeclaration, trace: BindingTrace): KtAnnotationEntry? =
|
||||
declaration.annotationEntries.find { entry ->
|
||||
val annotationDescriptor = trace.get(BindingContext.ANNOTATION, entry)
|
||||
annotationDescriptor?.fqName == ExpectedActualDeclarationChecker.OPTIONAL_EXPECTATION_FQ_NAME
|
||||
}
|
||||
}
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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 org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
|
||||
object OptionalExpectationTargetChecker {
|
||||
fun check(
|
||||
declaration: KtDeclaration,
|
||||
descriptor: DeclarationDescriptor,
|
||||
trace: BindingTrace
|
||||
) {
|
||||
if (descriptor is MemberDescriptor && descriptor.isExpect) return
|
||||
|
||||
for (entry in declaration.annotationEntries) {
|
||||
val annotationDescriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
|
||||
if (annotationDescriptor.fqName == ExpectedActualDeclarationChecker.OPTIONAL_EXPECTATION_FQ_NAME) {
|
||||
trace.report(Errors.OPTIONAL_EXPECTATION_NOT_ON_EXPECTED.on(entry))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,3 +18,10 @@ annotation class InOtherAnnotation(val a: A)
|
||||
|
||||
@InOtherAnnotation(A())
|
||||
fun useInOtherAnnotation() {}
|
||||
|
||||
|
||||
|
||||
expect class C {
|
||||
@OptionalExpectation
|
||||
annotation class Nested
|
||||
}
|
||||
|
||||
@@ -4,3 +4,7 @@ annotation class AnotherAnnotation(val a: A)
|
||||
|
||||
@AnotherAnnotation(A())
|
||||
fun useInAnotherAnnotation() {}
|
||||
|
||||
actual class C {
|
||||
actual annotation class Nested
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@ annotation class InOtherAnnotation(val a: A)
|
||||
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:19:20: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
|
||||
@InOtherAnnotation(A())
|
||||
^
|
||||
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:25:5: error: '@OptionalExpectation' cannot be used on a nested class
|
||||
@OptionalExpectation
|
||||
^
|
||||
|
||||
-- JVM --
|
||||
Exit code: COMPILATION_ERROR
|
||||
@@ -38,6 +41,9 @@ annotation class InOtherAnnotation(val a: A)
|
||||
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:19:20: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
|
||||
@InOtherAnnotation(A())
|
||||
^
|
||||
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:25:5: error: '@OptionalExpectation' cannot be used on a nested class
|
||||
@OptionalExpectation
|
||||
^
|
||||
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
|
||||
^
|
||||
|
||||
Reference in New Issue
Block a user