<commit_before>package com.redhat.ceylon.compiler.js;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.Comprehension;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.ComprehensionClause;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.ExpressionComprehensionClause;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.ForComprehensionClause;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.ForIterator;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.IfComprehensionClause;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.InitialComprehensionClause;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.KeyValueIterator;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.ValueIterator;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.Variable;

/** This component is used by the main JS visitor to generate code for comprehensions.
 * 
 * @author <NAME>
 * @author <NAME>
 */
class ComprehensionGenerator {

    private final GenerateJsVisitor gen;
    private final JsIdentifierNames names;
    private final RetainedVars retainedVars = new RetainedVars();
    private final String finished;
    private final Set<Declaration> directAccess;

    ComprehensionGenerator(GenerateJsVisitor gen, JsIdentifierNames names, Set<Declaration> directDeclarations) {
        this.gen = gen;
        finished = String.format("%sgetFinished()", GenerateJsVisitor.getClAlias());
        this.names = names;
        directAccess = directDeclarations;
    }

    void generateComprehension(Comprehension that) {
        gen.out(GenerateJsVisitor.getClAlias(), "Comprehension(function()");
        gen.beginBlock();
        if (gen.opts.isComment()) {
            gen.out("//Comprehension"); gen.location(that); gen.endLine();
        }

        // gather information about all loops and conditions in the comprehension
        List<ComprehensionLoopInfo> loops = new ArrayList<ComprehensionLoopInfo>();
        Expression expression = null;
        ComprehensionClause startClause = that.getInitialComprehensionClause();
        String tail = null;
        /**
         * The number of initial "if" comprehension clauses, i.&nbsp;e., the number of blocks that have to be ended.
         */
        int initialIfClauses = 0;
        while (!(startClause instanceof ForComprehensionClause)) {
            if (startClause instanceof IfComprehensionClause) {
                // check the condition
                IfComprehensionClause ifClause = (IfComprehensionClause)startClause;
                gen.conds.specialConditions(
                        gen.conds.gatherVariables(ifClause.getConditionList()),
                        ifClause.getConditionList(),
                        "if");
                initialIfClauses++;
                gen.beginBlock();
                startClause = ifClause.getComprehensionClause();
                if (!(startClause instanceof IfComprehensionClause)) {
                    // we'll put the rest of the comprehension inside this if block;
                    // outside the if block, return nothing (if any condition isn't true)
                    tail = "return function(){return " + finished + ";}";
                }
            } else if (startClause instanceof ExpressionComprehensionClause) {
                // return the expression result
                gen.out("return function() {");
                ((ExpressionComprehensionClause)startClause).getExpression().visit(gen);
                gen.out("};");
                for (int i = 0; i < initialIfClauses; i++) {
                    gen.endBlock();
                }
                gen.endLine();
                gen.out(tail);
                gen.endBlock(); // end one more block - this one is for the function
                gen.out(",");
                TypeUtils.printTypeArguments(that, gen.getTypeUtils().wrapAsIterableArguments(that.getTypeModel()), gen);
                gen.out(")");
                return;
            } else {
                that.addError("No support for comprehension clause of type "
                              + startClause.getClass().getName());
                return;
            }
        }
        ForComprehensionClause forClause = (ForComprehensionClause)startClause;
        while (forClause != null) {
            ComprehensionLoopInfo loop = new ComprehensionLoopInfo(that, forClause.getForIterator());
            ComprehensionClause clause = forClause.getComprehensionClause();
            while ((clause != null) && !(clause instanceof ForComprehensionClause)) {<commit_msg>Fix stupid bug in "if+ expr" comprehensions<commit_after>package com.redhat.ceylon.compiler.js;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.Comprehension;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.ComprehensionClause;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.ExpressionComprehensionClause;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.ForComprehensionClause;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.ForIterator;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.IfComprehensionClause;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.InitialComprehensionClause;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.KeyValueIterator;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.ValueIterator;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.Variable;

/** This component is used by the main JS visitor to generate code for comprehensions.
 * 
 * @author <NAME>
 * @author <NAME>
 */
class ComprehensionGenerator {

    private final GenerateJsVisitor gen;
    private final JsIdentifierNames names;
    private final RetainedVars retainedVars = new RetainedVars();
    private final String finished;
    private final Set<Declaration> directAccess;

    ComprehensionGenerator(GenerateJsVisitor gen, JsIdentifierNames names, Set<Declaration> directDeclarations) {
        this.gen = gen;
        finished = String.format("%sgetFinished()", GenerateJsVisitor.getClAlias());
        this.names = names;
        directAccess = directDeclarations;
    }

    void generateComprehension(Comprehension that) {
        gen.out(GenerateJsVisitor.getClAlias(), "Comprehension(function()");
        gen.beginBlock();
        if (gen.opts.isComment()) {
            gen.out("//Comprehension"); gen.location(that); gen.endLine();
        }

        // gather information about all loops and conditions in the comprehension
        List<ComprehensionLoopInfo> loops = new ArrayList<ComprehensionLoopInfo>();
        Expression expression = null;
        ComprehensionClause startClause = that.getInitialComprehensionClause();
        String tail = null;
        /**
         * The number of initial "if" comprehension clauses, i.&nbsp;e., the number of blocks that have to be ended.
         */
        int initialIfClauses = 0;
        while (!(startClause instanceof ForComprehensionClause)) {
            if (startClause instanceof IfComprehensionClause) {
                // check the condition
                IfComprehensionClause ifClause = (IfComprehensionClause)startClause;
                gen.conds.specialConditions(
                        gen.conds.gatherVariables(ifClause.getConditionList()),
                        ifClause.getConditionList(),
                        "if");
                initialIfClauses++;
                gen.beginBlock();
                startClause = ifClause.getComprehensionClause();
                if (!(startClause instanceof IfComprehensionClause)) {
                    // we'll put the rest of the comprehension inside this if block;
                    // outside the if block, return nothing (if any condition isn't true)
                    tail = "return function(){return " + finished + ";}";
                }
            } else if (startClause instanceof ExpressionComprehensionClause) {
                // return the expression result
                gen.out("return function(){return ");
                ((ExpressionComprehensionClause)startClause).getExpression().visit(gen);
                gen.out("};");
                for (int i = 0; i < initialIfClauses; i++) {
                    gen.endBlock();
                }
                gen.endLine();
                gen.out(tail);
                gen.endBlock(); // end one more block - this one is for the function
                gen.out(",");
                TypeUtils.printTypeArguments(that, gen.getTypeUtils().wrapAsIterableArguments(that.getTypeModel()), gen);
                gen.out(")");
                return;
            } else {
                that.addError("No support for comprehension clause of type "
                              + startClause.getClass().getName());
                return;
            }
        }
        ForComprehensionClause forClause = (ForComprehensionClause)startClause;
        while (forClause != null) {
            ComprehensionLoopInfo loop = new ComprehensionLoopInfo(that, forClause.getForIterator());
            ComprehensionClause clause = forClause.getComprehensionClause();
            while ((clause != null) && !(clause instanceof ForComprehensionClause)) {
{'fraction_non_alphanumeric': 0.09815005138746145, 'fraction_numerical': 0.00041109969167523125, 'mean_word_length': 2.5921004060538944, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '3634949', 'n_tokens_mistral': 2595, 'n_tokens_neox': 2538, 'n_words': 540}