merge @JetProperty and @JetMethod
because: * have common parts * reduce class size Also add helper JetMethodAnnotationWriter class And also do not generate @Jet* annotations for closures
This commit is contained in:
@@ -24,7 +24,6 @@ import org.objectweb.asm.commons.Method;
|
||||
import org.objectweb.asm.signature.SignatureWriter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -184,7 +183,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
final CodegenContext.ClosureContext closureContext = context.intoClosure(funDescriptor, function, name, this, state.getTypeMapper());
|
||||
FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state);
|
||||
JvmMethodSignature jvmMethodSignature = invokeSignature(funDescriptor);
|
||||
fc.generateMethod(body, jvmMethodSignature, null, funDescriptor);
|
||||
fc.generateMethod(body, jvmMethodSignature, false, null, funDescriptor);
|
||||
return closureContext.outerWasUsed;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
@@ -44,21 +43,26 @@ public class FunctionCodegen {
|
||||
final NamedFunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, f);
|
||||
assert functionDescriptor != null;
|
||||
JvmMethodSignature method = typeMapper.mapToCallableMethod(functionDescriptor, false, owner.getContextKind()).getSignature();
|
||||
generateMethod(f, method, null, functionDescriptor);
|
||||
generateMethod(f, method, true, null, functionDescriptor);
|
||||
}
|
||||
|
||||
public void generateMethod(JetDeclarationWithBody f, JvmMethodSignature jvmMethod, @Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor) {
|
||||
public void generateMethod(JetDeclarationWithBody f,
|
||||
JvmMethodSignature jvmMethod, boolean needJetAnnotations,
|
||||
@Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor) {
|
||||
|
||||
CodegenContext.MethodContext funContext = owner.intoFunction(functionDescriptor);
|
||||
|
||||
final JetExpression bodyExpression = f.getBodyExpression();
|
||||
generatedMethod(bodyExpression, jvmMethod, propertyTypeSignature, funContext, functionDescriptor, f);
|
||||
generatedMethod(bodyExpression, jvmMethod, needJetAnnotations, propertyTypeSignature, funContext, functionDescriptor, f);
|
||||
}
|
||||
|
||||
private void generatedMethod(JetExpression bodyExpressions,
|
||||
JvmMethodSignature jvmSignature,
|
||||
@Nullable String propertyTypeSignature,
|
||||
CodegenContext.MethodContext context,
|
||||
FunctionDescriptor functionDescriptor, JetDeclarationWithBody fun)
|
||||
JvmMethodSignature jvmSignature,
|
||||
boolean needJetAnnotations, @Nullable String propertyTypeSignature,
|
||||
CodegenContext.MethodContext context,
|
||||
FunctionDescriptor functionDescriptor,
|
||||
JetDeclarationWithBody fun
|
||||
)
|
||||
{
|
||||
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
|
||||
List<TypeParameterDescriptor> typeParameters = (functionDescriptor instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)functionDescriptor).getCorrespondingProperty(): functionDescriptor).getTypeParameters();
|
||||
@@ -77,6 +81,10 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
OwnerKind kind = context.getContextKind();
|
||||
|
||||
if (kind == OwnerKind.TRAIT_IMPL) {
|
||||
needJetAnnotations = false;
|
||||
}
|
||||
|
||||
ReceiverDescriptor expectedThisObject = functionDescriptor.getExpectedThisObject();
|
||||
ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter();
|
||||
@@ -92,62 +100,52 @@ public class FunctionCodegen {
|
||||
final MethodVisitor mv = v.newMethod(fun, flags, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(), jvmSignature.getGenericsSignature(), null);
|
||||
if(v.generateCode()) {
|
||||
int start = 0;
|
||||
if(kind != OwnerKind.TRAIT_IMPL) {
|
||||
if (needJetAnnotations) {
|
||||
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
|
||||
PropertyCodegen.generateJetPropertyAnnotation(mv, propertyTypeSignature, jvmSignature.getKotlinTypeParameter());
|
||||
} else if (functionDescriptor instanceof NamedFunctionDescriptor) {
|
||||
if (propertyTypeSignature != null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
AnnotationVisitor av = mv.visitAnnotation(JvmStdlibNames.JET_METHOD.getDescriptor(), true);
|
||||
if(functionDescriptor.getReturnType().isNullable()) {
|
||||
av.visit(JvmStdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, true);
|
||||
}
|
||||
if (jvmSignature.getKotlinReturnType() != null) {
|
||||
av.visit(JvmStdlibNames.JET_METHOD_RETURN_TYPE_FIELD, jvmSignature.getKotlinReturnType());
|
||||
}
|
||||
if (jvmSignature.getKotlinTypeParameter() != null) {
|
||||
av.visit(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, jvmSignature.getKotlinTypeParameter());
|
||||
}
|
||||
av.visitEnd();
|
||||
JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv);
|
||||
aw.writeKind(JvmStdlibNames.JET_METHOD_KIND_REGULAR);
|
||||
aw.writeNullableReturnType(functionDescriptor.getReturnType().isNullable());
|
||||
aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter());
|
||||
aw.writeReturnType(jvmSignature.getKotlinReturnType());
|
||||
aw.visitEnd();
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
if(kind == OwnerKind.TRAIT_IMPL) {
|
||||
AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$self");
|
||||
av.visitEnd();
|
||||
}
|
||||
if(receiverParameter.exists()) {
|
||||
AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$receiver");
|
||||
if(receiverParameter.getType().isNullable()) {
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
|
||||
if(receiverParameter.exists()) {
|
||||
AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$receiver");
|
||||
if(receiverParameter.getType().isNullable()) {
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
|
||||
}
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true);
|
||||
av.visitEnd();
|
||||
}
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true);
|
||||
av.visitEnd();
|
||||
}
|
||||
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||
AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_TYPE_PARAMETER.getDescriptor(), true);
|
||||
av.visit(JvmStdlibNames.JET_TYPE_PARAMETER_NAME_FIELD, typeParameterDescriptor.getName());
|
||||
av.visitEnd();
|
||||
}
|
||||
for(int i = 0; i != paramDescrs.size(); ++i) {
|
||||
AnnotationVisitor av = mv.visitParameterAnnotation(i + start, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
|
||||
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i);
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, parameterDescriptor.getName());
|
||||
if(parameterDescriptor.hasDefaultValue()) {
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD, true);
|
||||
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||
AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_TYPE_PARAMETER.getDescriptor(), true);
|
||||
av.visit(JvmStdlibNames.JET_TYPE_PARAMETER_NAME_FIELD, typeParameterDescriptor.getName());
|
||||
av.visitEnd();
|
||||
}
|
||||
if(parameterDescriptor.getOutType().isNullable()) {
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
|
||||
for(int i = 0; i != paramDescrs.size(); ++i) {
|
||||
AnnotationVisitor av = mv.visitParameterAnnotation(i + start, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
|
||||
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i);
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, parameterDescriptor.getName());
|
||||
if(parameterDescriptor.hasDefaultValue()) {
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD, true);
|
||||
}
|
||||
if(parameterDescriptor.getOutType().isNullable()) {
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
|
||||
}
|
||||
if (jvmSignature.getKotlinParameterTypes() != null && jvmSignature.getKotlinParameterTypes().get(i) != null) {
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(i + start).getKotlinSignature());
|
||||
}
|
||||
av.visitEnd();
|
||||
}
|
||||
if (jvmSignature.getKotlinParameterTypes() != null && jvmSignature.getKotlinParameterTypes().get(i) != null) {
|
||||
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(i + start).getKotlinSignature());
|
||||
}
|
||||
av.visitEnd();
|
||||
}
|
||||
}
|
||||
if (!isAbstract && v.generateCode()) {
|
||||
|
||||
@@ -245,7 +245,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod();
|
||||
MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
|
||||
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(), originalSignature.getJvmMethodSignature().getKotlinTypeParameter());
|
||||
mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true).visitEnd();
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
|
||||
@@ -269,7 +268,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod();
|
||||
MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
|
||||
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(), originalSignature2.getJvmMethodSignature().getKotlinTypeParameter());
|
||||
mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true).visitEnd();
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public class JetMethodAnnotationWriter {
|
||||
private final AnnotationVisitor av;
|
||||
|
||||
private JetMethodAnnotationWriter(AnnotationVisitor av) {
|
||||
this.av = av;
|
||||
}
|
||||
|
||||
public void writeKind(int kind) {
|
||||
if (kind != JvmStdlibNames.JET_METHOD_KIND_DEFAULT) {
|
||||
av.visit(JvmStdlibNames.JET_METHOD_KIND_FIELD, kind);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTypeParameters(@NotNull String typeParameters) {
|
||||
if (typeParameters.length() > 0) {
|
||||
av.visit(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, typeParameters);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeReturnType(@NotNull String returnType) {
|
||||
if (returnType.length() > 0) {
|
||||
av.visit(JvmStdlibNames.JET_METHOD_RETURN_TYPE_FIELD, returnType);
|
||||
}
|
||||
}
|
||||
|
||||
public void writePropertyType(@NotNull String propertyType) {
|
||||
if (propertyType.length() > 0) {
|
||||
av.visit(JvmStdlibNames.JET_METHOD_PROPERTY_TYPE_FIELD, propertyType);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeNullableReturnType(boolean nullableReturnType) {
|
||||
if (nullableReturnType) {
|
||||
av.visit(JvmStdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, nullableReturnType);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitEnd() {
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
public static JetMethodAnnotationWriter visitAnnotation(MethodVisitor mv) {
|
||||
return new JetMethodAnnotationWriter(mv.visitAnnotation(JvmStdlibNames.JET_METHOD.getDescriptor(), true));
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
@@ -89,7 +88,7 @@ public class PropertyCodegen {
|
||||
if (getter != null) {
|
||||
if (getter.getBodyExpression() != null) {
|
||||
JvmPropertyAccessorSignature signature = state.getTypeMapper().mapGetterSignature(propertyDescriptor, kind);
|
||||
functionCodegen.generateMethod(getter, signature.getJvmMethodSignature(), signature.getPropertyTypeKotlinSignature(), propertyDescriptor.getGetter());
|
||||
functionCodegen.generateMethod(getter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), propertyDescriptor.getGetter());
|
||||
}
|
||||
else if (!getter.hasModifier(JetTokens.PRIVATE_KEYWORD)) {
|
||||
generateDefaultGetter(p, getter);
|
||||
@@ -111,7 +110,7 @@ public class PropertyCodegen {
|
||||
final PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter();
|
||||
assert setterDescriptor != null;
|
||||
JvmPropertyAccessorSignature signature = state.getTypeMapper().mapSetterSignature(propertyDescriptor, kind);
|
||||
functionCodegen.generateMethod(setter, signature.getJvmMethodSignature(), signature.getPropertyTypeKotlinSignature(), setterDescriptor);
|
||||
functionCodegen.generateMethod(setter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), setterDescriptor);
|
||||
}
|
||||
else if (!p.hasModifier(JetTokens.PRIVATE_KEYWORD)) {
|
||||
generateDefaultSetter(p, setter);
|
||||
@@ -170,14 +169,11 @@ public class PropertyCodegen {
|
||||
}
|
||||
|
||||
public static void generateJetPropertyAnnotation(MethodVisitor mv, @NotNull String kotlinType, @NotNull String typeParameters) {
|
||||
AnnotationVisitor annotationVisitor = mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true);
|
||||
if (kotlinType.length() > 0) {
|
||||
annotationVisitor.visit(JvmStdlibNames.JET_PROPERTY_TYPE_FIELD, kotlinType);
|
||||
}
|
||||
if (typeParameters.length() > 0) {
|
||||
annotationVisitor.visit(JvmStdlibNames.JET_PROPERTY_TYPE_PARAMETERS_FIELD, typeParameters);
|
||||
}
|
||||
annotationVisitor.visitEnd();
|
||||
JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv);
|
||||
aw.writeKind(JvmStdlibNames.JET_METHOD_KIND_PROPERTY);
|
||||
aw.writeTypeParameters(typeParameters);
|
||||
aw.writePropertyType(kotlinType);
|
||||
aw.visitEnd();
|
||||
}
|
||||
|
||||
private void generateDefaultSetter(JetProperty p, JetDeclaration declaration) {
|
||||
|
||||
Reference in New Issue
Block a user