Use KotlinJvmCheckerProvider to check @publicField
This commit is contained in:
+50
-9
@@ -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())) {
|
||||
|
||||
+2
@@ -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);
|
||||
|
||||
|
||||
@@ -114,7 +114,6 @@ public interface Errors {
|
||||
DiagnosticFactory2<PsiElement, JetModifierKeywordToken, JetModifierKeywordToken> REDUNDANT_MODIFIER = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory0<PsiElement> INAPPLICABLE_ANNOTATION = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> INAPPLICABLE_PLATFORM_NAME = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> INAPPLICABLE_PUBLIC_FIELD = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
// Annotations
|
||||
|
||||
|
||||
-1
@@ -137,7 +137,6 @@ public class DefaultErrorMessages {
|
||||
MAP.put(REPEATED_MODIFIER, "Repeated ''{0}''", TO_STRING);
|
||||
MAP.put(INAPPLICABLE_ANNOTATION, "This annotation is only applicable to top level functions");
|
||||
MAP.put(INAPPLICABLE_PLATFORM_NAME, "platformName annotation is not applicable to this declaration");
|
||||
MAP.put(INAPPLICABLE_PUBLIC_FIELD, "publicField annotation is not applicable to this declaration");
|
||||
|
||||
MAP.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING);
|
||||
MAP.put(ABSTRACT_MODIFIER_IN_TRAIT, "Modifier ''abstract'' is redundant in interface");
|
||||
|
||||
@@ -23,7 +23,12 @@ import org.jetbrains.kotlin.builtins.*
|
||||
|
||||
|
||||
public class DataClassAnnotationChecker : DeclarationChecker {
|
||||
override fun check(declaration: JetDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) {
|
||||
override fun check(
|
||||
declaration: JetDeclaration,
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext
|
||||
) {
|
||||
if (descriptor !is ClassDescriptor) return
|
||||
if (declaration !is JetClassOrObject) return
|
||||
|
||||
|
||||
@@ -20,8 +20,12 @@ import org.jetbrains.kotlin.psi.JetDeclaration
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
|
||||
public trait DeclarationChecker {
|
||||
public interface DeclarationChecker {
|
||||
|
||||
public fun check(declaration: JetDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink);
|
||||
public fun check(
|
||||
declaration: JetDeclaration,
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext);
|
||||
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.lexer.JetTokens;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue;
|
||||
|
||||
@@ -150,7 +149,6 @@ public class ModifiersChecker {
|
||||
checkVarargsModifiers(modifierListOwner, descriptor);
|
||||
}
|
||||
checkPlatformNameApplicability(descriptor);
|
||||
checkPublicFieldApplicability(descriptor);
|
||||
runDeclarationCheckers(modifierListOwner, descriptor);
|
||||
}
|
||||
|
||||
@@ -164,7 +162,6 @@ public class ModifiersChecker {
|
||||
reportIllegalModalityModifiers(modifierListOwner);
|
||||
reportIllegalVisibilityModifiers(modifierListOwner);
|
||||
checkPlatformNameApplicability(descriptor);
|
||||
checkPublicFieldApplicability(descriptor);
|
||||
runDeclarationCheckers(modifierListOwner, descriptor);
|
||||
}
|
||||
|
||||
@@ -323,24 +320,6 @@ public class ModifiersChecker {
|
||||
|
||||
}
|
||||
|
||||
private void checkPublicFieldApplicability(@NotNull DeclarationDescriptor descriptor) {
|
||||
AnnotationDescriptor annotation = AnnotationsPackage.findPublicFieldAnnotation(descriptor);
|
||||
if (annotation == null) return;
|
||||
|
||||
JetAnnotationEntry annotationEntry = trace.get(BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT, annotation);
|
||||
if (annotationEntry == null) return;
|
||||
|
||||
if (!(descriptor instanceof PropertyDescriptor)) {
|
||||
trace.report(INAPPLICABLE_PUBLIC_FIELD.on(annotationEntry));
|
||||
return;
|
||||
}
|
||||
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||
if (Boolean.FALSE.equals(trace.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor))) {
|
||||
trace.report(INAPPLICABLE_PUBLIC_FIELD.on(annotationEntry));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isRenamableDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
||||
DeclarationDescriptor containingDescriptor = descriptor.getContainingDeclaration();
|
||||
|
||||
@@ -442,7 +421,7 @@ public class ModifiersChecker {
|
||||
|
||||
private void runDeclarationCheckers(@NotNull JetDeclaration declaration, @NotNull DeclarationDescriptor descriptor) {
|
||||
for (DeclarationChecker checker : additionalCheckerProvider.getDeclarationCheckers()) {
|
||||
checker.check(declaration, descriptor, trace);
|
||||
checker.check(declaration, descriptor, trace, trace.getBindingContext());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs
|
||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||
import org.jetbrains.kotlin.psi.JetDeclaration
|
||||
import org.jetbrains.kotlin.psi.JetNamedFunction
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
@@ -35,9 +36,13 @@ private abstract class AbstractNativeAnnotationsChecker(private val requiredAnno
|
||||
|
||||
open fun additionalCheck(declaration: JetNamedFunction, descriptor: FunctionDescriptor, diagnosticHolder: DiagnosticSink) {}
|
||||
|
||||
override fun check(declaration: JetDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) {
|
||||
val annotationDescriptor = descriptor.getAnnotations().findAnnotation(requiredAnnotation.fqName)
|
||||
if (annotationDescriptor == null) return
|
||||
override fun check(
|
||||
declaration: JetDeclaration,
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext
|
||||
) {
|
||||
val annotationDescriptor = descriptor.getAnnotations().findAnnotation(requiredAnnotation.fqName) ?: return
|
||||
|
||||
if (declaration !is JetNamedFunction || descriptor !is FunctionDescriptor) {
|
||||
diagnosticHolder.report(ErrorsJs.NATIVE_ANNOTATIONS_ALLOWED_ONLY_ON_MEMBER_OR_EXTENSION_FUN.on(declaration, annotationDescriptor.getType()))
|
||||
|
||||
@@ -26,12 +26,17 @@ import org.jetbrains.kotlin.diagnostics.rendering.renderKindWithName
|
||||
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs
|
||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
class ClassDeclarationChecker : DeclarationChecker {
|
||||
override fun check(declaration: JetDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) {
|
||||
|
||||
override fun check(
|
||||
declaration: JetDeclaration,
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext
|
||||
) {
|
||||
if (declaration !is JetClassOrObject || declaration is JetObjectDeclaration || declaration is JetEnumEntry) return
|
||||
|
||||
// hack to avoid to get diagnostics when compile kotlin builtins
|
||||
|
||||
Reference in New Issue
Block a user