001/*
002 * Copyright 2010-2013 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.jetbrains.k2js.translate.utils.mutator;
018
019import com.google.dart.compiler.backend.js.ast.*;
020import org.jetbrains.annotations.NotNull;
021
022import java.util.List;
023
024import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToStatement;
025
026public final class LastExpressionMutator {
027    public static JsStatement mutateLastExpression(@NotNull JsNode node, @NotNull Mutator mutator) {
028        return convertToStatement(new LastExpressionMutator(mutator).apply(node));
029    }
030
031    @NotNull
032    private final Mutator mutator;
033
034    private LastExpressionMutator(@NotNull Mutator mutator) {
035        this.mutator = mutator;
036    }
037
038    //TODO: visitor?
039    //TODO: when expression?
040    @NotNull
041    private JsNode apply(@NotNull JsNode node) {
042        if (node instanceof JsBlock) {
043            return applyToBlock((JsBlock) node);
044        }
045        if (node instanceof JsIf) {
046            return applyToIf((JsIf) node);
047        }
048        if (node instanceof JsExprStmt) {
049            return applyToStatement((JsExprStmt) node);
050        }
051        return mutator.mutate(node);
052    }
053
054    @NotNull
055    private JsNode applyToStatement(@NotNull JsExprStmt node) {
056        return convertToStatement(apply(node.getExpression()));
057    }
058
059    @NotNull
060    private JsNode applyToIf(@NotNull JsIf node) {
061        node.setThenStatement(convertToStatement(apply(node.getThenStatement())));
062        JsStatement elseStmt = node.getElseStatement();
063        if (elseStmt != null) {
064            node.setElseStatement(convertToStatement(apply(elseStmt)));
065        }
066        return node;
067    }
068
069    @NotNull
070    private JsNode applyToBlock(@NotNull JsBlock node) {
071        List<JsStatement> statements = node.getStatements();
072
073        if (statements.isEmpty()) return node;
074
075        int size = statements.size();
076        statements.set(size - 1, convertToStatement(apply(statements.get(size - 1))));
077        return node;
078    }
079}