<?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>pos, empty try block</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>3</expected-linenumbers>
        <expected-messages>
            <message>Empty try body</message>
        </expected-messages>
        <code><![CDATA[
            public class EmptyTryBlock1 {
                public void foo() {
                    try {
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>pos, empty try block</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>3</expected-linenumbers>
        <expected-messages>
            <message>Empty try body</message>
        </expected-messages>
        <code><![CDATA[
            public class EmptyTryBlock2 {
                public void foo() {
                    try {
                    } finally {
                        int x = 5;
                    }
                }
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>pos, empty finally block</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>5</expected-linenumbers>
        <expected-messages>
            <message>Empty finally clause</message>
        </expected-messages>
        <code><![CDATA[
            public class EmptyTryBlock2 {
                public void foo() {
                    try {
                        int x = 0;
                    } finally { // warn
                    }
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>pos, empty finally block</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            public class EmptyTryBlock3 {
                public void foo() {
                    try {
                        int f =2;
                    } finally {
                        int x = 5;
                    }
                }
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>pos, empty try and finally block</description>
        <expected-problems>2</expected-problems>
        <expected-messages>
            <message>Empty try body</message>
            <message>Empty finally clause</message>
        </expected-messages>
        <code><![CDATA[
            public class EmptyTryBlock3 {
                public void foo() {
                    try {
                    } finally {
                    }
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>#432 empty try-with-resource - not ok</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Empty try-with-resources statement. Rename the resource to `ignored`, `unused` or `_` (Java 22+).</message>
        </expected-messages>
        <code><![CDATA[
            class X {
                void method() {
                    try (ClientResponse response = execute(() -> target.request(mediaTypes).delete(), DELETE, new ExpectedResponse(status, required))) {
                        // was false positive
                        // EmptyTryBlock was fixed to ignore empty try-with-resources.
                        // This new rule will by default report also empty try-with-resource blocks,
                        // if the resource name is not "ignored", see next test case.
                    }
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>#432 empty try-with-resource - ok with unused var name</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            class X {
                void method() {
                    try (ClientResponse ignored = execute(() -> target.request(mediaTypes).delete(), DELETE, new ExpectedResponse(status, required))) {
                    }
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>empty concise try-with-resource - not ok</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>4</expected-linenumbers>
        <expected-messages>
            <message>Empty try-with-resources statement. Should be written in.close()</message>
        </expected-messages>
        <code><![CDATA[
            import java.io.InputStream;
            class X {
                void method(InputStream in) {
                    try (in) {
                    }
                }
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>Try with resources with several vars, ok</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            import java.io.InputStream;
            class X {
                void method(InputStream in) {
                    try (final var something = executeSomething(in);
                        something.field) {
                        // this is ok because writing the corresponding sequence of var decls
                        // and close statements would be noisy
                    }
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>pos, empty synchronized stmt</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Empty synchronized statement</message>
        </expected-messages>
        <code><![CDATA[
            public class Foo {
                void foo() {
                    synchronized (this) {}
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>neg, nonempty synchronized stmt</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            public class Foo {
                void foo() {
                    synchronized (this) {int x = 2;}
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>pos, empty switch stmt</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Empty switch statement</message>
        </expected-messages>
        <code><![CDATA[
            public class EmptySwitchStmt1 {
                public void bar() {
                    int x = 2;
                    switch (x) {}
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>neg, nonempty switch stmt</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            public class EmptySwitchStmt2 {
                public void bar() {
                    int x = 2;
                    switch (x) {
                    case 2: int y=4;
                    }
                }
            }
            ]]></code>
    </test-code>


    <test-code>
        <description>pos, empty block</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Empty block</message>
        </expected-messages>
        <code><![CDATA[
            public class Foo {
                public void bar() {
                    {}
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>statement block not empty</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            public class Foo {
                public void bar() {
                    { return; }
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>empty initializer failure case (non static)</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Empty initializer statement</message>
        </expected-messages>
        <code><![CDATA[
            public class Foo {
                {}
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>empty initializer failure case (static)</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Empty initializer statement</message>
        </expected-messages>
        <code><![CDATA[
            public class Foo {
                static {}
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>not an initializer - empty statement block</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Empty block</message>
        </expected-messages>
        <code><![CDATA[
            public class Foo {
                public void bar() {
                    { }
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>initializer not empty</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            public class Foo {
                {
                    System.out.print("something interesting");
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>static initializer not empty</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            public class Foo {
                static {
                    x++;
                }
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>pos, empty for</description>
        <expected-problems>2</expected-problems>
        <expected-linenumbers>3,5</expected-linenumbers>
        <expected-messages>
            <message>Empty for statement</message>
            <message>Empty for statement</message>
        </expected-messages>
        <code><![CDATA[
            public class Foo {
                public void bar() {
                    for (int i = 0; i < 2; i++) {
                    }
                    for (int i = 0; i < 2; i++);
                    for (int i = 0; i < 2; i++) { // neg, nonempty
                        System.out.println(i);
                    }
                }
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>pos, empty do..while</description>
        <expected-problems>2</expected-problems>
        <expected-linenumbers>4,6</expected-linenumbers>
        <expected-messages>
            <message>Empty do..while statement</message>
            <message>Empty do..while statement</message>
        </expected-messages>
        <code><![CDATA[
            public class Foo {
                public void bar() {
                    int i = 0;
                    do {
                    } while (i < 3);
                    do; while (i < 3);
                    do { // neg, nonempty
                        System.out.println(i);
                    } while (i < 3);
                }
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>pos, empty foreach</description>
        <expected-problems>2</expected-problems>
        <expected-linenumbers>6,8</expected-linenumbers>
        <expected-messages>
            <message>Empty foreach statement</message>
            <message>Empty foreach statement</message>
        </expected-messages>
        <code><![CDATA[
            import java.util.List;

            public class Foo {

                public void bar(List<Integer> list) {
                    for (int i : list) {
                    }
                    for (int i : list) ;
                    for (int i : list)  { // neg, nonempty
                        System.out.println(i);
                    }
                }
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>neg, empty foreach with unused var name</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            import java.util.List;

            public class Foo {

                public void bar(List<Integer> list) {
                    for (int ignored : list) {
                    }
                    for (int ignored2 : list) ;
                    for (int i : list) { // neg, nonempty
                        System.out.println(i);
                    }
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>pos, empty while</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>3</expected-linenumbers>
        <expected-messages>
            <message>Empty while statement</message>
        </expected-messages>
        <code><![CDATA[
            public class Foo {
                public void bar() {
                    while (true == true) {
                    }
                    while (true == true) {
                        String x = "";
                    }
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>while(true);</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Empty while statement</message>
        </expected-messages>
        <code><![CDATA[
            public class Foo {
                public void bar() {
                    while (true);
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>one empty if statement</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>3</expected-linenumbers>
        <expected-messages>
            <message>Empty if statement</message>
        </expected-messages>
        <code><![CDATA[
public class Foo {
    void bar(int x) {
        if (x > 2) {
        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>empty if with else statement</description>
        <expected-problems>2</expected-problems>
        <expected-linenumbers>3,4</expected-linenumbers>
        <expected-messages>
            <message>Empty if statement</message>
            <message>Empty else statement</message>
        </expected-messages>
        <code><![CDATA[
public class Foo {
    void bar(int x) {
        if (x > 2) {
        } else {
        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>empty if with else and else if statement</description>
        <expected-problems>3</expected-problems>
        <expected-linenumbers>3,4,5</expected-linenumbers>
        <expected-messages>
            <message>Empty if statement</message>
            <message>Empty if statement</message>
            <message>Empty else statement</message>
        </expected-messages>
        <code><![CDATA[
public class Foo {
    void bar(int x) {
        if (x > 2) {
        } else if (x > 3) {
        } else {
        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>one not empty if statement</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
    void bar(int x) {
        if (x > 2) {
            x = 1;
        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>empty if statement</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Empty if statement</message>
        </expected-messages>
        <code><![CDATA[
public class Foo {
    void bar(int x) {
        if (x > 2);
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>empty if statement with comment, disallow commented block</description>
        <rule-property name="allowCommentedBlocks">false</rule-property>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Empty if statement</message>
        </expected-messages>
        <code><![CDATA[
public class Foo {
    void bar(int x) {
        if (x == 0) {
            // empty!
        }
    }
}
        ]]></code>

    </test-code>
    <test-code>
        <description>empty if statement with comment, allow commented block (#4754)</description>
        <rule-property name="allowCommentedBlocks">true</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
    void bar(int x) {
        if (x == 0) {
            // empty!
        }
    }
}
        ]]></code>

    </test-code>
</test-data>
