Code duplication eliminated:

Ordinary local variables and multi-declarations are initialized using the same logic
This commit is contained in:
Andrey Breslav
2012-08-21 17:14:49 +04:00
parent 47362bf2ac
commit 119612fcc2
@@ -2596,54 +2596,54 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override @Override
public StackValue visitProperty(JetProperty property, StackValue receiver) { public StackValue visitProperty(JetProperty property, StackValue receiver) {
final JetExpression initializer = property.getInitializer();
VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, property); if (initializer == null) {
if (JetPsiUtil.isScriptDeclaration(property)) {
return StackValue.none(); return StackValue.none();
} }
int index = lookupLocal(variableDescriptor); initializeLocalVariable(property, new Function<VariableDescriptor, Void>() {
@Override
if (index < 0) { public Void fun(VariableDescriptor descriptor) {
throw new IllegalStateException("Local variable not found for " + variableDescriptor); Type varType = asmType(descriptor.getType());
}
Type sharedVarType = typeMapper.getSharedVarType(variableDescriptor);
assert variableDescriptor != null;
Type varType = asmType(variableDescriptor.getType());
JetExpression initializer = property.getInitializer();
if (initializer != null) {
if (JetPsiUtil.isScriptDeclaration(property)) {
gen(initializer, varType); gen(initializer, varType);
JetScript scriptPsi = JetPsiUtil.getScript(property); return null;
assert scriptPsi != null;
JvmClassName scriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptPsi(scriptPsi);
v.putfield(scriptClassName.getInternalName(), property.getName(), varType.getDescriptor());
}
else if (sharedVarType == null) {
gen(initializer, varType);
v.store(index, varType);
}
else {
v.load(index, TYPE_OBJECT);
gen(initializer, varType);
v.putfield(sharedVarType.getInternalName(), "ref",
sharedVarType == TYPE_SHARED_VAR ? "Ljava/lang/Object;" : varType.getDescriptor());
}
} }
});
return StackValue.none(); return StackValue.none();
} }
@Override @Override
public StackValue visitMultiDeclaration(JetMultiDeclaration multiDeclaration, StackValue receiver) { public StackValue visitMultiDeclaration(JetMultiDeclaration multiDeclaration, StackValue receiver) {
for (JetMultiDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) { JetExpression initializer = multiDeclaration.getInitializer();
if (initializer == null) return StackValue.none();
JetType initializerType = bindingContext.get(EXPRESSION_TYPE, initializer);
assert initializerType != null;
final ExpressionReceiver initializerAsReceiver = new ExpressionReceiver(initializer, initializerType);
for (final JetMultiDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) {
initializeLocalVariable(variableDeclaration, new Function<VariableDescriptor, Void>() {
@Override
public Void fun(VariableDescriptor descriptor) {
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(BindingContext.COMPONENT_RESOLVED_CALL, variableDeclaration);
assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText();
Call call = CallMaker.makeCall(initializerAsReceiver, (JetExpression) null);
invokeFunction(call, resolvedCall.getResultingDescriptor(), StackValue.none(), resolvedCall);
return null;
}
});
}
return StackValue.none();
}
private void initializeLocalVariable(
@NotNull JetVariableDeclaration variableDeclaration,
@NotNull Function<VariableDescriptor, Void> generateInitializer
) {
VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, variableDeclaration); VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, variableDeclaration);
if (JetPsiUtil.isScriptDeclaration(variableDeclaration)) { if (JetPsiUtil.isScriptDeclaration(variableDeclaration)) {
return StackValue.none(); return;
} }
int index = lookupLocal(variableDescriptor); int index = lookupLocal(variableDescriptor);
@@ -2656,40 +2656,25 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
Type varType = asmType(variableDescriptor.getType()); Type varType = asmType(variableDescriptor.getType());
JetExpression initializer = multiDeclaration.getInitializer();
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(BindingContext.COMPONENT_RESOLVED_CALL, variableDeclaration);
if (initializer != null) {
JetType type = bindingContext.get(EXPRESSION_TYPE, initializer);
assert type != null;
Call call = CallMaker.makeCall(new ExpressionReceiver(initializer, type), (JetExpression) null);
if (JetPsiUtil.isScriptDeclaration(variableDeclaration)) { if (JetPsiUtil.isScriptDeclaration(variableDeclaration)) {
invokeFunction(call, resolvedCall.getResultingDescriptor(), StackValue.none(), resolvedCall); generateInitializer.fun(variableDescriptor);
JetScript scriptPsi = JetPsiUtil.getScript(variableDeclaration); JetScript scriptPsi = JetPsiUtil.getScript(variableDeclaration);
assert scriptPsi != null; assert scriptPsi != null;
JvmClassName scriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptPsi(scriptPsi); JvmClassName scriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptPsi(scriptPsi);
v.putfield(scriptClassName.getInternalName(), variableDeclaration.getName(), varType.getDescriptor()); v.putfield(scriptClassName.getInternalName(), variableDeclaration.getName(), varType.getDescriptor());
} }
else if (sharedVarType == null) { else if (sharedVarType == null) {
invokeFunction(call, resolvedCall.getResultingDescriptor(), StackValue.none(), resolvedCall); generateInitializer.fun(variableDescriptor);
v.store(index, varType); v.store(index, varType);
} }
else { else {
v.load(index, TYPE_OBJECT); v.load(index, TYPE_OBJECT);
invokeFunction(call, resolvedCall.getResultingDescriptor(), StackValue.none(), resolvedCall); generateInitializer.fun(variableDescriptor);
v.putfield(sharedVarType.getInternalName(), "ref", v.putfield(sharedVarType.getInternalName(), "ref",
sharedVarType == TYPE_SHARED_VAR ? "Ljava/lang/Object;" : varType.getDescriptor()); sharedVarType == TYPE_SHARED_VAR ? "Ljava/lang/Object;" : varType.getDescriptor());
} }
} }
}
return StackValue.none();
}
private StackValue generateConstructorCall( private StackValue generateConstructorCall(
JetCallExpression expression, JetCallExpression expression,
JetSimpleNameExpression constructorReference, JetSimpleNameExpression constructorReference,