Simplify codegen of annotations, get rid of use-site targets

This commit is contained in:
Alexander Udalov
2018-08-14 16:36:15 +02:00
parent fc87043cb3
commit 753191e668
6 changed files with 15 additions and 58 deletions
@@ -99,28 +99,13 @@ public abstract class AnnotationCodegen {
* @param returnType can be null if not applicable (e.g. {@code annotated} is a class)
*/
public void genAnnotations(@Nullable Annotated annotated, @Nullable Type returnType) {
genAnnotations(annotated, returnType, null);
}
public void genAnnotations(@Nullable Annotated annotated, @Nullable Type returnType, @Nullable AnnotationUseSiteTarget allowedTarget) {
if (annotated == null) {
return;
}
if (annotated == null) return;
Set<String> annotationDescriptorsAlreadyPresent = new HashSet<>();
Annotations annotations = annotated.getAnnotations();
for (AnnotationWithTarget annotationWithTarget : annotations.getAllAnnotations()) {
AnnotationDescriptor annotation = annotationWithTarget.getAnnotation();
AnnotationUseSiteTarget annotationTarget = annotationWithTarget.getTarget();
// Skip targeted annotations by default
if (allowedTarget == null && annotationTarget != null) continue;
// Skip if the target is not the same
if (allowedTarget != null && annotationTarget != null && allowedTarget != annotationTarget) continue;
for (AnnotationDescriptor annotation : annotations) {
Set<KotlinTarget> applicableTargets = AnnotationChecker.applicableTargetSet(annotation);
if (annotated instanceof AnonymousFunctionDescriptor
&& !applicableTargets.contains(KotlinTarget.FUNCTION)
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt;
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
@@ -72,8 +71,6 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable;
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.PROPERTY_GETTER;
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.PROPERTY_SETTER;
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly;
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
@@ -232,9 +229,9 @@ public class FunctionCodegen {
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, CodegenUtilKt.unwrapFrontendVersion(functionDescriptor), asmMethod);
}
generateMethodAnnotations(functionDescriptor, asmMethod, mv, memberCodegen, typeMapper);
AnnotationCodegen.forMethod(mv, memberCodegen, typeMapper).genAnnotations(functionDescriptor, asmMethod.getReturnType());
generateParameterAnnotations(functionDescriptor, mv, jvmSignature);
generateParameterAnnotations(functionDescriptor, mv, jvmSignature, memberCodegen, state);
GenerateJava8ParameterNamesKt.generateParameterNames(functionDescriptor, mv, jvmSignature, state, (flags & ACC_SYNTHETIC) != 0);
if (contextKind != OwnerKind.ERASED_INLINE_CLASS) {
@@ -474,32 +471,6 @@ public class FunctionCodegen {
);
}
public static void generateMethodAnnotations(
@NotNull FunctionDescriptor functionDescriptor,
Method asmMethod,
MethodVisitor mv,
@NotNull InnerClassConsumer consumer,
@NotNull KotlinTypeMapper typeMapper
) {
AnnotationCodegen annotationCodegen = AnnotationCodegen.forMethod(mv, consumer, typeMapper);
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
AnnotationUseSiteTarget target = functionDescriptor instanceof PropertySetterDescriptor ? PROPERTY_SETTER : PROPERTY_GETTER;
annotationCodegen.genAnnotations(functionDescriptor, asmMethod.getReturnType(), target);
}
else {
annotationCodegen.genAnnotations(functionDescriptor, asmMethod.getReturnType());
}
}
private void generateParameterAnnotations(
@NotNull FunctionDescriptor functionDescriptor,
@NotNull MethodVisitor mv,
@NotNull JvmMethodSignature jvmSignature
) {
generateParameterAnnotations(functionDescriptor, mv, jvmSignature, memberCodegen, state);
}
public static void generateParameterAnnotations(
@NotNull FunctionDescriptor functionDescriptor,
@NotNull MethodVisitor mv,
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotatedImpl;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
@@ -249,19 +248,18 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
if (!isAnnotationsMethodOwner || annotations.getAllAnnotations().isEmpty()) return;
String name = JvmAbi.getSyntheticMethodNameForAnnotatedTypeAlias(typeAliasDescriptor.getName());
generateSyntheticAnnotationsMethod(typeAliasDescriptor, new Method(name, "()V"), annotations, null);
generateSyntheticAnnotationsMethod(typeAliasDescriptor, new Method(name, "()V"), annotations);
}
protected void generateSyntheticAnnotationsMethod(
@NotNull MemberDescriptor descriptor,
@NotNull Method syntheticMethod,
@NotNull Annotations annotations,
@Nullable AnnotationUseSiteTarget allowedTarget
@NotNull Annotations annotations
) {
int flags = ACC_DEPRECATED | ACC_STATIC | ACC_SYNTHETIC | AsmUtil.getVisibilityAccessFlag(descriptor);
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(descriptor), flags, syntheticMethod.getName(),
syntheticMethod.getDescriptor(), null, null);
AnnotationCodegen.forMethod(mv, this, typeMapper).genAnnotations(new AnnotatedImpl(annotations), Type.VOID_TYPE, allowedTarget);
AnnotationCodegen.forMethod(mv, this, typeMapper).genAnnotations(new AnnotatedImpl(annotations), Type.VOID_TYPE);
mv.visitCode();
mv.visitInsn(Opcodes.RETURN);
mv.visitEnd();
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtilKt;
import org.jetbrains.kotlin.load.java.JvmAbi;
@@ -261,7 +260,7 @@ public class PropertyCodegen {
PropertyGetterDescriptor getter = descriptor.getGetter();
assert getter != null : "Annotation property should have a getter: " + descriptor;
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, getter, asmMethod);
FunctionCodegen.generateMethodAnnotations(getter, asmMethod, mv, memberCodegen, typeMapper);
AnnotationCodegen.forMethod(mv, memberCodegen, typeMapper).genAnnotations(getter, asmMethod.getReturnType());
KtExpression defaultValue = loadAnnotationArgumentDefaultValue(parameter, descriptor, expectedAnnotationConstructor);
if (defaultValue != null) {
@@ -338,7 +337,7 @@ public class PropertyCodegen {
if (isBackingFieldOwner) {
if (!isInterface(context.getContextDescriptor()) ||
processInterfaceMethod(descriptor, kind, false, true, state.getJvmDefaultMode())) {
memberCodegen.generateSyntheticAnnotationsMethod(descriptor, signature, annotations, AnnotationUseSiteTarget.PROPERTY);
memberCodegen.generateSyntheticAnnotationsMethod(descriptor, signature, annotations);
}
}
}
@@ -99,7 +99,9 @@ class ScriptCodegen private constructor(
OtherOrigin(scriptDeclaration, scriptDescriptor.unsubstitutedPrimaryConstructor),
ACC_PUBLIC, jvmSignature.asmMethod.name, jvmSignature.asmMethod.descriptor, null, null)
FunctionCodegen.generateMethodAnnotations(scriptDescriptor.unsubstitutedPrimaryConstructor, asmMethod, mv, this, typeMapper)
AnnotationCodegen.forMethod(mv, this, typeMapper).genAnnotations(
scriptDescriptor.unsubstitutedPrimaryConstructor, asmMethod.returnType
)
if (state.classBuilderMode.generateBodies) {
mv.visitCode()
@@ -48,7 +48,9 @@ open class FunctionCodegen(private val irFunction: IrFunction, private val class
val flags = calculateMethodFlags(irFunction.isStatic)
val methodVisitor = createMethod(flags, signature)
FunctionCodegen.generateMethodAnnotations(descriptor, signature.asmMethod, methodVisitor, classCodegen, state.typeMapper)
AnnotationCodegen.forMethod(methodVisitor, classCodegen, state.typeMapper).genAnnotations(
descriptor, signature.asmMethod.returnType
)
FunctionCodegen.generateParameterAnnotations(descriptor, methodVisitor, signature, classCodegen, state)
if (!state.classBuilderMode.generateBodies || flags.and(Opcodes.ACC_ABSTRACT) != 0 || irFunction.isExternal) {