Refactor expression mutator.

This commit is contained in:
pTalanov
2012-02-29 19:38:48 +04:00
parent 6e27f2ab3d
commit cf2f8e162d
7 changed files with 168 additions and 65 deletions
@@ -35,8 +35,8 @@ import org.jetbrains.k2js.translate.operation.IncrementTranslator;
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
import org.jetbrains.k2js.translate.reference.*;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import org.jetbrains.k2js.translate.utils.mutator.AssignToExpressionMutator;
import java.util.List;
@@ -44,6 +44,7 @@ import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getObjectDeclarationName;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateInitializerForProperty;
import static org.jetbrains.k2js.translate.utils.mutator.LastExpressionMutator.mutateLastExpression;
/**
* @author Pavel Talanov
@@ -161,10 +162,9 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
return ifStatement;
}
TemporaryVariable result = context.declareTemporary(context.program().getNullLiteral());
JsAstUtils.SaveLastExpressionMutator saveResultToTemporaryMutator =
new JsAstUtils.SaveLastExpressionMutator(result.reference());
JsNode mutatedIfStatement = mutateLastExpression(ifStatement,
saveResultToTemporaryMutator);
AssignToExpressionMutator saveResultToTemporaryMutator =
new AssignToExpressionMutator(result.reference());
JsNode mutatedIfStatement = mutateLastExpression(ifStatement, saveResultToTemporaryMutator);
JsStatement resultingStatement = convertToStatement(mutatedIfStatement);
context.addStatementToCurrentBlock(resultingStatement);
return result.reference();
@@ -30,16 +30,18 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.utils.DescriptorUtils;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import org.jetbrains.k2js.translate.utils.mutator.Mutator;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.*;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToBlock;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setParameters;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.newAliasForThis;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.removeAliasForThis;
import static org.jetbrains.k2js.translate.utils.mutator.LastExpressionMutator.mutateLastExpression;
/**
@@ -164,7 +166,7 @@ public final class FunctionTranslator extends AbstractTranslator {
}
private static JsNode lastExpressionReturned(@NotNull JsNode body) {
return mutateLastExpression(body, new JsAstUtils.Mutator() {
return mutateLastExpression(body, new Mutator() {
@Override
@NotNull
public JsNode mutate(@NotNull JsNode node) {
@@ -25,7 +25,8 @@ import org.jetbrains.k2js.translate.context.TemporaryVariable;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import org.jetbrains.k2js.translate.utils.mutator.AssignToExpressionMutator;
import org.jetbrains.k2js.translate.utils.mutator.LastExpressionMutator;
import java.util.ArrayList;
import java.util.List;
@@ -121,8 +122,8 @@ public class WhenTranslator extends AbstractTranslator {
@NotNull
JsStatement withReturnValueCaptured(@NotNull JsNode node) {
return convertToStatement(mutateLastExpression(node,
new JsAstUtils.SaveLastExpressionMutator(result.reference())));
return convertToStatement(LastExpressionMutator.mutateLastExpression(node,
new AssignToExpressionMutator(result.reference())));
}
@NotNull
@@ -193,60 +193,6 @@ public final class JsAstUtils {
return jsObjectLiteral;
}
public interface Mutator {
JsNode mutate(JsNode node);
}
//TODO: move somewhere
//TODO: refactor and review
public static JsNode mutateLastExpression(@NotNull JsNode node, @NotNull Mutator mutator) {
if (node instanceof JsBlock) {
JsBlock block = (JsBlock) node;
List<JsStatement> statements = block.getStatements();
if (statements.isEmpty()) return block;
int size = statements.size();
statements.set(size - 1,
convertToStatement(mutateLastExpression(statements.get(size - 1), mutator)));
return block;
}
if (node instanceof JsIf) {
JsIf ifExpr = (JsIf) node;
ifExpr.setThenStmt(convertToStatement(mutateLastExpression(ifExpr.getThenStmt(), mutator)));
JsStatement elseStmt = ifExpr.getElseStmt();
if (elseStmt != null) {
ifExpr.setElseStmt(convertToStatement(mutateLastExpression(elseStmt, mutator)));
}
return ifExpr;
}
if (node instanceof JsExprStmt) {
return convertToStatement(mutateLastExpression(((JsExprStmt) node).getExpression(), mutator));
}
return mutator.mutate(node);
}
public static final class SaveLastExpressionMutator implements Mutator {
@NotNull
private final JsExpression toAssign;
public SaveLastExpressionMutator(@NotNull JsExpression toAssign) {
this.toAssign = toAssign;
}
@Override
public JsNode mutate(JsNode node) {
if (!(node instanceof JsExpression)) {
return node;
}
return assignment(toAssign, (JsExpression) node);
}
}
@NotNull
public static JsVars newVar(@NotNull JsName name, @Nullable JsExpression expr) {
JsVars.JsVar var = new JsVars.JsVar(name);
@@ -0,0 +1,45 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.k2js.translate.utils.mutator;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsNode;
import org.jetbrains.annotations.NotNull;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment;
/**
* @author Pavel Talanov
*/
public final class AssignToExpressionMutator implements Mutator {
@NotNull
private final JsExpression toAssign;
public AssignToExpressionMutator(@NotNull JsExpression toAssign) {
this.toAssign = toAssign;
}
@NotNull
@Override
public JsNode mutate(@NotNull JsNode node) {
if (!(node instanceof JsExpression)) {
return node;
}
return assignment(toAssign, (JsExpression) node);
}
}
@@ -0,0 +1,81 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.k2js.translate.utils.mutator;
import com.google.dart.compiler.backend.js.ast.*;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToStatement;
/**
* @author Pavel Talanov
*/
public final class LastExpressionMutator {
public static JsNode mutateLastExpression(@NotNull JsNode node, @NotNull Mutator mutator) {
return (new LastExpressionMutator(mutator)).apply(node);
}
@NotNull
private final Mutator mutator;
private LastExpressionMutator(@NotNull Mutator mutator) {
this.mutator = mutator;
}
@NotNull
private JsNode apply(@NotNull JsNode node) {
if (node instanceof JsBlock) {
return applyToBlock((JsBlock) node);
}
if (node instanceof JsIf) {
return applyToIf((JsIf) node);
}
if (node instanceof JsExprStmt) {
return applyToStatement((JsExprStmt) node);
}
return mutator.mutate(node);
}
@NotNull
private JsNode applyToStatement(@NotNull JsExprStmt node) {
return convertToStatement(apply(node.getExpression()));
}
@NotNull
private JsNode applyToIf(@NotNull JsIf node) {
node.setThenStmt(convertToStatement(apply(node.getThenStmt())));
JsStatement elseStmt = node.getElseStmt();
if (elseStmt != null) {
node.setElseStmt(convertToStatement(apply(elseStmt)));
}
return node;
}
@NotNull
private JsNode applyToBlock(@NotNull JsBlock node) {
List<JsStatement> statements = node.getStatements();
if (statements.isEmpty()) return node;
int size = statements.size();
statements.set(size - 1, convertToStatement(apply(statements.get(size - 1))));
return node;
}
}
@@ -0,0 +1,28 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.k2js.translate.utils.mutator;
import com.google.dart.compiler.backend.js.ast.JsNode;
import org.jetbrains.annotations.NotNull;
/**
* @author Pavel Talanov
*/
public interface Mutator {
@NotNull
JsNode mutate(@NotNull JsNode node);
}