delegate use-site targeted annotations: parser, front-end, codegen with some tests #KT-10502 Fixed
This commit is contained in:
@@ -130,16 +130,18 @@ public class PropertyCodegen {
|
||||
|
||||
private void genBackingFieldAndAnnotations(@NotNull KtNamedDeclaration declaration, @NotNull PropertyDescriptor descriptor, boolean isParameter) {
|
||||
boolean hasBackingField = hasBackingField(declaration, descriptor);
|
||||
boolean hasDelegate = declaration instanceof KtProperty && ((KtProperty) declaration).hasDelegate();
|
||||
|
||||
AnnotationSplitter annotationSplitter =
|
||||
AnnotationSplitter.create(LockBasedStorageManager.NO_LOCKS,
|
||||
descriptor.getAnnotations(),
|
||||
AnnotationSplitter.getTargetSet(isParameter, descriptor.isVar(), hasBackingField));
|
||||
AnnotationSplitter.getTargetSet(isParameter, descriptor.isVar(), hasBackingField, hasDelegate));
|
||||
|
||||
Annotations fieldAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.FIELD);
|
||||
Annotations delegateAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD);
|
||||
Annotations propertyAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY);
|
||||
|
||||
generateBackingField(declaration, descriptor, fieldAnnotations);
|
||||
generateBackingField(declaration, descriptor, fieldAnnotations, delegateAnnotations);
|
||||
generateSyntheticMethodIfNeeded(descriptor, propertyAnnotations);
|
||||
}
|
||||
|
||||
@@ -228,17 +230,18 @@ public class PropertyCodegen {
|
||||
private boolean generateBackingField(
|
||||
@NotNull KtNamedDeclaration p,
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@NotNull Annotations annotations
|
||||
@NotNull Annotations backingFieldAnnotations,
|
||||
@NotNull Annotations delegateAnnotations
|
||||
) {
|
||||
if (isJvmInterface(descriptor.getContainingDeclaration()) || kind == OwnerKind.DEFAULT_IMPLS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p instanceof KtProperty && ((KtProperty) p).hasDelegate()) {
|
||||
generatePropertyDelegateAccess((KtProperty) p, descriptor, annotations);
|
||||
generatePropertyDelegateAccess((KtProperty) p, descriptor, delegateAnnotations);
|
||||
}
|
||||
else if (Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor))) {
|
||||
generateBackingFieldAccess(p, descriptor, annotations);
|
||||
generateBackingFieldAccess(p, descriptor, backingFieldAnnotations);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
@@ -327,7 +330,8 @@ public class PropertyCodegen {
|
||||
typeMapper.mapFieldSignature(jetType, propertyDescriptor), defaultValue);
|
||||
|
||||
Annotated fieldAnnotated = new AnnotatedWithFakeAnnotations(propertyDescriptor, annotations);
|
||||
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(fieldAnnotated, type, AnnotationUseSiteTarget.FIELD);
|
||||
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(
|
||||
fieldAnnotated, type, isDelegate ? AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD : AnnotationUseSiteTarget.FIELD);
|
||||
}
|
||||
|
||||
private void generatePropertyDelegateAccess(KtProperty p, PropertyDescriptor propertyDescriptor, Annotations annotations) {
|
||||
|
||||
+15
-11
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.storage.getValue
|
||||
@@ -54,22 +56,24 @@ class AnnotationSplitter(
|
||||
}
|
||||
|
||||
@JvmStatic fun getTargetSet(parameter: Boolean, context: BindingContext, wrapper: PropertyWrapper): Set<AnnotationUseSiteTarget> {
|
||||
val property = wrapper.property
|
||||
assert(property != null)
|
||||
val hasBackingField = context[BindingContext.BACKING_FIELD_REQUIRED, property] ?: false
|
||||
return getTargetSet(parameter, property!!.isVar, hasBackingField)
|
||||
val descriptor = wrapper.descriptor
|
||||
assert(descriptor != null)
|
||||
val hasBackingField = context[BindingContext.BACKING_FIELD_REQUIRED, descriptor] ?: false
|
||||
val hasDelegate = wrapper.declaration is KtProperty && wrapper.declaration.hasDelegate()
|
||||
return getTargetSet(parameter, descriptor!!.isVar, hasBackingField, hasDelegate)
|
||||
}
|
||||
|
||||
@JvmStatic fun getTargetSet(parameter: Boolean, isVar: Boolean, hasBackingField: Boolean): Set<AnnotationUseSiteTarget> {
|
||||
return hashSetOf(PROPERTY, PROPERTY_GETTER).apply {
|
||||
if (parameter) add(CONSTRUCTOR_PARAMETER)
|
||||
if (hasBackingField) add(FIELD)
|
||||
if (isVar) add(PROPERTY_SETTER)
|
||||
}
|
||||
@JvmStatic fun getTargetSet(
|
||||
parameter: Boolean, isVar: Boolean, hasBackingField: Boolean, hasDelegate: Boolean
|
||||
): Set<AnnotationUseSiteTarget> = hashSetOf(PROPERTY, PROPERTY_GETTER).apply {
|
||||
if (parameter) add(CONSTRUCTOR_PARAMETER)
|
||||
if (hasBackingField) add(FIELD)
|
||||
if (isVar) add(PROPERTY_SETTER)
|
||||
if (hasDelegate) add(PROPERTY_DELEGATE_FIELD)
|
||||
}
|
||||
}
|
||||
|
||||
class PropertyWrapper(var property: PropertyDescriptor? = null)
|
||||
class PropertyWrapper @JvmOverloads constructor(val declaration: KtDeclaration, var descriptor: PropertyDescriptor? = null)
|
||||
|
||||
private val splitAnnotations = storageManager.createLazyValue {
|
||||
val map = hashMapOf<AnnotationUseSiteTarget, MutableList<AnnotationWithTarget>>()
|
||||
|
||||
@@ -167,7 +167,9 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtExpression> NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, String> INAPPLICABLE_TARGET_ON_PROPERTY = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> INAPPLICABLE_TARGET_PROPERTY_HAS_NO_BACKING_FIELD = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> INAPPLICABLE_RECEIVER_TARGET = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> INAPPLICABLE_PARAM_TARGET = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> REDUNDANT_ANNOTATION_TARGET = DiagnosticFactory1.create(WARNING);
|
||||
|
||||
+4
-2
@@ -157,8 +157,10 @@ public class DefaultErrorMessages {
|
||||
MAP.put(REPEATED_ANNOTATION, "This annotation is not repeatable");
|
||||
MAP.put(NON_SOURCE_ANNOTATION_ON_INLINED_LAMBDA_EXPRESSION, "The lambda expression here is an inlined argument so this annotation cannot be stored anywhere");
|
||||
|
||||
MAP.put(INAPPLICABLE_TARGET_ON_PROPERTY, "''@{0}'' annotations could be applied only to property declarations", TO_STRING);
|
||||
MAP.put(INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE, "Property must be mutable");
|
||||
MAP.put(INAPPLICABLE_TARGET_ON_PROPERTY, "''@{0}:'' annotations could be applied only to property declarations", TO_STRING);
|
||||
MAP.put(INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE, "''@{0}:'' annotations could be applied only to mutable properties", TO_STRING);
|
||||
MAP.put(INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE, "''@delegate:'' annotations could be applied only to delegated properties");
|
||||
MAP.put(INAPPLICABLE_TARGET_PROPERTY_HAS_NO_BACKING_FIELD, "''@field:'' annotations could be applied only to properties with backing fields");
|
||||
MAP.put(INAPPLICABLE_RECEIVER_TARGET, "''@receiver:'' annotations could be applied only to extension function or extension property declarations");
|
||||
MAP.put(INAPPLICABLE_PARAM_TARGET, "''@param:'' annotations could be applied only to primary constructor parameters");
|
||||
MAP.put(REDUNDANT_ANNOTATION_TARGET, "Redundant annotation target ''{0}''", STRING);
|
||||
|
||||
@@ -142,6 +142,7 @@ public interface KtTokens {
|
||||
KtKeywordToken RECEIVER_KEYWORD = KtKeywordToken.softKeyword("receiver");
|
||||
KtKeywordToken PARAM_KEYWORD = KtKeywordToken.softKeyword("param");
|
||||
KtKeywordToken SETPARAM_KEYWORD = KtKeywordToken.softKeyword("setparam");
|
||||
KtKeywordToken DELEGATE_KEYWORD = KtKeywordToken.softKeyword("delegate");
|
||||
KtKeywordToken IMPORT_KEYWORD = KtKeywordToken.softKeyword("import");
|
||||
KtKeywordToken WHERE_KEYWORD = KtKeywordToken.softKeyword("where");
|
||||
KtKeywordToken BY_KEYWORD = KtKeywordToken.softKeyword("by");
|
||||
@@ -203,6 +204,7 @@ public interface KtTokens {
|
||||
CATCH_KEYWORD, FINALLY_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, REIFIED_KEYWORD,
|
||||
DYNAMIC_KEYWORD, COMPANION_KEYWORD, CONSTRUCTOR_KEYWORD, INIT_KEYWORD, SEALED_KEYWORD,
|
||||
FIELD_KEYWORD, PROPERTY_KEYWORD, RECEIVER_KEYWORD, PARAM_KEYWORD, SETPARAM_KEYWORD,
|
||||
DELEGATE_KEYWORD,
|
||||
LATEINIT_KEYWORD,
|
||||
DATA_KEYWORD, INLINE_KEYWORD, NOINLINE_KEYWORD, TAILREC_KEYWORD, EXTERNAL_KEYWORD,
|
||||
ANNOTATION_KEYWORD, CROSSINLINE_KEYWORD, CONST_KEYWORD, OPERATOR_KEYWORD, INFIX_KEYWORD
|
||||
|
||||
@@ -64,7 +64,8 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
TokenSet.orSet(TokenSet.create(IDENTIFIER, LBRACKET), MODIFIER_KEYWORDS);
|
||||
private static final TokenSet SOFT_KEYWORDS_AT_MEMBER_START = TokenSet.create(CONSTRUCTOR_KEYWORD, INIT_KEYWORD);
|
||||
private static final TokenSet ANNOTATION_TARGETS = TokenSet.create(
|
||||
FILE_KEYWORD, FIELD_KEYWORD, GET_KEYWORD, SET_KEYWORD, PROPERTY_KEYWORD, RECEIVER_KEYWORD, PARAM_KEYWORD, SETPARAM_KEYWORD);
|
||||
FILE_KEYWORD, FIELD_KEYWORD, GET_KEYWORD, SET_KEYWORD, PROPERTY_KEYWORD,
|
||||
RECEIVER_KEYWORD, PARAM_KEYWORD, SETPARAM_KEYWORD, DELEGATE_KEYWORD);
|
||||
|
||||
static KotlinParsing createForTopLevel(SemanticWhitespaceAwarePsiBuilder builder) {
|
||||
KotlinParsing jetParsing = new KotlinParsing(builder);
|
||||
|
||||
@@ -54,6 +54,7 @@ class KtAnnotationUseSiteTarget : KtElementImplStub<KotlinAnnotationUseSiteTarge
|
||||
KtTokens.RECEIVER_KEYWORD -> AnnotationUseSiteTarget.RECEIVER
|
||||
KtTokens.PARAM_KEYWORD -> AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
|
||||
KtTokens.SETPARAM_KEYWORD -> AnnotationUseSiteTarget.SETTER_PARAMETER
|
||||
KtTokens.DELEGATE_KEYWORD -> AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
|
||||
else -> throw IllegalStateException("Unknown annotation target " + node.getText())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,9 +179,9 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
|
||||
if (annotated.isLocal)
|
||||
TargetLists.T_LOCAL_VARIABLE
|
||||
else if (annotated.parent is KtClassOrObject || annotated.parent is KtClassBody)
|
||||
TargetLists.T_MEMBER_PROPERTY(descriptor.hasBackingField(trace))
|
||||
TargetLists.T_MEMBER_PROPERTY(descriptor.hasBackingField(trace), annotated.hasDelegate())
|
||||
else
|
||||
TargetLists.T_TOP_LEVEL_PROPERTY(descriptor.hasBackingField(trace))
|
||||
TargetLists.T_TOP_LEVEL_PROPERTY(descriptor.hasBackingField(trace), annotated.hasDelegate())
|
||||
}
|
||||
is KtParameter -> {
|
||||
if (annotated.hasValOrVar())
|
||||
@@ -224,19 +224,31 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
|
||||
|
||||
val T_DESTRUCTURING_DECLARATION = targetList(DESTRUCTURING_DECLARATION)
|
||||
|
||||
fun T_MEMBER_PROPERTY(backingField: Boolean) =
|
||||
targetList(if (backingField) MEMBER_PROPERTY_WITH_FIELD else MEMBER_PROPERTY_WITHOUT_FIELD,
|
||||
MEMBER_PROPERTY, PROPERTY) {
|
||||
fun TargetListBuilder.propertyTargets(backingField: Boolean, delegate: Boolean) {
|
||||
if (backingField) extraTargets(FIELD)
|
||||
onlyWithUseSiteTarget(VALUE_PARAMETER, PROPERTY_GETTER, PROPERTY_SETTER)
|
||||
if (delegate) {
|
||||
onlyWithUseSiteTarget(VALUE_PARAMETER, PROPERTY_GETTER, PROPERTY_SETTER, FIELD)
|
||||
}
|
||||
else {
|
||||
onlyWithUseSiteTarget(VALUE_PARAMETER, PROPERTY_GETTER, PROPERTY_SETTER)
|
||||
}
|
||||
}
|
||||
|
||||
fun T_TOP_LEVEL_PROPERTY(backingField: Boolean) =
|
||||
targetList(if (backingField) TOP_LEVEL_PROPERTY_WITH_FIELD else TOP_LEVEL_PROPERTY_WITHOUT_FIELD,
|
||||
fun T_MEMBER_PROPERTY(backingField: Boolean, delegate: Boolean) =
|
||||
targetList(if (backingField) MEMBER_PROPERTY_WITH_BACKING_FIELD
|
||||
else if (delegate) MEMBER_PROPERTY_WITH_DELEGATE
|
||||
else MEMBER_PROPERTY_WITHOUT_FIELD_OR_DELEGATE,
|
||||
MEMBER_PROPERTY, PROPERTY) {
|
||||
propertyTargets(backingField, delegate)
|
||||
}
|
||||
|
||||
fun T_TOP_LEVEL_PROPERTY(backingField: Boolean, delegate: Boolean) =
|
||||
targetList(if (backingField) TOP_LEVEL_PROPERTY_WITH_BACKING_FIELD
|
||||
else if (delegate) TOP_LEVEL_PROPERTY_WITH_DELEGATE
|
||||
else TOP_LEVEL_PROPERTY_WITHOUT_FIELD_OR_DELEGATE,
|
||||
TOP_LEVEL_PROPERTY, PROPERTY) {
|
||||
if (backingField) extraTargets(FIELD)
|
||||
onlyWithUseSiteTarget(VALUE_PARAMETER, PROPERTY_GETTER, PROPERTY_SETTER)
|
||||
}
|
||||
propertyTargets(backingField, delegate)
|
||||
}
|
||||
|
||||
val T_PROPERTY_GETTER = targetList(PROPERTY_GETTER)
|
||||
val T_PROPERTY_SETTER = targetList(PROPERTY_SETTER)
|
||||
|
||||
+24
-4
@@ -28,6 +28,7 @@ object AnnotationUseSiteTargetChecker {
|
||||
|
||||
if (annotated is KtFunction) {
|
||||
for (parameter in annotated.valueParameters) {
|
||||
if (parameter.hasValOrVar()) continue
|
||||
val parameterDescriptor = trace.bindingContext[BindingContext.VALUE_PARAMETER, parameter] ?: continue
|
||||
trace.checkDeclaration(parameter, parameterDescriptor)
|
||||
}
|
||||
@@ -45,6 +46,7 @@ object AnnotationUseSiteTargetChecker {
|
||||
when (target) {
|
||||
AnnotationUseSiteTarget.RECEIVER -> {}
|
||||
AnnotationUseSiteTarget.FIELD,
|
||||
AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD,
|
||||
AnnotationUseSiteTarget.PROPERTY,
|
||||
AnnotationUseSiteTarget.PROPERTY_GETTER,
|
||||
AnnotationUseSiteTarget.PROPERTY_SETTER,
|
||||
@@ -62,9 +64,10 @@ object AnnotationUseSiteTargetChecker {
|
||||
val target = annotation.useSiteTarget?.getAnnotationUseSiteTarget() ?: continue
|
||||
|
||||
when (target) {
|
||||
AnnotationUseSiteTarget.FIELD,
|
||||
AnnotationUseSiteTarget.FIELD -> checkIfHasBackingField(annotated, descriptor, annotation)
|
||||
AnnotationUseSiteTarget.PROPERTY,
|
||||
AnnotationUseSiteTarget.PROPERTY_GETTER -> {}
|
||||
AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD -> checkIfDelegatedProperty(annotated, annotation)
|
||||
AnnotationUseSiteTarget.PROPERTY_SETTER -> checkIfMutableProperty(annotated, annotation)
|
||||
AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER -> {
|
||||
if (annotated !is KtParameter) {
|
||||
@@ -87,6 +90,22 @@ object AnnotationUseSiteTargetChecker {
|
||||
}
|
||||
}
|
||||
|
||||
private fun BindingTrace.checkIfDelegatedProperty(annotated: KtAnnotated, annotation: KtAnnotationEntry) {
|
||||
if (annotated is KtProperty && !annotated.hasDelegate() || annotated is KtParameter && annotated.hasValOrVar()) {
|
||||
report(INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE.on(annotation))
|
||||
}
|
||||
}
|
||||
|
||||
private fun BindingTrace.checkIfHasBackingField(annotated: KtAnnotated, descriptor: DeclarationDescriptor, annotation: KtAnnotationEntry) {
|
||||
if (annotated is KtProperty && annotated.hasDelegate() &&
|
||||
descriptor is PropertyDescriptor && get(BindingContext.BACKING_FIELD_REQUIRED, descriptor) != true) {
|
||||
report(INAPPLICABLE_TARGET_PROPERTY_HAS_NO_BACKING_FIELD.on(annotation))
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtAnnotationEntry.useSiteDescription() =
|
||||
useSiteTarget?.getAnnotationUseSiteTarget()?.renderName ?: "unknown target" // should not happen
|
||||
|
||||
private fun BindingTrace.checkIfMutableProperty(annotated: KtAnnotated, annotation: KtAnnotationEntry) {
|
||||
if (!checkIfProperty(annotated, annotation)) return
|
||||
|
||||
@@ -96,7 +115,9 @@ object AnnotationUseSiteTargetChecker {
|
||||
annotated.isMutable
|
||||
else false
|
||||
|
||||
if (!isMutable) report(INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE.on(annotation))
|
||||
if (!isMutable) {
|
||||
report(INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE.on(annotation, annotation.useSiteDescription()))
|
||||
}
|
||||
}
|
||||
|
||||
private fun BindingTrace.checkIfProperty(annotated: KtAnnotated, annotation: KtAnnotationEntry): Boolean {
|
||||
@@ -106,8 +127,7 @@ object AnnotationUseSiteTargetChecker {
|
||||
annotated.hasValOrVar()
|
||||
else false
|
||||
|
||||
val target = annotation.useSiteTarget?.getAnnotationUseSiteTarget()?.renderName ?: "unknown target" // should not happen
|
||||
if (!isProperty) report(INAPPLICABLE_TARGET_ON_PROPERTY.on(annotation, target))
|
||||
if (!isProperty) report(INAPPLICABLE_TARGET_ON_PROPERTY.on(annotation, annotation.useSiteDescription()))
|
||||
return isProperty
|
||||
}
|
||||
}
|
||||
@@ -676,7 +676,7 @@ public class DescriptorResolver {
|
||||
? resolveModalityFromModifiers(property, getDefaultModality(containingDeclaration, visibility, hasBody))
|
||||
: Modality.FINAL;
|
||||
|
||||
final AnnotationSplitter.PropertyWrapper wrapper = new AnnotationSplitter.PropertyWrapper();
|
||||
final AnnotationSplitter.PropertyWrapper wrapper = new AnnotationSplitter.PropertyWrapper(property);
|
||||
|
||||
Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace);
|
||||
AnnotationSplitter annotationSplitter =
|
||||
@@ -688,7 +688,7 @@ public class DescriptorResolver {
|
||||
});
|
||||
|
||||
Annotations propertyAnnotations = new CompositeAnnotations(CollectionsKt.listOf(
|
||||
annotationSplitter.getAnnotationsForTargets(PROPERTY, FIELD),
|
||||
annotationSplitter.getAnnotationsForTargets(PROPERTY, FIELD, PROPERTY_DELEGATE_FIELD),
|
||||
annotationSplitter.getOtherAnnotations()));
|
||||
|
||||
PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(
|
||||
@@ -703,7 +703,7 @@ public class DescriptorResolver {
|
||||
modifierList != null && modifierList.hasModifier(KtTokens.LATEINIT_KEYWORD),
|
||||
modifierList != null && modifierList.hasModifier(KtTokens.CONST_KEYWORD)
|
||||
);
|
||||
wrapper.setProperty(propertyDescriptor);
|
||||
wrapper.setDescriptor(propertyDescriptor);
|
||||
|
||||
List<TypeParameterDescriptorImpl> typeParameterDescriptors;
|
||||
LexicalScope scopeWithTypeParameters;
|
||||
@@ -938,7 +938,7 @@ public class DescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
final AnnotationSplitter.PropertyWrapper propertyWrapper = new AnnotationSplitter.PropertyWrapper();
|
||||
final AnnotationSplitter.PropertyWrapper propertyWrapper = new AnnotationSplitter.PropertyWrapper(parameter);
|
||||
Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, parameter.getModifierList(), trace);
|
||||
AnnotationSplitter annotationSplitter =
|
||||
new AnnotationSplitter(storageManager, allAnnotations, new Function0<Set<AnnotationUseSiteTarget>>() {
|
||||
@@ -964,7 +964,7 @@ public class DescriptorResolver {
|
||||
/* lateInit = */ false,
|
||||
/* isConst = */ false
|
||||
);
|
||||
propertyWrapper.setProperty(propertyDescriptor);
|
||||
propertyWrapper.setDescriptor(propertyDescriptor);
|
||||
propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(),
|
||||
getDispatchReceiverParameterIfNeeded(classDescriptor), (ReceiverParameterDescriptor) null);
|
||||
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import java.lang.reflect.Modifier
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class CustomDelegate {
|
||||
operator fun getValue(thisRef: Any?, prop: KProperty<*>): String = prop.name
|
||||
}
|
||||
|
||||
class C {
|
||||
@Volatile var vol = 1
|
||||
@Transient val tra = 1
|
||||
@delegate:Transient val del: String by CustomDelegate()
|
||||
|
||||
@Strictfp fun str() {}
|
||||
@Synchronized fun sync() {}
|
||||
@@ -13,6 +19,7 @@ fun box(): String {
|
||||
|
||||
if (c.getDeclaredField("vol").getModifiers() and Modifier.VOLATILE == 0) return "Fail: volatile"
|
||||
if (c.getDeclaredField("tra").getModifiers() and Modifier.TRANSIENT == 0) return "Fail: transient"
|
||||
if (c.getDeclaredField("del\$delegate").getModifiers() and Modifier.TRANSIENT == 0) return "Fail: delegate transient"
|
||||
|
||||
if (c.getDeclaredMethod("str").getModifiers() and Modifier.STRICT == 0) return "Fail: strict"
|
||||
if (c.getDeclaredMethod("sync").getModifiers() and Modifier.SYNCHRONIZED == 0) return "Fail: synchronized"
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
annotation class AnnProp
|
||||
annotation class AnnField
|
||||
annotation class AnnProp2
|
||||
annotation class AnnGetter
|
||||
annotation class AnnSetter
|
||||
annotation class AnnParam
|
||||
annotation class AnnDelegate
|
||||
|
||||
class CustomDelegate {
|
||||
operator fun getValue(thisRef: Any?, prop: KProperty<*>): String = prop.name
|
||||
}
|
||||
|
||||
public class A(@AnnParam @field:AnnField @property:AnnProp2 val x: Int, @param:AnnParam @get:AnnGetter @set:AnnSetter var y: Int) {
|
||||
|
||||
@AnnProp @field:AnnField @property:AnnProp2 @get:AnnGetter @set:AnnSetter @setparam:AnnParam
|
||||
var p: Int = 0
|
||||
|
||||
@AnnProp @property:AnnProp2 @delegate:AnnDelegate @property:AnnDelegate
|
||||
val s: String by CustomDelegate()
|
||||
|
||||
}
|
||||
@@ -1,18 +1,27 @@
|
||||
@kotlin.jvm.internal.KotlinClass
|
||||
public final class A {
|
||||
private synthetic final static field $$delegatedProperties: kotlin.reflect.KProperty[]
|
||||
private @AnnField field p: int
|
||||
private final @AnnDelegate @org.jetbrains.annotations.NotNull field s$delegate: CustomDelegate
|
||||
private final @AnnField field x: int
|
||||
private field y: int
|
||||
static method <clinit>(): void
|
||||
public method <init>(@AnnParam p0: int, @AnnParam p1: int): void
|
||||
public final @AnnGetter method getP(): int
|
||||
public final @org.jetbrains.annotations.NotNull method getS(): java.lang.String
|
||||
public final method getX(): int
|
||||
public final @AnnGetter method getY(): int
|
||||
private synthetic deprecated final static @AnnProp @AnnProp2 method p$annotations(): void
|
||||
private synthetic deprecated final static @AnnProp @AnnProp2 @AnnDelegate method s$annotations(): void
|
||||
public final @AnnSetter method setP(@AnnParam p0: int): void
|
||||
public final @AnnSetter method setY(p0: int): void
|
||||
private synthetic deprecated final static @AnnProp2 method x$annotations(): void
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.jvm.internal.KotlinClass
|
||||
public abstract class AnnDelegate
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.jvm.internal.KotlinClass
|
||||
public abstract class AnnField
|
||||
@@ -35,4 +44,10 @@ public abstract class AnnProp2
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.jvm.internal.KotlinClass
|
||||
public abstract class AnnSetter
|
||||
public abstract class AnnSetter
|
||||
|
||||
@kotlin.jvm.internal.KotlinClass
|
||||
public final class CustomDelegate {
|
||||
public method <init>(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getValue(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.reflect.KProperty): java.lang.String
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@Target(AnnotationTarget.FIELD) annotation class Field
|
||||
|
||||
@Target(AnnotationTarget.PROPERTY) annotation class Prop
|
||||
|
||||
class CustomDelegate {
|
||||
operator fun getValue(thisRef: Any?, prop: KProperty<*>): String = prop.name
|
||||
}
|
||||
|
||||
<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@delegate:Field<!>
|
||||
class SomeClass {
|
||||
|
||||
<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@delegate:Field<!>
|
||||
constructor()
|
||||
|
||||
<!INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE!>@delegate:Field<!> <!INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE, WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@delegate:Prop<!>
|
||||
protected val simpleProperty: String = "text"
|
||||
|
||||
@delegate:Field <!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@delegate:Prop<!>
|
||||
protected val delegatedProperty: String by CustomDelegate()
|
||||
|
||||
<!INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE, WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@delegate:Field<!> <!INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE, WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@delegate:Prop<!>
|
||||
val propertyWithCustomGetter: Int
|
||||
get() = 5
|
||||
|
||||
}
|
||||
|
||||
class WithPrimaryConstructor(<!INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE!>@delegate:Field<!> <!INAPPLICABLE_TARGET_PROPERTY_HAS_NO_DELEGATE, WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@delegate:Prop<!> val a: String,
|
||||
<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@param:Field<!> <!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@param:Prop<!> val b: String)
|
||||
|
||||
fun foo(<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@delegate:Field<!> <!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@delegate:Prop<!> x: Int) = x
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package
|
||||
|
||||
public fun foo(/*0*/ @delegate:Field() @delegate:Prop() x: kotlin.Int): kotlin.Int
|
||||
|
||||
public final class CustomDelegate {
|
||||
public constructor CustomDelegate()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.reflect.KProperty<*>): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.FIELD}) public final annotation class Field : kotlin.Annotation {
|
||||
public constructor Field()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.PROPERTY}) public final annotation class Prop : kotlin.Annotation {
|
||||
public constructor Prop()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@delegate:Field() public final class SomeClass {
|
||||
@delegate:Field() public constructor SomeClass()
|
||||
@delegate:Field() @delegate:Prop() protected final val delegatedProperty: kotlin.String
|
||||
@delegate:Field() @delegate:Prop() public final val propertyWithCustomGetter: kotlin.Int
|
||||
@delegate:Field() @delegate:Prop() protected final val simpleProperty: kotlin.String = "text"
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class WithPrimaryConstructor {
|
||||
public constructor WithPrimaryConstructor(/*0*/ a: kotlin.String, /*1*/ @param:Field() @param:Prop() b: kotlin.String)
|
||||
@delegate:Field() @delegate:Prop() public final val a: kotlin.String
|
||||
public final val b: kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+1
-1
@@ -18,7 +18,7 @@ class SomeClass {
|
||||
@field:[Ann]
|
||||
protected val simplePropertyWithAnnotationList: String = "text"
|
||||
|
||||
<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@field:Ann<!>
|
||||
<!INAPPLICABLE_TARGET_PROPERTY_HAS_NO_BACKING_FIELD!>@field:Ann<!>
|
||||
protected val delegatedProperty: String by CustomDelegate()
|
||||
|
||||
<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@field:Ann<!>
|
||||
|
||||
+22
@@ -1,8 +1,14 @@
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
@Repeatable
|
||||
annotation class RepeatableAnn
|
||||
annotation class Ann
|
||||
|
||||
class CustomDelegate {
|
||||
operator fun getValue(thisRef: Any?, prop: KProperty<*>): String = prop.name
|
||||
}
|
||||
|
||||
public class A(@param:Ann <!REPEATED_ANNOTATION!>@Ann<!> val x: Int, @param: RepeatableAnn @Ann val y: Int) {
|
||||
|
||||
@field:Ann @property:Ann @RepeatableAnn @property:RepeatableAnn
|
||||
@@ -17,4 +23,20 @@ public class A(@param:Ann <!REPEATED_ANNOTATION!>@Ann<!> val x: Int, @param: Rep
|
||||
@property:RepeatableAnn @RepeatableAnn
|
||||
val d: Int = 0
|
||||
|
||||
@property:RepeatableAnn @RepeatableAnn @delegate:RepeatableAnn
|
||||
val e: String by CustomDelegate()
|
||||
|
||||
@property:Ann @delegate:Ann
|
||||
val f: String by CustomDelegate()
|
||||
|
||||
// Ideally we should not have repeated anotation here and below
|
||||
// (because @Ann should go to the property and the second annotation to its related field)
|
||||
@Ann <!REPEATED_ANNOTATION!>@delegate:Ann<!>
|
||||
val g: String by CustomDelegate()
|
||||
|
||||
@Ann <!REPEATED_ANNOTATION!>@field:Ann<!>
|
||||
val h: String = ""
|
||||
|
||||
@property:Ann @field:Ann
|
||||
val i: String = ""
|
||||
}
|
||||
+13
@@ -6,6 +6,11 @@ public final class A {
|
||||
@Ann() @property:Ann() @field:Ann() public final val b: kotlin.Int = 0
|
||||
@field:RepeatableAnn() @field:RepeatableAnn() public final val c: kotlin.Int = 0
|
||||
@property:RepeatableAnn() @RepeatableAnn() public final val d: kotlin.Int = 0
|
||||
@property:RepeatableAnn() @RepeatableAnn() @delegate:RepeatableAnn() public final val e: kotlin.String
|
||||
@property:Ann() @delegate:Ann() public final val f: kotlin.String
|
||||
@Ann() @delegate:Ann() public final val g: kotlin.String
|
||||
@Ann() @field:Ann() public final val h: kotlin.String = ""
|
||||
@property:Ann() @field:Ann() public final val i: kotlin.String = ""
|
||||
public final val x: kotlin.Int
|
||||
public final val y: kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@@ -20,6 +25,14 @@ public final annotation class Ann : kotlin.Annotation {
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class CustomDelegate {
|
||||
public constructor CustomDelegate()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.reflect.KProperty<*>): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.annotation.Retention(value = AnnotationRetention.SOURCE) @kotlin.annotation.Repeatable() public final annotation class RepeatableAnn : kotlin.Annotation {
|
||||
public constructor RepeatableAnn()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class C {
|
||||
val plainField: Int = 1
|
||||
@delegate:Transient
|
||||
val lazy by lazy { 1 }
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package
|
||||
|
||||
public final class C {
|
||||
public constructor C()
|
||||
@delegate:kotlin.jvm.Transient() public final val lazy: kotlin.Int
|
||||
public final val plainField: kotlin.Int = 1
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class C {
|
||||
@delegate:Transient
|
||||
val plainField: Int = 1
|
||||
|
||||
@delegate:Transient
|
||||
val lazy by lazy { 1 }
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
JetFile: delegate.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
<empty list>
|
||||
IMPORT_LIST
|
||||
<empty list>
|
||||
CLASS
|
||||
PsiElement(class)('class')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('C')
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS_BODY
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
PROPERTY
|
||||
MODIFIER_LIST
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
ANNOTATION_TARGET
|
||||
PsiElement(delegate)('delegate')
|
||||
PsiElement(COLON)(':')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Transient')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('plainField')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Int')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PROPERTY
|
||||
MODIFIER_LIST
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
ANNOTATION_TARGET
|
||||
PsiElement(delegate)('delegate')
|
||||
PsiElement(COLON)(':')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Transient')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('lazy')
|
||||
PsiWhiteSpace(' ')
|
||||
PROPERTY_DELEGATE
|
||||
PsiElement(by)('by')
|
||||
PsiWhiteSpace(' ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('lazy')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_ARGUMENT
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
@@ -1436,6 +1436,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/annotations/withUseSiteTarget"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("DelegateAnnotations.kt")
|
||||
public void testDelegateAnnotations() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/DelegateAnnotations.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("FieldAnnotations.kt")
|
||||
public void testFieldAnnotations() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/FieldAnnotations.kt");
|
||||
|
||||
@@ -169,6 +169,12 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TransientOnDelegate.kt")
|
||||
public void testTransientOnDelegate() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/TransientOnDelegate.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Volatile.kt")
|
||||
public void testVolatile() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.kt");
|
||||
|
||||
@@ -1003,6 +1003,12 @@ public class ParsingTestGenerated extends AbstractParsingTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/psi/annotation/targeted/onField"), Pattern.compile("^(.*)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("delegate.kt")
|
||||
public void testDelegate() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/annotation/targeted/onField/delegate.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("fqName.kt")
|
||||
public void testFqName() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/annotation/targeted/onField/fqName.kt");
|
||||
|
||||
+2
-1
@@ -26,7 +26,8 @@ enum class AnnotationUseSiteTarget(renderName: String? = null) {
|
||||
PROPERTY_SETTER("set"),
|
||||
RECEIVER(),
|
||||
CONSTRUCTOR_PARAMETER("param"),
|
||||
SETTER_PARAMETER("setparam");
|
||||
SETTER_PARAMETER("setparam"),
|
||||
PROPERTY_DELEGATE_FIELD("delegate");
|
||||
|
||||
val renderName: String = renderName ?: name.toLowerCase()
|
||||
|
||||
|
||||
@@ -57,12 +57,14 @@ enum class KotlinTarget(val description: String, val isDefault: Boolean = true)
|
||||
MEMBER_FUNCTION("member function", false),
|
||||
TOP_LEVEL_FUNCTION("top level function", false),
|
||||
|
||||
MEMBER_PROPERTY("member property", false), // includes PROPERTY_PARAMETER, with and without field
|
||||
MEMBER_PROPERTY_WITH_FIELD("member property with backing field", false),
|
||||
MEMBER_PROPERTY_WITHOUT_FIELD("member property without backing field", false),
|
||||
TOP_LEVEL_PROPERTY("top level property", false), // with and without field
|
||||
TOP_LEVEL_PROPERTY_WITH_FIELD("top level property with backing field", false),
|
||||
TOP_LEVEL_PROPERTY_WITHOUT_FIELD("top level property without backing field", false),
|
||||
MEMBER_PROPERTY("member property", false), // includes PROPERTY_PARAMETER, with and without field/delegate
|
||||
MEMBER_PROPERTY_WITH_BACKING_FIELD("member property with backing field", false),
|
||||
MEMBER_PROPERTY_WITH_DELEGATE("member property with delegate", false),
|
||||
MEMBER_PROPERTY_WITHOUT_FIELD_OR_DELEGATE("member property without backing field or delegate", false),
|
||||
TOP_LEVEL_PROPERTY("top level property", false), // with and without field/delegate
|
||||
TOP_LEVEL_PROPERTY_WITH_BACKING_FIELD("top level property with backing field", false),
|
||||
TOP_LEVEL_PROPERTY_WITH_DELEGATE("top level property with delegate", false),
|
||||
TOP_LEVEL_PROPERTY_WITHOUT_FIELD_OR_DELEGATE("top level property without backing field or delegate", false),
|
||||
|
||||
INITIALIZER("initializer", false),
|
||||
DESTRUCTURING_DECLARATION("destructuring declaration", false),
|
||||
@@ -125,7 +127,8 @@ enum class KotlinTarget(val description: String, val isDefault: Boolean = true)
|
||||
AnnotationUseSiteTarget.PROPERTY_GETTER to PROPERTY_GETTER,
|
||||
AnnotationUseSiteTarget.PROPERTY_SETTER to PROPERTY_SETTER,
|
||||
AnnotationUseSiteTarget.RECEIVER to VALUE_PARAMETER,
|
||||
AnnotationUseSiteTarget.SETTER_PARAMETER to VALUE_PARAMETER)
|
||||
AnnotationUseSiteTarget.SETTER_PARAMETER to VALUE_PARAMETER,
|
||||
AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD to FIELD)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,5 @@
|
||||
// EXIST: { itemText: "setparam:" }
|
||||
// EXIST: { itemText: "property:" }
|
||||
// EXIST: { itemText: "receiver:" }
|
||||
// EXIST: { itemText: "delegate:" }
|
||||
// NOTHING_ELSE
|
||||
|
||||
+1
@@ -11,4 +11,5 @@ class Completion(@get:Ann val p1: String, @<caret>)
|
||||
|
||||
/*TODO: in fact is not applicable */
|
||||
// EXIST: receiver
|
||||
// EXIST: delegate
|
||||
// NOTHING_ELSE
|
||||
|
||||
Reference in New Issue
Block a user