/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.symboltable;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTBlock;
import net.sourceforge.pmd.lang.java.ast.ASTCatchStatement;
import net.sourceforge.pmd.lang.java.ast.ASTEqualityExpression;
import net.sourceforge.pmd.lang.java.ast.ASTInitializer;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
import net.sourceforge.pmd.lang.symboltable.NameDeclaration;
import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
import net.sourceforge.pmd.lang.symboltable.Scope;
public class AcceptanceTest extends STBBaseTst {
@Test
public void testClashingSymbols() {
parseCode(TEST1);
}
@Test
public void testInitializer() {
parseCode(TEST_INITIALIZERS);
ASTInitializer a = acu.findDescendantsOfType(ASTInitializer.class).get(0);
assertFalse(a.isStatic());
a = acu.findDescendantsOfType(ASTInitializer.class).get(1);
assertTrue(a.isStatic());
}
@Test
public void testCatchBlocks() {
parseCode(TEST_CATCH_BLOCKS);
ASTCatchStatement c = acu.findDescendantsOfType(ASTCatchStatement.class).get(0);
ASTBlock a = c.findDescendantsOfType(ASTBlock.class).get(0);
Scope s = a.getScope();
Map<NameDeclaration, List<NameOccurrence>> vars = s.getParent().getDeclarations();
assertEquals(1, vars.size());
NameDeclaration v = vars.keySet().iterator().next();
assertEquals("e", v.getImage());
assertEquals(1, (vars.get(v)).size());
}
@Test
public void testEq() {
parseCode(TEST_EQ);
ASTEqualityExpression e = acu.findDescendantsOfType(ASTEqualityExpression.class).get(0);
ASTMethodDeclaration method = e.getFirstParentOfType(ASTMethodDeclaration.class);
Scope s = method.getScope();
Map<NameDeclaration, List<NameOccurrence>> m = s.getDeclarations();
assertEquals(2, m.size());
for (Map.Entry<NameDeclaration, List<NameOccurrence>> entry : m.entrySet()) {
NameDeclaration vnd = entry.getKey();
List<NameOccurrence> usages = entry.getValue();
if (vnd.getImage().equals("a") || vnd.getImage().equals("b")) {
assertEquals(1, usages.size());
assertEquals(3, usages.get(0).getLocation().getBeginLine());
} else {
fail("Unkown variable " + vnd);
}
}
}
@Test
public void testFieldFinder() {
parseCode(TEST_FIELD);
// System.out.println(TEST_FIELD);
ASTVariableDeclaratorId declaration = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(1);
assertEquals(3, declaration.getBeginLine());
assertEquals("bbbbbbbbbb", declaration.getImage());
assertEquals(1, declaration.getUsages().size());
NameOccurrence no = declaration.getUsages().get(0);
Node location = no.getLocation();
assertEquals(6, location.getBeginLine());
// System.out.println("variable " + declaration.getImage() + " is used
// here: " + location.getImage());
}
@Test
public void testDemo() {
parseCode(TEST_DEMO);
// System.out.println(TEST_DEMO);
ASTMethodDeclaration node = acu.findDescendantsOfType(ASTMethodDeclaration.class).get(0);
Scope s = node.getScope();
Map<NameDeclaration, List<NameOccurrence>> m = s.getDeclarations();
for (Iterator<NameDeclaration> i = m.keySet().iterator(); i.hasNext();) {
NameDeclaration d = i.next();
assertEquals("buz", d.getImage());
assertEquals("ArrayList", ((TypedNameDeclaration) d).getTypeImage());
List<NameOccurrence> u = m.get(d);
assertEquals(1, u.size());
NameOccurrence o = u.get(0);
int beginLine = o.getLocation().getBeginLine();
assertEquals(3, beginLine);
// System.out.println("Variable: " + d.getImage());
// System.out.println("Type: " + d.getTypeImage());
// System.out.println("Usages: " + u.size());
// System.out.println("Used in line " + beginLine);
}
}
@Test
public void testEnum() {
parseCode(NameOccurrencesTest.TEST_ENUM);
ASTVariableDeclaratorId vdi = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0);
List<NameOccurrence> usages = vdi.getUsages();
assertEquals(2, usages.size());
assertEquals(5, usages.get(0).getLocation().getBeginLine());
assertEquals(9, usages.get(1).getLocation().getBeginLine());
}
@Test
public void testInnerOuterClass() {
parseCode(TEST_INNER_CLASS);
ASTVariableDeclaratorId vdi = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0);
List<NameOccurrence> usages = vdi.getUsages();
assertEquals(2, usages.size());
assertEquals(5, usages.get(0).getLocation().getBeginLine());
assertEquals(10, usages.get(1).getLocation().getBeginLine());
}
/**
* Unit test for bug #1490
*
* @see <a href="https://sourceforge.net/p/pmd/bugs/1490/">#1490 [java] PMD
* Error while processing - NullPointerException</a>
*/
@Test
public void testNullPointerEnumValueOfOverloaded() {
parseCode("public enum EsmDcVoltageSensor {\n" + " A;\n" + " void bar(int ... args) {\n"
+ " int idx;\n" + " int startIdx;\n"
+ " String name = EsmDcVoltageSensor.valueOf((byte) (idx - startIdx)).getName();\n" + " }\n"
// that's the overloaded method
+ " public EsmDCVoltageSensor valueOf(byte b) {\n"
+ " }\n" + "}\n");
}
private static final String TEST_DEMO = "public class Foo {" + PMD.EOL + " void bar(ArrayList buz) { " + PMD.EOL
+ " buz.add(\"foo\");" + PMD.EOL + " } " + PMD.EOL + "}" + PMD.EOL;
private static final String TEST_EQ = "public class Foo {" + PMD.EOL + " boolean foo(String a, String b) { "
+ PMD.EOL + " return a == b; " + PMD.EOL + " } " + PMD.EOL + "}" + PMD.EOL;
private static final String TEST1 = "import java.io.*;" + PMD.EOL + "public class Foo {" + PMD.EOL
+ " void buz( ) {" + PMD.EOL + " Object o = new Serializable() { int x; };" + PMD.EOL
+ " Object o1 = new Serializable() { int x; };" + PMD.EOL + " }" + PMD.EOL + "}" + PMD.EOL;
private static final String TEST_INITIALIZERS = "public class Foo {" + PMD.EOL + " {} " + PMD.EOL + " static {} "
+ PMD.EOL + "}" + PMD.EOL;
private static final String TEST_CATCH_BLOCKS = "public class Foo {" + PMD.EOL + " void foo() { " + PMD.EOL
+ " try { " + PMD.EOL + " } catch (Exception e) { " + PMD.EOL + " e.printStackTrace(); " + PMD.EOL
+ " } " + PMD.EOL + " } " + PMD.EOL + "}" + PMD.EOL;
private static final String TEST_FIELD = "public class MyClass {" + PMD.EOL + " private int aaaaaaaaaa; " + PMD.EOL
+ " boolean bbbbbbbbbb = MyClass.ASCENDING; " + PMD.EOL + " private int zzzzzzzzzz;" + PMD.EOL
+ " private void doIt() {" + PMD.EOL + " if (bbbbbbbbbb) {" + PMD.EOL + " }" + PMD.EOL + " }" + PMD.EOL
+ "}" + PMD.EOL;
public static final String TEST_INNER_CLASS = "public class Outer {" + PMD.EOL + " private static class Inner {"
+ PMD.EOL + " private int i;" + PMD.EOL + " private Inner(int i) {" + PMD.EOL + " this.i = i;"
+ PMD.EOL + " }" + PMD.EOL + " }" + PMD.EOL + " public int modify(int i) {" + PMD.EOL
+ " Inner in = new Inner(i);" + PMD.EOL + " return in.i;" + PMD.EOL + " }" + PMD.EOL + "}" + PMD.EOL;
public static junit.framework.Test suite() {
return new junit.framework.JUnit4TestAdapter(AcceptanceTest.class);
}
}