From 119612fcc2ac6bd5ae95d7dee146cca6ae09acb1 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 21 Aug 2012 17:14:49 +0400 Subject: [PATCH] Code duplication eliminated: Ordinary local variables and multi-declarations are initialized using the same logic --- .../jet/codegen/ExpressionCodegen.java | 139 ++++++++---------- 1 file changed, 62 insertions(+), 77 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 8f2958d63f2..feb20ad615b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -2596,12 +2596,55 @@ public class ExpressionCodegen extends JetVisitor { @Override public StackValue visitProperty(JetProperty property, StackValue receiver) { - - VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, property); - - if (JetPsiUtil.isScriptDeclaration(property)) { + final JetExpression initializer = property.getInitializer(); + if (initializer == null) { return StackValue.none(); } + initializeLocalVariable(property, new Function() { + @Override + public Void fun(VariableDescriptor descriptor) { + Type varType = asmType(descriptor.getType()); + gen(initializer, varType); + return null; + } + }); + return StackValue.none(); + } + + @Override + public StackValue visitMultiDeclaration(JetMultiDeclaration multiDeclaration, StackValue receiver) { + 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() { + @Override + public Void fun(VariableDescriptor descriptor) { + ResolvedCall 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 generateInitializer + ) { + + VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, variableDeclaration); + + if (JetPsiUtil.isScriptDeclaration(variableDeclaration)) { + return; + } int index = lookupLocal(variableDescriptor); if (index < 0) { @@ -2613,81 +2656,23 @@ public class ExpressionCodegen extends JetVisitor { Type varType = asmType(variableDescriptor.getType()); - JetExpression initializer = property.getInitializer(); - if (initializer != null) { - if (JetPsiUtil.isScriptDeclaration(property)) { - gen(initializer, varType); - JetScript scriptPsi = JetPsiUtil.getScript(property); - 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()); - } + if (JetPsiUtil.isScriptDeclaration(variableDeclaration)) { + generateInitializer.fun(variableDescriptor); + JetScript scriptPsi = JetPsiUtil.getScript(variableDeclaration); + assert scriptPsi != null; + JvmClassName scriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptPsi(scriptPsi); + v.putfield(scriptClassName.getInternalName(), variableDeclaration.getName(), varType.getDescriptor()); } - return StackValue.none(); - } - - @Override - public StackValue visitMultiDeclaration(JetMultiDeclaration multiDeclaration, StackValue receiver) { - for (JetMultiDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) { - - VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, variableDeclaration); - - if (JetPsiUtil.isScriptDeclaration(variableDeclaration)) { - return StackValue.none(); - } - int index = lookupLocal(variableDescriptor); - - if (index < 0) { - throw new IllegalStateException("Local variable not found for " + variableDescriptor); - } - - Type sharedVarType = typeMapper.getSharedVarType(variableDescriptor); - assert variableDescriptor != null; - - Type varType = asmType(variableDescriptor.getType()); - - JetExpression initializer = multiDeclaration.getInitializer(); - - ResolvedCall 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)) { - invokeFunction(call, resolvedCall.getResultingDescriptor(), StackValue.none(), resolvedCall); - - JetScript scriptPsi = JetPsiUtil.getScript(variableDeclaration); - assert scriptPsi != null; - JvmClassName scriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptPsi(scriptPsi); - v.putfield(scriptClassName.getInternalName(), variableDeclaration.getName(), varType.getDescriptor()); - } - else if (sharedVarType == null) { - invokeFunction(call, resolvedCall.getResultingDescriptor(), StackValue.none(), resolvedCall); - - v.store(index, varType); - } - else { - v.load(index, TYPE_OBJECT); - invokeFunction(call, resolvedCall.getResultingDescriptor(), StackValue.none(), resolvedCall); - - v.putfield(sharedVarType.getInternalName(), "ref", - sharedVarType == TYPE_SHARED_VAR ? "Ljava/lang/Object;" : varType.getDescriptor()); - } - } - + else if (sharedVarType == null) { + generateInitializer.fun(variableDescriptor); + v.store(index, varType); + } + else { + v.load(index, TYPE_OBJECT); + generateInitializer.fun(variableDescriptor); + v.putfield(sharedVarType.getInternalName(), "ref", + sharedVarType == TYPE_SHARED_VAR ? "Ljava/lang/Object;" : varType.getDescriptor()); } - return StackValue.none(); } private StackValue generateConstructorCall(