Split annotations lazily
This commit is contained in:
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithFakeAnnotations;
|
import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithFakeAnnotations;
|
||||||
|
import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple;
|
||||||
import org.jetbrains.kotlin.codegen.context.*;
|
import org.jetbrains.kotlin.codegen.context.*;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||||
@@ -39,6 +40,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
|||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor;
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor;
|
||||||
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils;
|
import org.jetbrains.kotlin.types.ErrorUtils;
|
||||||
import org.jetbrains.kotlin.types.JetType;
|
import org.jetbrains.kotlin.types.JetType;
|
||||||
import org.jetbrains.kotlin.util.AnnotationSplitter;
|
import org.jetbrains.kotlin.util.AnnotationSplitter;
|
||||||
@@ -49,7 +51,9 @@ import org.jetbrains.org.objectweb.asm.Type;
|
|||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isInterface;
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isInterface;
|
||||||
@@ -117,8 +121,8 @@ public class PropertyCodegen {
|
|||||||
|
|
||||||
boolean hasBackingField = hasBackingField(declaration, descriptor);
|
boolean hasBackingField = hasBackingField(declaration, descriptor);
|
||||||
|
|
||||||
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(
|
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(LockBasedStorageManager.NO_LOCKS,
|
||||||
descriptor.getAnnotations(), false, hasBackingField, descriptor.isVar());
|
descriptor.getAnnotations(), AnnotationSplitter.getTargetSet(false, descriptor.isVar(), hasBackingField));
|
||||||
|
|
||||||
Annotations fieldAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.FIELD);
|
Annotations fieldAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.FIELD);
|
||||||
Annotations propertyAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY);
|
Annotations propertyAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY);
|
||||||
@@ -170,8 +174,8 @@ public class PropertyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void generatePrimaryConstructorProperty(JetParameter p, PropertyDescriptor descriptor) {
|
public void generatePrimaryConstructorProperty(JetParameter p, PropertyDescriptor descriptor) {
|
||||||
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(
|
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(LockBasedStorageManager.NO_LOCKS,
|
||||||
descriptor.getAnnotations(), true, hasBackingField(p, descriptor), descriptor.isVar());
|
descriptor.getAnnotations(), AnnotationSplitter.getTargetSet(true, descriptor.isVar(), hasBackingField(p, descriptor)));
|
||||||
|
|
||||||
Annotations fieldAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.FIELD);
|
Annotations fieldAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.FIELD);
|
||||||
Annotations propertyAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY);
|
Annotations propertyAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY);
|
||||||
@@ -212,12 +216,9 @@ public class PropertyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasBackingField(@NotNull JetNamedDeclaration p, @NotNull PropertyDescriptor descriptor) {
|
private boolean hasBackingField(@NotNull JetNamedDeclaration p, @NotNull PropertyDescriptor descriptor) {
|
||||||
if (isInterface(descriptor.getContainingDeclaration()) ||
|
return !isInterface(descriptor.getContainingDeclaration()) &&
|
||||||
kind == OwnerKind.TRAIT_IMPL ||
|
kind != OwnerKind.TRAIT_IMPL &&
|
||||||
Boolean.FALSE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor))) {
|
!Boolean.FALSE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor));
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean generateBackingField(
|
private boolean generateBackingField(
|
||||||
@@ -254,7 +255,7 @@ public class PropertyCodegen {
|
|||||||
int flags = ACC_DEPRECATED | ACC_FINAL | ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC;
|
int flags = ACC_DEPRECATED | ACC_FINAL | ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC;
|
||||||
MethodVisitor mv = v.newMethod(OtherOrigin(descriptor), flags, name, desc, null, null);
|
MethodVisitor mv = v.newMethod(OtherOrigin(descriptor), flags, name, desc, null, null);
|
||||||
AnnotationCodegen.forMethod(mv, typeMapper)
|
AnnotationCodegen.forMethod(mv, typeMapper)
|
||||||
.genAnnotations(new AnnotatedImpl(annotations), Type.VOID_TYPE, AnnotationUseSiteTarget.PROPERTY);
|
.genAnnotations(new AnnotatedSimple(annotations), Type.VOID_TYPE, AnnotationUseSiteTarget.PROPERTY);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
|
|||||||
@@ -342,7 +342,8 @@ public class DescriptorResolver {
|
|||||||
|
|
||||||
if (modifierList != null) {
|
if (modifierList != null) {
|
||||||
if (valueParameter.hasValOrVar()) {
|
if (valueParameter.hasValOrVar()) {
|
||||||
AnnotationSplitter annotationSplitter = new AnnotationSplitter(allAnnotations, KotlinPackage.setOf(CONSTRUCTOR_PARAMETER));
|
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(
|
||||||
|
storageManager, allAnnotations, KotlinPackage.setOf(CONSTRUCTOR_PARAMETER));
|
||||||
valueParameterAnnotations = annotationSplitter.getAnnotationsForTarget(CONSTRUCTOR_PARAMETER);
|
valueParameterAnnotations = annotationSplitter.getAnnotationsForTarget(CONSTRUCTOR_PARAMETER);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -702,7 +703,7 @@ public class DescriptorResolver {
|
|||||||
@NotNull DeclarationDescriptor containingDeclaration,
|
@NotNull DeclarationDescriptor containingDeclaration,
|
||||||
@NotNull LexicalScope scope,
|
@NotNull LexicalScope scope,
|
||||||
@NotNull JetProperty property,
|
@NotNull JetProperty property,
|
||||||
@NotNull BindingTrace trace,
|
@NotNull final BindingTrace trace,
|
||||||
@NotNull DataFlowInfo dataFlowInfo
|
@NotNull DataFlowInfo dataFlowInfo
|
||||||
) {
|
) {
|
||||||
JetModifierList modifierList = property.getModifierList();
|
JetModifierList modifierList = property.getModifierList();
|
||||||
@@ -714,15 +715,16 @@ public class DescriptorResolver {
|
|||||||
? resolveModalityFromModifiers(property, getDefaultModality(containingDeclaration, visibility, hasBody))
|
? resolveModalityFromModifiers(property, getDefaultModality(containingDeclaration, visibility, hasBody))
|
||||||
: Modality.FINAL;
|
: Modality.FINAL;
|
||||||
|
|
||||||
JetPropertyAccessor propertyGetter = property.getGetter();
|
final AnnotationSplitter.PropertyWrapper wrapper = new AnnotationSplitter.PropertyWrapper();
|
||||||
|
|
||||||
boolean hasBackingField = modality != Modality.ABSTRACT
|
|
||||||
&& property.hasDelegateExpressionOrInitializer()
|
|
||||||
&& (propertyGetter == null || !propertyGetter.hasBody());
|
|
||||||
|
|
||||||
Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace);
|
Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace);
|
||||||
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(allAnnotations,
|
AnnotationSplitter annotationSplitter =
|
||||||
/*parameter =*/ false, /*hasBackingField =*/ hasBackingField, /*isMutable =*/ isVar);
|
new AnnotationSplitter(storageManager, allAnnotations, new Function0<Set<AnnotationUseSiteTarget>>() {
|
||||||
|
@Override
|
||||||
|
public Set<AnnotationUseSiteTarget> invoke() {
|
||||||
|
return AnnotationSplitter.getTargetSet(false, trace.getBindingContext(), wrapper);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Annotations propertyAnnotations = new CompositeAnnotations(KotlinPackage.listOf(
|
Annotations propertyAnnotations = new CompositeAnnotations(KotlinPackage.listOf(
|
||||||
annotationSplitter.getAnnotationsForTargets(PROPERTY, FIELD),
|
annotationSplitter.getAnnotationsForTargets(PROPERTY, FIELD),
|
||||||
@@ -738,6 +740,7 @@ public class DescriptorResolver {
|
|||||||
CallableMemberDescriptor.Kind.DECLARATION,
|
CallableMemberDescriptor.Kind.DECLARATION,
|
||||||
toSourceElement(property)
|
toSourceElement(property)
|
||||||
);
|
);
|
||||||
|
wrapper.setProperty(propertyDescriptor);
|
||||||
|
|
||||||
List<TypeParameterDescriptorImpl> typeParameterDescriptors;
|
List<TypeParameterDescriptorImpl> typeParameterDescriptors;
|
||||||
LexicalScope scopeWithTypeParameters;
|
LexicalScope scopeWithTypeParameters;
|
||||||
@@ -1087,9 +1090,15 @@ public class DescriptorResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final AnnotationSplitter.PropertyWrapper propertyWrapper = new AnnotationSplitter.PropertyWrapper();
|
||||||
Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, parameter.getModifierList(), trace);
|
Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, parameter.getModifierList(), trace);
|
||||||
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(allAnnotations,
|
AnnotationSplitter annotationSplitter =
|
||||||
/*parameter =*/ true, /*hasBackingField =*/ true, /*isMutable =*/ isMutable);
|
new AnnotationSplitter(storageManager, allAnnotations, new Function0<Set<AnnotationUseSiteTarget>>() {
|
||||||
|
@Override
|
||||||
|
public Set<AnnotationUseSiteTarget> invoke() {
|
||||||
|
return AnnotationSplitter.getTargetSet(true, trace.getBindingContext(), propertyWrapper);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Annotations propertyAnnotations = new CompositeAnnotations(
|
Annotations propertyAnnotations = new CompositeAnnotations(
|
||||||
annotationSplitter.getAnnotationsForTargets(PROPERTY, FIELD),
|
annotationSplitter.getAnnotationsForTargets(PROPERTY, FIELD),
|
||||||
@@ -1105,6 +1114,7 @@ public class DescriptorResolver {
|
|||||||
CallableMemberDescriptor.Kind.DECLARATION,
|
CallableMemberDescriptor.Kind.DECLARATION,
|
||||||
toSourceElement(parameter)
|
toSourceElement(parameter)
|
||||||
);
|
);
|
||||||
|
propertyWrapper.setProperty(propertyDescriptor);
|
||||||
propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(),
|
propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
getDispatchReceiverParameterIfNeeded(classDescriptor), (ReceiverParameterDescriptor) null);
|
getDispatchReceiverParameterIfNeeded(classDescriptor), (ReceiverParameterDescriptor) null);
|
||||||
|
|
||||||
|
|||||||
@@ -16,20 +16,71 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.util
|
package org.jetbrains.kotlin.util
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.*
|
import org.jetbrains.kotlin.descriptors.annotations.*
|
||||||
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import kotlin.platform.platformStatic
|
import kotlin.platform.platformStatic
|
||||||
|
|
||||||
public class AnnotationSplitter(original: Annotations, applicableTargets: Set<AnnotationUseSiteTarget>) {
|
/*
|
||||||
private val annotations: Map<AnnotationUseSiteTarget, List<AnnotationWithTarget>>
|
This class lazily splits Annotations into several different Annotations according to declaration site target priority on property.
|
||||||
public val otherAnnotations: Annotations
|
Basically you pass an original Annotations and a list of targets applicable for your declaration.
|
||||||
|
|
||||||
init {
|
Example: Annotations = [@property:P1, @field:F1, F2, P2, T],
|
||||||
|
F2, P2, T are annotations with declaration site targets 'field', 'property' and 'type', respectively.
|
||||||
|
|
||||||
|
Annotations will be split as:
|
||||||
|
FIELD -> [F1, F2], (even if F2 is applicable to PROPERTY because of target priority)
|
||||||
|
PROPERTY -> [P1, P2],
|
||||||
|
other -> [T].
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class AnnotationSplitter(
|
||||||
|
storageManager: StorageManager,
|
||||||
|
allAnnotations: Annotations,
|
||||||
|
applicableTargetsLazy: () -> Set<AnnotationUseSiteTarget>
|
||||||
|
) {
|
||||||
|
public companion object {
|
||||||
|
private val TARGET_PRIORITIES = setOf(CONSTRUCTOR_PARAMETER, FIELD, PROPERTY, PROPERTY_SETTER, PROPERTY_GETTER)
|
||||||
|
|
||||||
|
@platformStatic
|
||||||
|
public fun create(
|
||||||
|
storageManager: StorageManager,
|
||||||
|
annotations: Annotations,
|
||||||
|
targets: Set<AnnotationUseSiteTarget>
|
||||||
|
): AnnotationSplitter {
|
||||||
|
return AnnotationSplitter(storageManager, annotations, { targets })
|
||||||
|
}
|
||||||
|
|
||||||
|
@platformStatic
|
||||||
|
public 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
@platformStatic
|
||||||
|
public 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PropertyWrapper(public var property: PropertyDescriptor? = null)
|
||||||
|
|
||||||
|
private val splitAnnotations = storageManager.createLazyValue {
|
||||||
val map = hashMapOf<AnnotationUseSiteTarget, MutableList<AnnotationWithTarget>>()
|
val map = hashMapOf<AnnotationUseSiteTarget, MutableList<AnnotationWithTarget>>()
|
||||||
val other = arrayListOf<AnnotationWithTarget>()
|
val other = arrayListOf<AnnotationWithTarget>()
|
||||||
|
val applicableTargets = applicableTargetsLazy()
|
||||||
|
|
||||||
outer@ for (annotationWithTarget in original.getAllAnnotations()) {
|
outer@ for (annotationWithTarget in allAnnotations.getAllAnnotations()) {
|
||||||
val useSiteTarget = annotationWithTarget.target
|
val useSiteTarget = annotationWithTarget.target
|
||||||
if (useSiteTarget != null) {
|
if (useSiteTarget != null) {
|
||||||
if (useSiteTarget in applicableTargets)
|
if (useSiteTarget in applicableTargets)
|
||||||
@@ -45,9 +96,8 @@ public class AnnotationSplitter(original: Annotations, applicableTargets: Set<An
|
|||||||
|
|
||||||
val declarationSiteTargetForCurrentTarget = KotlinTarget.USE_SITE_MAPPING[target] ?: continue
|
val declarationSiteTargetForCurrentTarget = KotlinTarget.USE_SITE_MAPPING[target] ?: continue
|
||||||
val applicableTargetsForAnnotation = AnnotationChecker.applicableTargetSet(annotationWithTarget.annotation)
|
val applicableTargetsForAnnotation = AnnotationChecker.applicableTargetSet(annotationWithTarget.annotation)
|
||||||
val applicable = applicableTargetsForAnnotation.any { it == declarationSiteTargetForCurrentTarget }
|
|
||||||
|
|
||||||
if (applicable) {
|
if (declarationSiteTargetForCurrentTarget in applicableTargetsForAnnotation) {
|
||||||
map.getOrPut(target, { arrayListOf() }).add(annotationWithTarget)
|
map.getOrPut(target, { arrayListOf() }).add(annotationWithTarget)
|
||||||
continue@outer
|
continue@outer
|
||||||
}
|
}
|
||||||
@@ -55,31 +105,34 @@ public class AnnotationSplitter(original: Annotations, applicableTargets: Set<An
|
|||||||
|
|
||||||
other.add(annotationWithTarget)
|
other.add(annotationWithTarget)
|
||||||
}
|
}
|
||||||
annotations = map
|
map to AnnotationsImpl.create(other)
|
||||||
otherAnnotations = AnnotationsImpl.create(other)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun getAnnotationsForTarget(target: AnnotationUseSiteTarget): Annotations {
|
public fun getOtherAnnotations(): Annotations = LazySplitAnnotations(null)
|
||||||
val annotations = annotations[target] ?: return Annotations.EMPTY
|
|
||||||
return AnnotationsImpl.create(annotations)
|
public fun getAnnotationsForTarget(target: AnnotationUseSiteTarget): Annotations = LazySplitAnnotations(target)
|
||||||
}
|
|
||||||
|
|
||||||
public fun getAnnotationsForTargets(vararg targets: AnnotationUseSiteTarget): Annotations {
|
public fun getAnnotationsForTargets(vararg targets: AnnotationUseSiteTarget): Annotations {
|
||||||
return CompositeAnnotations(targets.map { getAnnotationsForTarget(it) })
|
return CompositeAnnotations(targets.map { getAnnotationsForTarget(it) })
|
||||||
}
|
}
|
||||||
|
|
||||||
public companion object {
|
private inner class LazySplitAnnotations(target: AnnotationUseSiteTarget?) : Annotations {
|
||||||
private val TARGET_PRIORITIES = setOf(CONSTRUCTOR_PARAMETER, FIELD, PROPERTY, PROPERTY_SETTER, PROPERTY_GETTER)
|
private val annotations: Annotations by lazy {
|
||||||
|
val splitAnnotations = this@AnnotationSplitter.splitAnnotations()
|
||||||
|
|
||||||
platformStatic
|
if (target != null)
|
||||||
public fun create(original: Annotations, parameter: Boolean, hasBackingField: Boolean, isMutable: Boolean): AnnotationSplitter {
|
AnnotationsImpl.create(splitAnnotations.first[target] ?: emptyList())
|
||||||
return AnnotationSplitter(original, with(hashSetOf(PROPERTY, PROPERTY_GETTER)) {
|
else
|
||||||
if (parameter) add(CONSTRUCTOR_PARAMETER)
|
splitAnnotations.second
|
||||||
if (hasBackingField) add(FIELD)
|
|
||||||
if (isMutable) add(PROPERTY_SETTER)
|
|
||||||
this
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isEmpty() = annotations.isEmpty()
|
||||||
|
override fun findAnnotation(fqName: FqName) = annotations.findAnnotation(fqName)
|
||||||
|
override fun getUseSiteTargetedAnnotations() = annotations.getUseSiteTargetedAnnotations()
|
||||||
|
override fun getAllAnnotations() = annotations.getAllAnnotations()
|
||||||
|
override fun findExternalAnnotation(fqName: FqName) = annotations.findExternalAnnotation(fqName)
|
||||||
|
override fun iterator() = annotations.iterator()
|
||||||
|
override fun toString() = annotations.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user