public void testLinenoMultilineEq() {
    AstRoot root =
        parse(
            "\nif\n"
                + "    (((a == \n"
                + "  3) && \n"
                + "  (b == 2)) || \n"
                + " (c == 1)) {\n"
                + "}\n");
    IfStatement ifStmt = (IfStatement) root.getFirstChild();
    InfixExpression orTest = (InfixExpression) ifStmt.getCondition();
    ParenthesizedExpression cTestParen = (ParenthesizedExpression) orTest.getRight();
    InfixExpression cTest = (InfixExpression) cTestParen.getExpression();
    ParenthesizedExpression andTestParen = (ParenthesizedExpression) orTest.getLeft();
    InfixExpression andTest = (InfixExpression) andTestParen.getExpression();
    AstNode aTest = andTest.getLeft();
    AstNode bTest = andTest.getRight();

    assertEquals(1, ifStmt.getLineno());
    assertEquals(2, orTest.getLineno());
    assertEquals(2, andTest.getLineno());
    assertEquals(2, aTest.getLineno());
    assertEquals(4, bTest.getLineno());
    assertEquals(5, cTest.getLineno());
    assertEquals(5, cTestParen.getLineno());
    assertEquals(2, andTestParen.getLineno());
  }
  public void testLinenoEq() {
    AstRoot root = parse("\na\n" + "==\n" + "b\n");
    ExpressionStatement expr = (ExpressionStatement) root.getFirstChild();
    InfixExpression compare = (InfixExpression) expr.getExpression();
    AstNode lhs = compare.getLeft();
    AstNode rhs = compare.getRight();

    assertEquals(1, lhs.getLineno());
    assertEquals(1, compare.getLineno());
    assertEquals(3, rhs.getLineno());
  }
  public void testLinenoComma() {
    AstRoot root = parse("\na,\n" + "    b,\n" + "    c;\n");

    ExpressionStatement stmt = (ExpressionStatement) root.getFirstChild();
    InfixExpression comma1 = (InfixExpression) stmt.getExpression();
    InfixExpression comma2 = (InfixExpression) comma1.getLeft();
    AstNode cRef = comma1.getRight();
    AstNode aRef = comma2.getLeft();
    AstNode bRef = comma2.getRight();

    assertEquals(1, comma1.getLineno());
    assertEquals(1, comma2.getLineno());
    assertEquals(1, aRef.getLineno());
    assertEquals(2, bRef.getLineno());
    assertEquals(3, cRef.getLineno());
  }
  public void testNestedOr() {
    AstNode root =
        parse("\nif (a && \n" + "    b() || \n" + "    /* comment */\n" + "    c) {\n" + "}\n");

    IfStatement ifStmt = (IfStatement) root.getFirstChild();
    InfixExpression orClause = (InfixExpression) ifStmt.getCondition();
    InfixExpression andClause = (InfixExpression) orClause.getLeft();
    AstNode cName = orClause.getRight();

    assertEquals(1, ifStmt.getLineno());
    assertEquals(1, orClause.getLineno());
    assertEquals(1, andClause.getLineno());
    assertEquals(4, cName.getLineno());
  }
 @Override
 public AstNode binary(BinaryOperator operator, Iterable<AstNode> operands) {
   // this is to deal with the COMMA operator who can have less than two operands
   if (Iterables.isEmpty(operands)) {
     return new EmptyExpression();
   }
   if (Iterables.size(operands) == 1) {
     return operands.iterator().next();
   }
   InfixExpression list = new InfixExpression();
   list.setOperator(operator.getJavaScript());
   Iterator<AstNode> it = operands.iterator();
   list.setLeft(it.next());
   list.setRight(it.next());
   while (it.hasNext()) {
     InfixExpression tmpIncrements = new InfixExpression();
     tmpIncrements.setOperator(operator.getJavaScript());
     tmpIncrements.setLeft(list);
     tmpIncrements.setRight(it.next());
     list = tmpIncrements;
   }
   return list;
 }
  public void testLinenoMultilineBitTest() {
    AstRoot root =
        parse(
            "\nif (\n"
                + "      ((a \n"
                + "        | 3 \n"
                + "       ) == \n"
                + "       (b \n"
                + "        & 2)) && \n"
                + "      ((a \n"
                + "         ^ 0xffff) \n"
                + "       != \n"
                + "       (c \n"
                + "        << 1))) {\n"
                + "}\n");

    IfStatement ifStmt = (IfStatement) root.getFirstChild();
    InfixExpression andTest = (InfixExpression) ifStmt.getCondition();
    ParenthesizedExpression bigLHSExpr = (ParenthesizedExpression) andTest.getLeft();
    ParenthesizedExpression bigRHSExpr = (ParenthesizedExpression) andTest.getRight();

    InfixExpression eqTest = (InfixExpression) bigLHSExpr.getExpression();
    InfixExpression notEqTest = (InfixExpression) bigRHSExpr.getExpression();

    ParenthesizedExpression test1Expr = (ParenthesizedExpression) eqTest.getLeft();
    ParenthesizedExpression test2Expr = (ParenthesizedExpression) eqTest.getRight();

    ParenthesizedExpression test3Expr = (ParenthesizedExpression) notEqTest.getLeft();
    ParenthesizedExpression test4Expr = (ParenthesizedExpression) notEqTest.getRight();

    InfixExpression bitOrTest = (InfixExpression) test1Expr.getExpression();
    InfixExpression bitAndTest = (InfixExpression) test2Expr.getExpression();
    InfixExpression bitXorTest = (InfixExpression) test3Expr.getExpression();
    InfixExpression bitShiftTest = (InfixExpression) test4Expr.getExpression();

    assertEquals(1, ifStmt.getLineno());

    assertEquals(2, bigLHSExpr.getLineno());
    assertEquals(7, bigRHSExpr.getLineno());
    assertEquals(2, eqTest.getLineno());
    assertEquals(7, notEqTest.getLineno());

    assertEquals(2, test1Expr.getLineno());
    assertEquals(5, test2Expr.getLineno());
    assertEquals(7, test3Expr.getLineno());
    assertEquals(10, test4Expr.getLineno());

    assertEquals(2, bitOrTest.getLineno());
    assertEquals(5, bitAndTest.getLineno());
    assertEquals(7, bitXorTest.getLineno());
    assertEquals(10, bitShiftTest.getLineno());
  }
  public void testLinenoInfix() {
    AstRoot root =
        parse(
            "\nvar d = a\n"
                + "    + \n"
                + "    b;\n"
                + "var\n"
                + "    e =\n"
                + "    a +\n"
                + "    c;\n"
                + "var f = b\n"
                + "    / c;\n");

    VariableDeclaration stmt1 = (VariableDeclaration) root.getFirstChild();
    List<VariableInitializer> vars1 = stmt1.getVariables();
    VariableInitializer var1 = vars1.get(0);
    Name firstVarName = (Name) var1.getTarget();
    InfixExpression var1Add = (InfixExpression) var1.getInitializer();

    VariableDeclaration stmt2 = (VariableDeclaration) stmt1.getNext();
    List<VariableInitializer> vars2 = stmt2.getVariables();
    VariableInitializer var2 = vars2.get(0);
    Name secondVarName = (Name) var2.getTarget();
    InfixExpression var2Add = (InfixExpression) var2.getInitializer();

    VariableDeclaration stmt3 = (VariableDeclaration) stmt2.getNext();
    List<VariableInitializer> vars3 = stmt3.getVariables();
    VariableInitializer var3 = vars3.get(0);
    Name thirdVarName = (Name) var3.getTarget();
    InfixExpression thirdVarDiv = (InfixExpression) var3.getInitializer();

    ReturnStatement returnStmt = (ReturnStatement) stmt3.getNext();

    assertEquals(1, var1.getLineno());
    assertEquals(1, firstVarName.getLineno());
    assertEquals(1, var1Add.getLineno());
    assertEquals(1, var1Add.getLeft().getLineno());
    assertEquals(3, var1Add.getRight().getLineno());

    // var directive with name on next line wrong --
    // should be 6.
    assertEquals(5, var2.getLineno());
    assertEquals(5, secondVarName.getLineno());
    assertEquals(6, var2Add.getLineno());
    assertEquals(6, var2Add.getLeft().getLineno());
    assertEquals(7, var2Add.getRight().getLineno());

    assertEquals(8, var3.getLineno());
    assertEquals(8, thirdVarName.getLineno());
    assertEquals(8, thirdVarDiv.getLineno());
    assertEquals(8, thirdVarDiv.getLeft().getLineno());
    assertEquals(9, thirdVarDiv.getRight().getLineno());
  }