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:
@@ -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.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration;
|
||||
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;
|
||||
|
||||
public class FunctionCodegen extends GenerationStateAware {
|
||||
@@ -69,14 +70,23 @@ public class FunctionCodegen extends GenerationStateAware {
|
||||
public void gen(JetNamedFunction f) {
|
||||
SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, f);
|
||||
assert functionDescriptor != null;
|
||||
|
||||
OwnerKind kind = owner.getContextKind();
|
||||
JvmMethodSignature method =
|
||||
typeMapper.mapToCallableMethod(
|
||||
functionDescriptor,
|
||||
false,
|
||||
isCallInsideSameClassAsDeclared(functionDescriptor, owner),
|
||||
isCallInsideSameModuleAsDeclared(functionDescriptor, owner),
|
||||
owner.getContextKind()).getSignature();
|
||||
generateMethod(f, method, true, null, functionDescriptor);
|
||||
kind).getSignature();
|
||||
|
||||
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);
|
||||
|
||||
OwnerKind kind = owner.getContextKind();
|
||||
generateMethodHeaderAndBody(declaration, jvmSignature, needJetAnnotations, propertyTypeSignature, functionDescriptor);
|
||||
|
||||
if (kind == OwnerKind.TRAIT_IMPL) {
|
||||
needJetAnnotations = false;
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL && !isAbstract(functionDescriptor, owner.getContextKind())) {
|
||||
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(
|
||||
@@ -116,14 +113,14 @@ public class FunctionCodegen extends GenerationStateAware {
|
||||
@NotNull JvmMethodSignature jvmSignature,
|
||||
boolean needJetAnnotations,
|
||||
@Nullable String propertyTypeSignature,
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull MethodContext context
|
||||
@NotNull FunctionDescriptor functionDescriptor
|
||||
) {
|
||||
OwnerKind kind = context.getContextKind();
|
||||
MethodContext context = owner.intoFunction(functionDescriptor);
|
||||
|
||||
Method asmMethod = jvmSignature.getAsmMethod();
|
||||
|
||||
MethodVisitor mv = v.newMethod(declaration,
|
||||
getMethodAsmFlags(functionDescriptor, kind),
|
||||
getMethodAsmFlags(functionDescriptor, context.getContextKind()),
|
||||
asmMethod.getName(),
|
||||
asmMethod.getDescriptor(),
|
||||
jvmSignature.getGenericsSignature(),
|
||||
@@ -136,7 +133,7 @@ public class FunctionCodegen extends GenerationStateAware {
|
||||
genJetAnnotations(state, functionDescriptor, jvmSignature, propertyTypeSignature, mv);
|
||||
}
|
||||
|
||||
if (isAbstract(functionDescriptor, kind)) return;
|
||||
if (isAbstract(functionDescriptor, context.getContextKind())) return;
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||
genStubCode(mv);
|
||||
@@ -147,23 +144,26 @@ public class FunctionCodegen extends GenerationStateAware {
|
||||
|
||||
MethodBounds methodBounds = generateMethodBody(mv, declaration, functionDescriptor, context, asmMethod, localVariablesInfo);
|
||||
|
||||
Type thisType;
|
||||
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;
|
||||
}
|
||||
|
||||
Type thisType = getThisTypeForFunction(functionDescriptor, context);
|
||||
generateLocalVariableTable(typeMapper, mv, functionDescriptor, thisType, localVariablesInfo, methodBounds);
|
||||
|
||||
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
|
||||
private MethodBounds generateMethodBody(
|
||||
@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.jet.codegen.AsmUtil.getDeprecatedAccessFlag;
|
||||
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;
|
||||
|
||||
public class PropertyCodegen extends GenerationStateAware {
|
||||
@@ -120,31 +119,40 @@ public class PropertyCodegen extends GenerationStateAware {
|
||||
}
|
||||
|
||||
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
|
||||
//if (getter != null && getter.getBodyExpression() != null || isExternallyAccessible(propertyDescriptor)) {
|
||||
JvmPropertyAccessorSignature signature = typeMapper.mapGetterSignature(propertyDescriptor, kind);
|
||||
PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter();
|
||||
getterDescriptor = getterDescriptor != null ? getterDescriptor : DescriptorResolver.createDefaultGetter(propertyDescriptor);
|
||||
//if (!defaultGetter || isExternallyAccessible(propertyDescriptor)) {
|
||||
JvmPropertyAccessorSignature signature = typeMapper.mapGetterSignature(propertyDescriptor, kind);
|
||||
PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter();
|
||||
getterDescriptor = getterDescriptor != null ? getterDescriptor : DescriptorResolver.createDefaultGetter(propertyDescriptor);
|
||||
|
||||
if (kind != OwnerKind.TRAIT_IMPL || !defaultGetter) {
|
||||
functionCodegen.generateMethod(getter != null ? getter : p,
|
||||
signature.getJvmMethodSignature(),
|
||||
true,
|
||||
signature.getPropertyTypeKotlinSignature(),
|
||||
getterDescriptor);
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
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
|
||||
if (/*setter != null && setter.getBodyExpression() != null
|
||||
|| isExternallyAccessible(propertyDescriptor) &&*/ propertyDescriptor.isVar()) {
|
||||
if (/*!defaultSetter || isExternallyAccessible(propertyDescriptor) &&*/ propertyDescriptor.isVar()) {
|
||||
JvmPropertyAccessorSignature signature = typeMapper.mapSetterSignature(propertyDescriptor, kind);
|
||||
PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter();
|
||||
setterDescriptor = setterDescriptor != null ? setterDescriptor : DescriptorResolver.createDefaultSetter(propertyDescriptor);
|
||||
functionCodegen.generateMethod(setter != null ? setter : p,
|
||||
signature.getJvmMethodSignature(),
|
||||
true,
|
||||
signature.getPropertyTypeKotlinSignature(),
|
||||
setterDescriptor);
|
||||
|
||||
if (kind != OwnerKind.TRAIT_IMPL || !defaultSetter) {
|
||||
functionCodegen.generateMethod(setter != null ? setter : p,
|
||||
signature.getJvmMethodSignature(),
|
||||
true,
|
||||
signature.getPropertyTypeKotlinSignature(),
|
||||
setterDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user