Add publicField annotation

This commit is contained in:
Yan Zhulanow
2015-06-25 01:50:07 +03:00
parent 441e72abed
commit bffb24b075
6 changed files with 48 additions and 1 deletions
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorFactory;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
@@ -256,9 +257,19 @@ public class PropertyCodegen {
ClassBuilder builder = v;
boolean hasPublicFieldAnnotation = AnnotationsPackage.findPublicFieldAnnotation(propertyDescriptor) != null;
FieldOwnerContext backingFieldContext = context;
if (AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
modifiers |= ACC_STATIC | getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegate);
modifiers |= ACC_STATIC;
if (hasPublicFieldAnnotation && !isDelegate) {
modifiers |= ACC_PUBLIC;
}
else {
modifiers |= getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegate);
}
if (AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
ImplementationBodyCodegen codegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
builder = codegen.v;
@@ -266,6 +277,9 @@ public class PropertyCodegen {
v.getSerializationBindings().put(STATIC_FIELD_IN_OUTER_CLASS, propertyDescriptor);
}
}
else if (!isDelegate && hasPublicFieldAnnotation) {
modifiers |= ACC_PUBLIC;
}
else if (kind != OwnerKind.PACKAGE || isDelegate) {
modifiers |= ACC_PRIVATE;
}
@@ -114,6 +114,7 @@ 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
@@ -137,6 +137,7 @@ 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");
@@ -32,6 +32,10 @@ public fun DeclarationDescriptor.hasPlatformStaticAnnotation(): Boolean {
return getAnnotations().findAnnotation(FqName("kotlin.platform.platformStatic")) != null
}
public fun DeclarationDescriptor.findPublicFieldAnnotation(): AnnotationDescriptor? {
return getAnnotations().findAnnotation(FqName("kotlin.jvm.publicField"))
}
public fun DeclarationDescriptor.hasIntrinsicAnnotation(): Boolean {
return getAnnotations().findAnnotation(FqName("kotlin.jvm.internal.Intrinsic")) != null
}
@@ -32,6 +32,7 @@ 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;
@@ -149,6 +150,7 @@ public class ModifiersChecker {
checkVarargsModifiers(modifierListOwner, descriptor);
}
checkPlatformNameApplicability(descriptor);
checkPublicFieldApplicability(descriptor);
runDeclarationCheckers(modifierListOwner, descriptor);
}
@@ -162,6 +164,7 @@ public class ModifiersChecker {
reportIllegalModalityModifiers(modifierListOwner);
reportIllegalVisibilityModifiers(modifierListOwner);
checkPlatformNameApplicability(descriptor);
checkPublicFieldApplicability(descriptor);
runDeclarationCheckers(modifierListOwner, descriptor);
}
@@ -320,6 +323,24 @@ 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();
@@ -27,3 +27,9 @@ import java.lang.annotation.RetentionPolicy
*/
Retention(RetentionPolicy.CLASS)
public annotation class jvmOverloads
/**
* Instructs the Kotlin compiler to generate a public backing field for this property.
*/
Retention(RetentionPolicy.SOURCE)
public annotation class publicField