Primary constructor generation via FunctionCodegen Strategy, local variable table generation via JvmMethodSignature and FunctionDescriptor

This commit is contained in:
Mikhael Bogdanov
2013-04-26 13:06:18 +04:00
parent 5fe6e32882
commit 83d8930c02
8 changed files with 239 additions and 213 deletions
@@ -147,7 +147,7 @@ public class AsmUtil {
int flags = getCommonCallableFlags(functionDescriptor); int flags = getCommonCallableFlags(functionDescriptor);
if (functionDescriptor.getModality() == Modality.FINAL) { if (functionDescriptor.getModality() == Modality.FINAL && !(functionDescriptor instanceof ConstructorDescriptor)) {
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
if (!(containingDeclaration instanceof ClassDescriptor) || if (!(containingDeclaration instanceof ClassDescriptor) ||
((ClassDescriptor) containingDeclaration).getKind() != ClassKind.TRAIT) { ((ClassDescriptor) containingDeclaration).getKind() != ClassKind.TRAIT) {
@@ -122,7 +122,7 @@ public class ClosureCodegen extends GenerationStateAware {
JvmMethodSignature jvmMethodSignature = typeMapper.mapSignature(interfaceFunction.getName(), funDescriptor); JvmMethodSignature jvmMethodSignature = typeMapper.mapSignature(interfaceFunction.getName(), funDescriptor);
FunctionCodegen fc = new FunctionCodegen(context, cv, state); FunctionCodegen fc = new FunctionCodegen(context, cv, state);
fc.generateMethod(fun, jvmMethodSignature, false, null, funDescriptor, strategy); fc.generateMethod(fun, jvmMethodSignature, false, funDescriptor, strategy);
this.constructor = generateConstructor(cv); this.constructor = generateConstructor(cv);
@@ -17,13 +17,10 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind; import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind;
import org.jetbrains.jet.codegen.signature.JvmMethodParameterSignature; import org.jetbrains.jet.codegen.signature.JvmMethodParameterSignature;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import java.util.Collections;
import java.util.List; import java.util.List;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
@@ -48,15 +45,6 @@ public class ConstructorFrameMap extends FrameMap {
} }
} }
} }
List<Type> explicitArgTypes = callableMethod.getValueParameterTypes();
List<ValueParameterDescriptor> paramDescrs = descriptor != null
? descriptor.getValueParameters()
: Collections.<ValueParameterDescriptor>emptyList();
for (int i = 0; i < paramDescrs.size(); i++) {
ValueParameterDescriptor parameter = paramDescrs.get(i);
enter(parameter, explicitArgTypes.get(i));
}
} }
public int getOuterThisIndex() { public int getOuterThisIndex() {
@@ -1249,7 +1249,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
JvmClassName closureSuperClass = samInterfaceClass == null ? getFunctionImplClassName(descriptor) : JvmClassName.byType(OBJECT_TYPE); JvmClassName closureSuperClass = samInterfaceClass == null ? getFunctionImplClassName(descriptor) : JvmClassName.byType(OBJECT_TYPE);
ClosureCodegen closureCodegen = new ClosureCodegen(state, declaration, descriptor, samInterfaceClass, closureSuperClass, context, ClosureCodegen closureCodegen = new ClosureCodegen(state, declaration, descriptor, samInterfaceClass, closureSuperClass, context,
this, new FunctionGenerationStrategy.Default(state, declaration)); this, new FunctionGenerationStrategy.FunctionDefault(state, descriptor, declaration));
closureCodegen.gen(); closureCodegen.gen();
@@ -2335,14 +2335,23 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
JvmClassName closureSuperClass = JvmClassName.byType(typeMapper.mapType(kFunctionImpl)); JvmClassName closureSuperClass = JvmClassName.byType(typeMapper.mapType(kFunctionImpl));
ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, closureSuperClass, context, this, ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, closureSuperClass, context, this,
new FunctionGenerationStrategy() { new FunctionGenerationStrategy.CodegenBased(state, functionDescriptor) {
@Override @Override
public void generateBody( public ExpressionCodegen initializeExpressionCodegen(
@NotNull MethodVisitor mv, JvmMethodSignature signature, MethodContext context, MethodVisitor mv,
@NotNull JvmMethodSignature signature, Type returnType
@NotNull MethodContext context,
@NotNull FrameMap frameMap
) { ) {
FunctionDescriptor referencedFunction = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
JetType returnJetType = referencedFunction.getReturnType();
assert returnJetType != null : "Return type can't be null: " + referencedFunction;
return super.initializeExpressionCodegen(signature, context,
mv, typeMapper.mapReturnType(returnJetType));
}
@Override
public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) {
/* /*
Here we need to put the arguments from our locals to the stack and invoke the referenced method. Since invokation Here we need to put the arguments from our locals to the stack and invoke the referenced method. Since invokation
of methods is highly dependent on expressions, we create a fake call expression. Then we create a new instance of of methods is highly dependent on expressions, we create a fake call expression. Then we create a new instance of
@@ -2352,17 +2361,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
*/ */
FunctionDescriptor referencedFunction = (FunctionDescriptor) resolvedCall.getResultingDescriptor(); FunctionDescriptor referencedFunction = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
JetType returnJetType = referencedFunction.getReturnType();
assert returnJetType != null : "Return type can't be null: " + referencedFunction;
Type returnType = typeMapper.mapReturnType(returnJetType);
JetCallExpression fakeExpression = constructFakeFunctionCall(referencedFunction); JetCallExpression fakeExpression = constructFakeFunctionCall(referencedFunction);
final List<? extends ValueArgument> fakeArguments = fakeExpression.getValueArguments(); final List<? extends ValueArgument> fakeArguments = fakeExpression.getValueArguments();
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, returnType, context, state);
final ReceiverValue receiverValue = computeAndSaveReceiver(signature, codegen); final ReceiverValue receiverValue = computeAndSaveReceiver(signature, codegen);
computeAndSaveArguments(frameMap, fakeArguments, codegen); computeAndSaveArguments(codegen.myFrameMap, fakeArguments, codegen);
ResolvedCall<CallableDescriptor> fakeResolvedCall = new DelegatingResolvedCall<CallableDescriptor>(resolvedCall) { ResolvedCall<CallableDescriptor> fakeResolvedCall = new DelegatingResolvedCall<CallableDescriptor>(resolvedCall) {
@NotNull @NotNull
@@ -2389,9 +2393,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}; };
StackValue result; StackValue result;
Type returnType = codegen.returnType;
if (referencedFunction instanceof ConstructorDescriptor) { if (referencedFunction instanceof ConstructorDescriptor) {
if (returnType.getSort() == Type.ARRAY) { if (returnType.getSort() == Type.ARRAY) {
codegen.generateNewArray(fakeExpression, returnJetType); codegen.generateNewArray(fakeExpression, referencedFunction.getReturnType());
result = StackValue.onStack(returnType); result = StackValue.onStack(returnType);
} }
else { else {
@@ -2403,7 +2408,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
result = codegen.invokeFunction(call, StackValue.none(), fakeResolvedCall); result = codegen.invokeFunction(call, StackValue.none(), fakeResolvedCall);
} }
InstructionAdapter v = new InstructionAdapter(mv); InstructionAdapter v = codegen.v;
result.put(returnType, v); result.put(returnType, v);
v.areturn(returnType); v.areturn(returnType);
} }
@@ -2463,11 +2468,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return new ExpressionReceiver(receiverExpression, receiver.getType()); return new ExpressionReceiver(receiverExpression, receiver.getType());
} }
@Override
public boolean needsLocalVariableTable() {
return false;
}
} }
); );
@@ -20,6 +20,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.psi.PsiElement; 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.asm4.AnnotationVisitor;
import org.jetbrains.asm4.Label; import org.jetbrains.asm4.Label;
import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Type; import org.jetbrains.asm4.Type;
@@ -28,8 +29,10 @@ import org.jetbrains.asm4.commons.Method;
import org.jetbrains.jet.codegen.binding.CodegenBinding; import org.jetbrains.jet.codegen.binding.CodegenBinding;
import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.context.CodegenContext;
import org.jetbrains.jet.codegen.context.MethodContext; import org.jetbrains.jet.codegen.context.MethodContext;
import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind;
import org.jetbrains.jet.codegen.signature.JvmMethodParameterSignature; import org.jetbrains.jet.codegen.signature.JvmMethodParameterSignature;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature;
import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter; import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter;
import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter; import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter;
import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationState;
@@ -81,8 +84,8 @@ public class FunctionCodegen extends GenerationStateAware {
if (kind != OwnerKind.TRAIT_IMPL || function.getBodyExpression() != null) { if (kind != OwnerKind.TRAIT_IMPL || function.getBodyExpression() != null) {
boolean needJetAnnotations = kind != OwnerKind.TRAIT_IMPL; boolean needJetAnnotations = kind != OwnerKind.TRAIT_IMPL;
generateMethod(function, method, needJetAnnotations, null, functionDescriptor, generateMethod(function, method, needJetAnnotations, functionDescriptor,
new FunctionGenerationStrategy.Default(state, function)); new FunctionGenerationStrategy.FunctionDefault(state, functionDescriptor, function));
} }
generateDefaultIfNeeded(owner.intoFunction(functionDescriptor), state, v, method.getAsmMethod(), functionDescriptor, kind, generateDefaultIfNeeded(owner.intoFunction(functionDescriptor), state, v, method.getAsmMethod(), functionDescriptor, kind,
@@ -93,16 +96,25 @@ public class FunctionCodegen extends GenerationStateAware {
@Nullable PsiElement origin, @Nullable PsiElement origin,
@NotNull JvmMethodSignature jvmSignature, @NotNull JvmMethodSignature jvmSignature,
boolean needJetAnnotations, boolean needJetAnnotations,
@Nullable String propertyTypeSignature,
@NotNull FunctionDescriptor functionDescriptor, @NotNull FunctionDescriptor functionDescriptor,
@NotNull FunctionGenerationStrategy strategy @NotNull FunctionGenerationStrategy strategy
) { ) {
MethodContext context = owner.intoFunction(functionDescriptor); generateMethod(origin, jvmSignature, needJetAnnotations, functionDescriptor, owner.intoFunction(functionDescriptor), strategy);
}
public void generateMethod(
@Nullable PsiElement origin,
@NotNull JvmMethodSignature jvmSignature,
boolean needJetAnnotations,
@NotNull FunctionDescriptor functionDescriptor,
@NotNull MethodContext methodContext,
@NotNull FunctionGenerationStrategy strategy
) {
Method asmMethod = jvmSignature.getAsmMethod(); Method asmMethod = jvmSignature.getAsmMethod();
MethodVisitor mv = v.newMethod(origin, MethodVisitor mv = v.newMethod(origin,
getMethodAsmFlags(functionDescriptor, context.getContextKind()), getMethodAsmFlags(functionDescriptor, methodContext.getContextKind()),
asmMethod.getName(), asmMethod.getName(),
asmMethod.getDescriptor(), asmMethod.getDescriptor(),
jvmSignature.getGenericsSignature(), jvmSignature.getGenericsSignature(),
@@ -112,17 +124,17 @@ public class FunctionCodegen extends GenerationStateAware {
if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) return; if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) return;
if (needJetAnnotations) { if (needJetAnnotations) {
genJetAnnotations(mv, functionDescriptor, propertyTypeSignature); genJetAnnotations(mv, functionDescriptor, jvmSignature);
} }
if (isAbstract(functionDescriptor, context.getContextKind())) return; if (isAbstract(functionDescriptor, methodContext.getContextKind())) return;
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
genStubCode(mv); genStubCode(mv);
return; return;
} }
generateMethodBody(mv, functionDescriptor, context, jvmSignature, strategy); generateMethodBody(mv, functionDescriptor, methodContext, jvmSignature, strategy);
endVisit(mv, null, origin); endVisit(mv, null, origin);
@@ -132,7 +144,10 @@ public class FunctionCodegen extends GenerationStateAware {
@Nullable @Nullable
private Type getThisTypeForFunction(@NotNull FunctionDescriptor functionDescriptor, @NotNull MethodContext context) { private Type getThisTypeForFunction(@NotNull FunctionDescriptor functionDescriptor, @NotNull MethodContext context) {
ReceiverParameterDescriptor expectedThisObject = functionDescriptor.getExpectedThisObject(); ReceiverParameterDescriptor expectedThisObject = functionDescriptor.getExpectedThisObject();
if (expectedThisObject != null) { if (functionDescriptor instanceof ConstructorDescriptor) {
return typeMapper.mapType(functionDescriptor.getReturnType());
}
else if (expectedThisObject != null) {
return typeMapper.mapType(expectedThisObject.getType()); return typeMapper.mapType(expectedThisObject.getType());
} }
else if (isFunctionLiteral(functionDescriptor) || isLocalNamedFun(functionDescriptor)) { else if (isFunctionLiteral(functionDescriptor) || isLocalNamedFun(functionDescriptor)) {
@@ -164,7 +179,7 @@ public class FunctionCodegen extends GenerationStateAware {
generateStaticDelegateMethodBody(mv, signature.getAsmMethod(), (OwnerKind.StaticDelegateKind) kind); generateStaticDelegateMethodBody(mv, signature.getAsmMethod(), (OwnerKind.StaticDelegateKind) kind);
} }
else { else {
FrameMap frameMap = context.prepareFrame(typeMapper); FrameMap frameMap = strategy.getFrameMap(typeMapper, context);
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) { for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) {
frameMap.enter(parameter, typeMapper.mapType(parameter)); frameMap.enter(parameter, typeMapper.mapType(parameter));
@@ -174,7 +189,7 @@ public class FunctionCodegen extends GenerationStateAware {
genNotNullAssertionsForParameters(new InstructionAdapter(mv), state, functionDescriptor, frameMap); genNotNullAssertionsForParameters(new InstructionAdapter(mv), state, functionDescriptor, frameMap);
strategy.generateBody(mv, signature, context, frameMap); strategy.generateBody(mv, signature, context);
localVariableNames.addAll(strategy.getLocalVariableNames()); localVariableNames.addAll(strategy.getLocalVariableNames());
} }
@@ -182,10 +197,9 @@ public class FunctionCodegen extends GenerationStateAware {
Label methodEnd = new Label(); Label methodEnd = new Label();
mv.visitLabel(methodEnd); mv.visitLabel(methodEnd);
if (strategy.needsLocalVariableTable()) {
Type thisType = getThisTypeForFunction(functionDescriptor, context); Type thisType = getThisTypeForFunction(functionDescriptor, context);
generateLocalVariableTable(mv, functionDescriptor, thisType, methodBegin, methodEnd, localVariableNames, labelsForSharedVars); generateLocalVariableTable(mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, localVariableNames, labelsForSharedVars, kind);
}
} }
@NotNull @NotNull
@@ -200,47 +214,59 @@ public class FunctionCodegen extends GenerationStateAware {
private void generateLocalVariableTable( private void generateLocalVariableTable(
@NotNull MethodVisitor mv, @NotNull MethodVisitor mv,
@NotNull JvmMethodSignature jvmMethodSignature,
@NotNull FunctionDescriptor functionDescriptor, @NotNull FunctionDescriptor functionDescriptor,
@Nullable Type thisType, @Nullable Type thisType,
@NotNull Label methodBegin, @NotNull Label methodBegin,
@NotNull Label methodEnd, @NotNull Label methodEnd,
@NotNull Collection<String> localVariableNames, @NotNull Collection<String> localVariableNames,
@NotNull Map<Name, Label> labelsForSharedVars @NotNull Map<Name, Label> labelsForSharedVars,
@NotNull OwnerKind ownerKind
) { ) {
// TODO: specify signatures Iterator<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters().iterator();
List<JvmMethodParameterSignature> params = jvmMethodSignature.getKotlinParameterTypes();
int shift = 0;
int k = 0; boolean isStatic = isStatic(ownerKind) || ownerKind == OwnerKind.TRAIT_IMPL;
if (!isStatic) {
if (thisType != null) { //add this
mv.visitLocalVariable("this", thisType.getDescriptor(), null, methodBegin, methodEnd, k++); if (thisType != null) {
mv.visitLocalVariable("this", thisType.getDescriptor(), null, methodBegin, methodEnd, shift);
} else {
//sometimes there is no thisType for callable reference
}
shift++;
} }
ReceiverParameterDescriptor receiverParameter = functionDescriptor.getReceiverParameter(); for (int i = 0; i < params.size(); i++) {
if (receiverParameter != null) { JvmMethodParameterSignature param = params.get(i);
Type type = typeMapper.mapType(receiverParameter.getType()); JvmMethodParameterKind kind = param.getKind();
mv.visitLocalVariable(JvmAbi.RECEIVER_PARAMETER, type.getDescriptor(), null, methodBegin, methodEnd, k); String parameterName = "$" + param.getKind().name().toLowerCase();
k += type.getSize();
}
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) { if (needIndexForVar(kind)) {
Type type = typeMapper.mapType(parameter); parameterName = parameterName + "$" + i;
Label divideLabel = labelsForSharedVars.get(parameter.getName());
String parameterName = parameter.getName().getName();
if (divideLabel != null) {
mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, divideLabel, k);
String nameForSharedVar = createTmpVariableName(localVariableNames);
localVariableNames.add(nameForSharedVar);
Type sharedVarType = typeMapper.getSharedVarType(parameter);
mv.visitLocalVariable(nameForSharedVar, sharedVarType.getDescriptor(), null, divideLabel, methodEnd, k);
k += Math.max(type.getSize(), sharedVarType.getSize());
} }
else {
mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, methodEnd, k); Type type = param.getAsmType();
k += type.getSize(); if (kind == JvmMethodParameterKind.VALUE) {
ValueParameterDescriptor parameter = valueParameters.next();
Label divideLabel = labelsForSharedVars.get(parameter.getName());
parameterName = parameter.getName().getName();
if (divideLabel != null) {
mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, divideLabel, shift);
String nameForSharedVar = createTmpVariableName(localVariableNames);
localVariableNames.add(nameForSharedVar);
Type sharedVarType = typeMapper.getSharedVarType(parameter);
mv.visitLocalVariable(nameForSharedVar, sharedVarType.getDescriptor(), null, divideLabel, methodEnd, shift);
shift += Math.max(type.getSize(), sharedVarType.getSize());
continue;
}
} }
mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, methodEnd, shift);
shift += type.getSize();
} }
} }
@@ -304,18 +330,16 @@ public class FunctionCodegen extends GenerationStateAware {
private void genJetAnnotations( private void genJetAnnotations(
@NotNull MethodVisitor mv, @NotNull MethodVisitor mv,
@NotNull FunctionDescriptor functionDescriptor, @NotNull FunctionDescriptor functionDescriptor,
@Nullable String propertyTypeSignature @NotNull JvmMethodSignature jvmSignature
) { ) {
JvmMethodSignature jvmSignature =
typeMapper.mapToCallableMethod(functionDescriptor, false, false, false, OwnerKind.IMPLEMENTATION).getSignature();
if (functionDescriptor instanceof PropertyAccessorDescriptor) { if (functionDescriptor instanceof PropertyAccessorDescriptor) {
assert propertyTypeSignature != null; assert jvmSignature instanceof JvmPropertyAccessorSignature;
PropertyCodegen.generateJetPropertyAnnotation(mv, propertyTypeSignature, jvmSignature.getKotlinTypeParameter(), PropertyCodegen.generateJetPropertyAnnotation(mv, (JvmPropertyAccessorSignature) jvmSignature,
((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty(), functionDescriptor.getVisibility()); ((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty(), functionDescriptor.getVisibility());
} }
else if (functionDescriptor instanceof SimpleFunctionDescriptor) { else if (functionDescriptor instanceof SimpleFunctionDescriptor) {
if (propertyTypeSignature != null) { if (jvmSignature instanceof JvmPropertyAccessorSignature) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
Modality modality = functionDescriptor.getModality(); Modality modality = functionDescriptor.getModality();
@@ -334,36 +358,57 @@ public class FunctionCodegen extends GenerationStateAware {
aw.writeReturnType(jvmSignature.getKotlinReturnType()); aw.writeReturnType(jvmSignature.getKotlinReturnType());
aw.visitEnd(); aw.visitEnd();
} }
else if (functionDescriptor instanceof ConstructorDescriptor) {
AnnotationVisitor jetConstructorVisitor = mv.visitAnnotation(JvmStdlibNames.JET_CONSTRUCTOR.getDescriptor(), true);
int flagsValue = getFlagsForVisibility(functionDescriptor.getVisibility());
if (JvmStdlibNames.FLAGS_DEFAULT_VALUE != flagsValue) {
jetConstructorVisitor.visit(JvmStdlibNames.JET_FLAGS_FIELD, flagsValue);
}
jetConstructorVisitor.visitEnd();
}
else { else {
throw new IllegalStateException(); throw new IllegalStateException();
} }
Iterator<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters().iterator();
List<JvmMethodParameterSignature> kotlinParameterTypes = jvmSignature.getKotlinParameterTypes(); List<JvmMethodParameterSignature> kotlinParameterTypes = jvmSignature.getKotlinParameterTypes();
assert kotlinParameterTypes != null; assert kotlinParameterTypes != null;
int start = 0; for (int i = 0; i < kotlinParameterTypes.size(); i++) {
ReceiverParameterDescriptor receiverParameter = functionDescriptor.getReceiverParameter(); JvmMethodParameterSignature param = kotlinParameterTypes.get(i);
if (receiverParameter != null) { JvmMethodParameterKind kind = param.getKind();
JetValueParameterAnnotationWriter av = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, start++); String parameterName = "$" + param.getKind().name().toLowerCase();
av.writeName(JvmAbi.RECEIVER_PARAMETER);
av.writeReceiver(); ValueParameterDescriptor parameterDescriptor = null;
av.writeType(kotlinParameterTypes.get(0).getKotlinSignature()); if (kind == JvmMethodParameterKind.VALUE) {
av.visitEnd(); parameterDescriptor = valueParameters.next();
} parameterName = parameterDescriptor.getName().getName();
} else if (needIndexForVar(kind)) {
parameterName = parameterName + "$" + i;
}
List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
for (int i = 0; i != valueParameters.size(); ++i) {
ValueParameterDescriptor parameterDescriptor = valueParameters.get(i);
AnnotationCodegen.forParameter(i, mv, typeMapper).genAnnotations(parameterDescriptor); AnnotationCodegen.forParameter(i, mv, typeMapper).genAnnotations(parameterDescriptor);
JetValueParameterAnnotationWriter av = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i + start); JetValueParameterAnnotationWriter av = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i);
av.writeName(parameterDescriptor.getName().getName()); av.writeName(parameterName);
av.writeHasDefaultValue(parameterDescriptor.declaresDefaultValue()); if (kind == JvmMethodParameterKind.RECEIVER) {
av.writeVararg(parameterDescriptor.getVarargElementType() != null); av.writeReceiver();
av.writeType(kotlinParameterTypes.get(i + start).getKotlinSignature()); }
if (parameterDescriptor != null) {
av.writeHasDefaultValue(parameterDescriptor.declaresDefaultValue());
av.writeVararg(parameterDescriptor.getVarargElementType() != null);
}
av.writeType(param.getKotlinSignature());
av.visitEnd(); av.visitEnd();
} }
} }
private boolean needIndexForVar(JvmMethodParameterKind kind) {
return kind == JvmMethodParameterKind.SHARED_VAR || kind == JvmMethodParameterKind.SUPER_CALL_PARAM;
}
public static void endVisit(MethodVisitor mv, @Nullable String description, @Nullable PsiElement method) { public static void endVisit(MethodVisitor mv, @Nullable String description, @Nullable PsiElement method) {
try { try {
mv.visitMaxs(-1, -1); mv.visitMaxs(-1, -1);
@@ -18,22 +18,28 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.codegen.context.CodegenContext;
import org.jetbrains.jet.codegen.context.MethodContext; import org.jetbrains.jet.codegen.context.MethodContext;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody; import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
public abstract class FunctionGenerationStrategy { public abstract class FunctionGenerationStrategy<T extends CallableDescriptor> {
private final Collection<String> localVariableNames = new ArrayList<String>(); private final Collection<String> localVariableNames = new ArrayList<String>();
private FrameMap frameMap;
public abstract void generateBody( public abstract void generateBody(
@NotNull MethodVisitor mv, @NotNull MethodVisitor mv,
@NotNull JvmMethodSignature signature, @NotNull JvmMethodSignature signature,
@NotNull MethodContext context, @NotNull MethodContext context
@NotNull FrameMap frameMap
); );
protected void addLocalVariableName(@NotNull String name) { protected void addLocalVariableName(@NotNull String name) {
@@ -45,31 +51,72 @@ public abstract class FunctionGenerationStrategy {
return localVariableNames; return localVariableNames;
} }
public boolean needsLocalVariableTable() { @NotNull
return true; protected FrameMap createFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull CodegenContext context) {
return context.prepareFrame(typeMapper);
} }
@NotNull
public FrameMap getFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull CodegenContext context) {
if (frameMap == null) {
frameMap = createFrameMap(typeMapper, context);
}
return frameMap;
}
public static class FunctionDefault extends CodegenBased<CallableDescriptor> {
public static class Default extends FunctionGenerationStrategy {
private final GenerationState state;
private final JetDeclarationWithBody declaration; private final JetDeclarationWithBody declaration;
public Default(@NotNull GenerationState state, @NotNull JetDeclarationWithBody declaration) { public FunctionDefault(
this.state = state; @NotNull GenerationState state,
@NotNull CallableDescriptor descriptor,
@NotNull JetDeclarationWithBody declaration
) {
super(state, descriptor);
this.declaration = declaration; this.declaration = declaration;
} }
@Override
public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) {
codegen.returnExpression(declaration.getBodyExpression());
}
}
public abstract static class CodegenBased<T extends CallableDescriptor> extends FunctionGenerationStrategy<T> {
private final GenerationState state;
protected final T callableDescriptor;
public CodegenBased(@NotNull GenerationState state, T callableDescriptor) {
this.state = state;
this.callableDescriptor = callableDescriptor;
}
@Override @Override
public void generateBody( public void generateBody(
@NotNull MethodVisitor mv, @NotNull MethodVisitor mv,
@NotNull JvmMethodSignature signature, @NotNull JvmMethodSignature signature,
@NotNull MethodContext context, @NotNull MethodContext context
@NotNull FrameMap frameMap
) { ) {
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getAsmMethod().getReturnType(), context, state); ExpressionCodegen codegen = initializeExpressionCodegen(signature, context, mv, signature.getAsmMethod().getReturnType());
doGenerateBody(codegen, signature);
generateLocalVarNames(codegen);
}
codegen.returnExpression(declaration.getBodyExpression()); abstract public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature);
@NotNull
public ExpressionCodegen initializeExpressionCodegen(
JvmMethodSignature signature,
MethodContext context,
MethodVisitor mv,
Type returnType
) {
return new ExpressionCodegen(mv, getFrameMap(state.getTypeMapper(), context), returnType, context, state);
}
public void generateLocalVarNames(@NotNull ExpressionCodegen codegen) {
for (String name : codegen.getLocalVariableNamesForExpression()) { for (String name : codegen.getLocalVariableNamesForExpression()) {
addLocalVariableName(name); addLocalVariableName(name);
} }
@@ -681,13 +681,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
JvmMethodSignature signature = typeMapper.mapSignature(function); JvmMethodSignature signature = typeMapper.mapSignature(function);
FunctionCodegen fc = new FunctionCodegen(context, v, state); FunctionCodegen fc = new FunctionCodegen(context, v, state);
fc.generateMethod(myClass, signature, true, null, function, new FunctionGenerationStrategy() { fc.generateMethod(myClass, signature, true, function, new FunctionGenerationStrategy() {
@Override @Override
public void generateBody( public void generateBody(
@NotNull MethodVisitor mv, @NotNull MethodVisitor mv,
@NotNull JvmMethodSignature signature, @NotNull JvmMethodSignature signature,
@NotNull MethodContext context, @NotNull MethodContext context
@NotNull FrameMap frameMap
) { ) {
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
if (!componentType.equals(Type.VOID_TYPE)) { if (!componentType.equals(Type.VOID_TYPE)) {
@@ -706,13 +705,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
final Type thisDescriptorType = typeMapper.mapType(descriptor.getDefaultType()); final Type thisDescriptorType = typeMapper.mapType(descriptor.getDefaultType());
FunctionCodegen fc = new FunctionCodegen(context, v, state); FunctionCodegen fc = new FunctionCodegen(context, v, state);
fc.generateMethod(myClass, methodSignature, true, null, function, new FunctionGenerationStrategy() { fc.generateMethod(myClass, methodSignature, true, function, new FunctionGenerationStrategy() {
@Override @Override
public void generateBody( public void generateBody(
@NotNull MethodVisitor mv, @NotNull MethodVisitor mv,
@NotNull JvmMethodSignature signature, @NotNull JvmMethodSignature signature,
@NotNull MethodContext context, @NotNull MethodContext context
@NotNull FrameMap frameMap
) { ) {
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
@@ -860,10 +858,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod(); Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod();
MethodVisitor mv = MethodVisitor mv =
v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null); v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null);
PropertyGetterDescriptor getter = ((PropertyDescriptor) entry.getValue()).getGetter(); PropertyGetterDescriptor getter = bridge.getGetter();
assert getter != null; assert getter != null;
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(), PropertyCodegen.generateJetPropertyAnnotation(mv,
originalSignature.getJvmMethodSignature().getKotlinTypeParameter(), originalSignature,
original, original,
getter.getVisibility()); getter.getVisibility());
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
@@ -897,10 +895,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod(); Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod();
MethodVisitor mv = MethodVisitor mv =
v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null); v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
PropertySetterDescriptor setter = ((PropertyDescriptor) entry.getValue()).getSetter(); PropertySetterDescriptor setter = bridge.getSetter();
assert setter != null; assert setter != null;
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(), PropertyCodegen.generateJetPropertyAnnotation(mv,
originalSignature2.getJvmMethodSignature().getKotlinTypeParameter(), originalSignature2,
original, original,
setter.getVisibility()); setter.getVisibility());
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
@@ -967,6 +965,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
throw new IllegalStateException("incorrect kind for primary constructor: " + kind); throw new IllegalStateException("incorrect kind for primary constructor: " + kind);
} }
final MutableClosure closure = context.closure;
ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass); ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass);
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor); ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
@@ -975,60 +974,49 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
lookupConstructorExpressionsInClosureIfPresent(constructorContext); lookupConstructorExpressionsInClosureIfPresent(constructorContext);
} }
MutableClosure closure = context.closure; final CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, context.closure);
boolean hasCapturedThis = closure != null && closure.getCaptureThis() != null;
CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, context.closure);
JvmMethodSignature constructorMethod = callableMethod.getSignature(); JvmMethodSignature constructorMethod = callableMethod.getSignature();
assert constructorDescriptor != null; assert constructorDescriptor != null;
int flags = getConstructorAsmFlags(constructorDescriptor);
MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(),
constructorMethod.getGenericsSignature(), null);
if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) {
AnnotationVisitor jetConstructorVisitor = mv.visitAnnotation(JvmStdlibNames.JET_CONSTRUCTOR.getDescriptor(), true); FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state);
int flagsValue = getFlagsForVisibility(constructorDescriptor.getVisibility()); functionCodegen.generateMethod(null, constructorMethod, true, constructorDescriptor, constructorContext,
if (JvmStdlibNames.FLAGS_DEFAULT_VALUE != flagsValue) { new FunctionGenerationStrategy.CodegenBased<ConstructorDescriptor>(state, constructorDescriptor) {
jetConstructorVisitor.visit(JvmStdlibNames.JET_FLAGS_FIELD, flagsValue);
}
jetConstructorVisitor.visitEnd(); @NotNull
@Override
protected FrameMap createFrameMap(
@NotNull JetTypeMapper typeMapper, @NotNull CodegenContext context
) {
return new ConstructorFrameMap(callableMethod, callableDescriptor);
}
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(constructorDescriptor); @Override
public void doGenerateBody(
ExpressionCodegen codegen, JvmMethodSignature signature
) {
generatePrimaryConstructorImpl(callableDescriptor, codegen, closure);
}
});
writeParameterAnnotations(constructorDescriptor, constructorMethod, hasCapturedThis, mv); FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor,
OwnerKind.IMPLEMENTATION, DefaultParameterValueLoader.DEFAULT);
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
genStubCode(mv);
return;
}
generatePrimaryConstructorImpl(constructorDescriptor, constructorContext, constructorMethod, callableMethod, closure, mv);
}
FunctionCodegen.generateConstructorWithoutParametersIfNeeded(state, callableMethod, constructorDescriptor, v); FunctionCodegen.generateConstructorWithoutParametersIfNeeded(state, callableMethod, constructorDescriptor, v);
} }
private void generatePrimaryConstructorImpl( private void generatePrimaryConstructorImpl(
ConstructorDescriptor constructorDescriptor, ConstructorDescriptor constructorDescriptor,
ConstructorContext constructorContext, ExpressionCodegen codegen,
JvmMethodSignature constructorMethod, MutableClosure closure
CallableMethod callableMethod,
MutableClosure closure,
MethodVisitor mv
) { ) {
mv.visitCode();
List<ValueParameterDescriptor> paramDescrs = constructorDescriptor != null List<ValueParameterDescriptor> paramDescrs = constructorDescriptor != null
? constructorDescriptor.getValueParameters() ? constructorDescriptor.getValueParameters()
: Collections.<ValueParameterDescriptor>emptyList(); : Collections.<ValueParameterDescriptor>emptyList();
ConstructorFrameMap frameMap = new ConstructorFrameMap(callableMethod, constructorDescriptor); InstructionAdapter iv = codegen.v;
InstructionAdapter iv = new InstructionAdapter(mv);
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, constructorContext, state);
JvmClassName classname = JvmClassName.byType(classAsmType); JvmClassName classname = JvmClassName.byType(classAsmType);
@@ -1039,7 +1027,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
genSuperCallToDelegatorToSuperClass(iv); genSuperCallToDelegatorToSuperClass(iv);
} }
else { else {
generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor, frameMap); generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor);
} }
if (closure != null) { if (closure != null) {
@@ -1068,7 +1056,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
VariableDescriptor descriptor = paramDescrs.get(curParam); VariableDescriptor descriptor = paramDescrs.get(curParam);
Type type = typeMapper.mapType(descriptor); Type type = typeMapper.mapType(descriptor);
iv.load(0, classAsmType); iv.load(0, classAsmType);
iv.load(frameMap.getIndex(descriptor), type); iv.load(codegen.myFrameMap.getIndex(descriptor), type);
iv.putfield(classAsmType.getInternalName(), descriptor.getName().getName(), type.getDescriptor()); iv.putfield(classAsmType.getInternalName(), descriptor.getName().getName(), type.getDescriptor());
} }
curParam++; curParam++;
@@ -1076,12 +1064,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateInitializers(codegen, iv, myClass.getDeclarations(), bindingContext, state); generateInitializers(codegen, iv, myClass.getDeclarations(), bindingContext, state);
mv.visitInsn(RETURN); iv.visitInsn(RETURN);
FunctionCodegen.endVisit(mv, "constructor", myClass);
assert constructorDescriptor != null;
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor,
OwnerKind.IMPLEMENTATION, DefaultParameterValueLoader.DEFAULT);
} }
private void genSuperCallToDelegatorToSuperClass(InstructionAdapter iv) { private void genSuperCallToDelegatorToSuperClass(InstructionAdapter iv) {
@@ -1113,37 +1096,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
} }
} }
private void writeParameterAnnotations(
ConstructorDescriptor constructorDescriptor,
JvmMethodSignature constructorMethod,
boolean hasThis0,
MethodVisitor mv
) {
if (constructorDescriptor != null) {
int i = 0;
if (hasThis0) {
i++;
}
if (descriptor.getKind() == ClassKind.ENUM_CLASS || descriptor.getKind() == ClassKind.ENUM_ENTRY) {
i += 2;
}
for (ValueParameterDescriptor valueParameter : constructorDescriptor.getValueParameters()) {
AnnotationCodegen.forParameter(i, mv, state.getTypeMapper()).genAnnotations(valueParameter);
JetValueParameterAnnotationWriter jetValueParameterAnnotation =
JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i);
jetValueParameterAnnotation.writeName(valueParameter.getName().getName());
jetValueParameterAnnotation.writeHasDefaultValue(valueParameter.declaresDefaultValue());
jetValueParameterAnnotation.writeVararg(valueParameter.getVarargElementType() != null);
jetValueParameterAnnotation.writeType(constructorMethod.getKotlinParameterType(i));
jetValueParameterAnnotation.visitEnd();
++i;
}
}
}
private void genCallToDelegatorByExpressionSpecifier( private void genCallToDelegatorByExpressionSpecifier(
InstructionAdapter iv, InstructionAdapter iv,
ExpressionCodegen codegen, ExpressionCodegen codegen,
@@ -1450,8 +1402,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateDelegatorToConstructorCall( private void generateDelegatorToConstructorCall(
InstructionAdapter iv, ExpressionCodegen codegen, InstructionAdapter iv, ExpressionCodegen codegen,
ConstructorDescriptor constructorDescriptor, ConstructorDescriptor constructorDescriptor
ConstructorFrameMap frameMap
) { ) {
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration(); ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
@@ -1474,7 +1425,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, closureForSuper); CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, closureForSuper);
if (closureForSuper != null && closureForSuper.getCaptureThis() != null) { if (closureForSuper != null && closureForSuper.getCaptureThis() != null) {
iv.load(frameMap.getOuterThisIndex(), OBJECT_TYPE); iv.load(((ConstructorFrameMap)codegen.myFrameMap).getOuterThisIndex(), OBJECT_TYPE);
} }
if (myClass instanceof JetObjectDeclaration && if (myClass instanceof JetObjectDeclaration &&
@@ -41,8 +41,6 @@ import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.Collection;
import static org.jetbrains.asm4.Opcodes.*; import static org.jetbrains.asm4.Opcodes.*;
import static org.jetbrains.jet.codegen.AsmUtil.getDeprecatedAccessFlag; import static org.jetbrains.jet.codegen.AsmUtil.getDeprecatedAccessFlag;
import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.CodegenUtil.*;
@@ -135,11 +133,10 @@ public class PropertyCodegen extends GenerationStateAware {
FunctionGenerationStrategy strategy = FunctionGenerationStrategy strategy =
defaultGetter defaultGetter
? new DefaultPropertyAccessorStrategy(getterDescriptor) ? new DefaultPropertyAccessorStrategy(getterDescriptor)
: new FunctionGenerationStrategy.Default(state, getter); : new FunctionGenerationStrategy.FunctionDefault(state, getterDescriptor, getter);
functionCodegen.generateMethod(getter != null ? getter : p, functionCodegen.generateMethod(getter != null ? getter : p,
signature.getJvmMethodSignature(), signature.getJvmMethodSignature(),
true, true,
signature.getPropertyTypeKotlinSignature(),
getterDescriptor, getterDescriptor,
strategy); strategy);
} }
@@ -159,11 +156,10 @@ public class PropertyCodegen extends GenerationStateAware {
FunctionGenerationStrategy strategy = FunctionGenerationStrategy strategy =
defaultSetter defaultSetter
? new DefaultPropertyAccessorStrategy(setterDescriptor) ? new DefaultPropertyAccessorStrategy(setterDescriptor)
: new FunctionGenerationStrategy.Default(state, setter); : new FunctionGenerationStrategy.FunctionDefault(state, setterDescriptor, setter);
functionCodegen.generateMethod(setter != null ? setter : p, functionCodegen.generateMethod(setter != null ? setter : p,
signature.getJvmMethodSignature(), signature.getJvmMethodSignature(),
true, true,
signature.getPropertyTypeKotlinSignature(),
setterDescriptor, setterDescriptor,
strategy); strategy);
} }
@@ -182,8 +178,7 @@ public class PropertyCodegen extends GenerationStateAware {
public void generateBody( public void generateBody(
@NotNull MethodVisitor mv, @NotNull MethodVisitor mv,
@NotNull JvmMethodSignature signature, @NotNull JvmMethodSignature signature,
@NotNull MethodContext context, @NotNull MethodContext context
@NotNull FrameMap frameMap
) { ) {
generateDefaultAccessor(descriptor, new InstructionAdapter(mv), typeMapper, context); generateDefaultAccessor(descriptor, new InstructionAdapter(mv), typeMapper, context);
} }
@@ -233,7 +228,7 @@ public class PropertyCodegen extends GenerationStateAware {
} }
public static void generateJetPropertyAnnotation( public static void generateJetPropertyAnnotation(
MethodVisitor mv, @NotNull String kotlinType, @NotNull String typeParameters, MethodVisitor mv, @NotNull JvmPropertyAccessorSignature propertyAccessorSignature,
@NotNull PropertyDescriptor propertyDescriptor, @NotNull Visibility visibility @NotNull PropertyDescriptor propertyDescriptor, @NotNull Visibility visibility
) { ) {
JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv); JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv);
@@ -245,8 +240,8 @@ public class PropertyCodegen extends GenerationStateAware {
: JvmStdlibNames.FLAG_FORCE_OPEN_BIT; : JvmStdlibNames.FLAG_FORCE_OPEN_BIT;
} }
aw.writeFlags(flags | DescriptorKindUtils.kindToFlags(propertyDescriptor.getKind())); aw.writeFlags(flags | DescriptorKindUtils.kindToFlags(propertyDescriptor.getKind()));
aw.writeTypeParameters(typeParameters); aw.writeTypeParameters(propertyAccessorSignature.getKotlinTypeParameter());
aw.writePropertyType(kotlinType); aw.writePropertyType(propertyAccessorSignature.getPropertyTypeKotlinSignature());
aw.visitEnd(); aw.visitEnd();
} }