<?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><![CDATA[
failure case
     ]]></description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
 private int x;
 int bar(int y) {
  x = y + 5; 
  return x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
Ok, used for control flow
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private int x;
 int bar(int y) {
  if (y = 5)
    x = y + 5; 
  return x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
ok
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private int x;
 void setX(int x) {
  this.x = x;
 }
 int getX() {
  return x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
second method uses 'this'
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private int x;
 void setX(int x) {
  this.x = x;
 }
 int getX() {
  return this.x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
skip publics
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 public int x;
 int bar(int y) {
  x = y + 5; 
  return x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
skip statics
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private static int x;
 int bar(int y) {
  x = y + 5; 
  return x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
unused fields shouldn't show up
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 int a = 3;
 int b = 3;
 void bar() {
  foo(b); 
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
inner class
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private int a;
 void bar() {
  Object o = new FooAdapter() {
   public void bar(Event e) {
    a = e.GetInt();
   }
  }; 
 }
 int baz() {
  return a; 
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
initialized in constructor
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private int x;
 public Foo(int y) {
  x = y; 
 }
 int bar(int y) {
  x = y + 5; 
  return x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
ok case with Object
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private Integer x = null;
 private Integer getFoo() {
  if(x == null){
      x = new Integer(1);
  }
  return x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
ok, shouldn't catch unused variable
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private int x;
 void bar(int y) {
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
ok case with self-instantiation
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private Integer x = new Integer(1);
 private Integer getFoo() {
  return x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
Reuse variable name as params in method calls
     ]]></description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
 private Integer x = new Integer(1);
 public Foo(Integer x) {
 }
 private void getFoo(Integer x) {
  this.x = x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
Ok, instantiates own self internally
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private int x;
 int bar(int y) {
  x = y + 5; 
  return x;
 }
 private void bar() {
  Foo foo = new Foo();
  foo.x = new Integer(5);
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
ok, variable accessed twice in same method
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private Map map = new SomeMap();
 private boolean bar(Object o) {
     boolean ret = true;
     if(super.isTrue) {
     if(map.get(o) != null) {
         ret = false; 
     } else {
         map.put(o,o); 
     } 
     } 
     return ret; 
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
failure, static
     ]]></description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
 private int x;
 static {
  x = 5; 
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
failure, second method re-uses class level name
     ]]></description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
 private int x;
 void setX(int x) {
  this.x = x;
 }
 int doX() {
  int x = 5;
  return x*3;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
initialized in static initialization block
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private static Foo FOO = new Foo();
 private int x;
 static {
  FOO.x = 5; 
 }
 int bar(int y) {
  x = y + 5; 
  return x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
1409944, fields used to synchronize should not trigger
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {

    private final Object oSync = new Object();

    public void foo() {
        synchronized (oSync) {
            bar();
        }
    }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
1409944, fields not used to synchronize should trigger
     ]]></description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
    private final Object sync = new Object();
    private final Object noSync;

    public void foo() {
        synchronized (sync) {
            noSync = new String("test");
            call(noSync);
        }
    }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
1409944, field is used to change the flow of different calls
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
    private boolean bar = false;

    public void foo() {
        if (!bar) {
            onlyOnce();
            bar = true;
        }
    }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
Ok, used in outer class
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
    private class Bar {
        private int bar;
        
        private Bar(int barry) {
            bar = barry;
        }    
    }
    
    public int foo() {
        Bar bart = new Bar(5);
        return bart.bar;
    }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
Not ok, since inner classes are checked
     ]]></description>
        <rule-property name="checkInnerClasses">true</rule-property>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
    private class Bar {
        private int bar;
        
        private Bar(int barry) {
            bar = barry;
        }    
    }
    
    public int foo() {
        Bar bart = new Bar(5);
        return bart.bar;
    }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
Not ok, violation with first usage = non-assignment
     ]]></description>
        <rule-property name="disallowNotAssignment">true</rule-property>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
 private int x;
 int bar(int y) {
  x.snafu();
  x = y + 5; 
  return x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
Ok, field used to aggregate values
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private int x;
 int bar(int y) {
  x = x + y;
  return x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
Ok, setting values
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private Person p = new Person();
 public Foo(String name) {
  p.name = name;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
multiple fields on same line
     ]]></description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class Foo {
 private int x, foo;
 int bar(int y) {
  foo = y + 5; 
  return foo;
 }
 void setX(int x) {
  this.x = x;
 }
 int getX() {
  return x;
 }
}
     ]]></code>
    </test-code>
    <test-code>
        <description><![CDATA[
field in inner class
     ]]></description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Foo {
 private final Object bufferFilter = new Object() {
  public String toString() {
   final Object[] candidates;
   candidates = new Object[2];
   return null;
  }
 };
}
     ]]></code>
    </test-code>
    <test-code>
        <description>bug 3574133 - false + with enums</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public enum MyEnum {
    A("a"),
    B("b");

    private final String description; // <-- SingularField reported

    private MyEnum(String description) {
        this.description = description;
    }

    public static MyEnum byDescription(String description) {
        for (MyEnum myEnum : values()) {
            if (myEnum.description.equals(description)) { // <--- USED HERE
            return myEnum;
            }
        }
        return null;
    }
}
]]></code>
    </test-code>
    <test-code>
        <description>#1307 False positive: SingularField and lambda-expression</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package com.foo;

import java.util.Optional;

public enum Supplier {
    bar("Bar");

    private final String supplierName;

    private Supplier(String supplierName) {
        this.supplierName = supplierName;
    }

    public static String getSupplierNameIfPresent(String supplier) {
        return Optional.ofNullable(supplier).map(foo -> valueOf(supplier).supplierName).orElse("");
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1494 [java] SingularField: lombok.Data false positive - part1</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import lombok.Data;

@Data
public class MyClass {

    private String field1;

    public MyClass(String field1) {
        this.field1 = field1;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1494 [java] SingularField: lombok.Data false positive - part2</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import lombok.Getter;

public class MyClass {

    @Getter
    private String field1;

    public MyClass(String field1) {
        this.field1 = field1;
    }
}
        ]]></code>
    </test-code>


    <test-code>
        <description>#177 [java] SingularField with lambdas as final fields</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
/** Dummy class. */
public final class Test {
  private Timer timer1;
  private Timer timer2;

  /** Dummy constructor. */
  public Timer() {
    this.timer1 = new Timer(0, e -> {
      // do nothing for now
    });
    this.timer2 = new Timer(0, e -> {
      // do nothing for now
    });
  }

  /** Use a lambda expression to reference timer1 -- triggers SingularField error. */
  private final Runnable play1 = () -> {
    this.timer1.start();
  };

  /** Use an anonymous class to reference timer2 -- no error. */
  private final Runnable play2 = new Runnable() {
    @Override
    public void run() {
      this.timer2.start();
    }
  };
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#527 [java] Lombok getter annotation on enum is not recognized correctly</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import lombok.Getter;

@Getter
public enum Foo {
    BAR(1);

    private final int number;

    Foo(final int number) {
        this.number = number;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1056 [java] Property ignoredAnnotations does not work for SingularField and ImmutableField</description>
        <rule-property name="ignoredAnnotations">java.lang.Deprecated</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class Source {
    @Deprecated
    private Object o; //violation!

    Object m() {
        o = new Object();
        return o;
    }
}
        ]]></code>
    </test-code>
</test-data>
