<?xml version="1.0" encoding="UTF-8"?>
<test-data
    xmlns="http://pmd.sourceforge.net/rule-tests"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd">

    <test-code>
        <description>failure case, return statement</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
    public int bar() {
        return (0);
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>failure case, assignment</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
    public int bar(int x) {
        int y = (x + 5);
        return y;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>failure case, condition 1</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
    public int bar(int x) {
        if ((x % 2 == 0)) {
            return x;
        }
        return 0;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>failure case, condition 2</description>
        <rule-property name="ignoreClarifying">false</rule-property>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
    public int bar(int x) {
        if ((x % 2) == 0) {
            return x;
        }
        return 0;
    }
}
        ]]></code>
    </test-code>
    <test-code>
        <description>failure case, ignore clarifying</description>
        <rule-property name="ignoreClarifying">true</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
    public int bar(int x) {
        if ((x % 2) == 0) {
            return x;
        }
        return 0;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>useful parentheses, arithmetic</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
    public int bar(int x) {
        return (x + 2) * 5;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>useful parentheses, logic</description>
        <rule-property name="ignoreClarifying">true</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
    public int bar(int x) {
        if ((x % 2 == 0) || (x % 2 == 1)) {
            return x;
        } else {
            // it's the same with this extra parentheses
            return (x %2 == 0) ? x : -x;
        }
        return -x;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>typecast, ok</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
   public String bar(Object o) {
        return ((Exception) o).getMessage();
   }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>typecast with extra, bad</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
    public String bar(Object o) {
        return (((Exception) o)).getMessage();
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>false negatives</description>
        <rule-property name="ignoreClarifying">false</rule-property>
        <expected-problems>8</expected-problems>
        <expected-linenumbers>8,10,14,19,20,21,22,23</expected-linenumbers>
        <code><![CDATA[
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement;
import static somewhere.Unresolved.unresolved1;
import static somewhere.Unresolved.unresolved2;
public class Foo {
    private boolean isSimpleReturn(Node node) {
        return
            ( node instanceof ASTReturnStatement ) // rule triggers here
            &&
            ( node.getNumChildren() == 0 );     // and here
    }
    public String getLocalName(String name) {
        int colonIndex = name.indexOf(':');
        return (colonIndex >= 0)                // and here
                ? name.substring(colonIndex + 1)
                : name;
    }
    public void viewerModelChanged() {
        int startOffset = (unresolved1 + unresolved2) - 1; // here, the parenthesized expr has unresolved type
        startOffset = (unresolved1 + 1) - 1; // here, the parenthesized expr has resolved type
        startOffset = (1 + unresolved1) - 1;
        startOffset = (1 + 1) - 1;
        startOffset = 1 + (1 - 1); // necessary if
    }
}
        ]]></code>
    </test-code>
    <test-code>
        <description>Parentheses inside concat may be unnecessary</description>
        <rule-property name="ignoreClarifying">false</rule-property>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>4</expected-linenumbers>
        <code><![CDATA[
public class Foo {
    {
        String concat;
        concat = (1 + 1) + "";          // parentheses are unnecessary but clarifying
        concat = "" + (1 + 1);          // parentheses are necessary even if ignoring associativity
    }
}
        ]]></code>
    </test-code>
    <test-code>
        <description>Parentheses inside concat may be unnecessary</description>
        <rule-property name="ignoreClarifying">true</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
    {
        String concat;
        concat = (1 + 1) + "";          // parentheses are unnecessary but clarifying
        concat = "" + (1 + 1);          // parentheses are necessary even if ignoring associativity
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Parentheses around binary expressions are really necessary</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
    private final boolean isModifier(int mask) {
        return (modifiers & mask) == mask;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>3526992, false +. In this case the parentheses must stay.</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Test {
    public void testMethod() {
        String oneDay = "day";
        String moreDays = "days";
        int dayCount = 4;
        String description = dayCount + " " + (dayCount == 1 ? oneDay : moreDays);
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1012 False positive: Useless parentheses.</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Test {
    static int NUMBER = 0;
    static int STRING = 1;
    class Lookahead { int type; }
    public void testMethod(Lookahead lookahead, int baseType) {
        if((lookahead.type == STRING || lookahead.type == NUMBER) && lookahead.type != baseType)
            throw new RuntimeException("");
        System.out.println( "number " + ( 1 + 2 ) );

        if(lookahead.type != baseType && (lookahead.type == STRING || lookahead.type == NUMBER))
            throw new RuntimeException("");
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1111 False positive: Useless parentheses</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Test {
    public String check(boolean absolute, Integer amount) {
      return (absolute ? amount.abs() : amount).toString();
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1102 False positive: shift operator parenthesis</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Test {
    int getX() { return 0; }
    public void foo(Test e) {
        xCoord = e.getX() - (1 >> 1);
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1243 Useless Parentheses False Positive</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Test {
    public static int thisShouldBreak(final int x, final int y, final int z) {
        return x - (y + z);
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1282 False Positive with implicit String.valuesOf() (Java)</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package com.mycompany.mavenproject1;

import java.io.IOException;

public class NewClass {

    public void falsePositive(Boolean b) throws IOException {
        System.out.write(( "" + b ).getBytes());
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1366 UselessParentheses false positive on multiple equality operators</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Useless {
    public boolean test(Object a, Object b) {
        return (a == null) == (b == null);
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1407 UselessParentheses "&amp;" and "+" operator precedence</description>
        <rule-property name="ignoreClarifying">false</rule-property>
        <expected-problems>13</expected-problems>
        <expected-linenumbers>5,6,7,8,9,10,11,12,13,14,15,16,17</expected-linenumbers>
        <code><![CDATA[
class ExampleClass {
    void exampleExpressions() {
        int eUseless, eGood, a, b, c, d;
        a = b = c = d = 0;
        eUseless = (a++) + b;
        eUseless = (a--) + b;
        eUseless = (++a) + b;
        eUseless = (--a) + b;
        eUseless = (+a) + b;
        eUseless = (-a) + b;
        eUseless = (~a) + b;
        eUseless = (!a) + b;
        eUseless = (a * b) + c;
        eUseless = (a / b) + c;
        eUseless = (a % b) + c;
        eUseless = (a + b) + c;
        eUseless = (a - b) + c;
        eGood = (a << b) + c;
        eGood = (a >> b) + c;
        eGood = (a >>> b) + c;
        eGood = (a < b) + c;
        eGood = (a > b) + c;
        eGood = (a <= b) + c;
        eGood = (a >= b) + c;
        eGood = (a instanceof String) + c;
        eGood = (a == b) + c;
        eGood = (a != b) + c;
        eGood = (a & b) + c;
        eGood = (a ^ b) + c;
        eGood = (a | b) + c;
        eGood = (a && b) + c;
        eGood = (a || b) + c;
        eGood = (a ? b : c) + d;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>http://stackoverflow.com/questions/34911230/pmd-uselessparentheses-violation: false + with &amp; and &lt;&lt;</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Example {
    private int calculate() {
        return (bytes[0] & 0xff) + ((bytes[1] & 0xff) << 8);
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Verify #1519 [java] UselessParenthesis: False Positive: "Prohibits the use of useless parentheses" when more than one line</description>
        <expected-problems>2</expected-problems>
        <expected-linenumbers>3,7</expected-linenumbers>
        <code><![CDATA[
public class Pokemon {
    public void method(String pokeNick, Pokemon pokemon, Pokemon renameResult) {
        boolean isSkipped = (pokeNick.equals(getNickname())
            && 0 == getNumber());

        // now the same in one line
        boolean isSkipped2 = (pokeNick.equals(pokemon.getNickname()) && renameResult.getNumber() == 0);

        // now without the outer parenthesis - no additional violation.
        boolean isSkipped3 = pokeNick.equals(pokemon.getNickname()) && renameResult.getNumber() == 9;
    }
    String getNickname() {return null;}
    int getNumber() { return 0; }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#199 UselessParentheses false positive on multiple logical and operators</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Useless {
    int mNumber;
    String mName, mTemplateKey, mKey;
    public boolean test(Useless team) {
        return (mNumber != null ? mNumber.equals(team.mNumber) : team.mNumber == null)
            && (mKey != null ? mKey.equals(team.mKey) : team.mKey == null)
            && (mTemplateKey != null ? mTemplateKey.equals(team.mTemplateKey) : team.mTemplateKey == null)
            && (mName != null ? mName.equals(team.mName) : team.mName == null);
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#199 UselessParentheses false positive on multiple logical or operators</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Useless {
    int mNumber;
    String mName, mTemplateKey, mKey;
    public boolean test(Useless team) {
        return (mNumber != null ? mNumber.equals(team.mNumber) : team.mNumber == null)
            || (mKey != null ? mKey.equals(team.mKey) : team.mKey == null)
            || (mTemplateKey != null ? mTemplateKey.equals(team.mTemplateKey) : team.mTemplateKey == null)
            || (mName != null ? mName.equals(team.mName) : team.mName == null);
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#199 UselessParentheses false positive on equals operator</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Useless {
    int mNumber;
    String mKey;
    public boolean test(Useless team) {
        return (mNumber != null ? mNumber : team.mNumber)
            == (mKey != null ? mKey : team.mKey);
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>From controversial/UnnecessaryParentheses: #537 Trivial case with additive expression</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import my.Utils;
public class Foo {
    private String getData(final String header) {
        String result = ("[" + header + ":" + Utils.decode(header) + "]");
        return result;
    }
}
         ]]></code>
    </test-code>

    <test-code>
        <description>From controversial/UnnecessaryParentheses: #537 Trivial case with additive expression modified</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import my.Utils;
public class Foo {
    private String getData(final String header) {
        String result = ("[" + header + ":" + Utils.decode(header) + "]").foo();
        return result;
    }
}
         ]]></code>
    </test-code>

    <test-code>
        <description>From controversial/UnnecessaryParentheses: Parentheses around cast</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
    public void bar(Object o) {
        return ((String) "doo");
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>From controversial/UnnecessaryParentheses: Parentheses around call chain</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
    public Foo bar(Foo a) {
        return (a.bar()).foo();
    }
    Foo bar() { return this; }
    Foo foo() { return this; }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>From controversial/UnnecessaryParentheses: Unreported call chain</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
    public Foo bar(Foo a) {
        return a.bar().foo();
    }
    Foo bar() { return this; }
    Foo foo() { return this; }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>From controversial/UnnecessaryParentheses: bad, returning variable in parens</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
    int bar(int y) {
        return (y);
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>From controversial/UnnecessaryParentheses: Failure case, returning literal</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
    int bar() {
        String a = ((String) "foo");
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>FP on binary operator</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
    private boolean isModifier(int mask) {
        return (modifiers & mask) == mask;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>[java] False positive for useless parenthesis #1023</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Test {
    private String str1;

    public String themeName() {
        return (Character.toUpperCase(str1.charAt(0))
                + str1.substring(1)).replace('_', ' ');
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>[java] False positive "UselessParentheses" for parentheses that contain assignment #1285</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.regex.*;
public class Test {
    public void test() {
        Pattern p;
        Matcher m;
        if ((m = p.matcher("hello world")).matches()) {
            System.out.println("Hello world");
        }
    }
}
        ]]></code>
    </test-code>
    <test-code>
        <description>#2739 [java] False Positive UselessParenthesis for string concatenation</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Test {
    public static boolean isTest(final String alpha, final String bravo) {
        return "Charlie".equals(alpha) || (alpha + bravo).equals(alpha);
    }

}
        ]]></code>
    </test-code>
    <test-code>
        <!-- Note: this is why property ignoreClarifying was added  -->
        <description>[java] false-positive in UselessParentheses #1673</description>
        <rule-property name="ignoreClarifying">true</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Test {
    public static boolean isTest(final String discordClient, final String bravo) {
        throw new IllegalArgumentException(String.format(
                "Unsupported client with class '%s' given",
                (discordClient == null) ? null : discordClient.getClass()));
    }

}
        ]]></code>
    </test-code>
    <test-code>
        <!-- Note: this is why property ignoreClarifying was added  -->
        <description>[java] false-positive in UselessParentheses #1673 (!ignoreClarifying)</description>
        <rule-property name="ignoreClarifying">false</rule-property>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Test {
    public static boolean isTest(final String discordClient, final String bravo) {
        throw new IllegalArgumentException(String.format(
                "Unsupported client with class '%s' given",
                (discordClient == null) ? null : discordClient.getClass()));
    }

}
        ]]></code>
    </test-code>
    <test-code>
        <!-- Note: this is why property ignoreClarifying was added  -->
        <description>[Java] UselessParentheses: catch wrong case #1918 (ignoreClarifying)</description>
        <rule-property name="ignoreClarifying">true</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Test {
    public static boolean isTest() {
        boolean a,b,c,d;
        if(a || b || (c & d) || e) {
            //do sth
        }
    }

}
        ]]></code>
    </test-code>
    <test-code>
        <!-- Note: this is why property ignoreClarifying was added  -->
        <description>[Java] UselessParentheses: catch wrong case #1918 (!ignoreClarifying)</description>
        <rule-property name="ignoreClarifying">false</rule-property>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Test {
    public static boolean isTest() {
        boolean a,b,c,d;
        if(a || b || (c & d) || e) {
            //do sth
        }
    }

}
        ]]></code>
    </test-code>
    <test-code>
        <description>[java] False positive for rule UselessParentheses #2910</description>
        <rule-property name="ignoreClarifying">false</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            package jls;

            public final class TestStringInterned {

                public static void main(String[] args) {
                    String hello = "Hello";
                    String lo = "lo";
                    System.out.println(hello == ("Hel" + lo).intern());
                }
            }
            ]]></code>
    </test-code>
</test-data>
