<commit_before>/*
 *  Copyright 2012 <NAME>.
 *
 *  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.teavm.javascript;

import java.util.*;
import org.teavm.javascript.ast.*;

/**
 *
 * @author <NAME>
 */
class OptimizingVisitor implements StatementVisitor, ExprVisitor {
    public Expr resultExpr;
    public Statement resultStmt;
    private ReadWriteStatsBuilder stats;
    private List<Statement> resultSequence;

    public OptimizingVisitor(ReadWriteStatsBuilder stats) {
        this.stats = stats;
    }

    private static boolean isZero(Expr expr) {
        return expr instanceof ConstantExpr && Integer.valueOf(0).equals(((ConstantExpr)expr).getValue());
    }

    private static boolean isComparison(Expr expr) {
        return expr instanceof BinaryExpr && ((BinaryExpr)expr).getOperation() == BinaryOperation.COMPARE;
    }

    @Override
    public void visit(BinaryExpr expr) {
        switch (expr.getOperation()) {
            case AND:
            case OR:
                resultExpr = expr;
                return;
            default:
                break;
        }
        expr.getSecondOperand().acceptVisitor(this);
        Expr b = resultExpr;
        expr.getFirstOperand().acceptVisitor(this);
        Expr a = resultExpr;
        Expr p = a;
        Expr q = b;
        boolean invert = false;
        if (isZero(p)) {
            Expr tmp = p;
            p = q;
            q = tmp;
            invert = true;
        }
        if (isComparison(p) && isZero(q)) {
            switch (expr.getOperation()) {
                case EQUALS:
                case NOT_EQUALS:
                case LESS:
                case LESS_OR_EQUALS:
                case GREATER:
                case GREATER_OR_EQUALS: {
                    BinaryExpr comparison = (BinaryExpr)p;
                    Expr result = BinaryExpr.binary(expr.getOperation(),
                            comparison.getFirstOperand(), comparison.getSecondOperand());
                    result.setLocation(comparison.getLocation());
                    if (invert) {
                        result = ExprOptimizer.invert(result);
                    }
                    resultExpr = result;
                    return;
                }
                default:
                    break;
            }
        }
        expr.setFirstOperand(a);
        expr.setSecondOperand(b);
        resultExpr = expr;
    }

    @Override
    public void visit(UnaryExpr expr) {
        expr.getOperand().acceptVisitor(this);
        Expr operand = resultExpr;
        expr.setOperand(operand);
        resultExpr = expr;
    }

    @Override
    public void visit(ConditionalExpr expr) {
        expr.getCondition().acceptVisitor(this);
        Expr cond = resultExpr;
        expr.getConsequent().acceptVisitor(this);
        Expr consequent = resultExpr;
        expr.getAlternative().acceptVisitor(this);
        Expr alternative = resultExpr;
        expr.setCondition(cond);
        expr.setConsequent(consequent);
        expr.setAlternative(alternative);
        resultExpr = expr;
    }

    @Override
    public void visit(ConstantExpr expr) {
        resultExpr = expr;
    }

    @Override
    public void visit(VariableExpr expr) {
        int index = expr.getIndex();
        resultExpr = expr;
        if (stats.reads[index] != 1 || stats.writes[index] != 1) {
            return;
        }
        if (resultSequence.isEmpty()) {
            return;
        }
        Statement last = resultSequence.get(resultSequence.size() - 1);
        if (!(last instanceof AssignmentStatement)) {
            return;
        }
        AssignmentStatement assignment = (AssignmentStatement)last;
        if (!(assignment.getLeftValue() instanceof VariableExpr)) {
            return;
        }
        VariableExpr var = (VariableExpr)assignment.getLeftValue();
        if (var.getLocation() != null && assignment.getLocation() != null &&
                !assignment.getLocation().equals(var.getLocation())) {
            return;
        }
        if (var.getIndex() == index) {
            resultSequence.remove(resultSequence.size() - 1);
            assignment.getRightValue().setLocation(assignment.getLocation());
            assignment.getRightValue().acceptVisitor(this);
        }
    }

    @Override
    public void visit(SubscriptExpr expr) {
        expr.getIndex().acceptVisitor(this);
        Expr index = resultExpr;
        expr.getArray().acceptVisitor(this);
        Expr array = resultExpr;
        expr.setArray(array);
        expr.setIndex(index);
        resultExpr = expr;
    }

    @Override
    public void visit(UnwrapArrayExpr expr) {
        expr.getArray().acceptVisitor(this);
        Expr arrayExpr = resultExpr;<commit_msg>Prevent async assigment from optimization<commit_after>/*
 *  Copyright 2012 <NAME>.
 *
 *  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.teavm.javascript;

import java.util.*;
import org.teavm.javascript.ast.*;

/**
 *
 * @author <NAME>
 */
class OptimizingVisitor implements StatementVisitor, ExprVisitor {
    public Expr resultExpr;
    public Statement resultStmt;
    private ReadWriteStatsBuilder stats;
    private List<Statement> resultSequence;

    public OptimizingVisitor(ReadWriteStatsBuilder stats) {
        this.stats = stats;
    }

    private static boolean isZero(Expr expr) {
        return expr instanceof ConstantExpr && Integer.valueOf(0).equals(((ConstantExpr)expr).getValue());
    }

    private static boolean isComparison(Expr expr) {
        return expr instanceof BinaryExpr && ((BinaryExpr)expr).getOperation() == BinaryOperation.COMPARE;
    }

    @Override
    public void visit(BinaryExpr expr) {
        switch (expr.getOperation()) {
            case AND:
            case OR:
                resultExpr = expr;
                return;
            default:
                break;
        }
        expr.getSecondOperand().acceptVisitor(this);
        Expr b = resultExpr;
        expr.getFirstOperand().acceptVisitor(this);
        Expr a = resultExpr;
        Expr p = a;
        Expr q = b;
        boolean invert = false;
        if (isZero(p)) {
            Expr tmp = p;
            p = q;
            q = tmp;
            invert = true;
        }
        if (isComparison(p) && isZero(q)) {
            switch (expr.getOperation()) {
                case EQUALS:
                case NOT_EQUALS:
                case LESS:
                case LESS_OR_EQUALS:
                case GREATER:
                case GREATER_OR_EQUALS: {
                    BinaryExpr comparison = (BinaryExpr)p;
                    Expr result = BinaryExpr.binary(expr.getOperation(),
                            comparison.getFirstOperand(), comparison.getSecondOperand());
                    result.setLocation(comparison.getLocation());
                    if (invert) {
                        result = ExprOptimizer.invert(result);
                    }
                    resultExpr = result;
                    return;
                }
                default:
                    break;
            }
        }
        expr.setFirstOperand(a);
        expr.setSecondOperand(b);
        resultExpr = expr;
    }

    @Override
    public void visit(UnaryExpr expr) {
        expr.getOperand().acceptVisitor(this);
        Expr operand = resultExpr;
        expr.setOperand(operand);
        resultExpr = expr;
    }

    @Override
    public void visit(ConditionalExpr expr) {
        expr.getCondition().acceptVisitor(this);
        Expr cond = resultExpr;
        expr.getConsequent().acceptVisitor(this);
        Expr consequent = resultExpr;
        expr.getAlternative().acceptVisitor(this);
        Expr alternative = resultExpr;
        expr.setCondition(cond);
        expr.setConsequent(consequent);
        expr.setAlternative(alternative);
        resultExpr = expr;
    }

    @Override
    public void visit(ConstantExpr expr) {
        resultExpr = expr;
    }

    @Override
    public void visit(VariableExpr expr) {
        int index = expr.getIndex();
        resultExpr = expr;
        if (stats.reads[index] != 1 || stats.writes[index] != 1) {
            return;
        }
        if (resultSequence.isEmpty()) {
            return;
        }
        Statement last = resultSequence.get(resultSequence.size() - 1);
        if (!(last instanceof AssignmentStatement)) {
            return;
        }
        AssignmentStatement assignment = (AssignmentStatement)last;
        if (assignment.isAsync()) {
            return;
        }
        if (!(assignment.getLeftValue() instanceof VariableExpr)) {
            return;
        }
        VariableExpr var = (VariableExpr)assignment.getLeftValue();
        if (var.getLocation() != null && assignment.getLocation() != null &&
                !assignment.getLocation().equals(var.getLocation())) {
            return;
        }
        if (var.getIndex() == index) {
            resultSequence.remove(resultSequence.size() - 1);
            assignment.getRightValue().setLocation(assignment.getLocation());
            assignment.getRightValue().acceptVisitor(this);
        }
    }

    @Override
    public void visit(SubscriptExpr expr) {
        expr.getIndex().acceptVisitor(this);
        Expr index = resultExpr;
        expr.getArray().acceptVisitor(this);
        Expr array = resultExpr;
        expr.setArray(array);
        expr.setIndex(index);
        resultExpr = expr;
    }

    @Override
    public void visit(UnwrapArrayExpr expr) {
        expr.getArray().acceptVisitor(this);
        Expr arrayExpr = resultExpr;
{'fraction_non_alphanumeric': 0.09714393085306276, 'fraction_numerical': 0.0024426907177752723, 'mean_word_length': 1.9512059883559745, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5044908', 'n_tokens_mistral': 2814, 'n_tokens_neox': 2706, 'n_words': 678}