Use KotlinJvmCheckerProvider to check @publicField

This commit is contained in:
Yan Zhulanow
2015-07-03 21:47:46 +03:00
parent 3bcdee2a20
commit 9c8ea54946
11 changed files with 89 additions and 42 deletions
@@ -26,10 +26,8 @@ import org.jetbrains.kotlin.load.java.lazy.types.isMarkedNullable
import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeFunChecker
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.AdditionalCheckerProvider
import org.jetbrains.kotlin.resolve.DeclarationChecker
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.annotations.findPublicFieldAnnotation
import org.jetbrains.kotlin.resolve.annotations.hasInlineAnnotation
import org.jetbrains.kotlin.resolve.annotations.hasIntrinsicAnnotation
import org.jetbrains.kotlin.resolve.annotations.hasPlatformStaticAnnotation
@@ -57,7 +55,8 @@ public class KotlinJvmCheckerProvider(private val module: ModuleDescriptor) : Ad
LocalFunInlineChecker(),
ReifiedTypeParameterAnnotationChecker(),
NativeFunChecker(),
OverloadsAnnotationChecker()),
OverloadsAnnotationChecker(),
PublicFieldAnnotationChecker()),
additionalCallCheckers = listOf(NeedSyntheticChecker(), JavaAnnotationCallChecker(),
JavaAnnotationMethodCallChecker(), TraitDefaultMethodCallChecker()),
@@ -68,7 +67,11 @@ public class KotlinJvmCheckerProvider(private val module: ModuleDescriptor) : Ad
public class LocalFunInlineChecker : DeclarationChecker {
override fun check(declaration: JetDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) {
override fun check(
declaration: JetDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext) {
if (descriptor.hasInlineAnnotation() &&
declaration is JetNamedFunction &&
descriptor is FunctionDescriptor &&
@@ -80,7 +83,12 @@ public class LocalFunInlineChecker : DeclarationChecker {
public class PlatformStaticAnnotationChecker : DeclarationChecker {
override fun check(declaration: JetDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) {
override fun check(
declaration: JetDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) {
if (descriptor.hasPlatformStaticAnnotation()) {
if (declaration is JetNamedFunction || declaration is JetProperty || declaration is JetPropertyAccessor) {
checkDeclaration(declaration, descriptor, diagnosticHolder)
@@ -119,7 +127,12 @@ public class PlatformStaticAnnotationChecker : DeclarationChecker {
}
public class OverloadsAnnotationChecker: DeclarationChecker {
override fun check(declaration: JetDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) {
override fun check(
declaration: JetDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) {
if (descriptor.getAnnotations().findAnnotation(FqName("kotlin.jvm.jvmOverloads")) != null) {
checkDeclaration(declaration, descriptor, diagnosticHolder)
}
@@ -142,9 +155,37 @@ public class OverloadsAnnotationChecker: DeclarationChecker {
}
}
public class PublicFieldAnnotationChecker: DeclarationChecker {
override fun check(
declaration: JetDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) {
val annotation = descriptor.findPublicFieldAnnotation() ?: return
fun report() {
val annotationEntry = bindingContext.get(BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT, annotation) ?: return
diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_PUBLIC_FIELD.on(annotationEntry))
}
if (descriptor !is PropertyDescriptor) {
report()
}
else if (!bindingContext.get<PropertyDescriptor, Boolean>(BindingContext.BACKING_FIELD_REQUIRED, descriptor)) {
report()
}
}
}
public class ReifiedTypeParameterAnnotationChecker : DeclarationChecker {
override fun check(declaration: JetDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) {
override fun check(
declaration: JetDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) {
if (descriptor.hasIntrinsicAnnotation()) return
if (descriptor is CallableDescriptor && !descriptor.hasInlineAnnotation()) {
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
import org.jetbrains.kotlin.psi.JetDeclarationWithBody
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.annotations.hasInlineAnnotation
import org.jetbrains.kotlin.resolve.diagnostics.SuppressDiagnosticsByAnnotations
import org.jetbrains.kotlin.resolve.diagnostics.FUNCTION_NO_BODY_ERRORS
@@ -41,7 +42,12 @@ public fun DeclarationDescriptor.hasNativeAnnotation(): Boolean {
public class SuppressNoBodyErrorsForNativeDeclarations : SuppressDiagnosticsByAnnotations(FUNCTION_NO_BODY_ERRORS, NATIVE_ANNOTATION_CLASS_NAME)
public class NativeFunChecker : DeclarationChecker {
override fun check(declaration: JetDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) {
override fun check(
declaration: JetDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) {
if (!descriptor.hasNativeAnnotation()) return
if (DescriptorUtils.isTrait(descriptor.getContainingDeclaration())) {
@@ -68,6 +68,8 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
MAP.put(ErrorsJvm.TRAIT_CANT_CALL_DEFAULT_METHOD_VIA_SUPER, "Interfaces can't call Java default methods via super");
MAP.put(ErrorsJvm.WHEN_ENUM_CAN_BE_NULL_IN_JAVA, "Enum argument can be null in Java, but exhaustive when contains no null branch");
MAP.put(ErrorsJvm.INAPPLICABLE_PUBLIC_FIELD, "publicField annotation is not applicable to this declaration");
}
@NotNull
@@ -56,6 +56,8 @@ public interface ErrorsJvm {
DiagnosticFactory0<JetElement> TRAIT_CANT_CALL_DEFAULT_METHOD_VIA_SUPER = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetElement> INAPPLICABLE_PUBLIC_FIELD = DiagnosticFactory0.create(ERROR);
// TODO: make this a warning
DiagnosticFactory1<JetExpression, JetExpression> NO_REFLECTION_IN_CLASS_PATH = DiagnosticFactory1.create(ERROR);