Minor refactoring in Function/PropertyCodegen

Check if we need to generate code before calling generateMethod()
There were 4 such checks, 2 of them in PropertyCodegen, one in
FunctionCodegen.gen() and one in ClosureCodegen. Every usage except the last
was prepended with the check
This commit is contained in:
Alexander Udalov
2013-04-09 13:44:29 +04:00
parent 559b742737
commit 099fa6c11e
2 changed files with 55 additions and 47 deletions
@@ -54,6 +54,7 @@ import static org.jetbrains.jet.codegen.CodegenUtil.*;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.isLocalNamedFun; import static org.jetbrains.jet.codegen.binding.CodegenBinding.isLocalNamedFun;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isFunctionLiteral;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
public class FunctionCodegen extends GenerationStateAware { public class FunctionCodegen extends GenerationStateAware {
@@ -69,14 +70,23 @@ public class FunctionCodegen extends GenerationStateAware {
public void gen(JetNamedFunction f) { public void gen(JetNamedFunction f) {
SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, f); SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, f);
assert functionDescriptor != null; assert functionDescriptor != null;
OwnerKind kind = owner.getContextKind();
JvmMethodSignature method = JvmMethodSignature method =
typeMapper.mapToCallableMethod( typeMapper.mapToCallableMethod(
functionDescriptor, functionDescriptor,
false, false,
isCallInsideSameClassAsDeclared(functionDescriptor, owner), isCallInsideSameClassAsDeclared(functionDescriptor, owner),
isCallInsideSameModuleAsDeclared(functionDescriptor, owner), isCallInsideSameModuleAsDeclared(functionDescriptor, owner),
owner.getContextKind()).getSignature(); kind).getSignature();
generateMethod(f, method, true, null, functionDescriptor);
if (kind != OwnerKind.TRAIT_IMPL || hasBodyExpression(f)) {
boolean needJetAnnotations = kind != OwnerKind.TRAIT_IMPL;
generateMethod(f, method, needJetAnnotations, null, functionDescriptor);
}
generateDefaultIfNeeded(owner.intoFunction(functionDescriptor), state, v, method.getAsmMethod(), functionDescriptor, kind,
DefaultParameterValueLoader.DEFAULT);
} }
@@ -91,24 +101,11 @@ public class FunctionCodegen extends GenerationStateAware {
checkMustGenerateCode(functionDescriptor); checkMustGenerateCode(functionDescriptor);
OwnerKind kind = owner.getContextKind(); generateMethodHeaderAndBody(declaration, jvmSignature, needJetAnnotations, propertyTypeSignature, functionDescriptor);
if (kind == OwnerKind.TRAIT_IMPL) { if (state.getClassBuilderMode() == ClassBuilderMode.FULL && !isAbstract(functionDescriptor, owner.getContextKind())) {
needJetAnnotations = false; generateBridgeIfNeeded(owner, state, v, jvmSignature.getAsmMethod(), functionDescriptor);
} }
boolean hasBodyExpression = hasBodyExpression(declaration);
MethodContext context = owner.intoFunction(functionDescriptor);
if (kind != OwnerKind.TRAIT_IMPL || hasBodyExpression) {
generateMethodHeaderAndBody(declaration, jvmSignature, needJetAnnotations, propertyTypeSignature, functionDescriptor, context);
if (state.getClassBuilderMode() == ClassBuilderMode.FULL && !isAbstract(functionDescriptor, kind)) {
generateBridgeIfNeeded(owner, state, v, jvmSignature.getAsmMethod(), functionDescriptor);
}
}
generateDefaultIfNeeded(context, state, v, jvmSignature.getAsmMethod(), functionDescriptor, kind, DefaultParameterValueLoader.DEFAULT);
} }
private void generateMethodHeaderAndBody( private void generateMethodHeaderAndBody(
@@ -116,14 +113,14 @@ public class FunctionCodegen extends GenerationStateAware {
@NotNull JvmMethodSignature jvmSignature, @NotNull JvmMethodSignature jvmSignature,
boolean needJetAnnotations, boolean needJetAnnotations,
@Nullable String propertyTypeSignature, @Nullable String propertyTypeSignature,
@NotNull FunctionDescriptor functionDescriptor, @NotNull FunctionDescriptor functionDescriptor
@NotNull MethodContext context
) { ) {
OwnerKind kind = context.getContextKind(); MethodContext context = owner.intoFunction(functionDescriptor);
Method asmMethod = jvmSignature.getAsmMethod(); Method asmMethod = jvmSignature.getAsmMethod();
MethodVisitor mv = v.newMethod(declaration, MethodVisitor mv = v.newMethod(declaration,
getMethodAsmFlags(functionDescriptor, kind), getMethodAsmFlags(functionDescriptor, context.getContextKind()),
asmMethod.getName(), asmMethod.getName(),
asmMethod.getDescriptor(), asmMethod.getDescriptor(),
jvmSignature.getGenericsSignature(), jvmSignature.getGenericsSignature(),
@@ -136,7 +133,7 @@ public class FunctionCodegen extends GenerationStateAware {
genJetAnnotations(state, functionDescriptor, jvmSignature, propertyTypeSignature, mv); genJetAnnotations(state, functionDescriptor, jvmSignature, propertyTypeSignature, mv);
} }
if (isAbstract(functionDescriptor, kind)) return; if (isAbstract(functionDescriptor, context.getContextKind())) return;
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
genStubCode(mv); genStubCode(mv);
@@ -147,23 +144,26 @@ public class FunctionCodegen extends GenerationStateAware {
MethodBounds methodBounds = generateMethodBody(mv, declaration, functionDescriptor, context, asmMethod, localVariablesInfo); MethodBounds methodBounds = generateMethodBody(mv, declaration, functionDescriptor, context, asmMethod, localVariablesInfo);
Type thisType; Type thisType = getThisTypeForFunction(functionDescriptor, context);
ReceiverParameterDescriptor expectedThisObject = functionDescriptor.getExpectedThisObject();
if (expectedThisObject != null) {
thisType = typeMapper.mapType(expectedThisObject.getType());
}
else if (declaration instanceof JetFunctionLiteral || isLocalNamedFun(functionDescriptor)) {
thisType = typeMapper.mapType(context.getThisDescriptor());
}
else {
thisType = null;
}
generateLocalVariableTable(typeMapper, mv, functionDescriptor, thisType, localVariablesInfo, methodBounds); generateLocalVariableTable(typeMapper, mv, functionDescriptor, thisType, localVariablesInfo, methodBounds);
endVisit(mv, null, declaration); endVisit(mv, null, declaration);
} }
@Nullable
private Type getThisTypeForFunction(@NotNull FunctionDescriptor functionDescriptor, @NotNull MethodContext context) {
ReceiverParameterDescriptor expectedThisObject = functionDescriptor.getExpectedThisObject();
if (expectedThisObject != null) {
return typeMapper.mapType(expectedThisObject.getType());
}
else if (isFunctionLiteral(functionDescriptor) || isLocalNamedFun(functionDescriptor)) {
return typeMapper.mapType(context.getThisDescriptor());
}
else {
return null;
}
}
@NotNull @NotNull
private MethodBounds generateMethodBody( private MethodBounds generateMethodBody(
@NotNull MethodVisitor mv, @NotNull MethodVisitor mv,
@@ -42,7 +42,6 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
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.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isExternallyAccessible;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
public class PropertyCodegen extends GenerationStateAware { public class PropertyCodegen extends GenerationStateAware {
@@ -120,31 +119,40 @@ public class PropertyCodegen extends GenerationStateAware {
} }
private void generateGetter(JetNamedDeclaration p, PropertyDescriptor propertyDescriptor, JetPropertyAccessor getter) { private void generateGetter(JetNamedDeclaration p, PropertyDescriptor propertyDescriptor, JetPropertyAccessor getter) {
boolean defaultGetter = getter == null || getter.getBodyExpression() == null;
//TODO: Now it's not enough information to properly resolve property from bytecode without generated getter and setter //TODO: Now it's not enough information to properly resolve property from bytecode without generated getter and setter
//if (getter != null && getter.getBodyExpression() != null || isExternallyAccessible(propertyDescriptor)) { //if (!defaultGetter || isExternallyAccessible(propertyDescriptor)) {
JvmPropertyAccessorSignature signature = typeMapper.mapGetterSignature(propertyDescriptor, kind); JvmPropertyAccessorSignature signature = typeMapper.mapGetterSignature(propertyDescriptor, kind);
PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter(); PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter();
getterDescriptor = getterDescriptor != null ? getterDescriptor : DescriptorResolver.createDefaultGetter(propertyDescriptor); getterDescriptor = getterDescriptor != null ? getterDescriptor : DescriptorResolver.createDefaultGetter(propertyDescriptor);
if (kind != OwnerKind.TRAIT_IMPL || !defaultGetter) {
functionCodegen.generateMethod(getter != null ? getter : p, functionCodegen.generateMethod(getter != null ? getter : p,
signature.getJvmMethodSignature(), signature.getJvmMethodSignature(),
true, true,
signature.getPropertyTypeKotlinSignature(), signature.getPropertyTypeKotlinSignature(),
getterDescriptor); getterDescriptor);
}
//} //}
} }
private void generateSetter(JetNamedDeclaration p, PropertyDescriptor propertyDescriptor, JetPropertyAccessor setter) { private void generateSetter(JetNamedDeclaration p, PropertyDescriptor propertyDescriptor, JetPropertyAccessor setter) {
boolean defaultSetter = setter == null || setter.getBodyExpression() == null;
//TODO: Now it's not enough information to properly resolve property from bytecode without generated getter and setter //TODO: Now it's not enough information to properly resolve property from bytecode without generated getter and setter
if (/*setter != null && setter.getBodyExpression() != null if (/*!defaultSetter || isExternallyAccessible(propertyDescriptor) &&*/ propertyDescriptor.isVar()) {
|| isExternallyAccessible(propertyDescriptor) &&*/ propertyDescriptor.isVar()) {
JvmPropertyAccessorSignature signature = typeMapper.mapSetterSignature(propertyDescriptor, kind); JvmPropertyAccessorSignature signature = typeMapper.mapSetterSignature(propertyDescriptor, kind);
PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter(); PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter();
setterDescriptor = setterDescriptor != null ? setterDescriptor : DescriptorResolver.createDefaultSetter(propertyDescriptor); setterDescriptor = setterDescriptor != null ? setterDescriptor : DescriptorResolver.createDefaultSetter(propertyDescriptor);
functionCodegen.generateMethod(setter != null ? setter : p,
signature.getJvmMethodSignature(), if (kind != OwnerKind.TRAIT_IMPL || !defaultSetter) {
true, functionCodegen.generateMethod(setter != null ? setter : p,
signature.getPropertyTypeKotlinSignature(), signature.getJvmMethodSignature(),
setterDescriptor); true,
signature.getPropertyTypeKotlinSignature(),
setterDescriptor);
}
} }
} }