diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index b08918fdb4..f83648ab1e 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -71,11 +71,21 @@ system-rules test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileVisitor.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileVisitor.java index d617a19388..66d796d408 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileVisitor.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileVisitor.java @@ -8,6 +8,7 @@ import java.util.Stack; import net.sourceforge.pmd.lang.apex.ast.ASTMethod; import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface; +import net.sourceforge.pmd.lang.apex.ast.ASTUserTrigger; import net.sourceforge.pmd.lang.apex.ast.ApexParserVisitorReducedAdapter; /** @@ -34,6 +35,11 @@ public class ApexMultifileVisitor extends ApexParserVisitorReducedAdapter { return data; } + @Override + public Object visit(ASTUserTrigger node, Object data) { + return data; // ignore + } + @Override public Object visit(ASTMethod node, Object data) { diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTFieldTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTFieldTest.java index f694ac55f1..b7cda1793c 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTFieldTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTFieldTest.java @@ -4,14 +4,12 @@ package net.sourceforge.pmd.lang.apex.ast; -import static net.sourceforge.pmd.lang.apex.ast.ApexParserTestHelpers.parse; - import org.junit.Assert; import org.junit.Test; import apex.jorje.semantic.ast.compilation.Compilation; -public class ASTFieldTest { +public class ASTFieldTest extends ApexParserTestBase { @Test public void testGetType() { diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTMethodTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTMethodTest.java index 402a732c88..d29e8116d1 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTMethodTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTMethodTest.java @@ -4,8 +4,6 @@ package net.sourceforge.pmd.lang.apex.ast; -import static net.sourceforge.pmd.lang.apex.ast.ApexParserTestHelpers.parse; - import java.util.List; import org.junit.Assert; @@ -13,7 +11,7 @@ import org.junit.Test; import apex.jorje.semantic.ast.compilation.Compilation; -public class ASTMethodTest { +public class ASTMethodTest extends ApexParserTestBase { @Test public void testConstructorName() { diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTNewKeyValueObjectExpressionTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTNewKeyValueObjectExpressionTest.java index ec393cc753..82fd256867 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTNewKeyValueObjectExpressionTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTNewKeyValueObjectExpressionTest.java @@ -4,8 +4,6 @@ package net.sourceforge.pmd.lang.apex.ast; -import static net.sourceforge.pmd.lang.apex.ast.ApexParserTestHelpers.parse; - import java.util.List; import org.junit.Assert; @@ -13,7 +11,7 @@ import org.junit.Test; import apex.jorje.semantic.ast.compilation.Compilation; -public class ASTNewKeyValueObjectExpressionTest { +public class ASTNewKeyValueObjectExpressionTest extends ApexParserTestBase { @Test public void testParameterName() { diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTSoqlExpressionTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTSoqlExpressionTest.java index 8709d9a551..aa421fc83e 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTSoqlExpressionTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTSoqlExpressionTest.java @@ -4,14 +4,12 @@ package net.sourceforge.pmd.lang.apex.ast; -import static net.sourceforge.pmd.lang.apex.ast.ApexParserTestHelpers.parse; - import org.junit.Assert; import org.junit.Test; import apex.jorje.semantic.ast.compilation.Compilation; -public class ASTSoqlExpressionTest { +public class ASTSoqlExpressionTest extends ApexParserTestBase { @Test public void testQuery() { diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserClassTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserClassTest.java index 7ab8865df3..4fa039f9ce 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserClassTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserClassTest.java @@ -4,8 +4,6 @@ package net.sourceforge.pmd.lang.apex.ast; -import static net.sourceforge.pmd.lang.apex.ast.ApexParserTestHelpers.parse; - import java.util.Arrays; import org.junit.Assert; @@ -13,7 +11,7 @@ import org.junit.Test; import apex.jorje.semantic.ast.compilation.Compilation; -public class ASTUserClassTest { +public class ASTUserClassTest extends ApexParserTestBase { @Test public void testClassName() { diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserEnumTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserEnumTest.java index 827833e4bd..cf67095019 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserEnumTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserEnumTest.java @@ -4,14 +4,12 @@ package net.sourceforge.pmd.lang.apex.ast; -import static net.sourceforge.pmd.lang.apex.ast.ApexParserTestHelpers.parse; - import org.junit.Assert; import org.junit.Test; import apex.jorje.semantic.ast.compilation.Compilation; -public class ASTUserEnumTest { +public class ASTUserEnumTest extends ApexParserTestBase { @Test public void testEnumName() { diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserInterfaceTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserInterfaceTest.java index e9c1f47ff6..a53124139b 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserInterfaceTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserInterfaceTest.java @@ -4,14 +4,12 @@ package net.sourceforge.pmd.lang.apex.ast; -import static net.sourceforge.pmd.lang.apex.ast.ApexParserTestHelpers.parse; - import org.junit.Assert; import org.junit.Test; import apex.jorje.semantic.ast.compilation.Compilation; -public class ASTUserInterfaceTest { +public class ASTUserInterfaceTest extends ApexParserTestBase { @Test public void testInterfaceName() { diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserTriggerTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserTriggerTest.java index c39d51a87b..728588cd61 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserTriggerTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserTriggerTest.java @@ -4,14 +4,12 @@ package net.sourceforge.pmd.lang.apex.ast; -import static net.sourceforge.pmd.lang.apex.ast.ApexParserTestHelpers.parse; - import java.util.Arrays; import org.junit.Assert; import org.junit.Test; -public class ASTUserTriggerTest { +public class ASTUserTriggerTest extends ApexParserTestBase { @Test public void testTriggerName() { diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCompilerSoqlTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCompilerSoqlTest.java index 6a7c763e9a..32a4914fef 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCompilerSoqlTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCompilerSoqlTest.java @@ -4,27 +4,18 @@ package net.sourceforge.pmd.lang.apex.ast; -import java.io.StringReader; - -import org.junit.Assert; import org.junit.Test; -import net.sourceforge.pmd.lang.apex.ApexParserOptions; - -import apex.jorje.semantic.ast.compilation.Compilation; - -public class ApexCompilerSoqlTest { +public class ApexCompilerSoqlTest extends ApexParserTestBase { private static final String CODE = "public class Foo {\n" - + " public List test1() {\n" - + " return Database.query(\'Select Id from Account LIMIT 100\');\n" - + " }\n" - + "}\n"; + + " public List test1() {\n" + + " return Database.query(\'Select Id from Account LIMIT 100\');\n" + + " }\n" + + "}\n"; @Test public void testSoqlCompilation() { - ApexParser parser = new ApexParser(new ApexParserOptions()); - ApexNode cu = parser.parse(new StringReader(CODE)); - Assert.assertNotNull(cu); + apex.parse(CODE); } } diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTest.java index 6b7e8554e6..05fcb51a57 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTest.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.lang.apex.ast; -import static net.sourceforge.pmd.lang.apex.ast.ApexParserTestHelpers.parse; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -22,14 +21,14 @@ import net.sourceforge.pmd.lang.ast.Node; import apex.jorje.semantic.ast.compilation.Compilation; -public class ApexParserTest { +public class ApexParserTest extends ApexParserTestBase { @Test public void understandsSimpleFile() { // Setup String code = "@isTest\n public class SimpleClass {\n" + " @isTest\n public static void testAnything() {\n" - + " \n" + " }\n" + "}"; + + " \n" + " }\n" + "}"; // Exercise ApexNode rootNode = parse(code); @@ -136,7 +135,7 @@ public class ApexParserTest { /** * See bug #1485 - * + * * @see #1485 [apex] Analysis of some apex classes cause a stackoverflow error */ @Test diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTestBase.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTestBase.java new file mode 100644 index 0000000000..74f8e59c43 --- /dev/null +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTestBase.java @@ -0,0 +1,21 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.ast; + +import apex.jorje.semantic.ast.compilation.Compilation; + +public class ApexParserTestBase { + + protected final ApexParsingHelper apex = ApexParsingHelper.DEFAULT.withResourceContext(getClass()); + + + protected ApexNode parse(String code) { + return (ApexNode) apex.parse(code); + } + + protected ApexNode parseResource(String code) { + return (ApexNode) apex.parseResource(code); + } +} diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTestHelpers.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTestHelpers.java deleted file mode 100644 index 0a993b719a..0000000000 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTestHelpers.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.apex.ast; - -import java.io.Reader; -import java.io.StringReader; - -import net.sourceforge.pmd.lang.apex.ApexParserOptions; - -import apex.jorje.semantic.ast.compilation.Compilation; - -public class ApexParserTestHelpers { - private ApexParserTestHelpers() { } - - public static ApexNode parse(String code) { - ApexParser parser = new ApexParser(new ApexParserOptions()); - Reader reader = new StringReader(code); - return parser.parse(reader); - } - -} diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserXPathTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserXPathTest.java index a7b1f2012d..ddb770c7a6 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserXPathTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserXPathTest.java @@ -4,8 +4,6 @@ package net.sourceforge.pmd.lang.apex.ast; -import static net.sourceforge.pmd.lang.apex.ast.ApexParserTestHelpers.parse; - import java.nio.charset.StandardCharsets; import java.util.List; @@ -17,7 +15,7 @@ import net.sourceforge.pmd.lang.ast.Node; import apex.jorje.semantic.ast.compilation.Compilation; -public class ApexParserXPathTest { +public class ApexParserXPathTest extends ApexParserTestBase { @Test public void testBooleanExpressions() throws Exception { diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParsingHelper.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParsingHelper.java new file mode 100644 index 0000000000..5fb0ea501d --- /dev/null +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParsingHelper.java @@ -0,0 +1,32 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.ast; + +import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.LanguageVersionHandler; +import net.sourceforge.pmd.lang.apex.ApexLanguageModule; +import net.sourceforge.pmd.lang.ast.RootNode; +import net.sourceforge.pmd.lang.ast.test.BaseParsingHelper; + +public class ApexParsingHelper extends BaseParsingHelper { + + public static final ApexParsingHelper DEFAULT = new ApexParsingHelper(Params.getDefaultProcess()); + + + private ApexParsingHelper(Params p) { + super(ApexLanguageModule.NAME, RootNode.class, p); + } + + @Override + protected ApexParsingHelper clone(Params params) { + return new ApexParsingHelper(params); + } + + @Override + protected void postProcessing(LanguageVersionHandler handler, LanguageVersion lversion, RootNode rootNode) { + super.postProcessing(handler, lversion, rootNode); + handler.getMultifileFacade().start(rootNode); + } +} diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexQualifiedNameTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexQualifiedNameTest.java index 4bb620c654..c7171b2d7f 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexQualifiedNameTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexQualifiedNameTest.java @@ -19,11 +19,11 @@ import apex.jorje.semantic.ast.compilation.Compilation; /** * @author Clément Fournier */ -public class ApexQualifiedNameTest { +public class ApexQualifiedNameTest extends ApexParserTestBase { @Test public void testClass() { - ApexNode root = ApexParserTestHelpers.parse("public class Foo {}"); + ApexNode root = parse("public class Foo {}"); ApexQualifiedName qname = ASTUserClass.class.cast(root).getQualifiedName(); assertEquals("c__Foo", qname.toString()); @@ -35,7 +35,7 @@ public class ApexQualifiedNameTest { @Test public void testNestedClass() { - ApexNode root = ApexParserTestHelpers.parse("public class Foo { class Bar {}}"); + ApexNode root = parse("public class Foo { class Bar {}}"); ApexQualifiedName qname = root.getFirstDescendantOfType(ASTUserClass.class).getQualifiedName(); assertEquals("c__Foo.Bar", qname.toString()); @@ -47,7 +47,7 @@ public class ApexQualifiedNameTest { @Test public void testSimpleMethod() { - ApexNode root = ApexParserTestHelpers.parse("public class Foo { String foo() {}}"); + ApexNode root = parse("public class Foo { String foo() {}}"); ApexQualifiedName qname = root.getFirstDescendantOfType(ASTMethod.class).getQualifiedName(); assertEquals("c__Foo#foo()", qname.toString()); assertEquals(1, qname.getClasses().length); @@ -58,7 +58,7 @@ public class ApexQualifiedNameTest { @Test public void testMethodWithArguments() { - ApexNode root = ApexParserTestHelpers.parse("public class Foo { String foo(String h, Foo g) {}}"); + ApexNode root = parse("public class Foo { String foo(String h, Foo g) {}}"); ApexQualifiedName qname = root.getFirstDescendantOfType(ASTMethod.class).getQualifiedName(); assertEquals("c__Foo#foo(String,Foo)", qname.toString()); assertEquals(1, qname.getClasses().length); @@ -69,7 +69,7 @@ public class ApexQualifiedNameTest { @Test public void testOverLoads() { - ApexNode root = ApexParserTestHelpers.parse("public class Foo { " + ApexNode root = parse("public class Foo { " + "String foo(String h) {} " + "String foo(int c) {}" + "String foo(Foo c) {}}"); @@ -88,7 +88,7 @@ public class ApexQualifiedNameTest { @Test public void testTrigger() { - ApexNode root = ApexParserTestHelpers.parse("trigger myAccountTrigger on Account (before insert, before update) {}"); + ApexNode root = parse("trigger myAccountTrigger on Account (before insert, before update) {}"); List methods = root.findDescendantsOfType(ASTMethod.class); diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexProjectMirrorTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexProjectMirrorTest.java index 49d077318b..97832b1e2c 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexProjectMirrorTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexProjectMirrorTest.java @@ -7,27 +7,21 @@ package net.sourceforge.pmd.lang.apex.metrics; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Random; -import org.apache.commons.io.IOUtils; +import org.junit.Before; import org.junit.Test; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.LanguageVersionHandler; -import net.sourceforge.pmd.lang.apex.ApexLanguageModule; import net.sourceforge.pmd.lang.apex.ast.ASTMethod; import net.sourceforge.pmd.lang.apex.ast.ASTUserClass; import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface; import net.sourceforge.pmd.lang.apex.ast.ApexNode; -import net.sourceforge.pmd.lang.apex.ast.ApexParserTestHelpers; +import net.sourceforge.pmd.lang.apex.ast.ApexParserTestBase; import net.sourceforge.pmd.lang.apex.ast.ApexParserVisitorAdapter; import net.sourceforge.pmd.lang.apex.metrics.impl.AbstractApexClassMetric; import net.sourceforge.pmd.lang.apex.metrics.impl.AbstractApexOperationMetric; -import net.sourceforge.pmd.lang.apex.multifile.ApexMultifileVisitorTest; import net.sourceforge.pmd.lang.metrics.MetricKey; import net.sourceforge.pmd.lang.metrics.MetricKeyUtil; import net.sourceforge.pmd.lang.metrics.MetricMemoizer; @@ -38,21 +32,15 @@ import apex.jorje.semantic.ast.compilation.Compilation; /** * @author Clément Fournier */ -public class ApexProjectMirrorTest { +public class ApexProjectMirrorTest extends ApexParserTestBase { private static ApexNode acu; private MetricKey> classMetricKey = MetricKeyUtil.of(null, new RandomClassMetric()); private MetricKey opMetricKey = MetricKeyUtil.of(null, new RandomOperationMetric()); - - static { - try { - acu = parseAndVisitForString( - IOUtils.toString(ApexMultifileVisitorTest.class.getResourceAsStream("MetadataDeployController.cls"), - StandardCharsets.UTF_8)); - } catch (IOException ioe) { - // Should definitely not happen - } + @Before + public void setup() { + acu = parseResource("../multifile/MetadataDeployController.cls"); } @@ -101,7 +89,7 @@ public class ApexProjectMirrorTest { public Object visit(ASTUserClass node, Object data) { MetricMemoizer> clazz = toplevel.getClassMemoizer(node.getQualifiedName()); result.add((int) ApexMetricsComputer.getInstance().computeForType(classMetricKey, node, force, - MetricOptions.emptyOptions(), clazz)); + MetricOptions.emptyOptions(), clazz)); return super.visit(node, data); } }, null); @@ -110,15 +98,7 @@ public class ApexProjectMirrorTest { } - static ApexNode parseAndVisitForString(String source) { - LanguageVersionHandler languageVersionHandler = LanguageRegistry.getLanguage(ApexLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); - ApexNode acu = ApexParserTestHelpers.parse(source); - languageVersionHandler.getSymbolFacade().start(acu); - return acu; - } - - private class RandomOperationMetric extends AbstractApexOperationMetric { + private static class RandomOperationMetric extends AbstractApexOperationMetric { private Random random = new Random(); @@ -129,7 +109,7 @@ public class ApexProjectMirrorTest { } } - private class RandomClassMetric extends AbstractApexClassMetric { + private static class RandomClassMetric extends AbstractApexClassMetric { private Random random = new Random(); diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileVisitorTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileVisitorTest.java index e93eed7c85..bc87f5bb0b 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileVisitorTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileVisitorTest.java @@ -8,18 +8,12 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.IOException; -import java.nio.charset.StandardCharsets; -import org.apache.commons.io.IOUtils; import org.junit.Test; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.LanguageVersionHandler; -import net.sourceforge.pmd.lang.apex.ApexLanguageModule; import net.sourceforge.pmd.lang.apex.ast.ASTMethod; import net.sourceforge.pmd.lang.apex.ast.ApexNode; -import net.sourceforge.pmd.lang.apex.ast.ApexParserTest; -import net.sourceforge.pmd.lang.apex.ast.ApexParserTestHelpers; +import net.sourceforge.pmd.lang.apex.ast.ApexParserTestBase; import net.sourceforge.pmd.lang.apex.ast.ApexParserVisitorAdapter; import net.sourceforge.pmd.lang.apex.metrics.ApexSignatureMatcher; import net.sourceforge.pmd.lang.apex.metrics.signature.ApexOperationSigMask; @@ -29,7 +23,7 @@ import apex.jorje.semantic.ast.compilation.Compilation; /** * @author Clément Fournier */ -public class ApexMultifileVisitorTest extends ApexParserTest { +public class ApexMultifileVisitorTest extends ApexParserTestBase { @Test public void testProjectMirrorNotNull() { @@ -39,9 +33,7 @@ public class ApexMultifileVisitorTest extends ApexParserTest { @Test public void testOperationsAreThere() throws IOException { - ApexNode acu = parseAndVisitForString( - IOUtils.toString(ApexMultifileVisitorTest.class.getResourceAsStream("MetadataDeployController.cls"), - StandardCharsets.UTF_8)); + ApexNode acu = parseResource("MetadataDeployController.cls"); final ApexSignatureMatcher toplevel = ApexProjectMirror.INSTANCE; @@ -61,12 +53,4 @@ public class ApexMultifileVisitorTest extends ApexParserTest { } - static ApexNode parseAndVisitForString(String source) { - LanguageVersionHandler languageVersionHandler = LanguageRegistry.getLanguage(ApexLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); - ApexNode acu = ApexParserTestHelpers.parse(source); - languageVersionHandler.getSymbolFacade().start(acu); - languageVersionHandler.getMultifileFacade().start(acu); - return acu; - } } diff --git a/pmd-core/src/main/ant/alljavacc.xml b/pmd-core/src/main/ant/alljavacc.xml index 1cc67fb2c9..9e13af685f 100644 --- a/pmd-core/src/main/ant/alljavacc.xml +++ b/pmd-core/src/main/ant/alljavacc.xml @@ -9,8 +9,8 @@ - - + + - "Lexical error in file " + net.sourceforge.pmd.lang.ast.impl.javacc.AbstractTokenManager.getFileName() + " at line " + "Lexical error in file " + net.sourceforge.pmd.lang.ast.AbstractTokenManager.getFileName() + " at line " documentMaker) { + return new SimpleCharStream(input); + } + + /** + * A char stream that translates java unicode sequences. + */ + public static CharStream javaCharStream(Reader input) { + return javaCharStream(input, TokenDocument::new); + } + + /** + * A char stream that translates java unicode sequences. + */ + public static CharStream javaCharStream(Reader input, Function documentMaker) { + String source = toString(input); + return new JavaCharStream(source); + } + + /** + * @deprecated This shouldn't be used. IOExceptions should be handled properly, + * ie it should be expected that creating a parse may throw an IOException, + * in both CPD and PMD + */ + @Deprecated + public static String toString(Reader dstream) { + try (Reader r = dstream) { + return IOUtils.toString(r); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/AxisStream.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/AxisStream.java index 7c7cf64293..4942295f68 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/AxisStream.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/AxisStream.java @@ -199,7 +199,7 @@ abstract class AxisStream extends IteratorBasedNStream { @Override protected NodeStream copyWithFilter(Filtermap filterMap) { - return new FilteredDescendantStream<>(node, filterMap); + return new FilteredDescendantOrSelfStream<>(node, filterMap); } @Override diff --git a/pmd-cpp/etc/grammar/cpp.jj b/pmd-cpp/etc/grammar/cpp.jj index ed0145dda2..6367635f4d 100644 --- a/pmd-cpp/etc/grammar/cpp.jj +++ b/pmd-cpp/etc/grammar/cpp.jj @@ -32,7 +32,7 @@ options { PARSER_BEGIN(CppParser) package net.sourceforge.pmd.lang.cpp.ast; -import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; +import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.TokenMgrError; public final class CppParser { diff --git a/pmd-cpp/src/main/ant/alljavacc.xml b/pmd-cpp/src/main/ant/alljavacc.xml index 13a825f14a..d78f708cbb 100644 --- a/pmd-cpp/src/main/ant/alljavacc.xml +++ b/pmd-cpp/src/main/ant/alljavacc.xml @@ -36,7 +36,7 @@ javacchome="${javacc-home.path}" /> + value="class CppParserTokenManager extends net.sourceforge.pmd.lang.ast.AbstractTokenManager" /> diff --git a/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/CppCharStream.java b/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/CppCharStream.java index 8afb53f0d9..97e9540b85 100644 --- a/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/CppCharStream.java +++ b/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/CppCharStream.java @@ -8,7 +8,7 @@ import java.io.IOException; import java.io.Reader; import java.util.regex.Pattern; -import net.sourceforge.pmd.lang.ast.impl.javacc.SimpleCharStream; +import net.sourceforge.pmd.lang.ast.SimpleCharStream; /** * A SimpleCharStream, that supports the continuation of lines via backslash+newline, diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index 9e1c1cbdaa..ecd507949a 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -250,7 +250,7 @@ package net.sourceforge.pmd.lang.java.ast; import java.util.ArrayList; import java.util.List; import java.util.Map; -import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; +import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.GenericToken; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; import net.sourceforge.pmd.lang.ast.TokenMgrError; @@ -394,7 +394,7 @@ TOKEN_MGR_DECLS : SPECIAL_TOKEN : { - // those are private, just for code organisation + // those are private, just for code organisation < #HORIZONTAL_WHITESPACE: [" ", "\t", "\f"] > | < #LINE_TERMINATOR: "\n" | "\r" | "\r\n" > // this one is pushed, notice the (..)+ construct, to avoid @@ -1551,7 +1551,7 @@ ASTCompilationUnit CompilationUnit() : { jjtThis.setComments(token_source.comments); - jjtThis.setTokenDocument(((net.sourceforge.pmd.lang.ast.impl.javacc.JavaCharStream) token_source.input_stream).getTokenDocument()); + jjtThis.setTokenDocument(((net.sourceforge.pmd.lang.ast.JavaCharStream) token_source.input_stream).getTokenDocument()); return jjtThis; } } @@ -3025,15 +3025,15 @@ void AssertStatement() : void RUNSIGNEDSHIFT() #void: {} { - LOOKAHEAD({ JavaTokenFactory.getRealKind(getToken(1)) == RUNSIGNEDSHIFT}) - ">" ">" ">" + LOOKAHEAD({ JavaTokenFactory.getRealKind(getToken(1)) == RUNSIGNEDSHIFT}) + ">" ">" ">" } void RSIGNEDSHIFT() #void: {} { - LOOKAHEAD({ JavaTokenFactory.getRealKind(getToken(1)) == RSIGNEDSHIFT}) - ">" ">" + LOOKAHEAD({ JavaTokenFactory.getRealKind(getToken(1)) == RSIGNEDSHIFT}) + ">" ">" } /* Annotation syntax follows. */ diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 52b960630a..8c1ce621e6 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -88,6 +88,17 @@ + + add-kotlin-test-sources + + add-test-source + + + + ${project.basedir}/src/test/kotlin + + + diff --git a/pmd-java/src/main/ant/alljavacc.xml b/pmd-java/src/main/ant/alljavacc.xml index e16d618d9a..e62ef6c23d 100644 --- a/pmd-java/src/main/ant/alljavacc.xml +++ b/pmd-java/src/main/ant/alljavacc.xml @@ -15,6 +15,10 @@ + + + + - - + + + - - - + - - - - - - - - - - - + + + + + @@ -177,8 +174,8 @@ + token="class JavaParserTokenManager" + value="class JavaParserTokenManager extends net.sourceforge.pmd.lang.ast.AbstractTokenManager" /> @@ -193,8 +190,6 @@ - diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaTokenManager.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaTokenManager.java index ca7297c43a..4371e11903 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaTokenManager.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaTokenManager.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.lang.java; import java.io.Reader; import net.sourceforge.pmd.lang.TokenManager; -import net.sourceforge.pmd.lang.ast.impl.javacc.JavaCharStream; +import net.sourceforge.pmd.lang.ast.impl.javacc.CharStreamFactory; import net.sourceforge.pmd.lang.java.ast.JavaParserTokenManager; /** @@ -17,7 +17,7 @@ public class JavaTokenManager implements TokenManager { private final JavaParserTokenManager tokenManager; public JavaTokenManager(Reader source) { - tokenManager = new JavaParserTokenManager(new JavaCharStream(source)); + tokenManager = new JavaParserTokenManager(CharStreamFactory.javaCharStream(source)); } @Override diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java index 3d90298a70..76de17388b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java @@ -58,6 +58,7 @@ abstract class AbstractJavaNode extends AbstractNode implements JavaNode { } } + @Override public JavaNode jjtGetParent() { return (JavaNode) super.jjtGetParent(); @@ -105,7 +106,6 @@ abstract class AbstractJavaNode extends AbstractNode implements JavaNode { return scope; } - @Override public CharSequence getText() { if (text == null) { @@ -295,7 +295,7 @@ abstract class AbstractJavaNode extends AbstractNode implements JavaNode { } @Override - public String getXPathNodeName() { + public final String getXPathNodeName() { return JavaParserTreeConstants.jjtNodeName[id]; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/Comment.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/Comment.java index c745c9f741..fa66566766 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/Comment.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/Comment.java @@ -14,7 +14,7 @@ import org.apache.commons.lang3.StringUtils; import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.lang.ast.AbstractNode; -import net.sourceforge.pmd.lang.ast.GenericToken; +import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; public abstract class Comment extends AbstractNode { // single regex, that captures: the start of a multi-line comment (/**|/*), the start of a single line comment (//) @@ -24,10 +24,12 @@ public abstract class Comment extends AbstractNode { // Same as "\\R" - but \\R is only available with java8+ static final Pattern NEWLINES_PATTERN = Pattern.compile("\\u000D\\u000A|[\\u000A\\u000B\\u000C\\u000D\\u0085\\u2028\\u2029]"); - protected Comment(GenericToken t) { + protected Comment(JavaccToken t) { super(-1); setImage(t.getImage()); + jjtSetFirstToken(t); + jjtSetLastToken(t); } @Override @@ -35,6 +37,7 @@ public abstract class Comment extends AbstractNode { return getImage(); } + /** * Filters the comment by removing the leading comment marker (like {@code *}) of each line * as well as the start markers ({@code //}, {@code /*} or {@code /**} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/DummyJavaNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/DummyJavaNode.java index d0a27568dd..6eb44ab97b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/DummyJavaNode.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/DummyJavaNode.java @@ -26,16 +26,13 @@ public class DummyJavaNode extends AbstractJavaNode { super(parser, id); } - @Override public Object jjtAccept(JavaParserVisitor visitor, Object data) { - return visitor.visit(this, data); + return data; } - @Override public void jjtAccept(SideEffectingVisitor visitor, T data) { - visitor.visit(this, data); + // do nothing } - } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/FormalComment.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/FormalComment.java index 7faa85c011..8920d25414 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/FormalComment.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/FormalComment.java @@ -9,15 +9,15 @@ import java.util.Collection; import java.util.regex.Matcher; import java.util.regex.Pattern; -import net.sourceforge.pmd.lang.ast.GenericToken; import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; import net.sourceforge.pmd.lang.java.javadoc.JavadocTag; public class FormalComment extends Comment { private static final Pattern JAVADOC_TAG = Pattern.compile("@([A-Za-z0-9]+)"); - public FormalComment(GenericToken t) { + public FormalComment(JavaccToken t) { super(t); findJavadocs(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java index 4c822ac901..1524dcdb48 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java @@ -8,11 +8,12 @@ import java.io.Reader; import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.lang.ParserOptions; -import net.sourceforge.pmd.lang.ast.impl.javacc.AbstractTokenManager; -import net.sourceforge.pmd.lang.ast.impl.javacc.JavaCharStream; +import net.sourceforge.pmd.lang.ast.AbstractTokenManager; +import net.sourceforge.pmd.lang.ast.impl.javacc.CharStreamFactory; import net.sourceforge.pmd.lang.java.ast.internal.LanguageLevelChecker; import net.sourceforge.pmd.lang.java.qname.JavaOperationQualifiedName; import net.sourceforge.pmd.lang.java.qname.JavaTypeQualifiedName; +import net.sourceforge.pmd.lang.java.symbols.table.JSymbolTable; import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition; import net.sourceforge.pmd.lang.symboltable.Scope; @@ -33,6 +34,9 @@ public final class InternalApiBridge { } + public static void setSymbolTable(JavaNode node, JSymbolTable table) { + ((AbstractJavaNode) node).setSymbolTable(table); + } public static void setScope(JavaNode node, Scope scope) { ((AbstractJavaNode) node).setScope(scope); @@ -65,7 +69,7 @@ public final class InternalApiBridge { } public static ASTCompilationUnit parseInternal(String fileName, Reader source, LanguageLevelChecker checker, ParserOptions options) { - JavaParser parser = new JavaParser(new JavaCharStream(source)); + JavaParser parser = new JavaParser(CharStreamFactory.javaCharStream(source)); String suppressMarker = options.getSuppressMarker(); if (suppressMarker != null) { parser.setSuppressMarker(suppressMarker); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserVisitorAdapter.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserVisitorAdapter.java index 8d3c389fc3..adc44e84dd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserVisitorAdapter.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserVisitorAdapter.java @@ -252,6 +252,110 @@ public class JavaParserVisitorAdapter implements JavaParserVisitor { return visit((MethodLikeNode) node, data); } + @Override + public Object visit(ASTAssertStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTBlock node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTBreakStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTContinueStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTDoStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTEmptyStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTExplicitConstructorInvocation node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTExpressionStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTForeachStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTForStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTIfStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTLabeledStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTLocalClassStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTReturnStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTStatementExpressionList node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTSwitchStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTSynchronizedStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTThrowStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTTryStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTWhileStatement node, Object data) { + return visit((ASTStatement) node, data); + } + + @Override + public Object visit(ASTYieldStatement node, Object data) { + return visit((ASTStatement) node, data); + } public Object visit(ASTStatement node, Object data) { return visit((JavaNode) node, data); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaTokenFactory.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaTokenFactory.java index 3b82883821..0947a00739 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaTokenFactory.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaTokenFactory.java @@ -4,9 +4,9 @@ package net.sourceforge.pmd.lang.java.ast; +import net.sourceforge.pmd.lang.ast.CharStream; +import net.sourceforge.pmd.lang.ast.JavaCharStream; import net.sourceforge.pmd.lang.ast.impl.TokenDocument; -import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; -import net.sourceforge.pmd.lang.ast.impl.javacc.JavaCharStream; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; /** diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/MultiLineComment.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/MultiLineComment.java index 9eb08301a6..c8532e9a00 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/MultiLineComment.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/MultiLineComment.java @@ -4,11 +4,11 @@ package net.sourceforge.pmd.lang.java.ast; -import net.sourceforge.pmd.lang.ast.GenericToken; +import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; public class MultiLineComment extends Comment { - public MultiLineComment(GenericToken t) { + public MultiLineComment(JavaccToken t) { super(t); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/SideEffectingVisitorAdapter.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/SideEffectingVisitorAdapter.java index 4498bc3d82..93f1857ee1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/SideEffectingVisitorAdapter.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/SideEffectingVisitorAdapter.java @@ -44,4 +44,21 @@ public class SideEffectingVisitorAdapter implements SideEffectingVisitor { public void visit(ASTAnyTypeDeclaration node, T data) { visit((JavaNode) node, data); } + + @Override + public void visit(ASTClassOrInterfaceDeclaration node, T data) { + visit((ASTAnyTypeDeclaration) node, data); + } + + // public void visit(ASTAnonymousClassDeclaration node, T data) {visit((ASTAnyTypeDeclaration) node, data);} + + @Override + public void visit(ASTEnumDeclaration node, T data) { + visit((ASTAnyTypeDeclaration) node, data); + } + + @Override + public void visit(ASTAnnotationTypeDeclaration node, T data) { + visit((ASTAnyTypeDeclaration) node, data); + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/SingleLineComment.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/SingleLineComment.java index a8f9832682..f02ba836d0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/SingleLineComment.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/SingleLineComment.java @@ -4,11 +4,11 @@ package net.sourceforge.pmd.lang.java.ast; -import net.sourceforge.pmd.lang.ast.GenericToken; +import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; public class SingleLineComment extends Comment { - public SingleLineComment(GenericToken t) { + public SingleLineComment(JavaccToken t) { super(t); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java index 0258fdd3d4..1171b5981b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java @@ -181,7 +181,7 @@ public class LanguageLevelChecker { @Override public void visit(ASTEnumDeclaration node, T data) { check(node, RegularLanguageFeature.ENUMS, data); - visitChildren(node, data); + super.visit(node, data); } @Override @@ -288,6 +288,9 @@ public class LanguageLevelChecker { @Override public void visit(ASTAnyTypeDeclaration node, T data) { + if ("var".equals(node.getSimpleName())) { + check(node, ReservedIdentifiers.VAR_AS_A_TYPE_NAME, data); + } checkIdent(node, node.getSimpleName(), data); visitChildren(node, data); } @@ -299,9 +302,7 @@ public class LanguageLevelChecker { } private void checkIdent(JavaNode node, String simpleName, T acc) { - if ("var".equals(simpleName)) { - check(node, ReservedIdentifiers.VAR_AS_A_TYPE_NAME, acc); - } else if ("enum".equals(simpleName)) { + if ("enum".equals(simpleName)) { check(node, ReservedIdentifiers.ENUM_AS_AN_IDENTIFIER, acc); } else if ("assert".equals(simpleName)) { check(node, ReservedIdentifiers.ASSERT_AS_AN_IDENTIFIER, acc); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaProcessingStage.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaProcessingStage.java index 179e2bd51f..064d75a7b7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaProcessingStage.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaProcessingStage.java @@ -16,6 +16,7 @@ import net.sourceforge.pmd.lang.ast.AstProcessingStage; import net.sourceforge.pmd.lang.ast.RootNode; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.dfa.DataFlowFacade; +import net.sourceforge.pmd.lang.java.multifile.MultifileVisitorFacade; import net.sourceforge.pmd.lang.java.qname.QualifiedNameResolver; import net.sourceforge.pmd.lang.java.symboltable.SymbolFacade; import net.sourceforge.pmd.lang.java.typeresolution.TypeResolutionFacade; @@ -68,8 +69,17 @@ public enum JavaProcessingStage implements AstProcessingStage dependencies; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/PackageStats.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/PackageStats.java index 1799b31a4b..d022409847 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/PackageStats.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/PackageStats.java @@ -32,13 +32,6 @@ final class PackageStats implements ProjectMirror { private final Map classes = new HashMap<>(); - /** - * Default constructor. - */ - private PackageStats() { - } - - /** * Resets the entire data structure. */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSignature.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSignature.java index 45afbc061e..b166b9915a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSignature.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSignature.java @@ -125,11 +125,12 @@ public final class JavaOperationSignature extends JavaSignature extends JElementSymbol { - @Override - @Nullable - N getDeclaration(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JAccessibleElementSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JAccessibleElementSymbol.java new file mode 100644 index 0000000000..ffc49a8293 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JAccessibleElementSymbol.java @@ -0,0 +1,60 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + + +package net.sourceforge.pmd.lang.java.symbols; + +import java.lang.reflect.Modifier; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Represents declarations having access modifiers common to {@link JFieldSymbol}, + * {@link JClassSymbol}, {@link JMethodSymbol}, and {@link JConstructorSymbol}. + * + * @author Clément Fournier + * @since 7.0.0 + */ +public interface JAccessibleElementSymbol extends JElementSymbol { + + /** + * Conventional return value of {@link #getPackageName()} for + * primitive types. + */ + String PRIMITIVE_PACKAGE = "java.lang"; + + + /** + * Returns the modifiers of the element represented by this symbol, + * as decodable by the standard {@link Modifier} API. + */ + int getModifiers(); + + + /** + * Returns the class that directly encloses this declaration. + * This is equivalent to {@link Class#getEnclosingClass()}. + * Returns null if this is a top-level type declaration. + * + *

This is necessarily an already resolved symbol, because + * 1. if it's obtained from reflection, then the enclosing class is available + * 2. if it's obtained from an AST, then the enclosing class is in the same source file so we can + * know about it + */ + @Nullable + JClassSymbol getEnclosingClass(); + + + /** + * Returns the name of the package this element is declared in. This + * recurses into the enclosing elements if needed. If this is an array + * symbol, returns the package name of the element symbol. If this is + * a primitive type, returns {@value #PRIMITIVE_PACKAGE}. + * + *

This is consistent with Java 9's {@code getPackageName()}. + */ + @NonNull + String getPackageName(); +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java new file mode 100644 index 0000000000..0bf6d20ae8 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java @@ -0,0 +1,210 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + + +package net.sourceforge.pmd.lang.java.symbols; + +import java.lang.reflect.Modifier; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.NotImplementedException; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; + + +/** + * Abstraction over a {@link Class} instance. This is not a type, it's + * the *declaration* of a type. For example, a class symbol representing + * a generic class can provide access to the formal type parameters, but + * the symbol does not represent a specific parametrization of a type. + * + *

Class symbols represent the full range of types represented by {@link Class}: + * classes, interfaces, arrays, and primitives. This excludes type variables, + * intersection types, parameterized types, wildcard types, etc., which are only + * compile-time constructs. + * + * @author Clément Fournier + * @since 7.0.0 + */ +public interface JClassSymbol extends JTypeDeclSymbol, + JTypeParameterOwnerSymbol, + BoundToNode { + + /** + * Returns the binary name of this type, as specified by the JLS: + * the JLS. + * For array types this returns the binary name of the component followed by "[]". + */ + @NonNull + String getBinaryName(); + + + + /** + * Returns the simple name of this class, as specified by + * {@link Class#getCanonicalName()}. + */ + @Nullable + String getCanonicalName(); + + + /** + * Returns true if this class is a symbolic reference to an unresolved + * class. In that case no information about the symbol are known except + * its name, and the accessors of this class return default values. + * + *

This kind of symbol is introduced to allow for some best-effort + * symbolic resolution. For example in: + *

{@code
+     * import org.Bar;
+     *
+     * Bar foo = new Bar();
+     * }
+ * and supposing {@code org.Bar} is not on the classpath. The type + * of {@code foo} is {@code Bar}, which we can qualify to {@code org.Bar} thanks to the + * import (via symbol tables, and without even querying the classpath). + * Even though we don't know what members {@code org.Bar} has, a + * test for {@code typeIs("org.Bar")} would succeed with certainty, + * so it makes sense to preserve the name information and not give + * up too early. + * + *

Note that unresolved types are always created from an unresolved + * canonical name, so they can't be just any type. For example, + * they can't be array types, nor local classes (since those are lexically + * scoped, so always resolvable), nor anonymous classes (can only be referenced + * on their declaration site), etc. + */ + boolean isUnresolved(); + + + /** + * Returns the method or constructor this symbol is declared in, if + * it represents a {@linkplain #isLocalClass() local class declaration}. + * + *

Notice, that this returns null also if this class is local to + * a class or instance initializer. + */ + @Nullable + default JExecutableSymbol getEnclosingMethod() { + throw new NotImplementedException("TODO, trickier than it appears"); + } + + + @Override + default JTypeParameterOwnerSymbol getEnclosingTypeParameterOwner() { + JExecutableSymbol enclosingMethod = getEnclosingMethod(); + return enclosingMethod != null ? enclosingMethod : getEnclosingClass(); + } + + + /** + * Returns the member classes declared directly in this class. + * + * @see Class#getDeclaredClasses() + */ + List getDeclaredClasses(); + + + /** + * Returns the methods declared directly in this class. + * This excludes bridges and other synthetic methods. + * + *

For an array type T[], to the difference of {@link Class}, + * this method returns a one-element list with the {@link Cloneable#clone()} + * method, as if declared like so: {@code public final T[] clone() {...}}. + * + * @see Class#getDeclaredMethods() + */ + List getDeclaredMethods(); + + + /** + * Returns the constructors declared by this class. + * This excludes synthetic constructors. + * + *

For an array type T[], and to the difference of {@link Class}, + * this should return a one-element list with a constructor + * having the same modifiers as the array type, and a single + * {@code int} parameter. + * + * @see Class#getDeclaredConstructors() + */ + List getConstructors(); + + + /** + * Returns the fields declared directly in this class. + * This excludes synthetic fields. + * + *

For arrays, and to the difference of {@link Class}, + * this should return a one-element list with the + * {@code public final int length} field. + * + * @see Class#getDeclaredFields() + */ + List getDeclaredFields(); + + + /** Returns a field with the given name accessed defined in this class. */ + @Nullable + default JFieldSymbol getDeclaredField(String name) { + for (JFieldSymbol field : getDeclaredFields()) { + if (field.getSimpleName().equals(name)) { + return field; + } + } + return null; + } + + + /** Returns all methods with the given name declared in this class. */ + default List getDeclaredMethods(String name) { + return getDeclaredMethods().stream().filter(it -> it.getSimpleName().equals(name)).collect(Collectors.toList()); + } + + + /** + * Returns the superclass symbol if it exists. Returns null if this + * class represents an interface or the class {@link Object}. + */ + @Nullable + JClassSymbol getSuperclass(); + + + /** Returns the direct super-interfaces of this class or interface symbol. */ + List getSuperInterfaces(); + + + default boolean isAbstract() { + return Modifier.isAbstract(getModifiers()); + } + + + /** Returns the component symbol, returns null if this is not an array. */ + @Nullable + JTypeDeclSymbol getArrayComponent(); + + + boolean isArray(); + + boolean isPrimitive(); + + boolean isInterface(); + + boolean isEnum(); + + boolean isAnnotation(); + + boolean isLocalClass(); + + boolean isAnonymousClass(); + + default boolean isClass() { + return !isInterface() && !isArray() && !isPrimitive(); + } + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JConstructorSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JConstructorSymbol.java new file mode 100644 index 0000000000..b9d1dcb007 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JConstructorSymbol.java @@ -0,0 +1,28 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + + +package net.sourceforge.pmd.lang.java.symbols; + +import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration; + + +/** + * Represents a constructor declaration. + * + * @author Clément Fournier + * @since 7.0.0 + */ +public interface JConstructorSymbol extends JExecutableSymbol, BoundToNode { + + /** Common dummy name for constructor symbols. */ + String CTOR_NAME = "new"; + + + /** For constructors, this returns the special name {@value CTOR_NAME}. */ + @Override + default String getSimpleName() { + return CTOR_NAME; + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JElementSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JElementSymbol.java new file mode 100644 index 0000000000..f00e2e7462 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JElementSymbol.java @@ -0,0 +1,85 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + + +package net.sourceforge.pmd.lang.java.symbols; + +import net.sourceforge.pmd.annotation.Experimental; +import net.sourceforge.pmd.annotation.InternalApi; +import net.sourceforge.pmd.lang.java.symbols.internal.impl.SymbolFactory; +import net.sourceforge.pmd.lang.symboltable.NameDeclaration; + + +/** + * Represents a named program element that can be referred to by simple name. Abstracts over + * whether the declaration is in the analysed file or not, using reflection when it's not. + * + *

This type hierarchy is probably not directly relevant to users writing + * rules. It's mostly intended to unify the representation of type resolution + * and symbol analysis. + * + *

SymbolDeclarations have no reference to the scope they were found in, because + * that would tie the code reference to the analysed file, preventing the garbage + * collection of scopes and nodes. This is a major difference with {@link NameDeclaration}. + * The declaring scope would also vary from file to file. E.g. + * + *

+ * class Foo {
+ *     public int foo;
+ *     // here the declaring scope of Foo#foo would be the class scope of this file
+ * }
+ *
+ * class Bar extends Foo {
+ *     // here the declaring scope of Foo#foo would be the inherited scope from Foo
+ * }
+ * 
+ * + *

By storing no reference, we ensure that code references can be shared across the + * analysed project, allowing reflective resolution to be only done once. + * + * + * @author Clément Fournier + * @since 7.0.0 + */ +@Experimental +@InternalApi +public interface JElementSymbol { + + + /** + * Gets the name with which this declaration may be referred to, + * eg the name of the method, or the simple name of the class. + * + * @return the name + */ + String getSimpleName(); + + + /** + * Two symbols representing the same program element should be equal. + * So eg two {@link JClassSymbol}, even if their implementation class + * is different, should compare publicly observable properties (their + * binary name is enough). {@link #hashCode()} must of course be consistent + * with this contract. + * + *

Symbols should only be compared using this method, never with {@code ==}, + * because their unicity is not guaranteed (even for the static ones + * declared in {@link SymbolFactory}). + * + * @param o Comparand + * + * @return True if the other is a symbol of the same type and + */ + @Override + boolean equals(Object o); + + // TODO access to annotations could be added to the API if we publish it + + // TODO tests + + // TODO add type information when TypeDefinitions are reviewed + // We should be able to create a type definition from a java.lang.reflect.Type, + // paying attention to type variables of enclosing methods and types. + // We should also be able to do so from an ASTType, with support from a JSymbolTable. +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java new file mode 100644 index 0000000000..0a769cb05b --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java @@ -0,0 +1,55 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.List; + +import org.checkerframework.checker.nullness.qual.NonNull; + +/** + * Common supertype for {@linkplain JMethodSymbol method} + * and {@linkplain JConstructorSymbol constructor symbols}. + * + * @author Clément Fournier + */ +public interface JExecutableSymbol extends JAccessibleElementSymbol, JTypeParameterOwnerSymbol { + + + /** Returns the formal parameters this executable declares. */ + List getFormalParameters(); + + + /** Returns true if the last formal parameter is a varargs parameter. */ + boolean isVarargs(); + + + /** + * Returns the number of formal parameters expected. This must be the + * length of {@link #getFormalParameters()} but if it can be implemented + * without creating the formal parameters, it should. + * + *

A varargs parameter counts as a single parameter. + */ + int getArity(); + + + /** + * Returns the class symbol declaring this method or constructor. + * This is similar to {@link Constructor#getDeclaringClass()}, resp. + * {@link Method#getDeclaringClass()}. Never null. + */ + @Override + @NonNull + JClassSymbol getEnclosingClass(); + + + @Override + @NonNull + default String getPackageName() { + return getEnclosingClass().getPackageName(); + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JFieldSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JFieldSymbol.java new file mode 100644 index 0000000000..d82aee49c7 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JFieldSymbol.java @@ -0,0 +1,41 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + + +package net.sourceforge.pmd.lang.java.symbols; + +import java.lang.reflect.Modifier; + +import org.checkerframework.checker.nullness.qual.NonNull; + +/** + * Represents a field declaration. + * + * @author Clément Fournier + * @since 7.0.0 + */ +public interface JFieldSymbol extends JAccessibleElementSymbol, JValueSymbol { + + + /** Returns true if this field is an enum constant. */ + boolean isEnumConstant(); + + + @Override + default boolean isFinal() { + return Modifier.isFinal(getModifiers()); + } + + + @Override + @NonNull JClassSymbol getEnclosingClass(); + + + @Override + @NonNull + default String getPackageName() { + return getEnclosingClass().getPackageName(); + } + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JFormalParamSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JFormalParamSymbol.java new file mode 100644 index 0000000000..a0e179d22e --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JFormalParamSymbol.java @@ -0,0 +1,19 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + + +package net.sourceforge.pmd.lang.java.symbols; + +/** + * Represents a formal parameter of a {@link JExecutableSymbol}. + * + * @author Clément Fournier + * @since 7.0.0 + */ +public interface JFormalParamSymbol extends JValueSymbol { + + /** Returns the symbol declaring this parameter. */ + JExecutableSymbol getDeclaringSymbol(); + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JLocalVariableSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JLocalVariableSymbol.java similarity index 62% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JLocalVariableSymbol.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JLocalVariableSymbol.java index 580463a8c2..f7e42ceec5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JLocalVariableSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JLocalVariableSymbol.java @@ -1,16 +1,16 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.lang.java.symbols.internal; + +package net.sourceforge.pmd.lang.java.symbols; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; /** - * Represents all use cases of {@link ASTVariableDeclaratorId} except field declarations. - * TODO do we need to split those into their own type of reference? This is e.g. done in INRIA/Spoon, - * but for now doesn't appear to be an interesting tradeoff + * Represents all use cases of {@link ASTVariableDeclaratorId} except field declarations + * and method parameters. * * @author Clément Fournier * @since 7.0.0 diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JMethodSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JMethodSymbol.java new file mode 100644 index 0000000000..4859d09254 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JMethodSymbol.java @@ -0,0 +1,29 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + + +package net.sourceforge.pmd.lang.java.symbols; + +import java.lang.reflect.Modifier; + +import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; + + +/** + * Reference to a method. + * + * @author Clément Fournier + * @since 7.0.0 + */ +public interface JMethodSymbol extends JExecutableSymbol, BoundToNode { + + /** Returns true if this method is a default method of an interface. */ + default boolean isDefault() { + // Default methods are public non-abstract instance methods + // declared in an interface. + return (getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) == Modifier.PUBLIC + && getEnclosingClass().isInterface(); + } + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeDeclSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeDeclSymbol.java new file mode 100644 index 0000000000..aa748ce10f --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeDeclSymbol.java @@ -0,0 +1,46 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + + +package net.sourceforge.pmd.lang.java.symbols; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * A symbol that declares a type. These include + *

    + *
  • {@linkplain JClassSymbol class, interface, array & primitive symbols}
  • + *
  • {@linkplain JTypeParameterSymbol type parameters symbols}
  • + *
+ * + *

Note: type symbols are not types, they declare types. + * + * @author Clément Fournier + * @since 7.0.0 + */ +public interface JTypeDeclSymbol extends JElementSymbol, JAccessibleElementSymbol { + + + /** + * Returns the reflected class this node represents, if it's on the auxclasspath. + * There's no guarantee that this is even exists (this symbol may be notional). + * + *

This is provided to optimize some stuff, but ideally the symbol + * API should reflect everything there is to know about classes, + * and this method shouldn't be used. + */ + @Nullable + Class getJvmRepr(); + + + /** + * Returns the simple name of this class, as specified by + * {@link Class#getSimpleName()}. + */ + @Override + @NonNull + String getSimpleName(); + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterOwnerSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterOwnerSymbol.java new file mode 100644 index 0000000000..d58528ae66 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterOwnerSymbol.java @@ -0,0 +1,36 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + + +package net.sourceforge.pmd.lang.java.symbols; + +import java.util.List; + + +/** + * Represents a declaration that can declare type parameters, + * {@literal i.e.} {@link JClassSymbol} or {@link JMethodSymbol}. + * + * @author Clément Fournier + * @since 7.0.0 + */ +public interface JTypeParameterOwnerSymbol extends JAccessibleElementSymbol { + + List getTypeParameters(); + + + default int getTypeParameterCount() { + return getTypeParameters().size(); + } + + + /** + * Returns the {@link JClassSymbol#getEnclosingMethod() enclosing method} or + * the {@link #getEnclosingClass() enclosing class}, in that order + * of priority. + */ + default JTypeParameterOwnerSymbol getEnclosingTypeParameterOwner() { + return getEnclosingClass(); + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterSymbol.java new file mode 100644 index 0000000000..8cd87c5f9a --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterSymbol.java @@ -0,0 +1,53 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + + +package net.sourceforge.pmd.lang.java.symbols; + +import java.lang.reflect.Modifier; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import net.sourceforge.pmd.lang.java.ast.ASTTypeParameter; + + +/** + * Represents the declaration of a type variable, ie a type parameter. Type variables are reference + * types, but not class or interface types. They're also not declared with the same node. For those + * reasons this type of references is distinct from {@link JClassSymbol}. + * + * @author Clément Fournier + * @since 7.0.0 + */ +public interface JTypeParameterSymbol extends JTypeDeclSymbol, BoundToNode { + + + /** + * Returns the {@link JClassSymbol} or {@link JMethodSymbol} which declared + * this type parameter. + */ + JTypeParameterOwnerSymbol getDeclaringSymbol(); + + + @Override + @NonNull + default String getPackageName() { + return getDeclaringSymbol().getPackageName(); + } + + + @Override + default int getModifiers() { + return getDeclaringSymbol().getModifiers() | Modifier.ABSTRACT | Modifier.FINAL; + } + + + @Override + @Nullable + default JClassSymbol getEnclosingClass() { + JTypeParameterOwnerSymbol ownerSymbol = getDeclaringSymbol(); + return ownerSymbol instanceof JClassSymbol ? (JClassSymbol) ownerSymbol : ownerSymbol.getEnclosingClass(); + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JValueSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JValueSymbol.java new file mode 100644 index 0000000000..2fa94363cd --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JValueSymbol.java @@ -0,0 +1,25 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + + +package net.sourceforge.pmd.lang.java.symbols; + +import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; + + +/** + * Reference to a value, ie {@linkplain JLocalVariableSymbol local variable}, + * {@linkplain JFormalParamSymbol formal parameter}, or {@linkplain JFieldSymbol field}. + * + * @author Clément Fournier + * @since 7.0.0 + */ +public interface JValueSymbol extends BoundToNode { + + /** + * Returns true if this declaration is declared final. + * This takes implicit modifiers into account. + */ + boolean isFinal(); +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/SymbolResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/SymbolResolver.java new file mode 100644 index 0000000000..435f31e2ff --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/SymbolResolver.java @@ -0,0 +1,33 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Resolves symbols from their global name. This abstracts over whether + * we're looking on a classpath, in a file tree, in a serialized index, etc. + * + * @author Clément Fournier + */ +public interface SymbolResolver { + + /** + * Resolves a class symbol from its canonical name. Periods ('.') may + * be interpreted as nested-class separators. + */ + @Nullable + JClassSymbol resolveClassFromCanonicalName(@NonNull String canonicalName); + + + /** + * Loads the class like {@link #resolveClassFromCanonicalName(String)}, + * but if this fails, returns an {@link JClassSymbol#isUnresolved() unresolved symbol}. + */ + @NonNull + JClassSymbol resolveClassOrDefault(@NonNull String canonicalName); + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JAccessibleElementSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JAccessibleElementSymbol.java deleted file mode 100644 index 455a5f3ef7..0000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JAccessibleElementSymbol.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.symbols.internal; - -/** - * Represents declarations having access modifiers common to {@link JFieldSymbol}, - * {@link JClassSymbol}, {@link JMethodSymbol}, and {@link JConstructorSymbol}. - * - * @author Clément Fournier - * @since 7.0.0 - */ -public interface JAccessibleElementSymbol extends JElementSymbol { - - /** - * Returns the class that directly encloses this declaration. - * This is equivalent to {@link Class#getEnclosingClass()}. - * Returns null if this is a top-level type declaration. - * - * This is necessarily an already resolved symbol, because - * 1. if it's obtained from reflection, then the enclosing class is available - * 2. if it's obtained from an AST, then the enclosing class is in the same source file so we can - * know about it - */ - JClassSymbol getEnclosingClass(); - - boolean isPublic(); - - - boolean isPrivate(); - - - boolean isProtected(); - - - boolean isPackagePrivate(); -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbol.java deleted file mode 100644 index 88631f9ede..0000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbol.java +++ /dev/null @@ -1,107 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.symbols.internal; - -import java.util.List; - -import org.checkerframework.checker.nullness.qual.Nullable; - -import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; -import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration.TypeKind; - - -/** - * Represents a class or interface declaration. This is not a type! This corresponds - * closely to a {@link Class} instance. It's the *declaration* of a type. - * - *

Unlike {@link Class} this interface isn't used to represent either - * array types or primitive types. - * - * @author Clément Fournier - * @since 7.0.0 - */ -public interface JClassSymbol extends JSimpleTypeSymbol, - JTypeParameterOwnerSymbol, - BoundToNode { - - /** - * Returns the fully qualified name of this class, as specified by - * {@link Class#getName()}. - */ - String getName(); - - /** - * Returns the simple name of this class, as specified by - * {@link Class#getSimpleName()}. - */ - @Override - String getSimpleName(); - - /** - * Returns the simple name of this class, as specified by - * {@link Class#getCanonicalName()}. - */ - String getCanonicalName(); - - - /** - * Returns the reflected class this node represents, if it's on the auxclasspath. - * Ideally this shouldn't be used, and the symbol API should reflect everything - * there is to know about a class. - */ - @Nullable - Class getClassObject(); - - - List getDeclaredClasses(); - - - List getDeclaredMethods(); - - - List getConstructors(); - - - boolean isStrict(); - - - boolean isAbstract(); - - - default boolean isInterface() { - return getTypeKind() == TypeKind.INTERFACE; - } - - - default boolean isEnum() { - return getTypeKind() == TypeKind.ENUM; - } - - - default boolean isAnnotation() { - return getTypeKind() == TypeKind.ANNOTATION; - } - - - default boolean isClass() { - return getTypeKind() == TypeKind.CLASS; - } - - - - ASTAnyTypeDeclaration.TypeKind getTypeKind(); - - - /** - * Returns true if this declaration is declared final. - */ - boolean isFinal(); - - - /** - * Returns true if this declaration is static. - */ - boolean isStatic(); -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JConstructorSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JConstructorSymbol.java deleted file mode 100644 index 845bc50ff3..0000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JConstructorSymbol.java +++ /dev/null @@ -1,18 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.symbols.internal; - -import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration; - - -/** - * Represents a constructor declaration. - * - * @author Clément Fournier - * @since 7.0.0 - */ -public interface JConstructorSymbol extends JFormalParameterOwnerSymbol, BoundToNode { - -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JElementSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JElementSymbol.java deleted file mode 100644 index 6aeae7bb61..0000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JElementSymbol.java +++ /dev/null @@ -1,104 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.symbols.internal; - -import org.checkerframework.checker.nullness.qual.Nullable; - -import net.sourceforge.pmd.annotation.Experimental; -import net.sourceforge.pmd.annotation.InternalApi; -import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.symboltable.NameDeclaration; - - -/** - * Represents a named program element that can be referred to by simple name. Abstracts over - * whether the declaration is in the analysed file or not, using reflection when it's not. - * - *

This type hierarchy is probably not directly relevant to users writing - * rules. It's mostly intended to unify the representation of type resolution - * and symbol analysis. At least for now it's internal. - * - *

SymbolDeclarations have no reference to the scope they were found in, because - * that would tie the code reference to the analysed file, preventing the garbage - * collection of scopes and nodes. This is a major difference with {@link NameDeclaration}. - * The declaring scope would also vary from file to file. E.g. - * - *

- * class Foo {
- *     public int foo;
- *     // here the declaring scope of Foo#foo would be the class scope of this file
- * }
- *
- * class Bar extends Foo {
- *     // here the declaring scope of Foo#foo would be the inherited scope from Foo
- * }
- * 
- * - *

By storing no reference, we ensure that code references can be shared across the - * analysed project, allowing reflective resolution to be only done once. - * - *

About global caching

- * - *

TODO implement sharing of reflectively found code references across the analysed project - * It would be sufficient to cache JClassSymbols, since from there, all their members would - * be cached too. {@link JLocalVariableSymbol} doesn't need to be cached since you can't refer to - * it from another file. - * - *

That global cache could be used as a basis for multifile analysis, probably whose logic can probably - * be merged with {@link net.sourceforge.pmd.lang.java.multifile.ProjectMirror}. - * - * - *

TODO with global caching, use a (Weak|SoftReference) on the node to avoid memory leaks. - * Also, {@link Lazy} may cause memory leaks by holding strong references to nodes in the lambdas. - * This is no problem for now, because without global caching, symbols referring to the - * same entity are duplicated across analysed classes, and only the symbols created in the - * class where they're defined hold a node. So the symbols are garbage collected with the - * AST anyway. - * - * A global caching will probably be enough to mitigate the cost of creating symbols, - * and we can make those potential memory leaks strict. - * - * In the current state of affairs (no persistent analysis cache, incremental analysis), - * a global cache would *heavily* use reflection. So analysis without auxclasspath will be - * severely limited (like now tbh). There would be no access to classes that are in the - * analysed project which lack compiled classes. - * - * - * @author Clément Fournier - * @since 7.0.0 - */ -@Experimental -@InternalApi -public interface JElementSymbol { - - - /** - * Returns the node declaring this program element, if it is available. - * If the element was declared outside of the analysed sources (considering - * incremental analysis), its AST is not available. - * - * @return the AST node representing the declaration, or null - */ - @Nullable - Node getDeclaration(); - - - /** - * Gets the simple name with which this declaration may be referred to - * when unqualified, eg the simple name of the class, or the name of the method. - * - * @return the simple name - */ - String getSimpleName(); - - // TODO access to annotations could be added to the API if we publish it - - // TODO tests - - // TODO add type information when TypeDefinitions are reviewed - // We should be able to create a type definition from a java.lang.reflect.Type, - // paying attention to type variables of enclosing methods and types. - // We should also be able to do so from an ASTType, with support from a JSymbolTable. -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JFieldSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JFieldSymbol.java deleted file mode 100644 index dcca59a1ba..0000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JFieldSymbol.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.symbols.internal; - -/** - * Represents a field declaration. - * - * @author Clément Fournier - * @since 7.0.0 - */ -public interface JFieldSymbol extends JAccessibleElementSymbol, JValueSymbol { - /** Returns true if this field is volatile. */ - boolean isVolatile(); - - - /** Returns true if this field is transient. */ - boolean isTransient(); - - - /** Returns true if this field is static. */ - boolean isStatic(); -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JFormalParameterOwnerSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JFormalParameterOwnerSymbol.java deleted file mode 100644 index 7dc3f41555..0000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JFormalParameterOwnerSymbol.java +++ /dev/null @@ -1,21 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.symbols.internal; - -import java.util.List; - - -/** - * Represents a declaration that can declare type parameters, - * i.e. {@link JClassSymbol} or {@link JMethodSymbol}. - * - * @author Clément Fournier - * @since 7.0.0 - */ -public interface JFormalParameterOwnerSymbol extends JAccessibleElementSymbol { - - List getFormalParameters(); - -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JMethodSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JMethodSymbol.java deleted file mode 100644 index 14b8ec7f15..0000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JMethodSymbol.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.symbols.internal; - -import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; - - -/** - * Reference to a method. - * - * @author Clément Fournier - * @since 7.0.0 - */ -public interface JMethodSymbol extends JTypeParameterOwnerSymbol, - JFormalParameterOwnerSymbol, - BoundToNode { - - - /** Returns true if this declaration is declared final. */ - boolean isFinal(); - - - boolean isStrict(); - - - boolean isAbstract(); - - - boolean isVarargs(); - - - /** Returns true if this declaration is static. */ - boolean isStatic(); - - - boolean isSynchronized(); - - - boolean isNative(); - - - boolean isDefault(); - -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JResolvableClassSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JResolvableClassSymbol.java deleted file mode 100644 index a217f38e9c..0000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JResolvableClassSymbol.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.symbols.internal; - -import org.checkerframework.checker.nullness.qual.Nullable; - -import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; - - -/** - * Symbolic version of {@link JClassSymbol}, which doesn't load a type - * but provides access to its canonical name. It can try building a full type reference, - * but this may fail. This kind of reference may be used by functions like typeIs() or - * TypeHelper to test the type in the absence of a complete auxclasspath, but cannot - * be used properly by type resolution since it needs access to eg supertypes and members. - * - *

Naturally, anonymous and local classes may not be represented by - * this symbol. - * - * @author Clément Fournier - * @since 7.0.0 - */ -public interface JResolvableClassSymbol extends JSimpleTypeSymbol, BoundToNode { - - - /** - * Returns the qualified name representing this class. This is the - * {@link JClassSymbol#getCanonicalName() canonical name} of the class. - * - * @return a qualified name - */ - String getCanonicalName(); - - - /** - * Attempts to convert this reference into the richer {@link JClassSymbol} - * by loading the class. If the class can't be resolved (incomplete classpath), - * returns null. Also, maybe the class is already loaded. - */ - @Nullable - JClassSymbol loadClass(); -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JSimpleTypeSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JSimpleTypeSymbol.java deleted file mode 100644 index 3218c72406..0000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JSimpleTypeSymbol.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.symbols.internal; - -/** - * A reference type that can be referred to using a simple name. - * These include references to class or interfaces (be they - * {@linkplain JClassSymbol resolved} or only {@link JResolvableClassSymbol symbolic}), - * and references to {@linkplain JTypeParameterSymbol type parameters}, - * but not array types or parameterized types. Primitive types are - * excluded as well because that wouldn't be useful. - * - * This can probably be unified with types symbols (including array types, - * intersection types, wildcard types) in a later stage to make type - * resolution depend only on this abstract representation. - * - * @author Clément Fournier - * @since 7.0.0 - */ -public interface JSimpleTypeSymbol extends JElementSymbol { - - - /** - * Returns true if this is a resolved class reference, in - * which case it can be safely downcast to {@link JClassSymbol}. - */ - default boolean isResolvedClass() { - return this instanceof JClassSymbol; - } - - - /** - * Returns true if this is a class reference, in - * which case it can be safely downcast to {@link JResolvableClassSymbol}. - */ - default boolean isUnresolvedClass() { - return this instanceof JResolvableClassSymbol; - } - - - /** - * Returns true if this is a reference to a type variable, in - * which case it can be safely downcast to {@link JTypeParameterSymbol}. - */ - default boolean isTypeVariable() { - return this instanceof JTypeParameterSymbol; - } -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JTypeParameterOwnerSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JTypeParameterOwnerSymbol.java deleted file mode 100644 index 3b828f9f6a..0000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JTypeParameterOwnerSymbol.java +++ /dev/null @@ -1,21 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.symbols.internal; - -import java.util.List; - - -/** - * Represents a declaration that can declare type parameters, - * i.e. {@link JClassSymbol} or {@link JMethodSymbol}. - * - * @author Clément Fournier - * @since 7.0.0 - */ -public interface JTypeParameterOwnerSymbol extends JAccessibleElementSymbol { - - List getTypeParameters(); - -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JTypeParameterSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JTypeParameterSymbol.java deleted file mode 100644 index 43810f36e6..0000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JTypeParameterSymbol.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.symbols.internal; - -import net.sourceforge.pmd.lang.java.ast.ASTTypeParameter; - - -/** - * Represents the declaration of a type variable, ie a type parameter. Type variables are reference - * types, but not class or interface types. They're also not declared with the same node. For those - * reasons this type of references is distinct from {@link JResolvableClassSymbol}. - * - * @author Clément Fournier - * @since 7.0.0 - */ -public interface JTypeParameterSymbol extends JSimpleTypeSymbol, BoundToNode { - - - /** - * Returns the {@link JClassSymbol} or {@link JMethodSymbol} which declared - * this type parameter. - */ - JTypeParameterOwnerSymbol getDeclaringSymbol(); -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JValueSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JValueSymbol.java deleted file mode 100644 index 1cc0dac43f..0000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/JValueSymbol.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.symbols.internal; - -import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; - - -/** - * Reference to a value, ie {@linkplain JLocalVariableSymbol local variable} or {@linkplain JFieldSymbol field}. - * - * @author Clément Fournier - * @since 7.0.0 - */ -public interface JValueSymbol extends BoundToNode { - - - /** - * Returns true if this is a field reference, in - * which case it can be safely downcast to {@link JFieldSymbol}. - */ - default boolean isField() { - return this instanceof JFieldSymbol; - } - - - /** - * Returns true if this is a reference to a local variable, in - * which case it can be safely downcast to {@link JLocalVariableSymbol}. - */ - default boolean isLocalVar() { - return !isField(); - } - - - /** Returns true if this declaration is declared final. */ - boolean isFinal(); -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/ArraySymbolImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/ArraySymbolImpl.java new file mode 100644 index 0000000000..aa1fe51d1e --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/ArraySymbolImpl.java @@ -0,0 +1,386 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl; + +import java.lang.reflect.Array; +import java.lang.reflect.Modifier; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; +import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; +import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; +import net.sourceforge.pmd.lang.java.symbols.JFieldSymbol; +import net.sourceforge.pmd.lang.java.symbols.JFormalParamSymbol; +import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol; +import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol; +import net.sourceforge.pmd.lang.java.symbols.JTypeParameterSymbol; + +/** + * Generic implementation for array symbols, which does not rely on + * reflection. + */ +class ArraySymbolImpl implements JClassSymbol { + + private final JTypeDeclSymbol component; + + ArraySymbolImpl(@SuppressWarnings("PMD.UnusedFormalParameter") SymbolFactory factory, JTypeDeclSymbol component) { + this.component = Objects.requireNonNull(component, "Array symbol requires component"); + if (component instanceof JClassSymbol && ((JClassSymbol) component).isAnonymousClass()) { + throw new IllegalArgumentException("Anonymous classes cannot be array components: " + component); + } + } + + @Override + public @NonNull String getBinaryName() { + if (component instanceof JClassSymbol) { + return ((JClassSymbol) component).getBinaryName() + "[]"; + } + return component.getSimpleName() + "[]"; + } + + @Override + public String getCanonicalName() { + if (component instanceof JClassSymbol) { + String compName = ((JClassSymbol) component).getCanonicalName(); + return compName == null ? null : compName + "[]"; + } + return component.getSimpleName() + "[]"; + } + + @Override + public boolean isUnresolved() { + return false; + } + + @Override + public @Nullable Class getJvmRepr() { + JTypeDeclSymbol elt = this.getArrayComponent(); + int depth = 0; + while (elt instanceof JClassSymbol && ((JClassSymbol) elt).isArray()) { + elt = ((JClassSymbol) elt).getArrayComponent(); + depth++; + } + + Class eltType = elt.getJvmRepr(); + if (eltType == null) { + return null; + } + + return Array.newInstance(eltType, (int[]) Array.newInstance(int.class, depth)).getClass(); + } + + @Override + public @Nullable JExecutableSymbol getEnclosingMethod() { + return null; + } + + @Override + public List getDeclaredMethods() { + return Collections.singletonList(new ArrayCloneMethod(this)); + } + + @Override + public List getDeclaredFields() { + return Collections.singletonList(new ArrayLengthField(this)); + } + + @Override + public @Nullable JClassSymbol getSuperclass() { + return SymbolFactory.OBJECT_SYM; + } + + @Override + public List getSuperInterfaces() { + return SymbolFactory.ARRAY_SUPER_INTERFACES; + } + + @Override + public @NonNull JTypeDeclSymbol getArrayComponent() { + return component; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ArraySymbolImpl that = (ArraySymbolImpl) o; + return Objects.equals(component, that.component); + } + + @Override + public int hashCode() { + return Objects.hash(component); + } + + @Override + public List getDeclaredClasses() { + return Collections.emptyList(); + } + + @Override + public List getConstructors() { + return Collections.singletonList(new ArrayConstructor(this)); + } + + @Override + @NonNull + public String getPackageName() { + return getArrayComponent().getPackageName(); + } + + @Override + @NonNull + public String getSimpleName() { + return getArrayComponent().getSimpleName() + "[]"; + } + + @Override + public int getModifiers() { + int comp = getArrayComponent().getModifiers(); + return Modifier.FINAL | Modifier.ABSTRACT | (comp & ~Modifier.STATIC); + } + + @Override + public List getTypeParameters() { + return Collections.emptyList(); + } + + @Override + @Nullable + public JClassSymbol getEnclosingClass() { + return null; + } + + @Override + public boolean isArray() { + return true; + } + + @Override + public boolean isAnnotation() { + return false; + } + + @Override + public boolean isPrimitive() { + return false; + } + + @Override + public boolean isInterface() { + return false; + } + + @Override + public boolean isEnum() { + return false; + } + + @Override + public boolean isLocalClass() { + return false; + } + + @Override + public boolean isAnonymousClass() { + return false; + } + + @Override + public String toString() { + return "array(" + component.toString() + ")"; + } + + private static class ArrayLengthField implements JFieldSymbol { + + private final JClassSymbol arraySymbol; + + ArrayLengthField(JClassSymbol arraySymbol) { + this.arraySymbol = arraySymbol; + } + + @Override + public String getSimpleName() { + return "length"; + } + + @Override + public int getModifiers() { + return Modifier.PUBLIC | Modifier.FINAL; + } + + @Override + public boolean isEnumConstant() { + return false; + } + + @Override + public @NonNull JClassSymbol getEnclosingClass() { + return arraySymbol; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ArrayLengthField that = (ArrayLengthField) o; + return arraySymbol.equals(that.arraySymbol); + } + + @Override + public int hashCode() { + return Objects.hash(arraySymbol); + } + } + + private static class ArrayCloneMethod implements JMethodSymbol { + + private final ArraySymbolImpl arraySymbol; + + ArrayCloneMethod(ArraySymbolImpl arraySymbol) { + this.arraySymbol = arraySymbol; + } + + @Override + public String getSimpleName() { + return "clone"; + } + + @Override + public List getFormalParameters() { + return Collections.emptyList(); + } + + @Override + public boolean isVarargs() { + return false; + } + + @Override + public int getArity() { + return 0; + } + + @Override + public int getModifiers() { + return Modifier.PUBLIC; + } + + @Override + public @NonNull JClassSymbol getEnclosingClass() { + return arraySymbol; + } + + @Override + public List getTypeParameters() { + return Collections.emptyList(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ArrayCloneMethod that = (ArrayCloneMethod) o; + return Objects.equals(arraySymbol, that.arraySymbol); + } + + @Override + public int hashCode() { + return Objects.hash(arraySymbol); + } + } + + private static class ArrayConstructor implements JConstructorSymbol { + + private final ArraySymbolImpl arraySymbol; + + ArrayConstructor(ArraySymbolImpl arraySymbol) { + this.arraySymbol = arraySymbol; + } + + @Override + public List getFormalParameters() { + return Collections.singletonList(new JFormalParamSymbol() { + + @Override + public JExecutableSymbol getDeclaringSymbol() { + return ArrayConstructor.this; + } + + @Override + public String getSimpleName() { + return "arg0"; + } + + @Override + public boolean isFinal() { + return false; + } + + // TODO equals/hashcode? + }); + } + + @Override + public boolean isVarargs() { + return false; + } + + @Override + public int getArity() { + return 1; + } + + @Override + public int getModifiers() { + return Modifier.PUBLIC | Modifier.FINAL; + } + + @Override + public @NonNull JClassSymbol getEnclosingClass() { + return arraySymbol; + } + + @Override + public List getTypeParameters() { + return Collections.emptyList(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ArrayConstructor that = (ArrayConstructor) o; + return Objects.equals(arraySymbol, that.arraySymbol); + } + + @Override + public int hashCode() { + return Objects.hash(arraySymbol); + } + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/SymbolEquality.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/SymbolEquality.java new file mode 100644 index 0000000000..5def8a0679 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/SymbolEquality.java @@ -0,0 +1,175 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl; + +import java.util.Objects; + +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; +import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; +import net.sourceforge.pmd.lang.java.symbols.JElementSymbol; +import net.sourceforge.pmd.lang.java.symbols.JFieldSymbol; +import net.sourceforge.pmd.lang.java.symbols.JFormalParamSymbol; +import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol; +import net.sourceforge.pmd.lang.java.symbols.JTypeParameterSymbol; + +/** + * Routines to share logic for equality, respecting the contract of + * {@link JElementSymbol#equals(Object)}. + * + *

Despite this two equal symbols may not hold the same amount of + * information... Reflection symbols are nice, but they also add some + * synthetic stuff (eg implicit formal parameters, bridge methods), + * which we must either filter-out or replicate in AST symbols. This is TODO + */ +@SuppressWarnings("PMD.CompareObjectsWithEquals") +public final class SymbolEquality { + + private SymbolEquality() { + // util class + } + + public static final EqAndHash TYPE_PARAM = new EqAndHash() { + @Override + public int hash(JTypeParameterSymbol t1) { + return Objects.hash(t1.getDeclaringSymbol(), t1.getSimpleName()); + } + + @Override + public boolean equals(JTypeParameterSymbol m1, Object o) { + if (m1 == o) { + return true; + } + if (!(o instanceof JTypeParameterSymbol)) { + return false; + } + JTypeParameterSymbol m2 = (JTypeParameterSymbol) o; + + // FIXME arity check is not enough for overloads + return m1.getSimpleName().equals(m2.getSimpleName()) + && m1.getDeclaringSymbol().equals(m2.getDeclaringSymbol()); + } + }; + + public static final EqAndHash METHOD = new EqAndHash() { + @Override + public int hash(JMethodSymbol t1) { + return 0; + } + + @Override + public boolean equals(JMethodSymbol m1, Object o) { + if (m1 == o) { + return true; + } + if (!(o instanceof JMethodSymbol)) { + return false; + } + JMethodSymbol m2 = (JMethodSymbol) o; + + // FIXME arity check is not enough for overloads + return m1.getModifiers() == m2.getModifiers() + && m1.getArity() == m2.getArity() + && Objects.equals(m1.getSimpleName(), m2.getSimpleName()) + && m1.getEnclosingClass().equals(m2.getEnclosingClass()); + } + }; + + public static final EqAndHash CONSTRUCTOR = new EqAndHash() { + @Override + public int hash(JConstructorSymbol t1) { + return 0; + } + + @Override + public boolean equals(JConstructorSymbol m1, Object o) { + if (m1 == o) { + return true; + } + if (!(o instanceof JConstructorSymbol)) { + return false; + } + JConstructorSymbol m2 = (JConstructorSymbol) o; + + // FIXME arity check is not enough for overloads + return m1.getModifiers() == m2.getModifiers() + && m1.getArity() == m2.getArity() + && Objects.equals(m1.getSimpleName(), m2.getSimpleName()) + && m1.getEnclosingClass().equals(m2.getEnclosingClass()); + } + }; + + + public static final EqAndHash CLASS = new EqAndHash() { + @Override + public int hash(JClassSymbol t1) { + return t1.getBinaryName().hashCode(); + } + + @Override + public boolean equals(JClassSymbol m1, Object o) { + if (m1 == o) { + return true; + } + if (!(o instanceof JClassSymbol)) { + return false; + } + JClassSymbol m2 = (JClassSymbol) o; + + return m1.getBinaryName().equals(m2.getBinaryName()); + } + }; + + public static final EqAndHash FIELD = new EqAndHash() { + @Override + public int hash(JFieldSymbol t1) { + return Objects.hash(t1.getEnclosingClass(), t1.getSimpleName()); + } + + @Override + public boolean equals(JFieldSymbol f1, Object o) { + if (!(o instanceof JFieldSymbol)) { + return false; + } + JFieldSymbol f2 = (JFieldSymbol) o; + return f1.getSimpleName().equals(f2.getSimpleName()) + && f1.getEnclosingClass().equals(f2.getEnclosingClass()); + + } + }; + + public static final EqAndHash FORMAL_PARAM = new EqAndHash() { + @Override + public int hash(JFormalParamSymbol t1) { + return Objects.hash(t1.getDeclaringSymbol(), t1.getSimpleName()); + } + + @Override + public boolean equals(JFormalParamSymbol f1, Object o) { + if (!(o instanceof JFormalParamSymbol)) { + return false; + } + JFormalParamSymbol f2 = (JFormalParamSymbol) o; + return f1.getSimpleName().equals(f2.getSimpleName()) + && f1.getDeclaringSymbol().equals(f2.getDeclaringSymbol()); + + } + }; + + /** + * Strategy to perform equals/hashcode for a type T. There are libraries + * for that, whatever. + */ + public abstract static class EqAndHash { + + public abstract int hash(T t1); + + + public abstract boolean equals(T t1, Object t2); + + + } + + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/SymbolFactory.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/SymbolFactory.java new file mode 100644 index 0000000000..d7d4bec210 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/SymbolFactory.java @@ -0,0 +1,111 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl; + + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; +import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol; +import net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect.ReflectSymInternals; + +/** + * Builds symbols. + * + *

This may be improved later to eg cache and reuse the most recently + * accessed symbols (there may be a lot of cache hits in a typical java file). + * + * @param Type of stuff this factory can convert to symbols. We'll + * implement it for {@link Class} and {@link ASTAnyTypeDeclaration}. + */ +public interface SymbolFactory { + + + // object + JClassSymbol OBJECT_SYM = ReflectSymInternals.createSharedSym(Object.class); + // unresolved symbol + JClassSymbol UNRESOLVED_CLASS_SYM = new UnresolvedClassImpl("/*unresolved*/"); + + // primitives + JClassSymbol BOOLEAN_SYM = ReflectSymInternals.createSharedSym(boolean.class); + JClassSymbol BYTE_SYM = ReflectSymInternals.createSharedSym(byte.class); + JClassSymbol CHAR_SYM = ReflectSymInternals.createSharedSym(char.class); + JClassSymbol DOUBLE_SYM = ReflectSymInternals.createSharedSym(double.class); + JClassSymbol FLOAT_SYM = ReflectSymInternals.createSharedSym(float.class); + JClassSymbol INT_SYM = ReflectSymInternals.createSharedSym(int.class); + JClassSymbol LONG_SYM = ReflectSymInternals.createSharedSym(long.class); + JClassSymbol SHORT_SYM = ReflectSymInternals.createSharedSym(short.class); + JClassSymbol VOID_SYM = ReflectSymInternals.createSharedSym(void.class); + + // primitive wrappers + JClassSymbol BOXED_BOOLEAN_SYM = ReflectSymInternals.createSharedSym(Boolean.class); + JClassSymbol BOXED_BYTE_SYM = ReflectSymInternals.createSharedSym(Byte.class); + JClassSymbol BOXED_CHAR_SYM = ReflectSymInternals.createSharedSym(Character.class); + JClassSymbol BOXED_DOUBLE_SYM = ReflectSymInternals.createSharedSym(Double.class); + JClassSymbol BOXED_FLOAT_SYM = ReflectSymInternals.createSharedSym(Float.class); + JClassSymbol BOXED_INT_SYM = ReflectSymInternals.createSharedSym(Integer.class); + JClassSymbol BOXED_LONG_SYM = ReflectSymInternals.createSharedSym(Long.class); + JClassSymbol BOXED_SHORT_SYM = ReflectSymInternals.createSharedSym(Short.class); + JClassSymbol BOXED_VOID_SYM = ReflectSymInternals.createSharedSym(Void.class); + + // array supertypes + JClassSymbol CLONEABLE_SYM = ReflectSymInternals.createSharedSym(Cloneable.class); + JClassSymbol SERIALIZABLE_SYM = ReflectSymInternals.createSharedSym(Serializable.class); + List ARRAY_SUPER_INTERFACES = Collections.unmodifiableList(Arrays.asList(CLONEABLE_SYM, SERIALIZABLE_SYM)); + + // other important/common types + JClassSymbol CLASS_SYM = ReflectSymInternals.createSharedSym(Class.class); + JClassSymbol ITERABLE_SYM = ReflectSymInternals.createSharedSym(Iterable.class); + JClassSymbol ENUM_SYM = ReflectSymInternals.createSharedSym(Enum.class); + JClassSymbol STRING_SYM = ReflectSymInternals.createSharedSym(String.class); + + + /** + * Produces an unresolved class symbol from the given canonical name. + * + * @param canonicalName Canonical name of the returned symbol + * + * @throws NullPointerException If the name is null + * @throws IllegalArgumentException If the name is empty + */ + @NonNull + default JClassSymbol makeUnresolvedReference(String canonicalName) { + return new UnresolvedClassImpl(canonicalName); + } + + + /** + * Produces an array symbol from the given component symbol (one dimension). + * The component can naturally be another array symbol, but cannot be an + * anonymous class. + * + * @param component Component symbol of the array + * + * @throws NullPointerException If the component is null + * @throws IllegalArgumentException If the component is the symbol for an anonymous class + */ + @NonNull + default JClassSymbol makeArraySymbol(JTypeDeclSymbol component) { + return new ArraySymbolImpl(this, component); + } + + + /** + * Returns the symbol representing the given class. Returns null if + * the given class is itself null. + * + * @param klass Object representing a class + */ + JClassSymbol getClassSymbol(@Nullable T klass); + + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/UnresolvedClassImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/UnresolvedClassImpl.java new file mode 100644 index 0000000000..3d30d78996 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/UnresolvedClassImpl.java @@ -0,0 +1,202 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl; + +import java.lang.reflect.Modifier; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; +import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; +import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; +import net.sourceforge.pmd.lang.java.symbols.JFieldSymbol; +import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol; +import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol; +import net.sourceforge.pmd.lang.java.symbols.JTypeParameterSymbol; + +/** + * Unresolved external reference to a class. + * + * @see JClassSymbol#isUnresolved() + */ +class UnresolvedClassImpl implements JClassSymbol { + + private final @Nullable JClassSymbol enclosing; + private final String canonicalName; + + UnresolvedClassImpl(String canonicalName) { + this(null, canonicalName); + } + + UnresolvedClassImpl(@Nullable JClassSymbol enclosing, String canonicalName) { + this.enclosing = enclosing; + this.canonicalName = canonicalName; + } + + @Override + public boolean isUnresolved() { + return true; + } + + + @Override + public @Nullable JExecutableSymbol getEnclosingMethod() { + return null; + } + + @Override + public boolean isPrimitive() { + return false; + } + + @Override + public @NonNull String getBinaryName() { + return canonicalName; + } + + @NonNull + @Override + public String getSimpleName() { + int idx = canonicalName.lastIndexOf('.'); + if (idx < 0) { + return canonicalName; + } else { + return canonicalName.substring(idx + 1); + } + } + + @Override + public String getCanonicalName() { + return canonicalName; + } + + @Override + public @NonNull String getPackageName() { + int idx = canonicalName.lastIndexOf('.'); + if (idx < 0) { + return canonicalName; + } else { + return canonicalName.substring(0, idx); + } + } + + @Override + public @Nullable Class getJvmRepr() { + return null; + } + + + @Nullable + @Override + public JClassSymbol getSuperclass() { + return SymbolFactory.OBJECT_SYM; + } + + + @Override + public List getSuperInterfaces() { + return Collections.emptyList(); + } + + @Override + public List getDeclaredClasses() { + return Collections.emptyList(); + } + + @Override + public boolean isInterface() { + return false; + } + + @Override + public boolean isEnum() { + return false; + } + + @Override + public boolean isAnnotation() { + return false; + } + + @Override + public boolean isAnonymousClass() { + return false; + } + + @Override + public boolean isLocalClass() { + return false; + } + + @Override + public boolean isArray() { + return false; + } + + @Override + public JClassSymbol getEnclosingClass() { + return enclosing; + } + + @Override + public int getModifiers() { + return Modifier.PUBLIC; + } + + + @Nullable + @Override + public JTypeDeclSymbol getArrayComponent() { + return null; + } + + @Override + public List getDeclaredMethods() { + return Collections.emptyList(); + } + + @Override + public List getConstructors() { + return Collections.emptyList(); + } + + @Override + public List getDeclaredFields() { + return Collections.emptyList(); + } + + @Override + public String toString() { + return "unresolved(" + canonicalName + ")"; + } + + @Override + public List getTypeParameters() { + return Collections.emptyList(); + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof JClassSymbol)) { + return false; + } + JClassSymbol that = (JClassSymbol) o; + return Objects.equals(getBinaryName(), that.getBinaryName()); + } + + @Override + public int hashCode() { + return Objects.hash(this.getSimpleName()); + } + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/AbstractReflectedExecutableSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/AbstractReflectedExecutableSymbol.java new file mode 100644 index 0000000000..e52fb10483 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/AbstractReflectedExecutableSymbol.java @@ -0,0 +1,61 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect; + +import java.lang.reflect.Executable; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; +import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; +import net.sourceforge.pmd.lang.java.symbols.JFormalParamSymbol; + +abstract class AbstractReflectedExecutableSymbol extends AbstractTypeParamOwnerSymbol implements JExecutableSymbol { + + private final @NonNull ReflectedClassImpl owner; + private List params; + + + AbstractReflectedExecutableSymbol(@NonNull ReflectedClassImpl owner, T executable) { + super(owner.symFactory, executable); + this.owner = owner; + } + + + @NonNull + @Override + public final JClassSymbol getEnclosingClass() { + return owner; + } + + @Override + public boolean isVarargs() { + return reflected.isVarArgs(); + } + + @Override + public int getArity() { + return reflected.getParameterCount(); + } + + @Override + public int getModifiers() { + return reflected.getModifiers(); + } + + @Override + public final List getFormalParameters() { + if (params == null) { + this.params = Arrays.stream(reflected.getParameters()) + .map(p -> new ReflectedMethodParamImpl(this, p)) + .collect(Collectors.toList()); + } + + return params; + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/AbstractReflectedSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/AbstractReflectedSymbol.java new file mode 100644 index 0000000000..453c26e566 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/AbstractReflectedSymbol.java @@ -0,0 +1,20 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect; + +import net.sourceforge.pmd.lang.java.symbols.JElementSymbol; + +/** + * @author Clément Fournier + */ +abstract class AbstractReflectedSymbol implements JElementSymbol { + + protected final ReflectionSymFactory symFactory; + + AbstractReflectedSymbol(ReflectionSymFactory symFactory) { + this.symFactory = symFactory; + } + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/AbstractTypeParamOwnerSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/AbstractTypeParamOwnerSymbol.java new file mode 100644 index 0000000000..488a6846bb --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/AbstractTypeParamOwnerSymbol.java @@ -0,0 +1,59 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect; + +import static java.util.stream.Collectors.toList; + +import java.lang.reflect.GenericDeclaration; +import java.lang.reflect.TypeVariable; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.pmd.lang.java.symbols.JTypeParameterOwnerSymbol; +import net.sourceforge.pmd.lang.java.symbols.JTypeParameterSymbol; + +abstract class AbstractTypeParamOwnerSymbol extends AbstractReflectedSymbol implements JTypeParameterOwnerSymbol { + + protected final T reflected; + + private List typeParams; + + + AbstractTypeParamOwnerSymbol(ReflectionSymFactory factory, T tparamOwner) { + super(factory); + this.reflected = tparamOwner; + } + + + @Override + public final List getTypeParameters() { + if (typeParams == null) { + buildTypeParams(reflected.getTypeParameters()); + } + + return typeParams; + } + + private void buildTypeParams(TypeVariable[] tparams) { + + List result = + tparams.length == 0 + ? Collections.emptyList() + : Arrays.stream(tparams) + .map(tvar -> new ReflectedTypeParamImpl(symFactory, this, tvar)) + .collect(toList()); + + // this needs to be set before calling computeBounds + this.typeParams = Collections.unmodifiableList(result); + + } + + @Override + public int getTypeParameterCount() { + return typeParams != null ? typeParams.size() : reflected.getTypeParameters().length; + } + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ClasspathSymbolResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ClasspathSymbolResolver.java new file mode 100644 index 0000000000..56a6ca001b --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ClasspathSymbolResolver.java @@ -0,0 +1,57 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect; + + +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; +import net.sourceforge.pmd.lang.java.symbols.SymbolResolver; + +/** + * Resolves symbols by asking a classloader. + */ +public class ClasspathSymbolResolver implements SymbolResolver { + + private final ClassLoader classLoader; + private final ReflectionSymFactory factory; + + public ClasspathSymbolResolver(ClassLoader classLoader, ReflectionSymFactory factory) { + this.classLoader = classLoader; + this.factory = factory; + } + + + @Override + public JClassSymbol resolveClassFromCanonicalName(@NonNull String canonicalName) { + try { + return factory.getClassSymbol(classLoader.loadClass(canonicalName)); + } catch (ClassNotFoundException e) { + int lastDotIdx = canonicalName.lastIndexOf('.'); + if (lastDotIdx < 0) { + return null; + } else { + JClassSymbol outer = resolveClassFromCanonicalName(canonicalName.substring(0, lastDotIdx)); + if (outer != null) { + String innerName = canonicalName.substring(lastDotIdx + 1); + for (JClassSymbol inner : outer.getDeclaredClasses()) { + if (inner.getSimpleName().equals(innerName)) { + return inner; + } + } + } + } + } + + return null; + } + + @NonNull + @Override + public JClassSymbol resolveClassOrDefault(@NonNull String canonicalName) { + JClassSymbol symbol = resolveClassFromCanonicalName(canonicalName); + return symbol != null ? symbol : factory.makeUnresolvedReference(canonicalName); + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectSymInternals.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectSymInternals.java new file mode 100644 index 0000000000..d619f62619 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectSymInternals.java @@ -0,0 +1,29 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect; + +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; +import net.sourceforge.pmd.lang.java.symbols.internal.impl.SymbolFactory; + +/** + * Bridge into the internal API of this package. + */ +public final class ReflectSymInternals { + + private static final ReflectionSymFactory STATIC_FACTORY = new ReflectionSymFactory(); + + private ReflectSymInternals() { + // util class + } + + /** + * {@link SymbolFactory} cannot use {@link ReflectionSymFactory} + * directly, because of class init cycle. + */ + public static JClassSymbol createSharedSym(Class klass) { + return ReflectedClassImpl.createOuterClass(STATIC_FACTORY, klass); + } + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedClassImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedClassImpl.java new file mode 100644 index 0000000000..1a4a8c1a28 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedClassImpl.java @@ -0,0 +1,234 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect; + +import static java.util.stream.Collectors.toList; + +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang3.ClassUtils; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; +import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; +import net.sourceforge.pmd.lang.java.symbols.JFieldSymbol; +import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol; +import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol; +import net.sourceforge.pmd.lang.java.symbols.internal.impl.SymbolEquality; +import net.sourceforge.pmd.lang.java.symbols.internal.impl.SymbolFactory; + +final class ReflectedClassImpl extends AbstractTypeParamOwnerSymbol> implements JClassSymbol { + + private final Class myClass; + private final @Nullable JClassSymbol enclosing; + + private @Nullable JClassSymbol superclass; + private List superInterfaces; + + + private List declaredClasses; + private List declaredMethods; + private List declaredConstructors; + private List declaredFields; + + private ReflectedClassImpl(ReflectionSymFactory symbolFactory, Class myClass) { + this(symbolFactory, null, myClass); + } + + /** + * This assumes that the enclosing symbol is correct and doesn't + * check it itself unless assertions are enabled. + */ + private ReflectedClassImpl(ReflectionSymFactory symbolFactory, @Nullable JClassSymbol enclosing, Class myClass) { + super(symbolFactory, myClass); + + this.myClass = myClass; + this.enclosing = enclosing; + + assert !myClass.isArray() : "This class cannot represent array types"; + + assert enclosing == null && myClass.getEnclosingClass() == null + || myClass.getEnclosingClass() != null && enclosing != null + && myClass.getEnclosingClass().getName().equals(enclosing.getBinaryName()) + : "Wrong enclosing class " + enclosing + ", expecting " + myClass.getEnclosingClass(); + } + + @Override + public @NonNull String getBinaryName() { + return myClass.getName(); + } + + @NonNull + @Override + public String getSimpleName() { + return myClass.getSimpleName(); + } + + @Override + public String getCanonicalName() { + return myClass.getCanonicalName(); + } + + @Override + public boolean isUnresolved() { + return false; + } + + @Override + public @NonNull String getPackageName() { + return myClass.isPrimitive() ? PRIMITIVE_PACKAGE + : ClassUtils.getPackageName(myClass); + } + + @Override + public @Nullable Class getJvmRepr() { + return myClass; + } + + @Override + public boolean isPrimitive() { + return myClass.isPrimitive(); + } + + @Nullable + @Override + public JClassSymbol getSuperclass() { + if (superclass == null) { + superclass = symFactory.getClassSymbol(myClass.getSuperclass()); + } + return superclass; + } + + + @Override + public List getSuperInterfaces() { + if (superInterfaces == null) { + superInterfaces = myClass.isArray() ? SymbolFactory.ARRAY_SUPER_INTERFACES + : Arrays.stream(myClass.getInterfaces()).map(symFactory::getClassSymbol).collect(toList()); + } + return superInterfaces; + } + + @Override + public List getDeclaredClasses() { + if (declaredClasses == null) { + declaredClasses = Arrays.stream(myClass.getDeclaredClasses()) + .map(k -> createWithEnclosing(symFactory, this, k)) + .collect(toList()); + } + return declaredClasses; + } + + + @Override + public boolean isInterface() { + return myClass.isInterface(); + } + + @Override + public boolean isEnum() { + return myClass.isEnum(); + } + + @Override + public boolean isAnnotation() { + return myClass.isAnnotation(); + } + + @Override + public boolean isAnonymousClass() { + return myClass.isAnonymousClass(); + } + + @Override + public boolean isLocalClass() { + return myClass.isLocalClass(); + } + + @Override + public boolean isArray() { + return false; + } + + @Override + public JClassSymbol getEnclosingClass() { + return enclosing; + } + + @Override + public int getModifiers() { + return myClass.getModifiers(); + } + + + @Nullable + @Override + public JTypeDeclSymbol getArrayComponent() { + return null; + } + + @Override + public List getDeclaredMethods() { + if (declaredMethods == null) { + declaredMethods = Arrays.stream(myClass.getDeclaredMethods()) + .filter(it -> !it.isBridge() && !it.isSynthetic()) + .map(it -> new ReflectedMethodImpl(this, it)) + .collect(toList()); + } + return declaredMethods; + } + + @Override + public List getConstructors() { + if (declaredConstructors == null) { + declaredConstructors = Arrays.stream(myClass.getDeclaredConstructors()) + .filter(it -> !it.isSynthetic()) + .map(it -> new ReflectedCtorImpl(this, it)) + .collect(toList()); + } + return declaredConstructors; + } + + @Override + public List getDeclaredFields() { + if (declaredFields == null) { + declaredFields = Arrays.stream(myClass.getDeclaredFields()) + .filter(it -> !it.isSynthetic()) + .map(it -> new ReflectedFieldImpl(this, it)) + .collect(toList()); + } + return declaredFields; + } + + @Override + public String toString() { + return getBinaryName(); + } + + @Override + public boolean equals(Object o) { + return SymbolEquality.CLASS.equals(this, o); + } + + @Override + public int hashCode() { + return SymbolEquality.CLASS.hash(this); + } + + + + static ReflectedClassImpl createWithEnclosing(ReflectionSymFactory symbolFactory, + @Nullable JClassSymbol enclosing, + Class myClass) { + return new ReflectedClassImpl(symbolFactory, enclosing, myClass); + } + + static ReflectedClassImpl createOuterClass(ReflectionSymFactory symbolFactory, Class myClass) { + return new ReflectedClassImpl(symbolFactory, myClass); + } + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedCtorImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedCtorImpl.java new file mode 100644 index 0000000000..a8f83252e9 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedCtorImpl.java @@ -0,0 +1,30 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect; + +import java.lang.reflect.Constructor; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; +import net.sourceforge.pmd.lang.java.symbols.internal.impl.SymbolEquality; + + +class ReflectedCtorImpl extends AbstractReflectedExecutableSymbol> implements JConstructorSymbol { + + ReflectedCtorImpl(@NonNull ReflectedClassImpl owner, Constructor myConstructor) { + super(owner, myConstructor); + } + + @Override + public boolean equals(Object obj) { + return SymbolEquality.CONSTRUCTOR.equals(this, obj); + } + + @Override + public int hashCode() { + return SymbolEquality.CONSTRUCTOR.hash(this); + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedFieldImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedFieldImpl.java new file mode 100644 index 0000000000..58df439d81 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedFieldImpl.java @@ -0,0 +1,57 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect; + +import java.lang.reflect.Field; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; +import net.sourceforge.pmd.lang.java.symbols.JFieldSymbol; +import net.sourceforge.pmd.lang.java.symbols.internal.impl.SymbolEquality; + +class ReflectedFieldImpl extends AbstractReflectedSymbol implements JFieldSymbol { + + private final ReflectedClassImpl owner; + private final Field myField; + + ReflectedFieldImpl(ReflectedClassImpl owner, Field myField) { + super(owner.symFactory); + this.owner = owner; + this.myField = myField; + } + + @Override + public String getSimpleName() { + return myField.getName(); + } + + @Override + public boolean isEnumConstant() { + return myField.isEnumConstant(); + } + + @NonNull + @Override + public JClassSymbol getEnclosingClass() { + return owner; + } + + @Override + public int getModifiers() { + return myField.getModifiers(); + } + + + @Override + public boolean equals(Object o) { + return SymbolEquality.FIELD.equals(this, o); + } + + @Override + public int hashCode() { + return SymbolEquality.FIELD.hash(this); + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedMethodImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedMethodImpl.java new file mode 100644 index 0000000000..e415f9866a --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedMethodImpl.java @@ -0,0 +1,37 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect; + +import java.lang.reflect.Method; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol; +import net.sourceforge.pmd.lang.java.symbols.internal.impl.SymbolEquality; + + +class ReflectedMethodImpl extends AbstractReflectedExecutableSymbol implements JMethodSymbol { + + ReflectedMethodImpl(@NonNull ReflectedClassImpl owner, Method method) { + super(owner, method); + } + + + @Override + public String getSimpleName() { + return reflected.getName(); + } + + + @Override + public boolean equals(Object o) { + return SymbolEquality.METHOD.equals(this, o); + } + + @Override + public int hashCode() { + return SymbolEquality.METHOD.hash(this); + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedMethodParamImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedMethodParamImpl.java new file mode 100644 index 0000000000..64c335d27f --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedMethodParamImpl.java @@ -0,0 +1,50 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect; + +import java.lang.reflect.Modifier; +import java.lang.reflect.Parameter; + +import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; +import net.sourceforge.pmd.lang.java.symbols.JFormalParamSymbol; +import net.sourceforge.pmd.lang.java.symbols.internal.impl.SymbolEquality; + +final class ReflectedMethodParamImpl extends AbstractReflectedSymbol implements JFormalParamSymbol { + + private final AbstractReflectedExecutableSymbol owner; + private final Parameter reflected; + + /** Constructor for a reflected method or constructor parameter. */ + ReflectedMethodParamImpl(AbstractReflectedExecutableSymbol owner, Parameter reflected) { + super(owner.symFactory); + this.owner = owner; + this.reflected = reflected; + } + + @Override + public JExecutableSymbol getDeclaringSymbol() { + return owner; + } + + @Override + public boolean isFinal() { + return Modifier.isFinal(reflected.getModifiers()); + } + + @Override + public String getSimpleName() { + return reflected.getName(); + } + + @Override + public boolean equals(Object o) { + return SymbolEquality.FORMAL_PARAM.equals(this, o); + } + + @Override + public int hashCode() { + return SymbolEquality.FORMAL_PARAM.hash(this); + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedTypeParamImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedTypeParamImpl.java new file mode 100644 index 0000000000..1eae5f6789 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectedTypeParamImpl.java @@ -0,0 +1,59 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect; + +import java.lang.reflect.TypeVariable; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import net.sourceforge.pmd.lang.java.symbols.JTypeParameterOwnerSymbol; +import net.sourceforge.pmd.lang.java.symbols.JTypeParameterSymbol; +import net.sourceforge.pmd.lang.java.symbols.internal.impl.SymbolEquality; + +@SuppressWarnings("PMD") +// yeah this looks weird for now +// but it will fall into place when we introduce type mirrors +class ReflectedTypeParamImpl implements JTypeParameterSymbol { + + private final ReflectionSymFactory factory; + private final JTypeParameterOwnerSymbol ownerSymbol; + private final String name; + private final TypeVariable reflected; + + ReflectedTypeParamImpl(ReflectionSymFactory factory, JTypeParameterOwnerSymbol ownerSymbol, TypeVariable tvar) { + this.factory = factory; + this.ownerSymbol = ownerSymbol; + this.name = tvar.getName(); + this.reflected = tvar; + + } + + @Override + public @Nullable Class getJvmRepr() { + return Object.class; // TODO upper bound, when we have implemented types + } + + @Override + public JTypeParameterOwnerSymbol getDeclaringSymbol() { + return ownerSymbol; + } + + @NonNull + @Override + public String getSimpleName() { + return name; + } + + @Override + public boolean equals(Object o) { + return SymbolEquality.TYPE_PARAM.equals(this, o); + } + + @Override + public int hashCode() { + return SymbolEquality.TYPE_PARAM.hash(this); + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectionSymFactory.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectionSymFactory.java new file mode 100644 index 0000000000..7402fdd362 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/impl/reflect/ReflectionSymFactory.java @@ -0,0 +1,119 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect; + + +import static net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect.ReflectedClassImpl.createOuterClass; +import static net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect.ReflectedClassImpl.createWithEnclosing; + +import java.io.Serializable; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; +import net.sourceforge.pmd.lang.java.symbols.internal.impl.SymbolFactory; + +/** + * Symbol factory building type symbols from {@link Class} instances. + * Reflected symbol implementations carry an instance of this around, + * so as to allow caching recently accessed symbols later on. + */ +public final class ReflectionSymFactory implements SymbolFactory> { + + /** + * Lazy initialized to avoid class init cycle, because + * {@link SymbolFactory} creates reflected symbols. + */ + private static Map, JClassSymbol> commonSymbols; + + + @Override + @Nullable + public JClassSymbol getClassSymbol(@Nullable Class klass) { + if (klass == null) { + return null; + } + + Map, JClassSymbol> shared = getCommonSyms(); + if (shared.containsKey(klass)) { + return shared.get(klass); + } + + if (klass.getEnclosingClass() != null) { + JClassSymbol enclosing = getClassSymbol(klass.getEnclosingClass()); + assert enclosing != null; + return createWithEnclosing(this, enclosing, klass); + } + + if (klass.isArray()) { + JClassSymbol component = getClassSymbol(klass.getComponentType()); + return makeArraySymbol(component); + } + + return createOuterClass(this, klass); + } + + private static Map, JClassSymbol> getCommonSyms() { + Map, JClassSymbol> shared = commonSymbols; + if (shared == null) { + synchronized (ReflectionSymFactory.class) { + shared = commonSymbols; + if (shared == null) { + shared = initCommonSyms(); + commonSymbols = shared; + } + } + } + return shared; + } + + private static void putStr(Map, JClassSymbol> byClass, + Class booleanClass, + JClassSymbol booleanSym) { + byClass.put(booleanClass, booleanSym); + } + + + private static Map, JClassSymbol> initCommonSyms() { + // consider putting whole java.lang + java.util in there ? + + Map, JClassSymbol> specials = new HashMap<>(); + + putStr(specials, Object.class, OBJECT_SYM); + + putStr(specials, boolean.class, BOOLEAN_SYM); + putStr(specials, byte.class, BYTE_SYM); + putStr(specials, char.class, CHAR_SYM); + putStr(specials, double.class, DOUBLE_SYM); + putStr(specials, float.class, FLOAT_SYM); + putStr(specials, int.class, INT_SYM); + putStr(specials, long.class, LONG_SYM); + putStr(specials, short.class, SHORT_SYM); + putStr(specials, void.class, VOID_SYM); + + putStr(specials, Cloneable.class, CLONEABLE_SYM); + putStr(specials, Serializable.class, SERIALIZABLE_SYM); + + putStr(specials, Boolean.class, BOXED_BOOLEAN_SYM); + putStr(specials, Byte.class, BOXED_BYTE_SYM); + putStr(specials, Character.class, BOXED_CHAR_SYM); + putStr(specials, Double.class, BOXED_DOUBLE_SYM); + putStr(specials, Float.class, BOXED_FLOAT_SYM); + putStr(specials, Integer.class, BOXED_INT_SYM); + putStr(specials, Long.class, BOXED_LONG_SYM); + putStr(specials, Short.class, BOXED_SHORT_SYM); + putStr(specials, Void.class, BOXED_VOID_SYM); + + putStr(specials, Iterable.class, ITERABLE_SYM); + putStr(specials, Enum.class, ENUM_SYM); + putStr(specials, String.class, STRING_SYM); + + return Collections.unmodifiableMap(specials); + } + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/package-info.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/package-info.java index 48808224b7..c759d0e899 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/package-info.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/package-info.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ @@ -6,8 +6,9 @@ * Prototype of a new symbol resolution framework * that inter-operates cleanly with type resolution. * - * @see net.sourceforge.pmd.lang.java.symbols.internal.JElementSymbol + * @see net.sourceforge.pmd.lang.java.symbols.JElementSymbol * @see net.sourceforge.pmd.lang.java.symbols.table.JSymbolTable + * @see net.sourceforge.pmd.lang.java.symbols.SymbolResolver */ @Experimental diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/JSymbolTable.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/JSymbolTable.java index 9825b49dfe..2e0819857b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/JSymbolTable.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/JSymbolTable.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ @@ -9,14 +9,10 @@ import java.util.stream.Stream; import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.annotation.Experimental; -import net.sourceforge.pmd.lang.java.symbols.internal.JClassSymbol; -import net.sourceforge.pmd.lang.java.symbols.internal.JElementSymbol; -import net.sourceforge.pmd.lang.java.symbols.internal.JMethodSymbol; -import net.sourceforge.pmd.lang.java.symbols.internal.JResolvableClassSymbol; -import net.sourceforge.pmd.lang.java.symbols.internal.JSimpleTypeSymbol; -import net.sourceforge.pmd.lang.java.symbols.internal.JTypeParameterSymbol; -import net.sourceforge.pmd.lang.java.symbols.internal.JValueSymbol; -import net.sourceforge.pmd.lang.java.typeresolution.ClassTypeResolver; +import net.sourceforge.pmd.lang.java.symbols.JElementSymbol; +import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol; +import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol; +import net.sourceforge.pmd.lang.java.symbols.JValueSymbol; // @formatter:off /** @@ -36,33 +32,6 @@ import net.sourceforge.pmd.lang.java.typeresolution.ClassTypeResolver; * This allows directly encoding shadowing and hiding mechanisms in the parent-child * relationships. * - *

Why not keep the current symbol table

- * - *

The current symbol table framework was not built with the same goals in mind. - * It indexes the AST to reduce it to a simpler representation, which is mostly - * shortcuts to nodes. That representation hasn't proved very useful in rules, - * which mostly only use it to resolve variable accesses. - * - *

The biggest issue is that it was not designed to abstract over whether we - * have a node to represent a declaration or not. It can't work on reflection - * data, and thus cannot really help type resolution, even if a good symbol table - * would take the burden of resolving references off a type checker. The - * shortcomings of the current symbol table make the current typeres duplicate - * logic, and ultimately perform tasks that are not its responsibility, - * which is probably why {@link ClassTypeResolver} is so huge and nasty. - * - *

Having an abstraction layer to unify them allows the AST analyses to - * be complementary, and rely on each other, instead of being so self-reliant. - * The abstraction provided by {@link JElementSymbol} may in the future be used - * to build global indices of analysed projects to implement multifile analysis. - * - *

The goals of this rewrite should be: - *

    - *
  • To make our language analyses passes share information and be complementary - *
  • To have a symbol table that is precise and exhaustive enough that all rules can depend on it - *
  • To modularize the system so that it's more easily testable and documentable - *
- * * @author Clément Fournier * @since 7.0.0 */ @@ -78,23 +47,21 @@ public interface JSymbolTable { */ JSymbolTable getParent(); + // note that types and value names can be obscured, but that depends on the syntactic + // context of the *usage* and is not relevant to the symbol table stack. + /** * Resolves the type referred to by the given name. This must be a simple name, * ie, parameterized types and array types are not available. Primitive types are * also not considered because it's probably not useful. * - *

The returned type reference may be a {@link JResolvableClassSymbol}, a - * {@link JClassSymbol} if the type was already resolved, or a {@link JTypeParameterSymbol}. - * - *

Doesn't handle primitive types (there's no symbol for them). - * * @param simpleName Simple name of the type to look for * * @return The type reference if it can be found, otherwise {@code null} */ @Nullable - JSimpleTypeSymbol resolveTypeName(String simpleName); + JTypeDeclSymbol resolveTypeName(String simpleName); /** diff --git a/pmd-java/src/test/java/javasymbols/testdata/impls/GenericClass.java b/pmd-java/src/test/java/javasymbols/testdata/impls/GenericClass.java new file mode 100644 index 0000000000..37f3d7865a --- /dev/null +++ b/pmd-java/src/test/java/javasymbols/testdata/impls/GenericClass.java @@ -0,0 +1,23 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package javasymbols.testdata.impls; + + +import net.sourceforge.pmd.lang.ast.Node; + + +public class GenericClass { + + + public void anOverload(int bb) { + + } + + + public void anOverload(int bb, String bachir) { + + } + +} diff --git a/pmd-java/src/test/java/javasymbols/testdata/impls/GenericClassCopy.java b/pmd-java/src/test/java/javasymbols/testdata/impls/GenericClassCopy.java new file mode 100644 index 0000000000..da0a0ffee5 --- /dev/null +++ b/pmd-java/src/test/java/javasymbols/testdata/impls/GenericClassCopy.java @@ -0,0 +1,23 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package javasymbols.testdata.impls; + + +import net.sourceforge.pmd.lang.ast.Node; + + +public class GenericClassCopy { + + + public void anOverload(int bb) { + + } + + + public void anOverload(int bb, String bachir) { + + } + +} diff --git a/pmd-java/src/test/java/javasymbols/testdata/impls/IdenticalToSomeFields.java b/pmd-java/src/test/java/javasymbols/testdata/impls/IdenticalToSomeFields.java new file mode 100644 index 0000000000..fa757526e9 --- /dev/null +++ b/pmd-java/src/test/java/javasymbols/testdata/impls/IdenticalToSomeFields.java @@ -0,0 +1,28 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package javasymbols.testdata.impls; + + +public class IdenticalToSomeFields { + + + public final String foo = ""; + protected volatile int bb; + private int a; + + + public final String foo() { + return ""; + } + + public interface Other { + + default int defaultMethod() { + return 1; + } + + } + +} diff --git a/pmd-java/src/test/java/javasymbols/testdata/impls/Overloads.java b/pmd-java/src/test/java/javasymbols/testdata/impls/Overloads.java new file mode 100644 index 0000000000..05e10c0253 --- /dev/null +++ b/pmd-java/src/test/java/javasymbols/testdata/impls/Overloads.java @@ -0,0 +1,20 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package javasymbols.testdata.impls; + + +public class Overloads { + + + public void anOverload(int bb) { + + } + + + public void anOverload(int bb, String bachir) { + + } + +} diff --git a/pmd-java/src/test/java/javasymbols/testdata/impls/SomeFields.java b/pmd-java/src/test/java/javasymbols/testdata/impls/SomeFields.java new file mode 100644 index 0000000000..12424bf591 --- /dev/null +++ b/pmd-java/src/test/java/javasymbols/testdata/impls/SomeFields.java @@ -0,0 +1,15 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package javasymbols.testdata.impls; + + +public class SomeFields { + + public final String foo = ""; + private int a; + protected volatile int bb; + + +} diff --git a/pmd-java/src/test/java/javasymbols/testdata/impls/SomeInnerClasses.java b/pmd-java/src/test/java/javasymbols/testdata/impls/SomeInnerClasses.java new file mode 100644 index 0000000000..79b76c8a4c --- /dev/null +++ b/pmd-java/src/test/java/javasymbols/testdata/impls/SomeInnerClasses.java @@ -0,0 +1,18 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package javasymbols.testdata.impls; + + +public class SomeInnerClasses { + + public static class StaticInner { + + } + + public class Inner { + + } + +} diff --git a/pmd-java/src/test/java/javasymbols/testdata/impls/SomeMethodsNoOverloads.java b/pmd-java/src/test/java/javasymbols/testdata/impls/SomeMethodsNoOverloads.java new file mode 100644 index 0000000000..d18f300326 --- /dev/null +++ b/pmd-java/src/test/java/javasymbols/testdata/impls/SomeMethodsNoOverloads.java @@ -0,0 +1,22 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package javasymbols.testdata.impls; + + +public class SomeMethodsNoOverloads { + + public final String foo() { + return ""; + } + + + public interface Other { + + default int defaultMethod() { + return 1; + } + + } +} diff --git a/pmd-java/src/test/java/javasymbols/testdata/impls/WithSuperClass.java b/pmd-java/src/test/java/javasymbols/testdata/impls/WithSuperClass.java new file mode 100644 index 0000000000..546a54454b --- /dev/null +++ b/pmd-java/src/test/java/javasymbols/testdata/impls/WithSuperClass.java @@ -0,0 +1,23 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package javasymbols.testdata.impls; + + +import net.sourceforge.pmd.lang.ast.Node; + +public class WithSuperClass extends GenericClass { + + + @Override + public void anOverload(int bb) { + + } + + + public void anOverload(int bb, String bachir, int other) { + + } + +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java new file mode 100644 index 0000000000..e9b67a934d --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java @@ -0,0 +1,38 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.ast.test.BaseParsingHelper; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; + +public class JavaParsingHelper extends BaseParsingHelper { + + /** This just runs the parser and no processing stages. */ + public static final JavaParsingHelper JUST_PARSE = new JavaParsingHelper(Params.getDefaultNoProcess()); + /** This runs all processing stages when parsing. */ + public static final JavaParsingHelper WITH_PROCESSING = new JavaParsingHelper(Params.getDefaultProcess()); + + private JavaParsingHelper(Params params) { + super(JavaLanguageModule.NAME, ASTCompilationUnit.class, params); + } + + + @Override + protected JavaParsingHelper clone(Params params) { + return new JavaParsingHelper(params); + } + + public static List convertList(List nodes, Class target) { + List converted = new ArrayList<>(); + for (Node n : nodes) { + converted.add(target.cast(n)); + } + return converted; + } +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ParserTstUtil.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ParserTstUtil.java deleted file mode 100644 index ca9fb60996..0000000000 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ParserTstUtil.java +++ /dev/null @@ -1,316 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java; - -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.apache.commons.io.IOUtils; -import org.jaxen.JaxenException; - -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.LanguageVersion; -import net.sourceforge.pmd.lang.LanguageVersionHandler; -import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; -import net.sourceforge.pmd.lang.java.ast.JavaParserVisitor; -import net.sourceforge.pmd.lang.java.dfa.DataFlowFacade; -import net.sourceforge.pmd.lang.java.internal.JavaLanguageHandler; -import net.sourceforge.pmd.lang.java.qname.QualifiedNameResolver; -import net.sourceforge.pmd.lang.java.symboltable.SymbolFacade; - - -public class ParserTstUtil { - - private ParserTstUtil() { - - } - - private static class Collector implements InvocationHandler { - private Class clazz = null; - private Collection collection; - - Collector(Class clazz) { - this(clazz, new HashSet()); - } - - Collector(Class clazz, Collection coll) { - this.clazz = clazz; - this.collection = coll; - } - - public Collection getCollection() { - return collection; - } - - public Object invoke(Object proxy, Method method, Object[] params) throws NoSuchMethodException, - SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - if (method.getName().equals("visit")) { - if (clazz.isInstance(params[0])) { - collection.add(clazz.cast(params[0])); - } - } - - Method childrenAccept = params[0].getClass().getMethod("childrenAccept", - JavaParserVisitor.class, Object.class); - childrenAccept.invoke(params[0], (JavaParserVisitor) proxy, null); - return null; - } - } - - // TODO provide a configurable api to choose which visitors to invoke - // it makes no sense - - public static Set getNodes(Class clazz, String javaCode) { - return getNodes(LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getDefaultVersion(), clazz, javaCode); - } - - public static Set getNodes(LanguageVersion languageVersion, Class clazz, String javaCode) { - Collector coll = new Collector<>(clazz); - LanguageVersionHandler languageVersionHandler = languageVersion.getLanguageVersionHandler(); - ASTCompilationUnit cu = (ASTCompilationUnit) languageVersionHandler - .getParser(languageVersionHandler.getDefaultParserOptions()).parse(null, new StringReader(javaCode)); - JavaParserVisitor jpv = (JavaParserVisitor) Proxy.newProxyInstance(JavaParserVisitor.class.getClassLoader(), - new Class[] { JavaParserVisitor.class }, coll); - jpv.visit(cu, null); - return (Set) coll.getCollection(); - } - - public static List getOrderedNodes(Class clazz, String javaCode) { - Collector coll = new Collector<>(clazz, new ArrayList()); - LanguageVersionHandler languageVersionHandler = LanguageRegistry.getLanguage(JavaLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); - ASTCompilationUnit cu = (ASTCompilationUnit) languageVersionHandler - .getParser(languageVersionHandler.getDefaultParserOptions()).parse(null, new StringReader(javaCode)); - JavaParserVisitor jpv = (JavaParserVisitor) Proxy.newProxyInstance(JavaParserVisitor.class.getClassLoader(), - new Class[] { JavaParserVisitor.class }, coll); - jpv.visit(cu, null); - new QualifiedNameResolver().initializeWith(ParserTstUtil.class.getClassLoader(), cu); - new SymbolFacade().initializeWith(cu); - new DataFlowFacade().initializeWith(languageVersionHandler.getDataFlowHandler(), cu); - - return (List) coll.getCollection(); - } - - public static String dumpNodes(List list) { - StringBuilder sb = new StringBuilder(); - int index = 0; - for (E item : list) { - sb.append("\n node[").append(index).append(item.toString()); - index++; - } - return sb.toString(); - } - - public static ASTCompilationUnit buildDFA(String javaCode) { - LanguageVersionHandler languageVersionHandler = LanguageRegistry.getLanguage(JavaLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); - ASTCompilationUnit cu = (ASTCompilationUnit) languageVersionHandler - .getParser(languageVersionHandler.getDefaultParserOptions()).parse(null, new StringReader(javaCode)); - JavaParserVisitor jpv = (JavaParserVisitor) Proxy.newProxyInstance(JavaParserVisitor.class.getClassLoader(), - new Class[] { JavaParserVisitor.class }, new Collector<>(ASTCompilationUnit.class)); - jpv.visit(cu, null); - new SymbolFacade().initializeWith(cu); - new DataFlowFacade().initializeWith(languageVersionHandler.getDataFlowHandler(), cu); - return cu; - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava13(String code) { - return parseJava(getLanguageVersionHandler("1.3"), code); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava14(String code) { - return parseJava(getLanguageVersionHandler("1.4"), code); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava15(String code) { - return parseJava(getLanguageVersionHandler("1.5"), code); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava17(String code) { - return parseJava(getLanguageVersionHandler("1.7"), code); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava18(String code) { - return parseJava(getLanguageVersionHandler("1.8"), code); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava9(String code) { - return parseJava(getLanguageVersionHandler("9"), code); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava10(String code) { - return parseJava(getLanguageVersionHandler("10"), code); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava13(Class source) { - return parseJava13(getSourceFromClass(source)); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava14(Class source) { - return parseJava14(getSourceFromClass(source)); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava15(Class source) { - return parseJava15(getSourceFromClass(source)); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava17(Class source) { - return parseJava17(getSourceFromClass(source)); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava18(Class source) { - return parseJava18(getSourceFromClass(source)); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava9(Class source) { - return parseJava9(getSourceFromClass(source)); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJava10(Class source) { - return parseJava10(getSourceFromClass(source)); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJavaDefaultVersion(String source) { - return parseJava(getDefaultLanguageVersionHandler(), source); - } - - /** @see #parseJava(LanguageVersionHandler, String) */ - public static ASTCompilationUnit parseJavaDefaultVersion(Class source) { - return parseJavaDefaultVersion(getSourceFromClass(source)); - } - - - public static JavaLanguageHandler getLanguageVersionHandler(String version) { - return (JavaLanguageHandler) LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion(version).getLanguageVersionHandler(); - } - - public static JavaLanguageHandler getDefaultLanguageVersionHandler() { - return (JavaLanguageHandler) LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getDefaultVersion().getLanguageVersionHandler(); - } - - - /** - * Parses Java code and executes the symbol table visitor. - * - * @param languageVersionHandler The version handler for the wanted version - * @param code The source code - * - * @return The compilation unit - */ - public static ASTCompilationUnit parseJava(LanguageVersionHandler languageVersionHandler, String code) { - ASTCompilationUnit rootNode = (ASTCompilationUnit) languageVersionHandler - .getParser(languageVersionHandler.getDefaultParserOptions()).parse(null, new StringReader(code)); - languageVersionHandler.getQualifiedNameResolutionFacade(ParserTstUtil.class.getClassLoader()).start(rootNode); - languageVersionHandler.getSymbolFacade().start(rootNode); - return rootNode; - } - - - public static List selectNodes(String source, Class resultType, String xpath) throws JaxenException { - return selectNodes(source, "1.5", resultType, xpath); - } - - - // This is the master overload, others just default the parameters - public static List selectNodes(String source, String version, Class resultType, String xpath) throws JaxenException { - ASTCompilationUnit acu = parseAndTypeResolveJava(version, source); - return convertList(acu.findChildNodesWithXPath(xpath), resultType); - } - - - public static List selectNodes(Class source, Class resultType) { - return parseAndTypeResolveJava("1.5", getSourceFromClass(source)).findDescendantsOfType(resultType); - } - - - public static List selectNodes(Class source, Class resultType, String xpath) throws JaxenException { - return selectNodes(source, "1.5", resultType, xpath); - } - - - public static List selectNodes(Class source, String version, Class resultType, String xpath) throws JaxenException { - return selectNodes(ParserTstUtil.getSourceFromClass(source), version, resultType, xpath); - } - - - private static List convertList(List nodes, Class target) { - List converted = new ArrayList<>(); - for (Node n : nodes) { - converted.add(target.cast(n)); - } - return converted; - } - - - /** - * Gets the source from the source file in which the class was declared. - * Returns the source of the whole file even it it is not a top-level type. - * - * @param clazz Class to find the source for - * - * @return The source - * - * @throws IllegalArgumentException if the source file wasn't found - */ - public static String getSourceFromClass(Class clazz) { - String sourceFile = clazz.getName().replace('.', '/') + ".java"; - // Consider nested classes - if (clazz.getName().contains("$")) { - sourceFile = sourceFile.substring(0, clazz.getName().indexOf('$')) + ".java"; - } - InputStream is = ParserTstUtil.class.getClassLoader().getResourceAsStream(sourceFile); - if (is == null) { - throw new IllegalArgumentException( - "Unable to find source file " + sourceFile + " for " + clazz); - } - String source; - try { - source = IOUtils.toString(is, StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException(e); - } - return source; - } - - public static ASTCompilationUnit parseAndTypeResolveJava(String javaVersion, String sourceCode) { - LanguageVersionHandler languageVersionHandler = getLanguageVersionHandler(javaVersion); - ASTCompilationUnit rootNode = (ASTCompilationUnit) languageVersionHandler - .getParser(languageVersionHandler.getDefaultParserOptions()) - .parse(null, new StringReader(sourceCode)); - languageVersionHandler.getQualifiedNameResolutionFacade(ParserTstUtil.class.getClassLoader()).start(rootNode); - languageVersionHandler.getSymbolFacade().start(rootNode); - languageVersionHandler.getDataFlowFacade().start(rootNode); - languageVersionHandler.getTypeResolutionFacade(ParserTstUtil.class.getClassLoader()).start(rootNode); - languageVersionHandler.getMultifileFacade().start(rootNode); - return rootNode; - } -} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/SuppressWarningsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/SuppressWarningsTest.java index 71005ace71..6506f992b0 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/SuppressWarningsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/SuppressWarningsTest.java @@ -9,7 +9,6 @@ import static org.junit.Assert.assertEquals; import org.junit.Test; import net.sourceforge.pmd.FooRule; -import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.Report; import net.sourceforge.pmd.lang.LanguageRegistry; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; @@ -177,59 +176,39 @@ public class SuppressWarningsTest extends RuleTst { assertEquals(0, rpt.size()); } - private static final String TEST1 = "@SuppressWarnings(\"PMD\")" + PMD.EOL + "public class Foo {}"; + private static final String TEST1 = "@SuppressWarnings(\"PMD\")\npublic class Foo {}"; - private static final String TEST2 = "@SuppressWarnings(\"PMD\")" + PMD.EOL + "public class Foo {" + PMD.EOL - + " void bar() {" + PMD.EOL + " int foo;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST2 = "@SuppressWarnings(\"PMD\")\npublic class Foo {\n void bar() {\n int foo;\n }\n}"; - private static final String TEST3 = "public class Baz {" + PMD.EOL + " @SuppressWarnings(\"PMD\")" + PMD.EOL - + " public class Bar {" + PMD.EOL + " void bar() {" + PMD.EOL + " int foo;" + PMD.EOL + " }" + PMD.EOL - + " }" + PMD.EOL + "}"; + private static final String TEST3 = "public class Baz {\n @SuppressWarnings(\"PMD\")\n public class Bar {\n void bar() {\n int foo;\n }\n }\n}"; - private static final String TEST4 = "public class Foo {" + PMD.EOL + " @SuppressWarnings(\"PMD\")" + PMD.EOL - + " void bar() {" + PMD.EOL + " int foo;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST4 = "public class Foo {\n @SuppressWarnings(\"PMD\")\n void bar() {\n int foo;\n }\n}"; - private static final String TEST5 = "public class Bar {" + PMD.EOL + " @SuppressWarnings(\"PMD\")" + PMD.EOL - + " public Bar() {" + PMD.EOL + " int foo;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST5 = "public class Bar {\n @SuppressWarnings(\"PMD\")\n public Bar() {\n int foo;\n }\n}"; - private static final String TEST6 = "public class Bar {" + PMD.EOL + " @SuppressWarnings(\"PMD\")" + PMD.EOL - + " int foo;" + PMD.EOL + " void bar() {" + PMD.EOL + " int foo;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST6 = "public class Bar {\n @SuppressWarnings(\"PMD\")\n int foo;\n void bar() {\n int foo;\n }\n}"; - private static final String TEST7 = "public class Bar {" + PMD.EOL + " int foo;" + PMD.EOL - + " void bar(@SuppressWarnings(\"PMD\") int foo) {}" + PMD.EOL + "}"; + private static final String TEST7 = "public class Bar {\n int foo;\n void bar(@SuppressWarnings(\"PMD\") int foo) {}\n}"; - private static final String TEST8 = "public class Bar {" + PMD.EOL + " int foo;" + PMD.EOL + " void bar() {" - + PMD.EOL + " @SuppressWarnings(\"PMD\") int foo;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST8 = "public class Bar {\n int foo;\n void bar() {\n @SuppressWarnings(\"PMD\") int foo;\n }\n}"; - private static final String TEST9 = "public class Bar {" + PMD.EOL + " int foo;" + PMD.EOL + " void bar() {" - + PMD.EOL + " @SuppressWarnings(\"PMD.NoFoo\") int foo;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST9 = "public class Bar {\n int foo;\n void bar() {\n @SuppressWarnings(\"PMD.NoFoo\") int foo;\n }\n}"; - private static final String TEST9_VALUE1 = "public class Bar {" + PMD.EOL + " int foo;" + PMD.EOL + " void bar() {" - + PMD.EOL + " @SuppressWarnings(value = \"PMD.NoFoo\") int foo;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST9_VALUE1 = "public class Bar {\n int foo;\n void bar() {\n @SuppressWarnings(value = \"PMD.NoFoo\") int foo;\n }\n}"; - private static final String TEST9_VALUE2 = "public class Bar {" + PMD.EOL + " int foo;" + PMD.EOL + " void bar() {" - + PMD.EOL + " @SuppressWarnings({\"PMD.NoFoo\"}) int foo;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST9_VALUE2 = "public class Bar {\n int foo;\n void bar() {\n @SuppressWarnings({\"PMD.NoFoo\"}) int foo;\n }\n}"; - private static final String TEST9_VALUE3 = "public class Bar {" + PMD.EOL + " int foo;" + PMD.EOL + " void bar() {" - + PMD.EOL + " @SuppressWarnings(value = {\"PMD.NoFoo\"}) int foo;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST9_VALUE3 = "public class Bar {\n int foo;\n void bar() {\n @SuppressWarnings(value = {\"PMD.NoFoo\"}) int foo;\n }\n}"; - private static final String TEST9_MULTIPLE_VALUES_1 = "@SuppressWarnings({\"PMD.NoFoo\", \"PMD.NoBar\"})" + PMD.EOL - + "public class Bar {" + PMD.EOL + " int foo;" + PMD.EOL + " void bar() {" + PMD.EOL + " int foo;" - + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST9_MULTIPLE_VALUES_1 = "@SuppressWarnings({\"PMD.NoFoo\", \"PMD.NoBar\"})\npublic class Bar {\n int foo;\n void bar() {\n int foo;\n }\n}"; - private static final String TEST9_MULTIPLE_VALUES_2 = "@SuppressWarnings(value = {\"PMD.NoFoo\", \"PMD.NoBar\"})" - + PMD.EOL + "public class Bar {" + PMD.EOL + " int foo;" + PMD.EOL + " void bar() {" + PMD.EOL - + " int foo;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST9_MULTIPLE_VALUES_2 = "@SuppressWarnings(value = {\"PMD.NoFoo\", \"PMD.NoBar\"})\npublic class Bar {\n int foo;\n void bar() {\n int foo;\n }\n}"; - private static final String TEST10 = "public class Bar {" + PMD.EOL + " int foo;" + PMD.EOL + " void bar() {" - + PMD.EOL + " @SuppressWarnings(\"\") int foo;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST10 = "public class Bar {\n int foo;\n void bar() {\n @SuppressWarnings(\"\") int foo;\n }\n}"; - private static final String TEST11 = "public class Bar {" + PMD.EOL + " int foo;" + PMD.EOL + " void bar() {" - + PMD.EOL + " @SuppressWarnings(\"SomethingElse\") int foo;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST11 = "public class Bar {\n int foo;\n void bar() {\n @SuppressWarnings(\"SomethingElse\") int foo;\n }\n}"; - private static final String TEST12 = "public class Bar {" + PMD.EOL + " @SuppressWarnings(\"all\") int foo;" - + PMD.EOL + "}"; + private static final String TEST12 = "public class Bar {\n @SuppressWarnings(\"all\") int foo;\n}"; - private static final String TEST13 = "@SuppressWarnings(\"PMD.NoBar\")" + PMD.EOL + "public class Bar {" + PMD.EOL - + "}"; + private static final String TEST13 = "@SuppressWarnings(\"PMD.NoBar\")\npublic class Bar {\n}"; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteralTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteralTest.java index 0394f2aa14..084684ec9e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteralTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteralTest.java @@ -4,33 +4,30 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.Set; +import java.util.List; import org.junit.Test; -import net.sourceforge.pmd.PMD; - -public class ASTBooleanLiteralTest { +public class ASTBooleanLiteralTest extends BaseParserTest { @Test public void testTrue() { - Set ops = getNodes(ASTBooleanLiteral.class, TEST1); - ASTBooleanLiteral b = ops.iterator().next(); + List ops = java.getNodes(ASTBooleanLiteral.class, TEST1); + ASTBooleanLiteral b = ops.get(0); assertTrue(b.isTrue()); } @Test public void testFalse() { - Set ops = getNodes(ASTBooleanLiteral.class, TEST2); - ASTBooleanLiteral b = ops.iterator().next(); + List ops = java.getNodes(ASTBooleanLiteral.class, TEST2); + ASTBooleanLiteral b = ops.get(0); assertFalse(b.isTrue()); } - private static final String TEST1 = "class Foo { " + PMD.EOL + " boolean bar = true; " + PMD.EOL + "} "; + private static final String TEST1 = "class Foo { \n boolean bar = true; \n} "; - private static final String TEST2 = "class Foo { " + PMD.EOL + " boolean bar = false; " + PMD.EOL + "} "; + private static final String TEST2 = "class Foo { \n boolean bar = false; \n} "; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclarationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclarationTest.java index 0390203714..1e00823936 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclarationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclarationTest.java @@ -11,7 +11,7 @@ import java.util.List; import org.junit.Test; -import net.sourceforge.pmd.lang.java.ParserTstUtil; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; /** @@ -41,7 +41,7 @@ public class ASTClassOrInterfaceDeclarationTest { @Test public void testLocalInMethod() { - List classes = ParserTstUtil.getOrderedNodes(ASTClassOrInterfaceDeclaration.class, LOCAL_CLASS_IN_METHOD); + List classes = getClassDecls(LOCAL_CLASS_IN_METHOD); assertTrue(classes.size() == 2); assertFalse("Local class false-positive", classes.get(0).isLocal()); @@ -51,7 +51,7 @@ public class ASTClassOrInterfaceDeclarationTest { @Test public void testLocalInInitializer() { - List classes = ParserTstUtil.getOrderedNodes(ASTClassOrInterfaceDeclaration.class, LOCAL_CLASS_IN_INITIALIZER); + List classes = getClassDecls(LOCAL_CLASS_IN_INITIALIZER); assertTrue(classes.size() == 2); assertFalse("Local class false-positive", classes.get(0).isLocal()); @@ -62,7 +62,7 @@ public class ASTClassOrInterfaceDeclarationTest { @Test public void testLocalAbstractClass() { - List classes = ParserTstUtil.getOrderedNodes(ASTClassOrInterfaceDeclaration.class, LOCAL_CLASS_WITH_MODIFIERS); + List classes = getClassDecls(LOCAL_CLASS_WITH_MODIFIERS); assertTrue(classes.size() == 2); assertFalse("Local class false-positive", classes.get(0).isLocal()); @@ -73,7 +73,7 @@ public class ASTClassOrInterfaceDeclarationTest { @Test public void testLocalClassWithMixedModifiers() { - List classes = ParserTstUtil.getOrderedNodes(ASTClassOrInterfaceDeclaration.class, LOCAL_CLASS_WITH_MIXED_MODIFIER_ANNOTATIONS); + List classes = getClassDecls(LOCAL_CLASS_WITH_MIXED_MODIFIER_ANNOTATIONS); assertTrue(classes.size() == 2); assertFalse("Local class false-positive", classes.get(0).isLocal()); @@ -85,7 +85,7 @@ public class ASTClassOrInterfaceDeclarationTest { @Test public void testLocalClassVisibility() { - List classes = ParserTstUtil.getOrderedNodes(ASTClassOrInterfaceDeclaration.class, LOCAL_CLASS_WITH_MODIFIERS); + List classes = getClassDecls(LOCAL_CLASS_WITH_MODIFIERS); assertTrue(classes.size() == 2); assertFalse("Local class false-positive", classes.get(0).isLocal()); @@ -99,7 +99,7 @@ public class ASTClassOrInterfaceDeclarationTest { @Test public void testNestedClassIsNotLocal() { - List classes = ParserTstUtil.getOrderedNodes(ASTClassOrInterfaceDeclaration.class, NESTED_CLASS_IS_NOT_LOCAL); + List classes = getClassDecls(NESTED_CLASS_IS_NOT_LOCAL); assertTrue(classes.size() == 2); assertFalse("Local class false-positive", classes.get(0).isLocal()); @@ -109,7 +109,7 @@ public class ASTClassOrInterfaceDeclarationTest { @Test public void testLocalChildrenAreNotAlwaysLocal() { - List classes = ParserTstUtil.getOrderedNodes(ASTClassOrInterfaceDeclaration.class, LOCAL_CHILDREN_ARE_NOT_ALWAYS_LOCAL); + List classes = getClassDecls(LOCAL_CHILDREN_ARE_NOT_ALWAYS_LOCAL); assertTrue(classes.size() == 4); assertFalse("Local class false-positive", classes.get(0).isLocal()); // class Foo @@ -117,4 +117,9 @@ public class ASTClassOrInterfaceDeclarationTest { assertFalse("Local class false-positive", classes.get(2).isLocal()); // class Nested assertTrue("Local class false-negative", classes.get(3).isLocal()); // class Local2 } + + + private List getClassDecls(String code) { + return JavaParsingHelper.WITH_PROCESSING.getNodes(ASTClassOrInterfaceDeclaration.class, code); + } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameterTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameterTest.java index fbfa65ae47..046dcc5b78 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameterTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameterTest.java @@ -4,31 +4,23 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.Iterator; -import java.util.Set; +import java.util.List; import org.junit.Test; -import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.java.JavaLanguageModule; - -public class ASTFormalParameterTest { +public class ASTFormalParameterTest extends BaseParserTest { @Test public void testVarargs() { int nrOfVarArgs = 0; int nrOfNoVarArgs = 0; - Set ops = getNodes(LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("1.5"), - ASTFormalParameter.class, TEST1); - for (Iterator iter = ops.iterator(); iter.hasNext();) { - ASTFormalParameter b = iter.next(); + List ops = java.getNodes(ASTFormalParameter.class, TEST1, "1.5"); + for (ASTFormalParameter b : ops) { ASTVariableDeclaratorId variableDeclId = b.getFirstDescendantOfType(ASTVariableDeclaratorId.class); if (!"x".equals(variableDeclId.getImage())) { assertTrue(b.isVarargs()); @@ -44,5 +36,5 @@ public class ASTFormalParameterTest { assertEquals(1, nrOfNoVarArgs); } - private static final String TEST1 = "class Foo {" + PMD.EOL + " void bar(int x, int... others) {}" + PMD.EOL + "}"; + private static final String TEST1 = "class Foo {\n void bar(int x, int... others) {}\n}"; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclarationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclarationTest.java index 2e85435124..ef2a96075f 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclarationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclarationTest.java @@ -4,48 +4,42 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import java.util.Set; +import java.util.List; import org.junit.Test; -import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.java.JavaLanguageModule; - -public class ASTImportDeclarationTest { +public class ASTImportDeclarationTest extends BaseParserTest { @Test public void testImportOnDemand() { - Set ops = getNodes(ASTImportDeclaration.class, TEST1); - assertTrue(ops.iterator().next().isImportOnDemand()); + List ops = java.getNodes(ASTImportDeclaration.class, TEST1); + assertTrue(ops.get(0).isImportOnDemand()); } @Test public void testGetImportedNameNode() { - ASTImportDeclaration i = getNodes(ASTImportDeclaration.class, TEST2).iterator().next(); + ASTImportDeclaration i = java.getNodes(ASTImportDeclaration.class, TEST2).get(0); assertEquals("foo.bar.Baz", i.getImportedName()); } @Test public void testStaticImport() { - Set ops = getNodes(ASTImportDeclaration.class, TEST3); - ASTImportDeclaration i = ops.iterator().next(); + List ops = java.getNodes(ASTImportDeclaration.class, TEST3); + ASTImportDeclaration i = ops.get(0); assertTrue(i.isStatic()); } @Test(expected = ParseException.class) public void testStaticImportFailsWithJDK14() { - getNodes(LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("1.4"), ASTImportDeclaration.class, - TEST3); + java.parse(TEST3, "1.4"); } - private static final String TEST1 = "import foo.bar.*;" + PMD.EOL + "public class Foo {}"; + private static final String TEST1 = "import foo.bar.*;\npublic class Foo {}"; - private static final String TEST2 = "import foo.bar.Baz;" + PMD.EOL + "public class Foo {}"; + private static final String TEST2 = "import foo.bar.Baz;\npublic class Foo {}"; - private static final String TEST3 = "import static foo.bar.Baz;" + PMD.EOL + "public class Foo {}"; + private static final String TEST3 = "import static foo.bar.Baz;\npublic class Foo {}"; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTInitializerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTInitializerTest.java index 670ab82738..f333179d1b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTInitializerTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTInitializerTest.java @@ -4,19 +4,14 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; - import org.junit.Test; -import net.sourceforge.pmd.PMD; - -public class ASTInitializerTest { +public class ASTInitializerTest extends BaseParserTest { @Test public void testDontCrashOnBlockStatement() { - getNodes(ASTInitializer.class, TEST1); + java.parse(TEST1); } - private static final String TEST1 = "public class Foo {" + PMD.EOL + " {" + PMD.EOL + " x = 5;" + PMD.EOL + " }" - + PMD.EOL + "}"; + private static final String TEST1 = "public class Foo {\n {\n x = 5;\n }\n}"; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDeclarationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDeclarationTest.java index 60223d57d3..8031cd667b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDeclarationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDeclarationTest.java @@ -4,31 +4,19 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava9; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Test; -public class ASTModuleDeclarationTest { - private static String loadSource(String name) { - try { - return IOUtils.toString(ASTModuleDeclarationTest.class.getResourceAsStream("jdkversiontests/" + name), - StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException(e); - } - } +public class ASTModuleDeclarationTest extends BaseParserTest { @Test public final void jdk9ModuleInfo() { - ASTCompilationUnit ast = parseJava9(loadSource("jdk9_module_info.java")); + ASTCompilationUnit ast = java9.parseResource("jdkversiontests/jdk9_module_info.java"); List modules = ast.findDescendantsOfType(ASTModuleDeclaration.class); assertEquals(1, modules.size()); ASTModuleDeclaration module = modules.get(0); @@ -37,7 +25,7 @@ public class ASTModuleDeclarationTest { assertEquals(7, module.jjtGetNumChildren()); List directives = module.findChildrenOfType(ASTModuleDirective.class); assertEquals(7, directives.size()); - + // requires com.example.foo.http; assertEquals(ASTModuleDirective.DirectiveType.REQUIRES.name(), directives.get(0).getType()); assertNull(directives.get(0).getRequiresModifier()); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTPackageDeclarationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTPackageDeclarationTest.java index d261a1c903..991ab72612 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTPackageDeclarationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTPackageDeclarationTest.java @@ -4,29 +4,22 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; import static org.junit.Assert.assertEquals; -import java.util.Set; - import org.junit.Test; -import net.sourceforge.pmd.PMD; +public class ASTPackageDeclarationTest extends BaseParserTest { -public class ASTPackageDeclarationTest { - - private static final String PACKAGE_INFO_ANNOTATED = "@Deprecated" + PMD.EOL + "package net.sourceforge.pmd.foobar;" - + PMD.EOL; + private static final String PACKAGE_INFO_ANNOTATED = "@Deprecated\npackage net.sourceforge.pmd.foobar;\n"; /** * Regression test for bug 3524607. */ @Test public void testPackageName() { - Set nodes = getNodes(ASTPackageDeclaration.class, PACKAGE_INFO_ANNOTATED); + ASTCompilationUnit nodes = java.parse(PACKAGE_INFO_ANNOTATED); - assertEquals(1, nodes.size()); - ASTPackageDeclaration packageNode = nodes.iterator().next(); - assertEquals("net.sourceforge.pmd.foobar", packageNode.getPackageNameImage()); + assertEquals("net.sourceforge.pmd.foobar", nodes.getPackageDeclaration().getPackageNameImage()); + assertEquals("net.sourceforge.pmd.foobar", nodes.getPackageName()); } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.java index 1838d70eeb..abf5bb6c6c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.java @@ -4,33 +4,28 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.Set; +import java.util.List; import org.junit.Test; -import net.sourceforge.pmd.PMD; - -public class ASTSwitchLabelTest { +public class ASTSwitchLabelTest extends BaseParserTest { @Test public void testDefaultOff() { - Set ops = getNodes(ASTSwitchLabel.class, TEST1); - assertFalse(ops.iterator().next().isDefault()); + List ops = java.getNodes(ASTSwitchLabel.class, TEST1); + assertFalse(ops.get(0).isDefault()); } @Test public void testDefaultSet() { - Set ops = getNodes(ASTSwitchLabel.class, TEST2); - assertTrue(ops.iterator().next().isDefault()); + List ops = java.getNodes(ASTSwitchLabel.class, TEST2); + assertTrue(ops.get(0).isDefault()); } - private static final String TEST1 = "public class Foo {" + PMD.EOL + " void bar() {" + PMD.EOL + " switch (x) {" - + PMD.EOL + " case 1: y = 2;" + PMD.EOL + " }" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST1 = "public class Foo {\n void bar() {\n switch (x) {\n case 1: y = 2;\n }\n }\n}"; - private static final String TEST2 = "public class Foo {" + PMD.EOL + " void bar() {" + PMD.EOL + " switch (x) {" - + PMD.EOL + " default: y = 2;" + PMD.EOL + " }" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST2 = "public class Foo {\n void bar() {\n switch (x) {\n default: y = 2;\n }\n }\n}"; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTTests.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTTests.java deleted file mode 100644 index b65be821e5..0000000000 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTTests.java +++ /dev/null @@ -1,16 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.ast; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ ASTImportDeclarationTest.class, ASTVariableDeclaratorIdTest.class, AccessNodeTest.class, - ClassDeclTest.class, FieldDeclTest.class, MethodDeclTest.class, SimpleNodeTest.class }) -public class ASTTests { - -} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTThrowStatementTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTThrowStatementTest.java index 04a05d1b3a..c31912118a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTThrowStatementTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTThrowStatementTest.java @@ -4,35 +4,30 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import org.junit.Test; -import net.sourceforge.pmd.PMD; - /** - * Created on Jan 19, 2005 + * Created on Jan 19, 2005 * @author mgriffa */ -public class ASTThrowStatementTest { +public class ASTThrowStatementTest extends BaseParserTest { @Test public final void testGetFirstASTNameImageNull() { - ASTThrowStatement t = getNodes(ASTThrowStatement.class, NULL_NAME).iterator().next(); + ASTThrowStatement t = java.getNodes(ASTThrowStatement.class, NULL_NAME).get(0); assertNull(t.getFirstClassOrInterfaceTypeImage()); } @Test public final void testGetFirstASTNameImageNew() { - ASTThrowStatement t = getNodes(ASTThrowStatement.class, OK_NAME).iterator().next(); + ASTThrowStatement t = java.getNodes(ASTThrowStatement.class, OK_NAME).get(0); assertEquals("FooException", t.getFirstClassOrInterfaceTypeImage()); } - private static final String NULL_NAME = "public class Test {" + PMD.EOL + " void bar() {" + PMD.EOL + " throw e;" - + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String NULL_NAME = "public class Test {\n void bar() {\n throw e;\n }\n}"; - private static final String OK_NAME = "public class Test {" + PMD.EOL + " void bar() {" + PMD.EOL - + " throw new FooException();" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String OK_NAME = "public class Test {\n void bar() {\n throw new FooException();\n }\n}"; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorIdTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorIdTest.java index 64e8450015..d0230b626b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorIdTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorIdTest.java @@ -4,31 +4,25 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava18; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import org.junit.Test; -import net.sourceforge.pmd.PMD; - -public class ASTVariableDeclaratorIdTest { - - +public class ASTVariableDeclaratorIdTest extends BaseParserTest { @Test public void testIsExceptionBlockParameter() { - ASTCompilationUnit acu = getNodes(ASTCompilationUnit.class, EXCEPTION_PARAMETER).iterator().next(); + ASTCompilationUnit acu = java.parse(EXCEPTION_PARAMETER); ASTVariableDeclaratorId id = acu.getFirstDescendantOfType(ASTVariableDeclaratorId.class); assertTrue(id.isExceptionBlockParameter()); } @Test public void testTypeNameNode() { - ASTCompilationUnit acu = getNodes(ASTCompilationUnit.class, TYPE_NAME_NODE).iterator().next(); + ASTCompilationUnit acu = java.parse(TYPE_NAME_NODE); ASTVariableDeclaratorId id = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0); ASTClassOrInterfaceType name = (ASTClassOrInterfaceType) id.getTypeNameNode(); @@ -37,7 +31,7 @@ public class ASTVariableDeclaratorIdTest { @Test public void testAnnotations() { - ASTCompilationUnit acu = getNodes(ASTCompilationUnit.class, TEST_ANNOTATIONS).iterator().next(); + ASTCompilationUnit acu = java.parse(TEST_ANNOTATIONS); ASTVariableDeclaratorId id = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0); ASTClassOrInterfaceType name = (ASTClassOrInterfaceType) id.getTypeNode(); @@ -46,7 +40,7 @@ public class ASTVariableDeclaratorIdTest { @Test public void testLambdaWithType() throws Exception { - ASTCompilationUnit acu = parseJava18(TEST_LAMBDA_WITH_TYPE); + ASTCompilationUnit acu = java8.parse(TEST_LAMBDA_WITH_TYPE); ASTLambdaExpression lambda = acu.getFirstDescendantOfType(ASTLambdaExpression.class); ASTVariableDeclaratorId f = lambda.getFirstDescendantOfType(ASTVariableDeclaratorId.class); assertEquals("File", f.getTypeNode().getTypeImage()); @@ -54,21 +48,19 @@ public class ASTVariableDeclaratorIdTest { @Test public void testLambdaWithoutType() throws Exception { - ASTCompilationUnit acu = parseJava18(TEST_LAMBDA_WITHOUT_TYPE); + ASTCompilationUnit acu = java8.parse(TEST_LAMBDA_WITHOUT_TYPE); ASTLambdaExpression lambda = acu.getFirstDescendantOfType(ASTLambdaExpression.class); ASTVariableDeclaratorId f = lambda.getFirstDescendantOfType(ASTVariableDeclaratorId.class); assertNull(f.getTypeNode()); } - private static final String TYPE_NAME_NODE = "public class Test {" + PMD.EOL + " private String bar;" + PMD.EOL - + "}"; + private static final String TYPE_NAME_NODE = "public class Test {\n private String bar;\n}"; private static final String EXCEPTION_PARAMETER = "public class Test { { try {} catch(Exception ie) {} } }"; - private static final String TEST_ANNOTATIONS = "public class Foo {" + PMD.EOL - + " public void bar(@A1 @A2 String s) {}" + PMD.EOL + "}"; - private static final String TEST_LAMBDA_WITH_TYPE = "public class Foo {\n" + " public void bar() {\n" - + " FileFilter java = (File f) -> f.getName().endsWith(\".java\");\n" + " }\n" + "}\n"; - private static final String TEST_LAMBDA_WITHOUT_TYPE = "public class Foo {\n" + " public void bar() {\n" - + " FileFilter java2 = f -> f.getName().endsWith(\".java\");\n" + " }\n" + "}\n"; + private static final String TEST_ANNOTATIONS = "public class Foo {\n public void bar(@A1 @A2 String s) {}\n}"; + private static final String TEST_LAMBDA_WITH_TYPE = + "public class Foo {\n public void bar() {\n FileFilter java = (File f) -> f.getName().endsWith(\".java\");\n }\n}\n"; + private static final String TEST_LAMBDA_WITHOUT_TYPE = + "public class Foo {\n public void bar() {\n FileFilter java2 = f -> f.getName().endsWith(\".java\");\n }\n}\n"; public static junit.framework.Test suite() { return new junit.framework.JUnit4TestAdapter(ASTVariableDeclaratorIdTest.class); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AccessNodeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AccessNodeTest.java index 93e8657730..e430036fbf 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AccessNodeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AccessNodeTest.java @@ -4,15 +4,18 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.Set; +import java.util.List; import org.junit.Test; -public class AccessNodeTest { +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; + +public class AccessNodeTest extends BaseParserTest { public static class MyAccessNode extends AbstractJavaAccessNode { public MyAccessNode(int i) { @@ -37,8 +40,8 @@ public class AccessNodeTest { @Test public void testModifiersOnClassDecl() { - Set ops = getNodes(ASTClassOrInterfaceDeclaration.class, TEST1); - assertTrue(ops.iterator().next().isPublic()); + List ops = java.getNodes(ASTClassOrInterfaceDeclaration.class, TEST1); + assertTrue(ops.get(0).isPublic()); } private static final String TEST1 = "public class Foo {}"; @@ -144,4 +147,24 @@ public class AccessNodeTest { InternalApiBridge.setModifier(node, AccessNode.PROTECTED); assertFalse("Node set to protected, still package private.", node.isPackagePrivate()); } + + + private static String makeAccessJavaCode(String[] access, String declRest) { + String result = "public class Test { "; + for (String s : access) { + result += s + " "; + } + return result + " " + declRest + " }"; + } + + + public static T getDeclWithModifiers(String[] access, Class target, String declRest) { + ASTCompilationUnit acu = JavaParsingHelper.JUST_PARSE.parse(makeAccessJavaCode(access, declRest)); + + List declarations = acu.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class) + .findDescendantsOfType(target); + + assertEquals("Wrong number of declarations", 1, declarations.size()); + return declarations.get(0); + } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/BaseParserTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/BaseParserTest.java new file mode 100644 index 0000000000..3901cd87b0 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/BaseParserTest.java @@ -0,0 +1,31 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast; + +import java.util.List; + +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; + +/** + * Base class for tests that usually need processing stages to run when + * parsing code. + */ +public abstract class BaseParserTest { + + protected final JavaParsingHelper java = JavaParsingHelper.JUST_PARSE.withResourceContext(getClass()); + protected final JavaParsingHelper java5 = java.withDefaultVersion("1.5"); + protected final JavaParsingHelper java8 = java.withDefaultVersion("1.8"); + protected final JavaParsingHelper java9 = java.withDefaultVersion("9"); + + + protected ASTCompilationUnit parseCode(final String code) { + return java.parse(code); + } + + protected List getNodes(Class target, String code) { + return JavaParsingHelper.WITH_PROCESSING.getNodes(target, code); + } +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ClassDeclTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ClassDeclTest.java index 0201a71c55..518a977497 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ClassDeclTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ClassDeclTest.java @@ -4,18 +4,15 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; import static org.junit.Assert.assertEquals; -import java.util.Set; - import org.junit.Test; -public class ClassDeclTest { +public class ClassDeclTest extends BaseParserTest { @Test public void testPublic() { - String[] access = { "public" }; + String[] access = {"public"}; ASTClassOrInterfaceDeclaration acd = getClassDecl(access); verifyFlags(acd, true, false, false, false); } @@ -57,17 +54,6 @@ public class ClassDeclTest { } public ASTClassOrInterfaceDeclaration getClassDecl(String[] access) { - String javaCode = ""; - - for (int i = 0; i < access.length; i++) { - javaCode += access[i] + " "; - } - - javaCode += " class Test { } "; - - Set classes = getNodes(ASTClassOrInterfaceDeclaration.class, javaCode); - - assertEquals("Wrong number of classes", 1, classes.size()); - return classes.iterator().next(); + return AccessNodeTest.getDeclWithModifiers(access, ASTClassOrInterfaceDeclaration.class, "class Test {}"); } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/EncodingTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/EncodingTest.java index e005e1a866..bc4ced4c2a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/EncodingTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/EncodingTest.java @@ -4,22 +4,18 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava14; import static org.junit.Assert.assertEquals; import org.junit.Test; -import net.sourceforge.pmd.PMD; - -public class EncodingTest { +public class EncodingTest extends BaseParserTest { @Test - public void testDecodingOfUTF8() throws Exception { - ASTCompilationUnit acu = parseJava14(TEST_UTF8); + public void testDecodingOfUTF8() { + ASTCompilationUnit acu = java.parse(TEST_UTF8); String methodName = acu.getFirstDescendantOfType(ASTMethodDeclaration.class).getImage(); assertEquals("é", methodName); } - private static final String TEST_UTF8 = "class Foo {" + PMD.EOL + " void é() {}" + PMD.EOL + " void fiddle() {}" - + PMD.EOL + "}"; + private static final String TEST_UTF8 = "class Foo {\n void é() {}\n void fiddle() {}\n}"; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/FieldDeclTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/FieldDeclTest.java index 38dfeb6670..c229b53690 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/FieldDeclTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/FieldDeclTest.java @@ -4,31 +4,19 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; -import static org.junit.Assert.assertEquals; +import static net.sourceforge.pmd.lang.java.ast.AccessNodeTest.getDeclWithModifiers; import static org.junit.Assert.assertTrue; -import java.util.Set; - import org.junit.Test; -public class FieldDeclTest { +public class FieldDeclTest extends BaseParserTest { - public String makeAccessJavaCode(String[] access) { - String result = "public class Test { "; - for (int i = 0; i < access.length; i++) { - result += access[i] + " "; - } - return result + " int j; }"; - } public ASTFieldDeclaration getFieldDecl(String[] access) { - Set fields = getNodes(ASTFieldDeclaration.class, makeAccessJavaCode(access)); - - assertEquals("Wrong number of fields", 1, fields.size()); - return fields.iterator().next(); + return getDeclWithModifiers(access, ASTFieldDeclaration.class, "int j;"); } + @Test public void testPublic() { String[] access = { "public" }; diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JDKVersionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JDKVersionTest.java index 2f39c71b1e..97fda69133 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JDKVersionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JDKVersionTest.java @@ -4,283 +4,277 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava13; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava14; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava15; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava17; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava18; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava9; 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.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Test; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; + public class JDKVersionTest { - private static String loadSource(String name) { - try { - return IOUtils.toString(JDKVersionTest.class.getResourceAsStream("jdkversiontests/" + name), - StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + private final JavaParsingHelper java3 = JavaParsingHelper.JUST_PARSE + .withDefaultVersion("1.3") + .withResourceContext(JDKVersionTest.class, "jdkversiontests/"); + + private final JavaParsingHelper java4 = java3.withDefaultVersion("1.4"); + private final JavaParsingHelper java5 = java3.withDefaultVersion("1.5"); + private final JavaParsingHelper java7 = java3.withDefaultVersion("1.7"); + private final JavaParsingHelper java8 = java3.withDefaultVersion("1.8"); + private final JavaParsingHelper java9 = java3.withDefaultVersion("9"); // enum keyword/identifier @Test(expected = ParseException.class) public void testEnumAsKeywordShouldFailWith14() { - parseJava15(loadSource("jdk14_enum.java")); + java5.parseResource("jdk14_enum.java"); } @Test public void testEnumAsIdentifierShouldPassWith14() { - parseJava14(loadSource("jdk14_enum.java")); + java4.parseResource("jdk14_enum.java"); } @Test public void testEnumAsKeywordShouldPassWith15() { - parseJava15(loadSource("jdk15_enum.java")); + java5.parseResource("jdk15_enum.java"); } @Test(expected = ParseException.class) public void testEnumAsIdentifierShouldFailWith15() { - parseJava15(loadSource("jdk14_enum.java")); + java5.parseResource("jdk14_enum.java"); } // enum keyword/identifier // assert keyword/identifier @Test public void testAssertAsKeywordVariantsSucceedWith14() { - parseJava14(loadSource("assert_test1.java")); - parseJava14(loadSource("assert_test2.java")); - parseJava14(loadSource("assert_test3.java")); - parseJava14(loadSource("assert_test4.java")); + java4.parseResource("assert_test1.java"); + java4.parseResource("assert_test2.java"); + java4.parseResource("assert_test3.java"); + java4.parseResource("assert_test4.java"); } @Test(expected = ParseException.class) public void testAssertAsVariableDeclIdentifierFailsWith14() { - parseJava14(loadSource("assert_test5.java")); + java4.parseResource("assert_test5.java"); } @Test(expected = ParseException.class) public void testAssertAsMethodNameIdentifierFailsWith14() { - parseJava14(loadSource("assert_test7.java")); + java4.parseResource("assert_test7.java"); } @Test public void testAssertAsIdentifierSucceedsWith13() { - parseJava13(loadSource("assert_test5.java")); + java3.parseResource("assert_test5.java"); } @Test(expected = ParseException.class) public void testAssertAsKeywordFailsWith13() { - parseJava13(loadSource("assert_test6.java")); + java3.parseResource("assert_test6.java"); } // assert keyword/identifier @Test public void testVarargsShouldPassWith15() { - parseJava15(loadSource("jdk15_varargs.java")); + java5.parseResource("jdk15_varargs.java"); } @Test(expected = ParseException.class) public void testVarargsShouldFailWith14() { - parseJava14(loadSource("jdk15_varargs.java")); + java4.parseResource("jdk15_varargs.java"); } @Test public void testJDK15ForLoopSyntaxShouldPassWith15() { - parseJava15(loadSource("jdk15_forloop.java")); + java5.parseResource("jdk15_forloop.java"); } @Test public void testJDK15ForLoopSyntaxWithModifiers() { - parseJava15(loadSource("jdk15_forloop_with_modifier.java")); + java5.parseResource("jdk15_forloop_with_modifier.java"); } @Test(expected = ParseException.class) public void testJDK15ForLoopShouldFailWith14() { - parseJava14(loadSource("jdk15_forloop.java")); + java4.parseResource("jdk15_forloop.java"); } @Test public void testJDK15GenericsSyntaxShouldPassWith15() { - parseJava15(loadSource("jdk15_generics.java")); + java5.parseResource("jdk15_generics.java"); } @Test public void testVariousParserBugs() { - parseJava15(loadSource("fields_bug.java")); - parseJava15(loadSource("gt_bug.java")); - parseJava15(loadSource("annotations_bug.java")); - parseJava15(loadSource("constant_field_in_annotation_bug.java")); - parseJava15(loadSource("generic_in_field.java")); + java5.parseResource("fields_bug.java"); + java5.parseResource("gt_bug.java"); + java5.parseResource("annotations_bug.java"); + java5.parseResource("constant_field_in_annotation_bug.java"); + java5.parseResource("generic_in_field.java"); } @Test public void testNestedClassInMethodBug() { - parseJava15(loadSource("inner_bug.java")); - parseJava15(loadSource("inner_bug2.java")); + java5.parseResource("inner_bug.java"); + java5.parseResource("inner_bug2.java"); } @Test public void testGenericsInMethodCall() { - parseJava15(loadSource("generic_in_method_call.java")); + java5.parseResource("generic_in_method_call.java"); } @Test public void testGenericINAnnotation() { - parseJava15(loadSource("generic_in_annotation.java")); + java5.parseResource("generic_in_annotation.java"); } @Test public void testGenericReturnType() { - parseJava15(loadSource("generic_return_type.java")); + java5.parseResource("generic_return_type.java"); } @Test public void testMultipleGenerics() { // See java/lang/concurrent/CopyOnWriteArraySet - parseJava15(loadSource("funky_generics.java")); + java5.parseResource("funky_generics.java"); // See java/lang/concurrent/ConcurrentHashMap - parseJava15(loadSource("multiple_generics.java")); + java5.parseResource("multiple_generics.java"); } @Test public void testAnnotatedParams() { - parseJava15(loadSource("annotated_params.java")); + java5.parseResource("annotated_params.java"); } @Test public void testAnnotatedLocals() { - parseJava15(loadSource("annotated_locals.java")); + java5.parseResource("annotated_locals.java"); } @Test public void testAssertAsIdentifierSucceedsWith13Test2() { - parseJava13(loadSource("assert_test5_a.java")); + java3.parseResource("assert_test5_a.java"); } @Test public final void testBinaryAndUnderscoresInNumericalLiterals() { - parseJava17(loadSource("jdk17_numerical_literals.java")); + java7.parseResource("jdk17_numerical_literals.java"); } @Test public final void testStringInSwitch() { - parseJava17(loadSource("jdk17_string_in_switch.java")); + java7.parseResource("jdk17_string_in_switch.java"); } @Test public final void testGenericDiamond() { - parseJava17(loadSource("jdk17_generic_diamond.java")); + java7.parseResource("jdk17_generic_diamond.java"); } @Test public final void testTryWithResources() { - parseJava17(loadSource("jdk17_try_with_resources.java")); + java7.parseResource("jdk17_try_with_resources.java"); } @Test public final void testTryWithResourcesSemi() { - parseJava17(loadSource("jdk17_try_with_resources_semi.java")); + java7.parseResource("jdk17_try_with_resources_semi.java"); } @Test public final void testTryWithResourcesMulti() { - parseJava17(loadSource("jdk17_try_with_resources_multi.java")); + java7.parseResource("jdk17_try_with_resources_multi.java"); } @Test public final void testTryWithResourcesWithAnnotations() { - parseJava17(loadSource("jdk17_try_with_resources_with_annotations.java")); + java7.parseResource("jdk17_try_with_resources_with_annotations.java"); } @Test public final void testMulticatch() { - parseJava17(loadSource("jdk17_multicatch.java")); + java7.parseResource("jdk17_multicatch.java"); } @Test public final void testMulticatchWithAnnotations() { - parseJava17(loadSource("jdk17_multicatch_with_annotations.java")); + java7.parseResource("jdk17_multicatch_with_annotations.java"); } @Test(expected = ParseException.class) public final void jdk9PrivateInterfaceMethodsInJava18() { - parseJava18(loadSource("jdk9_private_interface_methods.java")); + java8.parseResource("jdk9_private_interface_methods.java"); } @Test public final void testPrivateMethods() { - parseJava18("public class Foo { private void bar() { } }"); + java8.parse("public class Foo { private void bar() { } }"); } @Test public final void testNestedPrivateMethods() { - parseJava18("public interface Baz { public static class Foo { private void bar() { } } }"); + java8.parse("public interface Baz { public static class Foo { private void bar() { } } }"); } @Test public final void jdk9PrivateInterfaceMethods() { - parseJava9(loadSource("jdk9_private_interface_methods.java")); + java9.parseResource("jdk9_private_interface_methods.java"); } @Test public final void jdk9InvalidIdentifierInJava18() { - parseJava18(loadSource("jdk9_invalid_identifier.java")); + java8.parseResource("jdk9_invalid_identifier.java"); } @Test(expected = ParseException.class) public final void jdk9InvalidIdentifier() { - parseJava9(loadSource("jdk9_invalid_identifier.java")); + java9.parseResource("jdk9_invalid_identifier.java"); } @Test(expected = ParseException.class) public final void jdk9AnonymousDiamondInJava8() { - parseJava18(loadSource("jdk9_anonymous_diamond.java")); + java8.parseResource("jdk9_anonymous_diamond.java"); } @Test public final void jdk9AnonymousDiamond() { - parseJava9(loadSource("jdk9_anonymous_diamond.java")); + java9.parseResource("jdk9_anonymous_diamond.java"); } @Test(expected = ParseException.class) public final void jdk9ModuleInfoInJava8() { - parseJava18(loadSource("jdk9_module_info.java")); + java8.parseResource("jdk9_module_info.java"); } @Test public final void jdk9ModuleInfo() { - parseJava9(loadSource("jdk9_module_info.java")); + java9.parseResource("jdk9_module_info.java"); } @Test public void testAnnotatedModule() { - parseJava9(loadSource("jdk9_module_info_with_annot.java")); + java9.parseResource("jdk9_module_info_with_annot.java"); } @Test(expected = ParseException.class) public final void jdk9TryWithResourcesInJava8() { - parseJava18(loadSource("jdk9_try_with_resources.java")); + java8.parseResource("jdk9_try_with_resources.java"); } @Test public final void jdk9TryWithResources() { - parseJava9(loadSource("jdk9_try_with_resources.java")); + java9.parseResource("jdk9_try_with_resources.java"); } @Test public final void jdk7PrivateMethodInnerClassInterface1() { - ASTCompilationUnit acu = parseJava17(loadSource("private_method_in_inner_class_interface1.java")); + ASTCompilationUnit acu = java7.parseResource("private_method_in_inner_class_interface1.java"); List methods = acu.findDescendantsOfType(ASTMethodDeclaration.class, true); assertEquals(3, methods.size()); for (ASTMethodDeclaration method : methods) { @@ -291,7 +285,7 @@ public class JDKVersionTest { @Test public final void jdk7PrivateMethodInnerClassInterface2() { try { - ASTCompilationUnit acu = parseJava17(loadSource("private_method_in_inner_class_interface2.java")); + ASTCompilationUnit acu = java7.parseResource("private_method_in_inner_class_interface2.java"); fail("Expected exception"); } catch (ParseException e) { assertTrue(e.getMessage().startsWith("Line 19")); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java10Test.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java10Test.java index 0632d5153d..b703fbb9ff 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java10Test.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java10Test.java @@ -10,17 +10,13 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.io.FileInputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; -import net.sourceforge.pmd.lang.java.ParserTstUtil; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition; /** @@ -29,22 +25,18 @@ import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefin @Ignore("These tests are failing because type resolution has not been updated") public class Java10Test { - private static String loadSource(String name) { - try { - return IOUtils.toString(Java10Test.class.getResourceAsStream("jdkversiontests/java10/" + name), - StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + private final JavaParsingHelper java10 = + JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("10") + .withResourceContext(Java10Test.class, "jdkversiontests/java10/"); + + private final JavaParsingHelper java9 = java10.withDefaultVersion("9"); @Test public void testLocalVarInferenceBeforeJava10() { // note, it can be parsed, but we'll have a ReferenceType of "var" - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("9", - loadSource("LocalVariableTypeInference.java")); - List localVars = compilationUnit.findDescendantsOfType(ASTLocalVariableDeclaration.class); + List localVars = java9.parseResource("LocalVariableTypeInference.java") + .findDescendantsOfType(ASTLocalVariableDeclaration.class); assertEquals(3, localVars.size()); // first: var list = new ArrayList(); @@ -64,8 +56,7 @@ public class Java10Test { @Test public void testLocalVarInferenceCanBeParsedJava10() { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("10", - loadSource("LocalVariableTypeInference.java")); + ASTCompilationUnit compilationUnit = java10.parseResource("LocalVariableTypeInference.java"); List localVars = compilationUnit.findDescendantsOfType(ASTLocalVariableDeclaration.class); assertEquals(3, localVars.size()); @@ -97,9 +88,8 @@ public class Java10Test { @Test public void testForLoopWithVar() { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("10", - loadSource("LocalVariableTypeInferenceForLoop.java")); - List localVars = compilationUnit.findDescendantsOfType(ASTLocalVariableDeclaration.class); + List localVars = java10.parseResource("LocalVariableTypeInferenceForLoop.java") + .findDescendantsOfType(ASTLocalVariableDeclaration.class); assertEquals(1, localVars.size()); assertNull(localVars.get(0).getTypeNode()); @@ -109,9 +99,8 @@ public class Java10Test { @Test public void testForLoopEnhancedWithVar() { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("10", - loadSource("LocalVariableTypeInferenceForLoopEnhanced.java")); - List localVars = compilationUnit.findDescendantsOfType(ASTLocalVariableDeclaration.class); + List localVars = java10.parseResource("LocalVariableTypeInferenceForLoopEnhanced.java") + .findDescendantsOfType(ASTLocalVariableDeclaration.class); assertEquals(1, localVars.size()); assertNull(localVars.get(0).getTypeNode()); @@ -121,9 +110,8 @@ public class Java10Test { @Test public void testForLoopEnhancedWithVar2() { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("10", - loadSource("LocalVariableTypeInferenceForLoopEnhanced2.java")); - List localVars = compilationUnit.findDescendantsOfType(ASTLocalVariableDeclaration.class); + List localVars = java10.parseResource("LocalVariableTypeInferenceForLoopEnhanced2.java") + .findDescendantsOfType(ASTLocalVariableDeclaration.class); assertEquals(4, localVars.size()); assertNull(localVars.get(1).getTypeNode()); @@ -139,9 +127,8 @@ public class Java10Test { @Test public void testTryWithResourcesWithVar() { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("10", - loadSource("LocalVariableTypeInferenceTryWithResources.java")); - List resources = compilationUnit.findDescendantsOfType(ASTResource.class); + List resources = java10.parseResource("LocalVariableTypeInferenceTryWithResources.java") + .findDescendantsOfType(ASTResource.class); assertEquals(1, resources.size()); assertNull(resources.get(0).asLocalVariableDeclaration().getTypeNode()); @@ -151,33 +138,7 @@ public class Java10Test { @Test public void testTypeResNullPointer() { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("10", - loadSource("LocalVariableTypeInference_typeres.java")); - Assert.assertNotNull(compilationUnit); + java10.parseResource("LocalVariableTypeInference_typeres.java"); } - @Test - public void testVarAsIdentifier() { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("10", - loadSource("LocalVariableTypeInference_varAsIdentifier.java")); - Assert.assertNotNull(compilationUnit); - } - - @Test(expected = ParseException.class) - public void testVarAsTypeIdentifier() { - ParserTstUtil.parseAndTypeResolveJava("10", - loadSource("LocalVariableTypeInference_varAsTypeIdentifier.java")); - } - - @Test(expected = ParseException.class) - public void testVarAsAnnotationName() { - ParserTstUtil.parseAndTypeResolveJava("10", - loadSource("LocalVariableTypeInference_varAsAnnotationName.java")); - } - - @Test(expected = ParseException.class) - public void testVarAsEnumName() { - ParserTstUtil.parseAndTypeResolveJava("10", - loadSource("LocalVariableTypeInference_varAsEnumName.java")); - } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java12Test.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java12Test.java index 224d23fdbf..9fb90cec9f 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java12Test.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java12Test.java @@ -4,38 +4,32 @@ package net.sourceforge.pmd.lang.java.ast; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; import net.sourceforge.pmd.lang.ast.ParseException; -import net.sourceforge.pmd.lang.java.ParserTstUtil; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; @Ignore("those tests depend on type resolution") public class Java12Test { - private static String loadSource(String name) { - try { - return IOUtils.toString(Java12Test.class.getResourceAsStream("jdkversiontests/java12/" + name), - StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + + + private final JavaParsingHelper java11 = + JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("11") + .withResourceContext(Java12Test.class, "jdkversiontests/java12/"); + + private final JavaParsingHelper java12p = java11.withDefaultVersion("12-preview"); + @Test(expected = ParseException.class) public void testMultipleCaseLabelsJava11() { - ParserTstUtil.parseAndTypeResolveJava("11", loadSource("MultipleCaseLabels.java")); + java11.parseResource("MultipleCaseLabels.java"); } @Test public void testMultipleCaseLabels() { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("12-preview", - loadSource("MultipleCaseLabels.java")); - Assert.assertNotNull(compilationUnit); + ASTCompilationUnit compilationUnit = java12p.parseResource("MultipleCaseLabels.java"); ASTSwitchStatement switchStatement = compilationUnit.getFirstDescendantOfType(ASTSwitchStatement.class); Assert.assertTrue(switchStatement.jjtGetChild(0) instanceof ASTExpression); Assert.assertTrue(switchStatement.jjtGetChild(1) instanceof ASTSwitchLabel); @@ -45,14 +39,12 @@ public class Java12Test { @Test(expected = ParseException.class) public void testSwitchRulesJava11() { - ParserTstUtil.parseAndTypeResolveJava("11", loadSource("SwitchRules.java")); + java11.parseResource("SwitchRules.java"); } @Test public void testSwitchRules() { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("12-preview", - loadSource("SwitchRules.java")); - Assert.assertNotNull(compilationUnit); + ASTCompilationUnit compilationUnit = java12p.parseResource("SwitchRules.java"); ASTSwitchStatement switchStatement = compilationUnit.getFirstDescendantOfType(ASTSwitchStatement.class); Assert.assertTrue(switchStatement.jjtGetChild(0) instanceof ASTExpression); Assert.assertTrue(switchStatement.jjtGetChild(1) instanceof ASTSwitchLabeledExpression); @@ -74,14 +66,12 @@ public class Java12Test { @Test(expected = ParseException.class) public void testSwitchExpressionsJava11() { - ParserTstUtil.parseAndTypeResolveJava("11", loadSource("SwitchExpressions.java")); + java11.parseResource("SwitchExpressions.java"); } @Test public void testSwitchExpressions() { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("12-preview", - loadSource("SwitchExpressions.java")); - Assert.assertNotNull(compilationUnit); + ASTCompilationUnit compilationUnit = java12p.parseResource("SwitchExpressions.java"); ASTSwitchExpression switchExpression = compilationUnit.getFirstDescendantOfType(ASTSwitchExpression.class); Assert.assertEquals(6, switchExpression.jjtGetNumChildren()); @@ -96,9 +86,7 @@ public class Java12Test { @Test public void testSwitchExpressionsBreak() { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("12-preview", - loadSource("SwitchExpressionsBreak.java")); - Assert.assertNotNull(compilationUnit); + ASTCompilationUnit compilationUnit = java12p.parseResource("SwitchExpressionsBreak.java"); ASTSwitchExpression switchExpression = compilationUnit.getFirstDescendantOfType(ASTSwitchExpression.class); Assert.assertEquals(11, switchExpression.jjtGetNumChildren()); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java13Test.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java13Test.java index 359828f482..3783bc14c8 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java13Test.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java13Test.java @@ -4,34 +4,29 @@ package net.sourceforge.pmd.lang.java.ast; -import java.io.IOException; -import java.nio.charset.StandardCharsets; +import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; import net.sourceforge.pmd.lang.ast.ParseException; -import net.sourceforge.pmd.lang.java.ParserTstUtil; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; @Ignore("those tests depend on type resolution") public class Java13Test { - private static String loadSource(String name) { - try { - return IOUtils.toString(Java13Test.class.getResourceAsStream("jdkversiontests/java13/" + name), - StandardCharsets.UTF_8) - .replaceAll("\\R", "\n"); // normalize line separators to \n - } catch (IOException e) { - throw new RuntimeException(e); - } - } + + + private final JavaParsingHelper java12 = + JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("12") + .withResourceContext(Java13Test.class, "jdkversiontests/java13/"); + + private final JavaParsingHelper java13p = java12.withDefaultVersion("13-preview"); + @Test public void testSwitchExpressions() { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("13-preview", - loadSource("SwitchExpressions.java")); - Assert.assertNotNull(compilationUnit); + ASTCompilationUnit compilationUnit = java13p.parseResource("SwitchExpressions.java"); ASTSwitchExpression switchExpression = compilationUnit.getFirstDescendantOfType(ASTSwitchExpression.class); Assert.assertEquals(4, switchExpression.jjtGetNumChildren()); @@ -45,9 +40,7 @@ public class Java13Test { @Test public void testSwitchExpressionsYield() { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("13-preview", - loadSource("SwitchExpressionsYield.java")); - Assert.assertNotNull(compilationUnit); + ASTCompilationUnit compilationUnit = java13p.parseResource("SwitchExpressionsYield.java"); ASTSwitchExpression switchExpression = compilationUnit.getFirstDescendantOfType(ASTSwitchExpression.class); Assert.assertEquals(11, switchExpression.jjtGetNumChildren()); @@ -68,8 +61,33 @@ public class Java13Test { @Test(expected = ParseException.class) public void testSwitchExpressionsBeforeJava13() { - ParserTstUtil.parseAndTypeResolveJava("12", loadSource("SwitchExpressions.java")); + java12.parseResource("SwitchExpressions.java"); } + @Test + public void testTextBlocks() { + ASTCompilationUnit compilationUnit = java13p.parseResource("TextBlocks.java"); + List literals = compilationUnit.findDescendantsOfType(ASTStringLiteral.class); + Assert.assertEquals(10, literals.size()); + for (int i = 0; i < 8; i++) { + ASTStringLiteral literal = literals.get(i); + Assert.assertTrue(literal.isTextBlock()); + } + Assert.assertEquals("\"\"\"\n" + + " \n" + + " \n" + + "

Hello, world

\n" + + " \n" + + " \n" + + " \"\"\"", + literals.get(0).getImage()); + Assert.assertFalse(literals.get(8).isTextBlock()); + Assert.assertTrue(literals.get(9).isTextBlock()); + } + + @Test(expected = ParseException.class) + public void testTextBlocksBeforeJava13() { + java12.parseResource("TextBlocks.java"); + } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java8Test.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java8Test.java index 42af570ec6..2ef6717ffd 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java8Test.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java8Test.java @@ -6,18 +6,22 @@ package net.sourceforge.pmd.lang.java.ast; import org.junit.Test; -import net.sourceforge.pmd.lang.java.ParserTstUtil; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.typeresolution.testdata.java8.UsesJavaStreams; import net.sourceforge.pmd.typeresolution.testdata.java8.UsesRepeatableAnnotations; public class Java8Test { + private final JavaParsingHelper java8 = + JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("8") + .withResourceContext(Java8Test.class); + @Test public void interfaceMethodShouldBeParseable() { - ParserTstUtil.parseJava18(UsesJavaStreams.class); + java8.parseClass(UsesJavaStreams.class); } @Test public void repeatableAnnotationsMethodShouldBeParseable() { - ParserTstUtil.parseJava18(UsesRepeatableAnnotations.class); + java8.parseClass(UsesRepeatableAnnotations.class); } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedNameTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedNameTest.java index 04acc6d1ab..b48d0971c9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedNameTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedNameTest.java @@ -16,7 +16,8 @@ import java.util.List; import org.junit.Test; -import net.sourceforge.pmd.lang.java.ParserTstUtil; +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.java.qname.JavaOperationQualifiedName; import net.sourceforge.pmd.lang.java.qname.JavaTypeQualifiedName; import net.sourceforge.pmd.lang.java.qname.QualifiedNameFactory; @@ -27,8 +28,9 @@ import net.sourceforge.pmd.lang.java.qname.QualifiedNameFactory; */ public class JavaQualifiedNameTest { - private List getNodes(Class nodeType, String source) { - return ParserTstUtil.getOrderedNodes(nodeType, source); + + private List getNodes(Class target, String code) { + return JavaParsingHelper.WITH_PROCESSING.getNodes(target, code); } @Test @@ -49,8 +51,7 @@ public class JavaQualifiedNameTest { public void testPackage() { final String TEST = "package foo.bar; class Bzaz{}"; - List nodes = getNodes(ASTClassOrInterfaceDeclaration.class, - TEST); + List nodes = getNodes(ASTClassOrInterfaceDeclaration.class, TEST); for (ASTClassOrInterfaceDeclaration coid : nodes) { JavaTypeQualifiedName qname = coid.getQualifiedName(); assertEquals("foo.bar.Bzaz", qname.toString()); @@ -203,8 +204,7 @@ public class JavaQualifiedNameTest { public void testConstructorOverload() { final String TEST = "package bar; class Bzaz{ public Bzaz(int j) {} public Bzaz(int j, String k){}}"; - List nodes = getNodes(ASTConstructorDeclaration.class, - TEST); + List nodes = getNodes(ASTConstructorDeclaration.class, TEST); ASTConstructorDeclaration[] arr = nodes.toArray(new ASTConstructorDeclaration[2]); assertNotEquals(arr[0].getQualifiedName(), arr[1].getQualifiedName()); @@ -343,7 +343,7 @@ public class JavaQualifiedNameTest { final String TEST = "package bar; class Boron { public void foo(String j) { class Local {} } }"; List classes - = ParserTstUtil.getOrderedNodes(ASTClassOrInterfaceDeclaration.class, TEST); + = getNodes(ASTClassOrInterfaceDeclaration.class, TEST); JavaQualifiedName qname = QualifiedNameFactory.ofString("bar.Boron$1Local"); @@ -356,7 +356,7 @@ public class JavaQualifiedNameTest { final String TEST = "package bar; class Bzaz{ void foo() { class Local {} } {// initializer\n class Local {}}}"; List classes - = ParserTstUtil.getOrderedNodes(ASTClassOrInterfaceDeclaration.class, TEST); + = getNodes(ASTClassOrInterfaceDeclaration.class, TEST); assertNotEquals(classes.get(1).getQualifiedName(), classes.get(2).getQualifiedName()); @@ -379,7 +379,7 @@ public class JavaQualifiedNameTest { + "}}"; List classes - = ParserTstUtil.getOrderedNodes(ASTClassOrInterfaceDeclaration.class, TEST); + = getNodes(ASTClassOrInterfaceDeclaration.class, TEST); assertNotEquals(classes.get(1).getQualifiedName(), classes.get(2).getQualifiedName()); @@ -398,7 +398,7 @@ public class JavaQualifiedNameTest { + " };" + "}}"; - List classes = ParserTstUtil.getOrderedNodes(ASTAnonymousClassDeclaration.class, TEST); + List classes = getNodes(ASTAnonymousClassDeclaration.class, TEST); assertEquals(QualifiedNameFactory.ofString("Bzaz$1"), classes.get(0).getQualifiedName()); assertFalse(classes.get(0).getQualifiedName().isLocalClass()); @@ -419,7 +419,7 @@ public class JavaQualifiedNameTest { + " };" + "}}"; - List classes = ParserTstUtil.getOrderedNodes(ASTAnonymousClassDeclaration.class, TEST); + List classes = getNodes(ASTAnonymousClassDeclaration.class, TEST); assertNotEquals(classes.get(0), classes.get(1)); assertEquals(QualifiedNameFactory.ofString("Bzaz$1"), classes.get(0).getQualifiedName()); @@ -440,7 +440,7 @@ public class JavaQualifiedNameTest { + " };" + "}}"; - List classes = ParserTstUtil.getOrderedNodes(ASTAnonymousClassDeclaration.class, TEST); + List classes = getNodes(ASTAnonymousClassDeclaration.class, TEST); assertNotEquals(classes.get(0), classes.get(1)); assertEquals(QualifiedNameFactory.ofString("Bzaz$1"), classes.get(0).getQualifiedName()); @@ -459,7 +459,7 @@ public class JavaQualifiedNameTest { + " };" + "}}"; - List classes = ParserTstUtil.getOrderedNodes(ASTClassOrInterfaceDeclaration.class, TEST); + List classes = getNodes(ASTClassOrInterfaceDeclaration.class, TEST); assertTrue(classes.get(1).isLocal()); assertEquals(QualifiedNameFactory.ofString("Bzaz$1$1FooRunnable"), classes.get(1).getQualifiedName()); @@ -479,7 +479,7 @@ public class JavaQualifiedNameTest { + "}"; - List lambdas = ParserTstUtil.getOrderedNodes(ASTLambdaExpression.class, TEST); + List lambdas = getNodes(ASTLambdaExpression.class, TEST); assertEquals(QualifiedNameFactory.ofString("Bzaz#lambda$static$0"), lambdas.get(0).getQualifiedName()); } @@ -504,7 +504,7 @@ public class JavaQualifiedNameTest { + " }" + "}"; - List lambdas = ParserTstUtil.getOrderedNodes(ASTLambdaExpression.class, TEST); + List lambdas = getNodes(ASTLambdaExpression.class, TEST); assertEquals(QualifiedNameFactory.ofString("Bzaz#lambda$new$0"), lambdas.get(0).getQualifiedName()); assertEquals(QualifiedNameFactory.ofString("Bzaz#lambda$new$1"), lambdas.get(1).getQualifiedName()); @@ -524,7 +524,7 @@ public class JavaQualifiedNameTest { + " };" + "}"; - List lambdas = ParserTstUtil.getOrderedNodes(ASTLambdaExpression.class, TEST); + List lambdas = getNodes(ASTLambdaExpression.class, TEST); assertEquals(QualifiedNameFactory.ofString("Bzaz#lambda$new$0"), lambdas.get(0).getQualifiedName()); assertEquals(QualifiedNameFactory.ofString("Bzaz#lambda$static$1"), lambdas.get(1).getQualifiedName()); @@ -544,7 +544,7 @@ public class JavaQualifiedNameTest { + " };" + "}"; - List lambdas = ParserTstUtil.getOrderedNodes(ASTLambdaExpression.class, TEST); + List lambdas = getNodes(ASTLambdaExpression.class, TEST); assertEquals(QualifiedNameFactory.ofString("Bzaz#lambda$static$0"), lambdas.get(0).getQualifiedName()); assertEquals(QualifiedNameFactory.ofString("Bzaz#lambda$static$1"), lambdas.get(1).getQualifiedName()); @@ -565,7 +565,7 @@ public class JavaQualifiedNameTest { + " }" + "}"; - List lambdas = ParserTstUtil.getOrderedNodes(ASTLambdaExpression.class, TEST); + List lambdas = getNodes(ASTLambdaExpression.class, TEST); assertEquals(QualifiedNameFactory.ofString("Bzaz$1Local#lambda$Local$0"), lambdas.get(0).getQualifiedName()); } @@ -585,7 +585,7 @@ public class JavaQualifiedNameTest { + " }" + "}"; - List lambdas = ParserTstUtil.getOrderedNodes(ASTLambdaExpression.class, TEST); + List lambdas = getNodes(ASTLambdaExpression.class, TEST); assertEquals(QualifiedNameFactory.ofString("Bzaz$1#lambda$$0"), lambdas.get(0).getQualifiedName()); @@ -623,7 +623,7 @@ public class JavaQualifiedNameTest { + " }" + "}"; - List lambdas = ParserTstUtil.getOrderedNodes(ASTLambdaExpression.class, TEST); + List lambdas = getNodes(ASTLambdaExpression.class, TEST); assertEquals(QualifiedNameFactory.ofString("Bzaz#lambda$bar$0"), lambdas.get(0).getQualifiedName()); assertEquals(QualifiedNameFactory.ofString("Bzaz#lambda$fooBar$1"), lambdas.get(1).getQualifiedName()); @@ -662,7 +662,7 @@ public class JavaQualifiedNameTest { + " }" + "}"; - List lambdas = ParserTstUtil.getOrderedNodes(ASTLambdaExpression.class, TEST); + List lambdas = getNodes(ASTLambdaExpression.class, TEST); assertEquals(QualifiedNameFactory.ofString("Bzaz#lambda$static$0"), lambdas.get(0).getQualifiedName()); assertEquals(QualifiedNameFactory.ofString("Bzaz#lambda$new$1"), lambdas.get(1).getQualifiedName()); @@ -686,6 +686,5 @@ public class JavaQualifiedNameTest { assertEquals(qname.getType(), ASTAdditiveExpression.class); } - } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/MethodDeclTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/MethodDeclTest.java index a61f2d8588..99ae118166 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/MethodDeclTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/MethodDeclTest.java @@ -4,12 +4,8 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import java.util.Set; - import org.junit.Test; public class MethodDeclTest { @@ -75,18 +71,7 @@ public class MethodDeclTest { assertTrue("Expecting method to be public.", amd.isPublic()); } - public ASTMethodDeclaration getMethodDecl(String[] access) { - String javaCode = "public class Test { "; - for (int i = 0; i < access.length; i++) { - javaCode += access[i] + " "; - } - - javaCode += " void stuff() { } }"; - - Set methods = getNodes(ASTMethodDeclaration.class, javaCode); - - assertEquals("Wrong number of methods", 1, methods.size()); - - return methods.iterator().next(); + private ASTMethodDeclaration getMethodDecl(String[] access) { + return AccessNodeTest.getDeclWithModifiers(access, ASTMethodDeclaration.class, "void stuff(){}"); } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java index 5d0fa458aa..4a09365788 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java @@ -4,43 +4,45 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava14; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava15; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava17; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava18; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Ignore; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; -import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.lang.java.ParserTstUtil; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.symboltable.NameDeclaration; import net.sourceforge.pmd.lang.symboltable.NameOccurrence; public class ParserCornersTest { + private static final String MULTICATCH = "public class Foo { public void bar() { " + + "try { System.out.println(); } catch (RuntimeException | IOException e) {} } }"; + private final JavaParsingHelper java = JavaParsingHelper.WITH_PROCESSING.withResourceContext(ParserCornersTest.class); + private final JavaParsingHelper java8 = java.withDefaultVersion("1.8"); + private final JavaParsingHelper java4 = java.withDefaultVersion("1.4"); + private final JavaParsingHelper java5 = java.withDefaultVersion("1.5"); + private final JavaParsingHelper java7 = java.withDefaultVersion("1.7"); + @Rule + public ExpectedException expect = ExpectedException.none(); + /** * #1107 PMD 5.0.4 couldn't parse call of parent outer java class method * from inner class. */ @Test public void testInnerOuterClass() { - parseJava17("/**\n" + " * @author azagorulko\n" + " *\n" + " */\n" - + "public class TestInnerClassCallsOuterParent {\n" + "\n" + " public void test() {\n" - + " new Runnable() {\n" + " @Override\n" + " public void run() {\n" - + " TestInnerClassCallsOuterParent.super.toString();\n" + " }\n" - + " };\n" + " }\n" + "}\n"); + java7.parse("/**\n" + " * @author azagorulko\n" + " *\n" + " */\n" + + "public class TestInnerClassCallsOuterParent {\n" + "\n" + " public void test() {\n" + + " new Runnable() {\n" + " @Override\n" + " public void run() {\n" + + " TestInnerClassCallsOuterParent.super.toString();\n" + " }\n" + + " };\n" + " }\n" + "}\n"); } /** @@ -48,7 +50,7 @@ public class ParserCornersTest { */ @Test public void testDiamondUsageJava8() { - parseJava18("public class PMDExceptionTest {\n" + java8.parse("public class PMDExceptionTest {\n" + " private Component makeUI() {\n" + " String[] model = {\"123456\", \"7890\"};\n" + " JComboBox comboBox = new JComboBox<>(model);\n" @@ -72,12 +74,12 @@ public class ParserCornersTest { @Test public final void testGetFirstASTNameImageNull() { - parseJava14(ABSTRACT_METHOD_LEVEL_CLASS_DECL); + java4.parse(ABSTRACT_METHOD_LEVEL_CLASS_DECL); } @Test public final void testCastLookaheadProblem() { - parseJava14(CAST_LOOKAHEAD_PROBLEM); + java4.parse(CAST_LOOKAHEAD_PROBLEM); } /** @@ -86,26 +88,23 @@ public class ParserCornersTest { */ @Test public void testGenericsProblem() { - parseJava15(GENERICS_PROBLEM); - parseJava17(GENERICS_PROBLEM); + java5.parse(GENERICS_PROBLEM); + java7.parse(GENERICS_PROBLEM); } @Test public void testParsersCases15() { - String test15 = readAsString("/net/sourceforge/pmd/ast/ParserCornerCases.java"); - parseJava15(test15); + java5.parseResource("ParserCornerCases.java"); } @Test public void testParsersCases17() { - String test17 = readAsString("/net/sourceforge/pmd/ast/ParserCornerCases17.java"); - parseJava17(test17); + java7.parseResource("ParserCornerCases17.java"); } @Test public void testParsersCases18() throws Exception { - String test18 = readAsString("/net/sourceforge/pmd/ast/ParserCornerCases18.java"); - ASTCompilationUnit cu = parseJava18(test18); + ASTCompilationUnit cu = java8.parseResource("ParserCornerCases18.java"); Assert.assertEquals(9, cu.findChildNodesWithXPath("//FormalParameter").size()); Assert.assertEquals(32, cu.findChildNodesWithXPath("//LambdaParameter").size()); @@ -115,8 +114,7 @@ public class ParserCornersTest { @Test public void testTypeAnnotations() { - String test18 = readAsString("/net/sourceforge/pmd/ast/FullTypeAnnotations.java"); - parseJava18(test18); + java8.parseResource("/net/sourceforge/pmd/ast/FullTypeAnnotations.java"); } /** @@ -124,19 +122,19 @@ public class ParserCornersTest { */ @Test public void testLambdaBug1333() { - parseJava18("final class Bug1333 {\n" - + " private static final Logger LOG = LoggerFactory.getLogger(Foo.class);\n" + "\n" - + " public void deleteDirectoriesByNamePattern() {\n" - + " delete(path -> deleteDirectory(path));\n" + " }\n" + "\n" - + " private void delete(Consumer consumer) {\n" - + " LOG.debug(consumer.toString());\n" + " }\n" + "\n" - + " private void deleteDirectory(String path) {\n" + " LOG.debug(path);\n" + " }\n" + "}"); + java8.parse("final class Bug1333 {\n" + + " private static final Logger LOG = LoggerFactory.getLogger(Foo.class);\n" + "\n" + + " public void deleteDirectoriesByNamePattern() {\n" + + " delete(path -> deleteDirectory(path));\n" + " }\n" + "\n" + + " private void delete(Consumer consumer) {\n" + + " LOG.debug(consumer.toString());\n" + " }\n" + "\n" + + " private void deleteDirectory(String path) {\n" + " LOG.debug(path);\n" + " }\n" + + "}"); } @Test public void testLambdaBug1470() { - String code = readAsString("LambdaBug1470.java"); - parseJava18(code); + java8.parseResource("LambdaBug1470.java"); } /** @@ -144,96 +142,73 @@ public class ParserCornersTest { */ @Test public void emptyFileJustComment() { - parseJava18("// just a comment"); + java8.parse("// just a comment"); } - @Test - public void testMultipleExceptionCatching() { - String code = "public class Foo { public void bar() { " - + "try { System.out.println(); } catch (RuntimeException | IOException e) {} } }"; - try { - parseJava15(code); - fail("Expected exception"); - } catch (ParseException e) { - assertEquals( - "Line 1, Column 70: Composite catch clauses are a feature of Java 1.7, you should select your language version accordingly", - e.getMessage()); - } - try { - parseJava17(code); - // no exception expected - } catch (ParseException e) { - fail(); - } + @Test + public void testMultipleExceptionCatchingJava7() { + java7.parse(MULTICATCH); } @Test public void testBug1429ParseError() { - String c = readAsString("Bug1429.java"); - parseJava18(c); + java8.parseResource("Bug1429.java"); } @Test public void testBug1530ParseError() { - String c = readAsString("Bug1530.java"); - parseJava18(c); + java8.parseResource("Bug1530.java"); } @Test public void testGitHubBug207() { - String c = readAsString("GitHubBug207.java"); - parseJava18(c); + java8.parseResource("GitHubBug207.java"); } @Test - public void testBug206() throws Exception { - String code = "public @interface Foo {" + PMD.EOL - + "static final ThreadLocal> interner =" + PMD.EOL - + " ThreadLocal.withInitial(Interners::newStrongInterner);" + PMD.EOL - + "}"; - parseJava18(code); + public void testBug206() { + java8.parse("public @interface Foo {" + "\n" + + "static final ThreadLocal> interner =" + "\n" + + " ThreadLocal.withInitial(Interners::newStrongInterner);" + "\n" + + "}"); } @Test public void testGitHubBug208ParseError() { - String c = readAsString("GitHubBug208.java"); - parseJava15(c); + java5.parseResource("GitHubBug208.java"); } @Test - public void testGitHubBug257NonExistingCast() throws Exception { - String code = "public class Test {" + PMD.EOL - + " public static void main(String[] args) {" + PMD.EOL - + " double a = 4.0;" + PMD.EOL - + " double b = 2.0;" + PMD.EOL - + " double result = Math.sqrt((a) - b);" + PMD.EOL - + " System.out.println(result);" + PMD.EOL - + " }" + PMD.EOL - + "}"; - ASTCompilationUnit compilationUnit = parseJava15(code); - assertEquals("A cast was found when none expected", 0, compilationUnit.findDescendantsOfType(ASTCastExpression.class).size()); + public void testGitHubBug257NonExistingCast() { + String code = "public class Test {" + "\n" + + " public static void main(String[] args) {" + "\n" + + " double a = 4.0;" + "\n" + + " double b = 2.0;" + "\n" + + " double result = Math.sqrt((a) - b);" + "\n" + + " System.out.println(result);" + "\n" + + " }" + "\n" + + "}"; + + assertEquals("A cast was found when none expected", + 0, + java5.parse(code).findDescendantsOfType(ASTCastExpression.class).size()); } @Test - public void testGitHubBug309() throws Exception { - String code = readAsString("GitHubBug309.java"); - ASTCompilationUnit compilationUnit = parseJava18(code); - assertNotNull(compilationUnit); + public void testGitHubBug309() { + java8.parseResource("GitHubBug309.java"); } /** * This triggered bug #1484 UnusedLocalVariable - false positive - * parenthesis - * - * @throws Exception */ @Test - public void stringConcatentationShouldNotBeCast() throws Exception { + public void stringConcatentationShouldNotBeCast() { String code = "public class Test {\n" + " public static void main(String[] args) {\n" - + " System.out.println(\"X\" + (args) + \"Y\");\n" + " }\n" + "}"; - ASTCompilationUnit cu = parseJava18(code); - Assert.assertEquals(0, cu.findDescendantsOfType(ASTCastExpression.class).size()); + + " System.out.println(\"X\" + (args) + \"Y\");\n" + " }\n" + "}"; + Assert.assertEquals(0, java8.parse(code).findDescendantsOfType(ASTCastExpression.class).size()); } /** @@ -242,28 +217,27 @@ public class ParserCornersTest { * @see github issue 378 */ @Test - public void testParseEmptyStatements() throws Exception { + public void testParseEmptyStatements() { String code = "import a;;import b; public class Foo {}"; - ASTCompilationUnit cu = parseJava18(code); + ASTCompilationUnit cu = java8.parse(code); assertNotNull(cu); Assert.assertEquals(ASTEmptyDeclaration.class, cu.jjtGetChild(1).getClass()); String code2 = "package c;; import a; import b; public class Foo {}"; - ASTCompilationUnit cu2 = parseJava18(code2); + ASTCompilationUnit cu2 = java8.parse(code2); assertNotNull(cu2); Assert.assertEquals(ASTEmptyDeclaration.class, cu2.jjtGetChild(1).getClass()); String code3 = "package c; import a; import b; public class Foo {};"; - ASTCompilationUnit cu3 = parseJava18(code3); + ASTCompilationUnit cu3 = java8.parse(code3); assertNotNull(cu3); Assert.assertEquals(ASTEmptyDeclaration.class, cu3.jjtGetChild(4).getClass()); } @Test @Ignore("this test depends on usage resolution") - public void testMethodReferenceConfused() throws Exception { - String code = readAsString("MethodReferenceConfused.java"); - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("10", code); + public void testMethodReferenceConfused() { + ASTCompilationUnit compilationUnit = java.parseResource("MethodReferenceConfused.java", "10"); Assert.assertNotNull(compilationUnit); ASTBlock firstBlock = compilationUnit.getFirstDescendantOfType(ASTBlock.class); Map> declarations = firstBlock.getScope().getDeclarations(); @@ -282,38 +256,31 @@ public class ParserCornersTest { } @Test - public void testSwitchWithFallthrough() throws Exception { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("11", readAsString("SwitchWithFallthrough.java")); - Assert.assertNotNull(compilationUnit); + public void testSwitchWithFallthrough() { + ASTCompilationUnit compilationUnit = java.parseResource("SwitchWithFallthrough.java", "11"); ASTSwitchStatement switchStatement = compilationUnit.getFirstDescendantOfType(ASTSwitchStatement.class); Assert.assertEquals(2, switchStatement.findChildrenOfType(ASTSwitchLabel.class).size()); } @Test - public void testSwitchStatements() throws Exception { - ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("11", readAsString("SwitchStatements.java")); - Assert.assertNotNull(compilationUnit); + public void testSwitchStatements() { + ASTCompilationUnit compilationUnit = java.parseResource("SwitchStatements.java", "11"); ASTSwitchStatement switchStatement = compilationUnit.getFirstDescendantOfType(ASTSwitchStatement.class); Assert.assertEquals(2, switchStatement.findChildrenOfType(ASTSwitchLabel.class).size()); } - private String readAsString(String resource) { - try (InputStream in = ParserCornersTest.class.getResourceAsStream(resource)) { - return IOUtils.toString(in, StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + private static final String GENERICS_PROBLEM = + "public class Test {\n public void test() {\n String o = super. doStuff(\"\");\n }\n}"; - private static final String GENERICS_PROBLEM = "public class Test {" + PMD.EOL + " public void test() {" + PMD.EOL - + " String o = super. doStuff(\"\");" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String ABSTRACT_METHOD_LEVEL_CLASS_DECL = + "public class Test {\n" + + " void bar() {\n" + + " abstract class X { public abstract void f(); }\n" + + " class Y extends X { public void f() { new Y().f(); } }\n" + + " }\n" + + "}"; - private static final String ABSTRACT_METHOD_LEVEL_CLASS_DECL = "public class Test {" + PMD.EOL + " void bar() {" - + PMD.EOL + " abstract class X { public abstract void f(); }" + PMD.EOL - + " class Y extends X { public void f() {" + PMD.EOL + " new Y().f();" + PMD.EOL + " }}" + PMD.EOL - + " }" + PMD.EOL + "}"; - - private static final String CAST_LOOKAHEAD_PROBLEM = "public class BadClass {" + PMD.EOL + " public Class foo() {" - + PMD.EOL + " return (byte[].class);" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String CAST_LOOKAHEAD_PROBLEM = + "public class BadClass {\n public Class foo() {\n return (byte[].class);\n }\n}"; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/SimpleNodeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/SimpleNodeTest.java index e64386b2eb..4fceaffc47 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/SimpleNodeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/SimpleNodeTest.java @@ -4,83 +4,71 @@ package net.sourceforge.pmd.lang.java.ast; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava14; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import java.util.Iterator; import java.util.List; -import java.util.Set; import org.jaxen.JaxenException; import org.junit.Ignore; import org.junit.Test; -import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; @Ignore("This test is Java specific even though parts of it should apply to any language implementation") // The Java specific parts depend on the grammar and are subject to breaking during the grammar update process // Most of it is just garbage though -public class SimpleNodeTest { +public class SimpleNodeTest extends BaseParserTest { @Test public void testMethodDiffLines() { - Set methods = getNodes(ASTMethodDeclaration.class, METHOD_DIFF_LINES); + List methods = java.getNodes(ASTMethodDeclaration.class, METHOD_DIFF_LINES); verifyNode(methods.iterator().next(), 2, 9, 4, 2); } @Test public void testMethodSameLine() { - Set methods = getNodes(ASTMethodDeclaration.class, METHOD_SAME_LINE); + List methods = java.getNodes(ASTMethodDeclaration.class, METHOD_SAME_LINE); verifyNode(methods.iterator().next(), 2, 9, 2, 21); } @Test public void testNoLookahead() { - String code = NO_LOOKAHEAD; // 1, 8 -> 1, 20 - Set uCD = getNodes(ASTClassOrInterfaceDeclaration.class, code); + List uCD = java.getNodes(ASTClassOrInterfaceDeclaration.class, NO_LOOKAHEAD); verifyNode(uCD.iterator().next(), 1, 8, 1, 20); } @Test public void testHasExplicitExtends() { - String code = HAS_EXPLICIT_EXTENDS; - ASTClassOrInterfaceDeclaration ucd = getNodes(ASTClassOrInterfaceDeclaration.class, code).iterator().next(); + ASTClassOrInterfaceDeclaration ucd = java.getNodes(ASTClassOrInterfaceDeclaration.class, HAS_EXPLICIT_EXTENDS).iterator().next(); assertTrue(ucd.jjtGetChild(0) instanceof ASTExtendsList); } @Test public void testNoExplicitExtends() { - String code = NO_EXPLICIT_EXTENDS; - ASTClassOrInterfaceDeclaration ucd = getNodes(ASTClassOrInterfaceDeclaration.class, code).iterator().next(); + ASTClassOrInterfaceDeclaration ucd = java.getNodes(ASTClassOrInterfaceDeclaration.class, NO_EXPLICIT_EXTENDS).iterator().next(); assertFalse(ucd.jjtGetChild(0) instanceof ASTExtendsList); } @Test public void testHasExplicitImplements() { - String code = HAS_EXPLICIT_IMPLEMENTS; - ASTClassOrInterfaceDeclaration ucd = getNodes(ASTClassOrInterfaceDeclaration.class, code).iterator().next(); + ASTClassOrInterfaceDeclaration ucd = java.getNodes(ASTClassOrInterfaceDeclaration.class, HAS_EXPLICIT_IMPLEMENTS).iterator().next(); assertTrue(ucd.jjtGetChild(0) instanceof ASTImplementsList); } @Test public void testNoExplicitImplements() { - String code = NO_EXPLICIT_IMPLEMENTS; - ASTClassOrInterfaceDeclaration ucd = getNodes(ASTClassOrInterfaceDeclaration.class, code).iterator().next(); + ASTClassOrInterfaceDeclaration ucd = java.getNodes(ASTClassOrInterfaceDeclaration.class, NO_EXPLICIT_IMPLEMENTS).iterator().next(); assertFalse(ucd.jjtGetChild(0) instanceof ASTImplementsList); } @Test public void testColumnsOnQualifiedName() { - Set name = getNodes(ASTName.class, QUALIFIED_NAME); - Iterator i = name.iterator(); - while (i.hasNext()) { - Node node = i.next(); + for (Node node : java.getNodes(ASTName.class, QUALIFIED_NAME)) { if (node.getImage().equals("java.io.File")) { verifyNode(node, 1, 8, 1, 19); } @@ -89,10 +77,7 @@ public class SimpleNodeTest { @Test public void testLineNumbersForNameSplitOverTwoLines() { - Set name = getNodes(ASTName.class, BROKEN_LINE_IN_NAME); - Iterator i = name.iterator(); - while (i.hasNext()) { - Node node = i.next(); + for (Node node : java.getNodes(ASTName.class, BROKEN_LINE_IN_NAME)) { if (node.getImage().equals("java.io.File")) { verifyNode(node, 1, 8, 2, 4); } @@ -101,16 +86,16 @@ public class SimpleNodeTest { } } } - // + // @Test // public void testLineNumbersAreSetOnAllSiblings() { - // for (ASTBlock b : getNodes(ASTBlock.class, LINE_NUMBERS_ON_SIBLINGS)) { + // for (ASTBlock b : java.getNodes(ASTBlock.class, LINE_NUMBERS_ON_SIBLINGS)) { // assertTrue(b.getBeginLine() > 0); // } - // for (ASTVariableInitializer b : getNodes(ASTVariableInitializer.class, LINE_NUMBERS_ON_SIBLINGS)) { + // for (ASTVariableInitializer b : java.getNodes(ASTVariableInitializer.class, LINE_NUMBERS_ON_SIBLINGS)) { // assertTrue(b.getBeginLine() > 0); // } - // for (ASTExpression b : getNodes(ASTExpression.class, LINE_NUMBERS_ON_SIBLINGS)) { + // for (ASTExpression b : java.getNodes(ASTExpression.class, LINE_NUMBERS_ON_SIBLINGS)) { // assertTrue(b.getBeginLine() > 0); // } // } @@ -189,7 +174,7 @@ public class SimpleNodeTest { @Test public void testParentMethods() { - ASTCompilationUnit u = parseJava14(TEST1); + ASTCompilationUnit u = JavaParsingHelper.JUST_PARSE.parse(TEST1); ASTMethodDeclarator d = u.getFirstDescendantOfType(ASTMethodDeclarator.class); assertSame("getFirstParentOfType ASTMethodDeclaration", d.jjtGetParent(), @@ -203,13 +188,12 @@ public class SimpleNodeTest { assertNull("getNthParent 8", d.getNthParent(8)); } - private static final String TEST1 = "public class Test {" + PMD.EOL + " void bar(String s) {" + PMD.EOL - + " s = s.toLowerCase();" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String TEST1 = "public class Test {\n void bar(String s) {\n s = s.toLowerCase();\n }\n}"; @Ignore @Test public void testContainsNoInner() { - ASTCompilationUnit c = getNodes(ASTCompilationUnit.class, CONTAINS_NO_INNER).iterator().next(); + ASTCompilationUnit c = java.getNodes(ASTCompilationUnit.class, CONTAINS_NO_INNER).iterator().next(); List res = c.findDescendantsOfType(ASTFieldDeclaration.class); assertTrue(res.isEmpty()); /* @@ -253,21 +237,21 @@ public class SimpleNodeTest { @Test public void testContainsNoInnerWithAnonInner() { - ASTCompilationUnit c = getNodes(ASTCompilationUnit.class, CONTAINS_NO_INNER_WITH_ANON_INNER).iterator().next(); + ASTCompilationUnit c = java.parse(CONTAINS_NO_INNER_WITH_ANON_INNER); List res = c.findDescendantsOfType(ASTFieldDeclaration.class); assertTrue(res.isEmpty()); } @Test public void testContainsChildOfType() { - ASTClassOrInterfaceDeclaration c = getNodes(ASTClassOrInterfaceDeclaration.class, CONTAINS_CHILDREN_OF_TYPE) + ASTClassOrInterfaceDeclaration c = java.getNodes(ASTClassOrInterfaceDeclaration.class, CONTAINS_CHILDREN_OF_TYPE) .iterator().next(); assertTrue(c.hasDescendantOfType(ASTFieldDeclaration.class)); } @Test public void testXPathNodeSelect() throws JaxenException { - ASTClassOrInterfaceDeclaration c = getNodes(ASTClassOrInterfaceDeclaration.class, TEST_XPATH).iterator().next(); + ASTClassOrInterfaceDeclaration c = java.getNodes(ASTClassOrInterfaceDeclaration.class, TEST_XPATH).iterator().next(); List nodes = c.findChildNodesWithXPath("//FieldDeclaration"); assertEquals(2, nodes.size()); assertTrue(nodes.get(0) instanceof ASTFieldDeclaration); @@ -278,7 +262,7 @@ public class SimpleNodeTest { @Test public void testUserData() { - ASTClassOrInterfaceDeclaration c = getNodes(ASTClassOrInterfaceDeclaration.class, HAS_EXPLICIT_EXTENDS) + ASTClassOrInterfaceDeclaration c = java.getNodes(ASTClassOrInterfaceDeclaration.class, HAS_EXPLICIT_EXTENDS) .iterator().next(); assertNull(c.getUserData()); c.setUserData("foo"); @@ -302,32 +286,24 @@ public class SimpleNodeTest { private static final String NO_EXPLICIT_IMPLEMENTS = "public class Test {}"; - private static final String METHOD_SAME_LINE = "public class Test {" + PMD.EOL + " public void foo() {}" + PMD.EOL - + "}"; + private static final String METHOD_SAME_LINE = "public class Test {\n public void foo() {}\n}"; - private static final String QUALIFIED_NAME = "import java.io.File;" + PMD.EOL + "public class Foo{}"; + private static final String QUALIFIED_NAME = "import java.io.File;\npublic class Foo{}"; - private static final String BROKEN_LINE_IN_NAME = "import java.io." + PMD.EOL + "File;" + PMD.EOL - + "public class Foo{}"; + private static final String BROKEN_LINE_IN_NAME = "import java.io.\nFile;\npublic class Foo{}"; - // private static final String LINE_NUMBERS_ON_SIBLINGS = "public class Foo {" + PMD.EOL + " void bar() {" + PMD.EOL - // + " try {" + PMD.EOL + " } catch (Exception1 e) {" + PMD.EOL + " int x =2;" + PMD.EOL + " }" + PMD.EOL - // + " if (x != null) {}" + PMD.EOL + " }" + PMD.EOL + "}"; + // private static final String LINE_NUMBERS_ON_SIBLINGS = + // "public class Foo {\n void bar() {\n try {\n } catch (Exception1 e) {\n int x =2;\n }\n if (x != null) {}\n }\n}"; private static final String NO_LOOKAHEAD = "public class Foo { }"; - private static final String METHOD_DIFF_LINES = "public class Test {" + PMD.EOL + " public void foo() {" + PMD.EOL - + " int x;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String METHOD_DIFF_LINES = "public class Test {\n public void foo() {\n int x;\n }\n}"; - private static final String CONTAINS_CHILDREN_OF_TYPE = "public class Test {" + PMD.EOL + " int x;" + PMD.EOL - + "}"; + private static final String CONTAINS_CHILDREN_OF_TYPE = "public class Test {\n int x;\n}"; - private static final String CONTAINS_NO_INNER = "public class Test {" + PMD.EOL + " public class Inner {" + PMD.EOL - + " int foo;" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String CONTAINS_NO_INNER = "public class Test {\n public class Inner {\n int foo;\n }\n}"; - private static final String CONTAINS_NO_INNER_WITH_ANON_INNER = "public class Test {" + PMD.EOL + " void bar() {" - + PMD.EOL + " foo(new Fuz() { int x = 2;});" + PMD.EOL + " }" + PMD.EOL + "}"; + private static final String CONTAINS_NO_INNER_WITH_ANON_INNER = "public class Test {\n void bar() {\n foo(new Fuz() { int x = 2;});\n }\n}"; - private static final String TEST_XPATH = "public class Test {" + PMD.EOL + " int x = 2;" + PMD.EOL - + " int y = 42;" + PMD.EOL + "}"; + private static final String TEST_XPATH = "public class Test {\n int x = 2;\n int y = 42;\n}"; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/AcceptanceTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/AcceptanceTest.java index a0380f0365..efe8d53d8b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/AcceptanceTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/AcceptanceTest.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.lang.java.dfa; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getOrderedNodes; import static org.junit.Assert.assertTrue; import java.util.List; @@ -15,12 +14,13 @@ import org.junit.Test; import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.lang.dfa.DataFlowNode; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator; +import net.sourceforge.pmd.lang.java.symboltable.BaseNonParserTest; /* * Created on 18.08.2004 */ @Ignore -public class AcceptanceTest { +public class AcceptanceTest extends BaseNonParserTest { @Test public void testbook() { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/DAAPathFinderTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/DAAPathFinderTest.java index 37e8885d6c..0d5d5a645f 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/DAAPathFinderTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/DAAPathFinderTest.java @@ -4,8 +4,6 @@ package net.sourceforge.pmd.lang.java.dfa; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getOrderedNodes; - import org.junit.Ignore; import org.junit.Test; @@ -13,15 +11,22 @@ import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.lang.dfa.pathfinder.CurrentPath; import net.sourceforge.pmd.lang.dfa.pathfinder.DAAPathFinder; import net.sourceforge.pmd.lang.dfa.pathfinder.Executable; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator; +import net.sourceforge.pmd.lang.java.symboltable.BaseNonParserTest; @Ignore -public class DAAPathFinderTest implements Executable { +public class DAAPathFinderTest extends BaseNonParserTest implements Executable { @Test public void testTwoUpdateDefs() { - ASTMethodDeclarator meth = getOrderedNodes(ASTMethodDeclarator.class, TWO_UPDATE_DEFS).get(0); - DAAPathFinder a = new DAAPathFinder(meth.getDataFlowNode().getFlow().get(0), this); + ASTMethodDeclarator meth = JavaParsingHelper.WITH_PROCESSING.getNodes(ASTMethodDeclarator.class, TWO_UPDATE_DEFS).get(0); + DAAPathFinder a = new DAAPathFinder(meth.getDataFlowNode().getFlow().get(0), new Executable() { + @Override + public void execute(CurrentPath path) { + + } + }); // a.run(); } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/GeneralFiddlingTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/GeneralFiddlingTest.java index 57ac6944f8..5a598c579a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/GeneralFiddlingTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/GeneralFiddlingTest.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.lang.java.dfa; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.buildDFA; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -17,23 +16,24 @@ import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.lang.dfa.DataFlowNode; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator; +import net.sourceforge.pmd.lang.java.symboltable.BaseNonParserTest; @Ignore -public class GeneralFiddlingTest { +public class GeneralFiddlingTest extends BaseNonParserTest { /** * Unit test for https://sourceforge.net/p/pmd/bugs/1325/ */ @Test public void innerClassShouldWork() { - ASTCompilationUnit acu = buildDFA( + ASTCompilationUnit acu = java.parse( "class Foo {" + " void bar() {" + " class X {}" + " int i;" + " }" + "}"); assertNotNull(acu); } @Test public void test1() { - ASTCompilationUnit acu = buildDFA(TEST1); + ASTCompilationUnit acu = java.parse(TEST1); ASTMethodDeclarator meth = acu.findDescendantsOfType(ASTMethodDeclarator.class).get(0); DataFlowNode n = meth.getDataFlowNode(); List f = n.getFlow(); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/StatementAndBraceFinderTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/StatementAndBraceFinderTest.java index 96e1a5808b..dab319821d 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/StatementAndBraceFinderTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/StatementAndBraceFinderTest.java @@ -4,8 +4,6 @@ package net.sourceforge.pmd.lang.java.dfa; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getOrderedNodes; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava15; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -22,9 +20,11 @@ import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator; +import net.sourceforge.pmd.lang.java.symboltable.BaseNonParserTest; @Ignore -public class StatementAndBraceFinderTest { +public class StatementAndBraceFinderTest extends BaseNonParserTest { + @Test public void testStatementExpressionParentChildLinks() { @@ -76,7 +76,7 @@ public class StatementAndBraceFinderTest { StatementAndBraceFinder sbf = new StatementAndBraceFinder(LanguageRegistry.getLanguage(JavaLanguageModule.NAME) .getDefaultVersion().getLanguageVersionHandler().getDataFlowHandler()); - ASTCompilationUnit astCompilationUnit = parseJava15(TEST1); + ASTCompilationUnit astCompilationUnit = java.parse(TEST1); sbf.buildDataFlowFor(astCompilationUnit.getFirstChildOfType(ASTMethodDeclaration.class)); // FIXME look at history of this test diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/StructureTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/StructureTest.java index 33f145751e..4bba4dad93 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/StructureTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/StructureTest.java @@ -10,19 +10,19 @@ import org.junit.Ignore; import org.junit.Test; import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.dfa.Structure; import net.sourceforge.pmd.lang.java.JavaLanguageModule; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; +import net.sourceforge.pmd.lang.java.symboltable.BaseNonParserTest; @Ignore -public class StructureTest { +public class StructureTest extends BaseNonParserTest { @Test public void testAddResultsinDFANodeContainingAddedNode() { + ASTMethodDeclaration n = java.parse("class Foo { void foo() { } }").descendants(ASTMethodDeclaration.class).first(); Structure s = new Structure(LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getDefaultVersion() - .getLanguageVersionHandler().getDataFlowHandler()); - Node n = new ASTMethodDeclaration(1); + .getLanguageVersionHandler().getDataFlowHandler()); assertEquals(n, s.createNewNode(n).getNode()); } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsProviderTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsProviderTest.java index 00f8599dfe..f33e3fd3b9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsProviderTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsProviderTest.java @@ -13,7 +13,7 @@ import java.util.Map; import org.junit.Ignore; import org.junit.Test; -import net.sourceforge.pmd.lang.java.ParserTstUtil; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.MethodLikeNode; @@ -29,13 +29,14 @@ import net.sourceforge.pmd.lang.metrics.MetricKey; @Ignore("metrics are like rules, they've not been ported to the new grammar yet") public class JavaMetricsProviderTest { + private final JavaParsingHelper java8 = JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("1.8"); + @Test public void testComputeAllMetrics() { - LanguageMetricsProvider provider = ParserTstUtil.getLanguageVersionHandler("1.8").getLanguageMetricsProvider(); + LanguageMetricsProvider provider = java8.getHandler("1.8").getLanguageMetricsProvider(); - ASTCompilationUnit acu = ParserTstUtil.parseAndTypeResolveJava("1.8", - "class Foo { void bar() { System.out.println(1); } }"); + ASTCompilationUnit acu = java8.parse("class Foo { void bar() { System.out.println(1); } }"); ASTAnyTypeDeclaration type = acu.getFirstDescendantOfType(ASTAnyTypeDeclaration.class); @@ -58,16 +59,16 @@ public class JavaMetricsProviderTest { @Test public void testThereIsNoMemoisation() { - LanguageMetricsProvider provider = ParserTstUtil.getLanguageVersionHandler("1.8").getLanguageMetricsProvider(); + LanguageMetricsProvider provider = java8.getHandler("1.8").getLanguageMetricsProvider(); - ASTAnyTypeDeclaration tdecl1 = ParserTstUtil.parseAndTypeResolveJava("1.8", - "class Foo { void bar() { System.out.println(1); } }").getFirstDescendantOfType(ASTAnyTypeDeclaration.class); + ASTAnyTypeDeclaration tdecl1 = java8.parse("class Foo { void bar() { System.out.println(1); } }") + .getFirstDescendantOfType(ASTAnyTypeDeclaration.class); Map, Double> reference = provider.computeAllMetricsFor(tdecl1); - ASTAnyTypeDeclaration tdecl2 = ParserTstUtil.parseAndTypeResolveJava("1.8", - // same name, different characteristics - "class Foo { void bar(){} \npublic void hey() { System.out.println(1); } }").getFirstDescendantOfType(ASTAnyTypeDeclaration.class); + // same name, different characteristics + ASTAnyTypeDeclaration tdecl2 = java8.parse("class Foo { void bar(){} \npublic void hey() { System.out.println(1); } }") + .getFirstDescendantOfType(ASTAnyTypeDeclaration.class); Map, Double> secondTest = provider.computeAllMetricsFor(tdecl2); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/ProjectMemoizerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/ProjectMemoizerTest.java index 6d42c08bd3..5f73475717 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/ProjectMemoizerTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/ProjectMemoizerTest.java @@ -14,13 +14,13 @@ import java.util.Random; import org.junit.Test; -import net.sourceforge.pmd.lang.java.ParserTstUtil; import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter; import net.sourceforge.pmd.lang.java.ast.MethodLikeNode; import net.sourceforge.pmd.lang.java.metrics.testdata.MetricsVisitorTestData; +import net.sourceforge.pmd.lang.java.symboltable.BaseNonParserTest; import net.sourceforge.pmd.lang.metrics.MetricKey; import net.sourceforge.pmd.lang.metrics.MetricKeyUtil; import net.sourceforge.pmd.lang.metrics.MetricMemoizer; @@ -29,7 +29,7 @@ import net.sourceforge.pmd.lang.metrics.MetricOptions; /** * @author Clément Fournier */ -public class ProjectMemoizerTest { +public class ProjectMemoizerTest extends BaseNonParserTest { private MetricKey classMetricKey = MetricKeyUtil.of(null, new RandomClassMetric()); private MetricKey opMetricKey = MetricKeyUtil.of(null, new RandomOperationMetric()); @@ -37,7 +37,7 @@ public class ProjectMemoizerTest { @Test public void memoizationTest() { - ASTCompilationUnit acu = ParserTstUtil.parseJavaDefaultVersion(MetricsVisitorTestData.class); + ASTCompilationUnit acu = java.parseClass(MetricsVisitorTestData.class); List expected = visitWith(acu, true); List real = visitWith(acu, false); @@ -49,7 +49,7 @@ public class ProjectMemoizerTest { @Test public void forceMemoizationTest() { - ASTCompilationUnit acu = ParserTstUtil.parseJavaDefaultVersion(MetricsVisitorTestData.class); + ASTCompilationUnit acu = java.parseClass(MetricsVisitorTestData.class); List reference = visitWith(acu, true); List real = visitWith(acu, true); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SigMaskTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SigMaskTest.java index fd84e5a0fd..8e09379079 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SigMaskTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SigMaskTest.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.lang.java.metrics; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getOrderedNodes; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -22,12 +21,13 @@ import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature; import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature.Role; import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; +import net.sourceforge.pmd.lang.java.symboltable.BaseNonParserTest; import net.sourceforge.pmd.lang.metrics.SigMask; /** * @author Clément Fournier */ -public class SigMaskTest { +public class SigMaskTest extends BaseNonParserTest { private static final String TEST_FIELDS = "class Bzaz{" + "public String x;" @@ -184,8 +184,7 @@ public class SigMaskTest { @Test public void testOperationVisibility() { - List nodes = getOrderedNodes(ASTMethodOrConstructorDeclaration.class, - TEST_OPERATIONS); + List nodes = getOrderedNodes(ASTMethodOrConstructorDeclaration.class, TEST_OPERATIONS); JavaOperationSigMask mask = new JavaOperationSigMask(); mask.coverAbstract(); @@ -233,8 +232,7 @@ public class SigMaskTest { @Test public void testOperationRoles() { - List nodes = getOrderedNodes(ASTMethodOrConstructorDeclaration.class, - TEST_OPERATIONS); + List nodes = getOrderedNodes(ASTMethodOrConstructorDeclaration.class, TEST_OPERATIONS); JavaOperationSigMask mask = new JavaOperationSigMask(); mask.restrictRolesTo(Role.STATIC); mask.coverAbstract(); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SignatureTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SignatureTest.java index dab6aa719e..0022641c44 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SignatureTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SignatureTest.java @@ -4,8 +4,6 @@ package net.sourceforge.pmd.lang.java.metrics; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getOrderedNodes; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.parseJava17; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -15,6 +13,7 @@ import java.util.List; import org.junit.Test; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; @@ -27,13 +26,14 @@ import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature; import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature.Role; import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature; import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; +import net.sourceforge.pmd.lang.java.symboltable.BaseNonParserTest; /** * Test class for {@link JavaSignature} and its subclasses. * * @author Clément Fournier */ -public class SignatureTest { +public class SignatureTest extends BaseNonParserTest { // common to operation and field signatures @Test @@ -103,7 +103,7 @@ public class SignatureTest { @Test public void testGetterDetection() { - ASTCompilationUnit compilationUnit = parseJava17(GetterDetection.class); + ASTCompilationUnit compilationUnit = JavaParsingHelper.WITH_PROCESSING.parseClass(GetterDetection.class); compilationUnit.jjtAccept(new JavaParserVisitorAdapter() { @Override @@ -116,7 +116,7 @@ public class SignatureTest { @Test public void testSetterDetection() { - ASTCompilationUnit compilationUnit = parseJava17(SetterDetection.class); + ASTCompilationUnit compilationUnit = JavaParsingHelper.WITH_PROCESSING.parseClass(SetterDetection.class); compilationUnit.jjtAccept(new JavaParserVisitorAdapter() { @Override @@ -255,13 +255,13 @@ public class SignatureTest { List sigs = new ArrayList<>(); List sigs2 = new ArrayList<>(); - for (int i = 0; i < sigs.size(); i++) { + for (int i = 0; i < nodes.size(); i++) { sigs.add(JavaFieldSignature.buildFor(nodes.get(i))); sigs2.add(JavaFieldSignature.buildFor(nodes2.get(i))); } - for (int i = 0; i < sigs.size() - 1; i++) { + for (int i = 0; i < nodes.size() - 1; i++) { assertTrue(sigs.get(i) == sigs.get(i + 1)); assertTrue(sigs2.get(i) == sigs2.get(i + 1)); } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java index aed08671d8..d0508b981d 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java @@ -11,6 +11,7 @@ import org.junit.Before; import org.junit.Ignore; import org.junit.Test; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSigMask; import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature.Role; @@ -33,7 +34,7 @@ public class ClassStatsTest { @Ignore("Exception in typeresolution visit") public void testCountOpSigs() { - JavaMultifileVisitorTest.parseAndVisitForClass(SignatureCountTestData.class); + JavaParsingHelper.WITH_PROCESSING.parseClass(SignatureCountTestData.class); final ProjectMirror toplevel = PackageStats.INSTANCE; diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/JavaMultifileVisitorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/JavaMultifileVisitorTest.java index 28524e29a6..760e3c811d 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/JavaMultifileVisitorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/JavaMultifileVisitorTest.java @@ -10,8 +10,6 @@ import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; -import net.sourceforge.pmd.lang.LanguageVersionHandler; -import net.sourceforge.pmd.lang.java.ParserTstUtil; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter; @@ -24,13 +22,14 @@ import net.sourceforge.pmd.lang.java.multifile.testdata.MultifileVisitorTestData import net.sourceforge.pmd.lang.java.qname.JavaOperationQualifiedName; import net.sourceforge.pmd.lang.java.qname.JavaTypeQualifiedName; import net.sourceforge.pmd.lang.java.qname.QualifiedNameFactory; +import net.sourceforge.pmd.lang.java.symboltable.BaseNonParserTest; /** * Tests of the multifile visitor. * * @author Clément Fournier */ -public class JavaMultifileVisitorTest { +public class JavaMultifileVisitorTest extends BaseNonParserTest { @Test @@ -47,7 +46,7 @@ public class JavaMultifileVisitorTest { @Test public void testOperationsAreThere() { - ASTCompilationUnit acu = parseAndVisitForClass(MultifileVisitorTestData2.class); + ASTCompilationUnit acu = java.parseClass(MultifileVisitorTestData2.class); final ProjectMirror toplevel = PackageStats.INSTANCE; @@ -66,7 +65,7 @@ public class JavaMultifileVisitorTest { @Test public void testFieldsAreThere() { - parseAndVisitForClass(MultifileVisitorTestData2.class); + java.parseClass(MultifileVisitorTestData2.class); final ProjectMirror toplevel = PackageStats.INSTANCE; @@ -86,8 +85,8 @@ public class JavaMultifileVisitorTest { @Test public void testBothClassesOperationsAreThere() { - parseAndVisitForClass(MultifileVisitorTestData2.class); - parseAndVisitForClass(MultifileVisitorTestData2.class); + java.parseClass(MultifileVisitorTestData2.class); + java.parseClass(MultifileVisitorTestData2.class); final ProjectMirror toplevel = PackageStats.INSTANCE; @@ -116,8 +115,8 @@ public class JavaMultifileVisitorTest { @Test public void testBothClassesFieldsAreThere() { - parseAndVisitForClass(MultifileVisitorTestData2.class); - parseAndVisitForClass(MultifileVisitorTestData2.class); + java.parseClass(MultifileVisitorTestData2.class); + java.parseClass(MultifileVisitorTestData2.class); final ProjectMirror toplevel = PackageStats.INSTANCE; @@ -138,12 +137,4 @@ public class JavaMultifileVisitorTest { } - static ASTCompilationUnit parseAndVisitForClass(Class clazz) { - ASTCompilationUnit acu = ParserTstUtil.parseJavaDefaultVersion(clazz); - LanguageVersionHandler handler = ParserTstUtil.getDefaultLanguageVersionHandler(); - handler.getQualifiedNameResolutionFacade(JavaMultifileVisitorTest.class.getClassLoader()).start(acu); - handler.getTypeResolutionFacade(JavaMultifileVisitorTest.class.getClassLoader()).start(acu); - handler.getMultifileFacade().start(acu); - return acu; - } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/PackageStatsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/PackageStatsTest.java index c5d536a6c1..1c47f9eff1 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/PackageStatsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/PackageStatsTest.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.lang.java.multifile; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getOrderedNodes; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -23,21 +22,21 @@ import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature; import net.sourceforge.pmd.lang.java.qname.JavaOperationQualifiedName; import net.sourceforge.pmd.lang.java.qname.JavaTypeQualifiedName; import net.sourceforge.pmd.lang.java.qname.QualifiedNameFactory; +import net.sourceforge.pmd.lang.java.symboltable.BaseNonParserTest; /** * Tests functionality of PackageStats * * @author Clément Fournier */ -public class PackageStatsTest { +public class PackageStatsTest extends BaseNonParserTest { private PackageStats pack; @Before public void setUp() { - pack = PackageStats.INSTANCE; - pack.reset(); + pack = new PackageStats(); } @@ -58,7 +57,7 @@ public class PackageStatsTest { final String TEST = "package org.foo; class Boo{ " + "public void foo(){}}"; - ASTMethodOrConstructorDeclaration node = getOrderedNodes(ASTMethodDeclaration.class, TEST).get(0); + ASTMethodOrConstructorDeclaration node = java.getNodes(ASTMethodDeclaration.class, TEST).get(0); JavaOperationQualifiedName qname = node.getQualifiedName(); JavaOperationSignature signature = JavaOperationSignature.buildFor(node); @@ -76,7 +75,7 @@ public class PackageStatsTest { final String TEST = "package org.foo; class Boo{ " + "public String bar;}"; - ASTFieldDeclaration node = getOrderedNodes(ASTFieldDeclaration.class, TEST).get(0); + ASTFieldDeclaration node = java.getNodes(ASTFieldDeclaration.class, TEST).get(0); JavaTypeQualifiedName qname = (JavaTypeQualifiedName) QualifiedNameFactory.ofString("org.foo.Boo"); String fieldName = "bar"; diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/AcceptanceTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/AcceptanceTest.java index 935bcb1e30..0cf99835e4 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/AcceptanceTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/AcceptanceTest.java @@ -20,6 +20,7 @@ import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTBlock; import net.sourceforge.pmd.lang.java.ast.ASTCatchClause; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTEqualityExpression; import net.sourceforge.pmd.lang.java.ast.ASTInitializer; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; @@ -29,7 +30,7 @@ import net.sourceforge.pmd.lang.symboltable.NameOccurrence; import net.sourceforge.pmd.lang.symboltable.Scope; @Ignore -public class AcceptanceTest extends STBBaseTst { +public class AcceptanceTest extends BaseNonParserTest { @Test public void testClashingSymbols() { @@ -38,7 +39,7 @@ public class AcceptanceTest extends STBBaseTst { @Test public void testInitializer() { - parseCode(TEST_INITIALIZERS); + ASTCompilationUnit acu = parseCode(TEST_INITIALIZERS); ASTInitializer a = acu.findDescendantsOfType(ASTInitializer.class).get(0); assertFalse(a.isStatic()); a = acu.findDescendantsOfType(ASTInitializer.class).get(1); @@ -47,7 +48,7 @@ public class AcceptanceTest extends STBBaseTst { @Test public void testCatchBlocks() { - parseCode(TEST_CATCH_BLOCKS); + ASTCompilationUnit acu = parseCode(TEST_CATCH_BLOCKS); ASTCatchClause c = acu.findDescendantsOfType(ASTCatchClause.class).get(0); ASTBlock a = c.findDescendantsOfType(ASTBlock.class).get(0); Scope s = a.getScope(); @@ -60,7 +61,7 @@ public class AcceptanceTest extends STBBaseTst { @Test public void testEq() { - parseCode(TEST_EQ); + ASTCompilationUnit acu = parseCode(TEST_EQ); ASTEqualityExpression e = acu.findDescendantsOfType(ASTEqualityExpression.class).get(0); ASTMethodDeclaration method = e.getFirstParentOfType(ASTMethodDeclaration.class); Scope s = method.getScope(); @@ -81,7 +82,7 @@ public class AcceptanceTest extends STBBaseTst { @Test public void testFieldFinder() { - parseCode(TEST_FIELD); + ASTCompilationUnit acu = parseCode(TEST_FIELD); // System.out.println(TEST_FIELD); ASTVariableDeclaratorId declaration = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(1); @@ -97,7 +98,7 @@ public class AcceptanceTest extends STBBaseTst { @Test public void testDemo() { - parseCode(TEST_DEMO); + ASTCompilationUnit acu = parseCode(TEST_DEMO); // System.out.println(TEST_DEMO); ASTMethodDeclaration node = acu.findDescendantsOfType(ASTMethodDeclaration.class).get(0); Scope s = node.getScope(); @@ -120,7 +121,7 @@ public class AcceptanceTest extends STBBaseTst { @Test public void testEnum() { - parseCode(NameOccurrencesTest.TEST_ENUM); + ASTCompilationUnit acu = parseCode(NameOccurrencesTest.TEST_ENUM); ASTVariableDeclaratorId vdi = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0); List usages = vdi.getUsages(); @@ -131,7 +132,7 @@ public class AcceptanceTest extends STBBaseTst { @Test public void testInnerOuterClass() { - parseCode(TEST_INNER_CLASS); + ASTCompilationUnit acu = parseCode(TEST_INNER_CLASS); ASTVariableDeclaratorId vdi = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(1) // get inner class .getFirstDescendantOfType(ASTVariableDeclaratorId.class); // get first declaration List usages = vdi.getUsages(); @@ -148,7 +149,7 @@ public class AcceptanceTest extends STBBaseTst { */ @Test public void testNullPointerEnumValueOfOverloaded() { - parseCode("public enum EsmDcVoltageSensor {\n" + " A;\n" + " void bar(int ... args) {\n" + ASTCompilationUnit acu = 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 diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/BaseNonParserTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/BaseNonParserTest.java new file mode 100644 index 0000000000..d59fc4e543 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/BaseNonParserTest.java @@ -0,0 +1,30 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symboltable; + +import java.util.List; + +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; + +/** + * Base class for tests that usually need processing stages to run when + * parsing code. + */ +public abstract class BaseNonParserTest { + + protected final JavaParsingHelper java = JavaParsingHelper.WITH_PROCESSING.withResourceContext(getClass()); + protected final JavaParsingHelper java5 = java.withDefaultVersion("1.5"); + + + protected ASTCompilationUnit parseCode(final String code) { + return java.parse(code); + } + + protected List getOrderedNodes(Class target, String code) { + return JavaParsingHelper.WITH_PROCESSING.getNodes(target, code); + } +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ClassScopeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ClassScopeTest.java index 20aacd247e..537bc7c4fe 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ClassScopeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ClassScopeTest.java @@ -18,6 +18,7 @@ import org.junit.Test; import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; import net.sourceforge.pmd.lang.java.ast.DummyJavaNode; @@ -29,21 +30,21 @@ import net.sourceforge.pmd.lang.symboltable.NameDeclaration; import net.sourceforge.pmd.lang.symboltable.NameOccurrence; @Ignore -public class ClassScopeTest extends STBBaseTst { +public class ClassScopeTest extends BaseNonParserTest { @Test public void testEnumsClassScope() { - parseCode15(ENUM_SCOPE); + java5.parse(ENUM_SCOPE); } @Test public void testEnumTypeParameter() { - parseCode15(ENUM_TYPE_PARAMETER); + java5.parse(ENUM_TYPE_PARAMETER); } @Test public void testVarArgsEmpty() { - parseCode15("public class Foo {\n" + " public void bar1(String s, Integer... i) {}\n" + java5.parse("public class Foo {\n" + " public void bar1(String s, Integer... i) {}\n" + " public void bar1() {}\n" + " public void c() {\n" + " bar1();\n" + " }\n" + "}\n"); } @@ -92,14 +93,14 @@ public class ClassScopeTest extends STBBaseTst { @Test public void testClassName() { - parseCode(CLASS_NAME); + ASTCompilationUnit acu = parseCode(CLASS_NAME); ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); assertEquals("Foo", n.getScope().getEnclosingScope(ClassScope.class).getClassName()); } @Test public void testMethodDeclarationRecorded() { - parseCode(METHOD_DECLARATIONS_RECORDED); + ASTCompilationUnit acu = parseCode(METHOD_DECLARATIONS_RECORDED); ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); ClassScope s = (ClassScope) n.getScope(); Map> m = s.getDeclarations(); @@ -113,7 +114,7 @@ public class ClassScopeTest extends STBBaseTst { @Test public void testTwoMethodsSameNameDiffArgs() { // TODO this won't work with String and java.lang.String - parseCode(METHODS_WITH_DIFF_ARG); + ASTCompilationUnit acu = parseCode(METHODS_WITH_DIFF_ARG); ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); Map> m = ((ClassScope) n.getScope()).getDeclarations(); assertEquals(2, m.size()); @@ -125,7 +126,7 @@ public class ClassScopeTest extends STBBaseTst { @Test public final void testOneParam() { - parseCode(ONE_PARAM); + ASTCompilationUnit acu = parseCode(ONE_PARAM); ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); Map> m = ((ClassScope) n.getScope()).getDeclarations(); MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next(); @@ -134,7 +135,7 @@ public class ClassScopeTest extends STBBaseTst { @Test public final void testTwoParams() { - parseCode(TWO_PARAMS); + ASTCompilationUnit acu = parseCode(TWO_PARAMS); ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); Map> m = ((ClassScope) n.getScope()).getDeclarations(); MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next(); @@ -143,7 +144,7 @@ public class ClassScopeTest extends STBBaseTst { @Test public final void testNoParams() { - parseCode(NO_PARAMS); + ASTCompilationUnit acu = parseCode(NO_PARAMS); ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); Map> m = ((ClassScope) n.getScope()).getDeclarations(); MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next(); @@ -152,7 +153,7 @@ public class ClassScopeTest extends STBBaseTst { @Test public final void testOneParamVararg() { - parseCode15(ONE_PARAM_VARARG); + ASTCompilationUnit acu = java5.parse(ONE_PARAM_VARARG); ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); Map> m = ((ClassScope) n.getScope()).getDeclarations(); MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next(); @@ -161,7 +162,7 @@ public class ClassScopeTest extends STBBaseTst { @Test public final void testTwoParamsVararg() { - parseCode15(TWO_PARAMS_VARARG); + ASTCompilationUnit acu = java5.parse(TWO_PARAMS_VARARG); ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); Map> m = ((ClassScope) n.getScope()).getDeclarations(); MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next(); @@ -170,7 +171,7 @@ public class ClassScopeTest extends STBBaseTst { @Test public void testNestedClassesOfImportResolution() { - parseCode(NESTED_CLASSES_OF_IMPORT); + ASTCompilationUnit acu = parseCode(NESTED_CLASSES_OF_IMPORT); final ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); final ClassScope c = (ClassScope) n.getScope(); assertEquals(EnumTest.class, c.resolveType("TheInnerClass.EnumTest")); @@ -178,8 +179,8 @@ public class ClassScopeTest extends STBBaseTst { @Test public void testNestedClassesResolution() { - parseForClass(InnerClass.class); - final ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); + final ASTClassOrInterfaceDeclaration n = java.parseClass(InnerClass.class) + .findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); final ClassScope c = (ClassScope) n.getScope(); assertEquals(InnerClass.class, c.resolveType("InnerClass")); assertEquals(TheInnerClass.class, c.resolveType("InnerClass.TheInnerClass")); @@ -188,7 +189,7 @@ public class ClassScopeTest extends STBBaseTst { @Test public void testImportNestedClassesResolution() { - parseCode(IMPORT_NESTED_CLASSES); + ASTCompilationUnit acu = parseCode(IMPORT_NESTED_CLASSES); final ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); final ClassScope c = (ClassScope) n.getScope(); assertEquals(EnumTest.class, c.resolveType("EnumTest")); @@ -196,7 +197,7 @@ public class ClassScopeTest extends STBBaseTst { @Test public final void testNestedClassDeclFound() { - parseCode(NESTED_CLASS_FOUND); + ASTCompilationUnit acu = parseCode(NESTED_CLASS_FOUND); ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); ClassScope c = (ClassScope) n.getScope(); Map> m = c.getDeclarations(); @@ -213,7 +214,7 @@ public class ClassScopeTest extends STBBaseTst { @Test public void testMethodUsageSeen() { - parseCode(METHOD_USAGE_SEEN); + ASTCompilationUnit acu = parseCode(METHOD_USAGE_SEEN); ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); Map> m = ((ClassScope) n.getScope()).getDeclarations(); Iterator>> i = m.entrySet().iterator(); @@ -232,7 +233,7 @@ public class ClassScopeTest extends STBBaseTst { @Test public void testMethodUsageSeenWithThis() { - parseCode(METHOD_USAGE_SEEN_WITH_THIS); + ASTCompilationUnit acu = parseCode(METHOD_USAGE_SEEN_WITH_THIS); ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); Map> m = ((ClassScope) n.getScope()).getDeclarations(); Iterator>> i = m.entrySet().iterator(); @@ -251,7 +252,7 @@ public class ClassScopeTest extends STBBaseTst { @Test public void testMethodUsageSeen2() { - parseCode(METHOD_USAGE_SEEN2); + ASTCompilationUnit acu = parseCode(METHOD_USAGE_SEEN2); ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); Map> m = ((ClassScope) n.getScope()).getDeclarations(); @@ -280,7 +281,7 @@ public class ClassScopeTest extends STBBaseTst { */ @Test public void testNestedClassFieldAndParameter() { - parseCode(NESTED_CLASS_FIELD_AND_PARAM); + ASTCompilationUnit acu = parseCode(NESTED_CLASS_FIELD_AND_PARAM); ASTMethodDeclaration node = acu.getFirstDescendantOfType(ASTMethodDeclaration.class); Map> vd = node.getScope().getDeclarations(VariableNameDeclaration.class); assertEquals(2, vd.size()); @@ -305,7 +306,7 @@ public class ClassScopeTest extends STBBaseTst { @Test public void testNullType() { - parseCode(TEST_NULL_TYPE); + ASTCompilationUnit acu = parseCode(TEST_NULL_TYPE); } private static final String NESTED_CLASS_FIELD_AND_PARAM = "public class Foo {" + PMD.EOL + " class Test {" diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/GlobalScopeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/GlobalScopeTest.java index d9dcc33f58..42a631f05e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/GlobalScopeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/GlobalScopeTest.java @@ -19,13 +19,12 @@ import net.sourceforge.pmd.lang.symboltable.NameOccurrence; import net.sourceforge.pmd.lang.symboltable.Scope; @Ignore -public class GlobalScopeTest extends STBBaseTst { +public class GlobalScopeTest extends BaseNonParserTest { @Test public void testClassDeclAppears() { - parseCode(TEST1); - ASTCompilationUnit decl = acu; - Scope scope = decl.getScope(); + ASTCompilationUnit acu = parseCode(TEST1); + Scope scope = acu.getScope(); Map> m = scope.getDeclarations(); ClassNameDeclaration classNameDeclaration = (ClassNameDeclaration) m.keySet().iterator().next(); assertEquals(classNameDeclaration.getImage(), "Foo"); @@ -33,7 +32,7 @@ public class GlobalScopeTest extends STBBaseTst { @Test public void testEnums() { - parseCode15(TEST2); + java5.parse(TEST2); } private static final String TEST1 = "public class Foo {}" + PMD.EOL; diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/LocalScopeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/LocalScopeTest.java index 0a1f8992cb..bad3289b4c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/LocalScopeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/LocalScopeTest.java @@ -13,6 +13,7 @@ import org.junit.Ignore; import org.junit.Test; import net.sourceforge.pmd.PMD; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter; import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; @@ -20,12 +21,12 @@ import net.sourceforge.pmd.lang.symboltable.NameDeclaration; import net.sourceforge.pmd.lang.symboltable.NameOccurrence; @Ignore -public class LocalScopeTest extends STBBaseTst { +public class LocalScopeTest extends BaseNonParserTest { @Test public void testLocalVariableDeclarationFound() { - parseCode(TEST1); + ASTCompilationUnit acu = parseCode(TEST1); List nodes = acu.findDescendantsOfType(ASTVariableDeclaratorId.class); ASTVariableDeclaratorId node = nodes.get(0); Map> vars = node.getScope().getDeclarations(); @@ -36,7 +37,7 @@ public class LocalScopeTest extends STBBaseTst { @Test public void testQualifiedNameOccurrence() { - parseCode(TEST2); + ASTCompilationUnit acu = parseCode(TEST2); List nodes = acu.findDescendantsOfType(ASTVariableDeclaratorId.class); ASTVariableDeclaratorId node = nodes.get(0); Map> vars = node.getScope().getDeclarations(); @@ -47,7 +48,7 @@ public class LocalScopeTest extends STBBaseTst { @Test public void testPostfixUsageIsRecorded() { - parseCode(TEST3); + ASTCompilationUnit acu = parseCode(TEST3); List nodes = acu.findDescendantsOfType(ASTVariableDeclaratorId.class); ASTVariableDeclaratorId node = nodes.get(0); Map> vars = node.getScope().getDeclarations(); @@ -59,7 +60,7 @@ public class LocalScopeTest extends STBBaseTst { @Test public void testLocalVariableTypesAreRecorded() { - parseCode(TEST1); + ASTCompilationUnit acu = parseCode(TEST1); List nodes = acu.findDescendantsOfType(ASTVariableDeclaratorId.class); Map> vars = nodes.get(0).getScope().getDeclarations(); VariableNameDeclaration decl = (VariableNameDeclaration) vars.keySet().iterator().next(); @@ -68,7 +69,7 @@ public class LocalScopeTest extends STBBaseTst { @Test public void testMethodArgumentTypesAreRecorded() { - parseCode(TEST5); + ASTCompilationUnit acu = parseCode(TEST5); List nodes = acu.findDescendantsOfType(ASTFormalParameter.class); Map> vars = nodes.get(0).getScope().getDeclarations(); VariableNameDeclaration decl = (VariableNameDeclaration) vars.keySet().iterator().next(); @@ -77,7 +78,7 @@ public class LocalScopeTest extends STBBaseTst { @Test public void testgetEnclosingMethodScope() { - parseCode(TEST4); + ASTCompilationUnit acu = parseCode(TEST4); ASTLocalVariableDeclaration node = acu.findDescendantsOfType(ASTLocalVariableDeclaration.class).get(0); LocalScope scope = (LocalScope) node.getScope(); MethodScope ms = scope.getEnclosingScope(MethodScope.class); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/MethodNameDeclarationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/MethodNameDeclarationTest.java index 97de8cf85c..48b3543079 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/MethodNameDeclarationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/MethodNameDeclarationTest.java @@ -15,16 +15,17 @@ import org.junit.Test; import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.symboltable.NameDeclaration; import net.sourceforge.pmd.lang.symboltable.NameOccurrence; @Ignore -public class MethodNameDeclarationTest extends STBBaseTst { +public class MethodNameDeclarationTest extends BaseNonParserTest { @Test public void testEquality() { // Verify proper number of nodes are not equal - parseCode15(SIMILAR); + ASTCompilationUnit acu = java5.parse(SIMILAR); ASTClassOrInterfaceDeclaration n = acu.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class).get(0); Map> m = ((ClassScope) n.getScope()).getDeclarations(); Set methodNameDeclarations = m.keySet(); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/MethodScopeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/MethodScopeTest.java index 75aefce9d5..34b6ccb5c6 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/MethodScopeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/MethodScopeTest.java @@ -13,16 +13,17 @@ import org.junit.Ignore; import org.junit.Test; import net.sourceforge.pmd.PMD; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.symboltable.NameDeclaration; import net.sourceforge.pmd.lang.symboltable.NameOccurrence; @Ignore -public class MethodScopeTest extends STBBaseTst { +public class MethodScopeTest extends BaseNonParserTest { @Test public void testMethodParameterOccurrenceRecorded() { - parseCode(TEST1); + ASTCompilationUnit acu = parseCode(TEST1); Map> m = acu.findDescendantsOfType(ASTMethodDeclaration.class).get(0) .getScope().getDeclarations(); NameDeclaration vnd = m.keySet().iterator().next(); @@ -34,7 +35,7 @@ public class MethodScopeTest extends STBBaseTst { @Test public void testMethodName() { - parseCode(TEST1); + ASTCompilationUnit acu = parseCode(TEST1); ASTMethodDeclaration meth = acu.findDescendantsOfType(ASTMethodDeclaration.class).get(0); MethodScope ms = (MethodScope) meth.getScope(); assertEquals(ms.getName(), "foo"); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/NameOccurrencesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/NameOccurrencesTest.java index 76bbb503ff..e2ac16f4f9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/NameOccurrencesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/NameOccurrencesTest.java @@ -14,14 +14,15 @@ import org.junit.Ignore; import org.junit.Test; import net.sourceforge.pmd.PMD; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; @Ignore -public class NameOccurrencesTest extends STBBaseTst { +public class NameOccurrencesTest extends BaseNonParserTest { @Test public void testSuper() { - parseCode(TEST1); + ASTCompilationUnit acu = parseCode(TEST1); List nodes = acu.findDescendantsOfType(ASTPrimaryExpression.class); NameFinder occs = new NameFinder(nodes.get(0)); assertEquals("super", occs.getNames().get(0).getImage()); @@ -29,7 +30,7 @@ public class NameOccurrencesTest extends STBBaseTst { @Test public void testThis() { - parseCode(TEST2); + ASTCompilationUnit acu = parseCode(TEST2); List nodes = acu.findDescendantsOfType(ASTPrimaryExpression.class); NameFinder occs = new NameFinder(nodes.get(0)); assertEquals("this", occs.getNames().get(0).getImage()); @@ -38,7 +39,7 @@ public class NameOccurrencesTest extends STBBaseTst { @Test public void testNameLinkage() { - parseCode(TEST2); + ASTCompilationUnit acu = parseCode(TEST2); List nodes = acu.findDescendantsOfType(ASTPrimaryExpression.class); NameFinder occs = new NameFinder(nodes.get(0)); JavaNameOccurrence thisNameOccurrence = occs.getNames().get(0); @@ -47,7 +48,7 @@ public class NameOccurrencesTest extends STBBaseTst { @Test public void testSimpleVariableOccurrence() { - parseCode(TEST3); + ASTCompilationUnit acu = parseCode(TEST3); List nodes = acu.findDescendantsOfType(ASTPrimaryExpression.class); NameFinder occs = new NameFinder(nodes.get(0)); assertEquals("x", occs.getNames().get(0).getImage()); @@ -58,7 +59,7 @@ public class NameOccurrencesTest extends STBBaseTst { @Test public void testQualifiedOccurrence() { - parseCode(TEST4); + ASTCompilationUnit acu = parseCode(TEST4); List nodes = acu.findDescendantsOfType(ASTPrimaryExpression.class); NameFinder occs = new NameFinder(nodes.get(0)); assertEquals("b", occs.getNames().get(0).getImage()); @@ -67,12 +68,12 @@ public class NameOccurrencesTest extends STBBaseTst { @Test public void testIsSelfAssignment() { - parseCode(TEST5); + ASTCompilationUnit acu = parseCode(TEST5); List nodes = acu.findDescendantsOfType(ASTPrimaryExpression.class); NameFinder occs = new NameFinder(nodes.get(2)); assertTrue(occs.getNames().get(0).isSelfAssignment()); - parseCode(TEST6); + acu = parseCode(TEST6); nodes = acu.findDescendantsOfType(ASTPrimaryExpression.class); occs = new NameFinder(nodes.get(2)); assertTrue(occs.getNames().get(0).isSelfAssignment()); @@ -80,7 +81,7 @@ public class NameOccurrencesTest extends STBBaseTst { @Test public void testEnumStaticUsage() { - parseCode(TEST_ENUM); + ASTCompilationUnit acu = parseCode(TEST_ENUM); List nodes = acu.findDescendantsOfType(ASTPrimaryExpression.class); NameFinder occs = new NameFinder(nodes.get(4)); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/STBBaseTst.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/STBBaseTst.java deleted file mode 100644 index b08fc9dc18..0000000000 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/STBBaseTst.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.symboltable; - -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; - -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.LanguageVersion; -import net.sourceforge.pmd.lang.LanguageVersionHandler; -import net.sourceforge.pmd.lang.java.JavaLanguageModule; -import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; - -public abstract class STBBaseTst { - - protected ASTCompilationUnit acu; - - protected void parseCode(final String code) { - parseCode(code, LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getDefaultVersion()); - } - - protected void parseCode15(String code) { - parseCode(code, LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("1.5")); - } - - protected void parseCode(final String code, final LanguageVersion languageVersion) { - final LanguageVersionHandler languageVersionHandler = languageVersion.getLanguageVersionHandler(); - acu = (ASTCompilationUnit) languageVersionHandler.getParser(languageVersionHandler.getDefaultParserOptions()) - .parse(null, new StringReader(code)); - languageVersionHandler.getQualifiedNameResolutionFacade(STBBaseTst.class.getClassLoader()).start(acu); - languageVersionHandler.getSymbolFacade(STBBaseTst.class.getClassLoader()).start(acu); - languageVersionHandler.getTypeResolutionFacade(STBBaseTst.class.getClassLoader()).start(acu); - } - - // Note: If you're using Eclipse or some other IDE to run this test, you - // _must_ have the src/test/java folder in the classpath. Normally the IDE - // doesn't put source directories themselves directly in the classpath, only - // the output directories are in the classpath. - protected void parseForClass(final Class clazz) { - final String sourceFile = clazz.getName().replace('.', '/') + ".java"; - final InputStream is = STBBaseTst.class.getClassLoader().getResourceAsStream(sourceFile); - if (is == null) { - throw new IllegalArgumentException("Unable to find source file " + sourceFile + " for " + clazz); - } - final String source; - try { - source = IOUtils.toString(is, StandardCharsets.UTF_8); - } catch (final IOException e) { - throw new RuntimeException(e); - } - parseCode(source, LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getDefaultVersion()); - } -} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ScopeAndDeclarationFinderTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ScopeAndDeclarationFinderTest.java index 6afa71d9f7..e8e5032834 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ScopeAndDeclarationFinderTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ScopeAndDeclarationFinderTest.java @@ -12,16 +12,15 @@ import org.junit.Ignore; import org.junit.Test; import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.java.JavaLanguageModule; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBody; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator; import net.sourceforge.pmd.lang.symboltable.NameDeclaration; @Ignore -public class ScopeAndDeclarationFinderTest extends STBBaseTst { +public class ScopeAndDeclarationFinderTest extends BaseNonParserTest { /** * Unit test for https://sourceforge.net/p/pmd/bugs/1317/ @@ -29,11 +28,10 @@ public class ScopeAndDeclarationFinderTest extends STBBaseTst { @Test public void testJava8LambdaScoping() { String source = "public class MultipleLambdas {\n" - + " Observer a = (o, arg) -> System.out.println(\"a:\" + arg);\n" - + " Observer b = (o, arg) -> System.out.println(\"b:\" + arg);\n" + "}"; - parseCode(source, LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("1.8")); + + " Observer a = (o, arg) -> System.out.println(\"a:\" + arg);\n" + + " Observer b = (o, arg) -> System.out.println(\"b:\" + arg);\n" + "}"; + List lambdas = java.parse(source, "1.8").findDescendantsOfType(ASTLambdaExpression.class); - List lambdas = acu.findDescendantsOfType(ASTLambdaExpression.class); Assert.assertEquals(2, lambdas.size()); LocalScope scope1 = (LocalScope) lambdas.get(0).getScope(); LocalScope scope2 = (LocalScope) lambdas.get(1).getScope(); @@ -63,7 +61,7 @@ public class ScopeAndDeclarationFinderTest extends STBBaseTst { + " }" + PMD.EOL + " };" + PMD.EOL + "}" + PMD.EOL; - parseCode(source, LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("1.6")); + ASTCompilationUnit acu = java.parse(source, "1.6"); ClassScope cs = (ClassScope) acu.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getScope(); Assert.assertEquals(1, cs.getClassDeclarations().size()); // There should be 1 anonymous class diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ScopeCreationVisitorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ScopeCreationVisitorTest.java index 0f431ce659..193c660243 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ScopeCreationVisitorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ScopeCreationVisitorTest.java @@ -11,14 +11,15 @@ import org.junit.Test; import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.lang.java.ast.ASTBlock; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; @Ignore -public class ScopeCreationVisitorTest extends STBBaseTst { +public class ScopeCreationVisitorTest extends BaseNonParserTest { @Test public void testScopesAreCreated() { - parseCode(TEST1); + ASTCompilationUnit acu = parseCode(TEST1); ASTBlock n = acu.getFirstDescendantOfType(ASTIfStatement.class) .getFirstDescendantOfType(ASTBlock.class); assertTrue(n.getScope() instanceof LocalScope); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/SourceFileScopeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/SourceFileScopeTest.java index a6d1f29a5c..609d7fa4aa 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/SourceFileScopeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/SourceFileScopeTest.java @@ -20,11 +20,11 @@ import net.sourceforge.pmd.lang.symboltable.NameDeclaration; import net.sourceforge.pmd.lang.symboltable.NameOccurrence; @Ignore -public class SourceFileScopeTest extends STBBaseTst { +public class SourceFileScopeTest extends BaseNonParserTest { @Test public void testClassDeclAppears() { - parseCode(TEST1); + ASTCompilationUnit acu = parseCode(TEST1); Map> m = acu.getScope().getDeclarations(); ClassNameDeclaration classNameDeclaration = (ClassNameDeclaration) m.keySet().iterator().next(); assertEquals(classNameDeclaration.getImage(), "Foo"); @@ -32,21 +32,19 @@ public class SourceFileScopeTest extends STBBaseTst { @Test public void testPackageIsEmptyString() { - parseCode(TEST1); - ASTCompilationUnit decl = acu; - assertEquals(decl.getScope().getEnclosingScope(SourceFileScope.class).getPackageName(), ""); + ASTCompilationUnit acu = parseCode(TEST1); + assertEquals(acu.getScope().getEnclosingScope(SourceFileScope.class).getPackageName(), ""); } @Test public void testPackageNameFound() { - parseCode(TEST2); - ASTCompilationUnit decl = acu; - assertEquals(decl.getScope().getEnclosingScope(SourceFileScope.class).getPackageName(), "foo.bar"); + ASTCompilationUnit acu = parseCode(TEST2); + assertEquals(acu.getScope().getEnclosingScope(SourceFileScope.class).getPackageName(), "foo.bar"); } @Test public void testNestedClasses() { - parseCode(TEST3); + ASTCompilationUnit acu = parseCode(TEST3); Map> m = acu.getScope().getDeclarations(); Iterator iterator = m.keySet().iterator(); ClassNameDeclaration classNameDeclaration = (ClassNameDeclaration) iterator.next(); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/VariableNameDeclarationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/VariableNameDeclarationTest.java index 399cd213d0..c205e5f492 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/VariableNameDeclarationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/VariableNameDeclarationTest.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.lang.java.symboltable; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.getNodes; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -22,11 +21,11 @@ import net.sourceforge.pmd.lang.symboltable.NameDeclaration; import net.sourceforge.pmd.lang.symboltable.Scope; @Ignore -public class VariableNameDeclarationTest extends STBBaseTst { +public class VariableNameDeclarationTest extends BaseNonParserTest { @Test public void testConstructor() { - parseCode(TEST1); + ASTCompilationUnit acu = parseCode(TEST1); List nodes = acu.findDescendantsOfType(ASTVariableDeclaratorId.class); Scope s = nodes.get(0).getScope(); NameDeclaration decl = s.getDeclarations().keySet().iterator().next(); @@ -36,14 +35,14 @@ public class VariableNameDeclarationTest extends STBBaseTst { @Test public void testExceptionBlkParam() { - ASTCompilationUnit acu = getNodes(ASTCompilationUnit.class, EXCEPTION_PARAMETER).iterator().next(); + ASTCompilationUnit acu = java.parse(EXCEPTION_PARAMETER); ASTVariableDeclaratorId id = acu.getFirstDescendantOfType(ASTVariableDeclaratorId.class); assertTrue(new VariableNameDeclaration(id).isExceptionBlockParameter()); } @Test public void testIsArray() { - parseCode(TEST3); + ASTCompilationUnit acu = parseCode(TEST3); VariableNameDeclaration decl = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0).getScope() .getDeclarations(VariableNameDeclaration.class).keySet().iterator().next(); assertTrue(decl.isArray()); @@ -51,7 +50,7 @@ public class VariableNameDeclarationTest extends STBBaseTst { @Test public void testPrimitiveType() { - parseCode(TEST1); + ASTCompilationUnit acu = parseCode(TEST1); VariableNameDeclaration decl = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0).getScope() .getDeclarations(VariableNameDeclaration.class).keySet().iterator().next(); assertTrue(decl.isPrimitiveType()); @@ -59,7 +58,7 @@ public class VariableNameDeclarationTest extends STBBaseTst { @Test public void testArrayIsReferenceType() { - parseCode(TEST3); + ASTCompilationUnit acu = parseCode(TEST3); VariableNameDeclaration decl = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0).getScope() .getDeclarations(VariableNameDeclaration.class).keySet().iterator().next(); assertTrue(decl.isReferenceType()); @@ -67,7 +66,7 @@ public class VariableNameDeclarationTest extends STBBaseTst { @Test public void testPrimitiveTypeImage() { - parseCode(TEST3); + ASTCompilationUnit acu = parseCode(TEST3); NameDeclaration decl = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0).getScope() .getDeclarations().keySet().iterator().next(); assertEquals("int", ((TypedNameDeclaration) decl).getTypeImage()); @@ -75,7 +74,7 @@ public class VariableNameDeclarationTest extends STBBaseTst { @Test public void testRefTypeImage() { - parseCode(TEST4); + ASTCompilationUnit acu = parseCode(TEST4); NameDeclaration decl = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0).getScope() .getDeclarations().keySet().iterator().next(); assertEquals("String", ((TypedNameDeclaration) decl).getTypeImage()); @@ -83,7 +82,7 @@ public class VariableNameDeclarationTest extends STBBaseTst { @Test public void testParamTypeImage() { - parseCode(TEST5); + ASTCompilationUnit acu = parseCode(TEST5); NameDeclaration decl = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0).getScope() .getDeclarations().keySet().iterator().next(); assertEquals("String", ((TypedNameDeclaration) decl).getTypeImage()); @@ -91,7 +90,7 @@ public class VariableNameDeclarationTest extends STBBaseTst { @Test public void testVarKeywordTypeImage() { - parseCode(TEST6); + ASTCompilationUnit acu = parseCode(TEST6); NameDeclaration decl = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0).getScope() .getDeclarations().keySet().iterator().next(); assertEquals("java.util.ArrayList", ((TypedNameDeclaration) decl).getType().getName()); @@ -101,7 +100,7 @@ public class VariableNameDeclarationTest extends STBBaseTst { @Test public void testVarKeywordWithPrimitiveTypeImage() { - parseCode(TEST7); + ASTCompilationUnit acu = parseCode(TEST7); NameDeclaration decl = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0).getScope() .getDeclarations().keySet().iterator().next(); assertEquals("long", ((TypedNameDeclaration) decl).getType().getName()); @@ -111,7 +110,7 @@ public class VariableNameDeclarationTest extends STBBaseTst { @Test public void testVarKeywordWithIndirectReference() { - parseCode(TEST8); + ASTCompilationUnit acu = parseCode(TEST8); Iterator nameDeclarationIterator = acu.findDescendantsOfType(ASTVariableDeclaratorId.class).get(0).getScope() .getDeclarations().keySet().iterator(); nameDeclarationIterator.next(); // first variable 'bar' @@ -123,7 +122,7 @@ public class VariableNameDeclarationTest extends STBBaseTst { @Test public void testLamdaParameterTypeImage() { - parseCode(TEST9); + ASTCompilationUnit acu = parseCode(TEST9); List variableDeclaratorIds = acu.findDescendantsOfType( ASTVariableDeclaratorId.class, true diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverJava8Test.java b/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverJava8Test.java index be9c427da3..9328a03983 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverJava8Test.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverJava8Test.java @@ -4,17 +4,16 @@ package net.sourceforge.pmd.typeresolution; +import static net.sourceforge.pmd.lang.java.JavaParsingHelper.convertList; import static org.junit.Assert.assertEquals; -import java.util.ArrayList; import java.util.List; import org.jaxen.JaxenException; import org.junit.Ignore; import org.junit.Test; -import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.java.ParserTstUtil; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix; @@ -27,9 +26,13 @@ import net.sourceforge.pmd.typeresolution.testdata.java8.ThisExpression; @Ignore public class ClassTypeResolverJava8Test { + private final JavaParsingHelper java8 = + JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("8") + .withResourceContext(ClassTypeResolverJava8Test.class); + @Test public void testThisExpression() throws JaxenException { - ASTCompilationUnit acu = parseAndTypeResolveForClass18(ThisExpression.class); + ASTCompilationUnit acu = java8.parseClass(ThisExpression.class); List expressions = convertList( acu.findChildNodesWithXPath("//VariableInitializer/Expression/PrimaryExpression"), @@ -52,7 +55,7 @@ public class ClassTypeResolverJava8Test { @Test public void testSuperExpression() throws JaxenException { - ASTCompilationUnit acu = parseAndTypeResolveForClass18(SuperExpression.class); + ASTCompilationUnit acu = java8.parseClass(SuperExpression.class); List expressions = convertList( acu.findChildNodesWithXPath("//VariableInitializer/Expression/PrimaryExpression/PrimaryPrefix"), @@ -65,17 +68,4 @@ public class ClassTypeResolverJava8Test { // Make sure we got them all assertEquals("All expressions not tested", index, expressions.size()); } - - private static List convertList(List nodes, Class target) { - List converted = new ArrayList<>(); - for (Node n : nodes) { - converted.add(target.cast(n)); - } - return converted; - } - - private ASTCompilationUnit parseAndTypeResolveForClass18(Class clazz) { - String source = ParserTstUtil.getSourceFromClass(clazz); - return ParserTstUtil.parseAndTypeResolveJava("1.8", source); - } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverTest.java index 5260dabf8d..d18eab75d4 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverTest.java @@ -5,7 +5,7 @@ package net.sourceforge.pmd.typeresolution; import static junit.framework.TestCase.assertTrue; -import static net.sourceforge.pmd.lang.java.ParserTstUtil.selectNodes; +import static net.sourceforge.pmd.lang.java.JavaParsingHelper.convertList; import static net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition.forClass; import static net.sourceforge.pmd.lang.java.typeresolution.typedefinition.TypeDefinitionType.LOWER_WILDCARD; import static net.sourceforge.pmd.lang.java.typeresolution.typedefinition.TypeDefinitionType.UPPER_WILDCARD; @@ -18,7 +18,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; -import java.io.StringReader; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; @@ -34,11 +33,8 @@ import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.LanguageVersionHandler; import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.java.JavaLanguageModule; -import net.sourceforge.pmd.lang.java.ParserTstUtil; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression; import net.sourceforge.pmd.lang.java.ast.ASTAnonymousClassDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTArgumentList; @@ -142,13 +138,20 @@ import net.sourceforge.pmd.typeresolution.testdata.dummytypes.SuperClassB2; @Ignore public class ClassTypeResolverTest { + private final JavaParsingHelper java8 = JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("1.8"); + private final JavaParsingHelper java4 = java8.withDefaultVersion("1.4"); + private final JavaParsingHelper java5 = java8.withDefaultVersion("1.5"); + private final JavaParsingHelper java7 = java8.withDefaultVersion("1.7"); + private final JavaParsingHelper java11 = java8.withDefaultVersion("11"); + private final JavaParsingHelper java9 = java8.withDefaultVersion("9"); + + @Test public void stackOverflowTest() { // See #831 https://github.com/pmd/pmd/issues/831 - [java] StackOverflow in JavaTypeDefinitionSimple.toString - parseAndTypeResolveForClass15(PmdStackOverflow.class); + java5.parseClass(PmdStackOverflow.class); } - @Test public void testClassNameExists() { ClassTypeResolver classTypeResolver = new ClassTypeResolver(); @@ -160,7 +163,7 @@ public class ClassTypeResolverTest { @Test public void acceptanceTest() { - ASTCompilationUnit acu = parseAndTypeResolveForClass15(ArrayListFound.class); + ASTCompilationUnit acu = java5.parseClass(ArrayListFound.class); assertEquals(ArrayListFound.class, acu.getFirstDescendantOfType(ASTTypeDeclaration.class).getType()); assertEquals(ArrayListFound.class, acu.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getType()); @@ -171,7 +174,7 @@ public class ClassTypeResolverTest { assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTVariableDeclaratorId.class).getType()); assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTVariableDeclarator.class).getType()); - acu = parseAndTypeResolveForClass15(DefaultJavaLangImport.class); + acu = java5.parseClass(DefaultJavaLangImport.class); assertEquals(String.class, acu.getFirstDescendantOfType(ASTClassOrInterfaceType.class).getType()); assertEquals(Override.class, acu.findDescendantsOfType(ASTName.class).get(1).getType()); } @@ -182,7 +185,7 @@ public class ClassTypeResolverTest { */ @Test public void testEnumAnonymousInnerClass() { - ASTCompilationUnit acu = parseAndTypeResolveForClass15(EnumWithAnonymousInnerClass.class); + ASTCompilationUnit acu = java5.parseClass(EnumWithAnonymousInnerClass.class); // try it in jshell, an enum constant with a body is compiled to an anonymous class, // the counter is shared with other anonymous classes of the enum Class enumAnon = acu.getFirstDescendantOfType(ASTAnonymousClassDeclaration.class).getQualifiedName().getType(); @@ -201,13 +204,13 @@ public class ClassTypeResolverTest { @Test public void testNPEInJavaTypeDefinitionToString() { // Just parsing this file throws a NPE - parseAndTypeResolveForClass(JavaTypeDefinitionToStringNPE.class, "1.8"); + java8.parseClass(JavaTypeDefinitionToStringNPE.class); } @Test public void testExtraTopLevelClass() throws ClassNotFoundException { - ASTCompilationUnit acu = parseAndTypeResolveForClass15(ExtraTopLevelClass.class); + ASTCompilationUnit acu = java5.parseClass(ExtraTopLevelClass.class); Class theExtraTopLevelClass = Class .forName("net.sourceforge.pmd.typeresolution.testdata.TheExtraTopLevelClass"); // First class @@ -225,7 +228,7 @@ public class ClassTypeResolverTest { @Test public void testInnerClass() throws ClassNotFoundException { - ASTCompilationUnit acu = parseAndTypeResolveForClass15(InnerClass.class); + ASTCompilationUnit acu = java5.parseClass(InnerClass.class); Class theInnerClass = Class.forName("net.sourceforge.pmd.typeresolution.testdata.InnerClass$TheInnerClass"); // Outer class ASTTypeDeclaration typeDeclaration = acu.getFirstDescendantOfType(ASTTypeDeclaration.class); @@ -250,11 +253,11 @@ public class ClassTypeResolverTest { */ @Test public void testInnerClassNotCompiled() throws Exception { - Node acu = parseAndTypeResolveForString("public class TestInnerClass {\n" + " public void foo() {\n" + Node acu = java8.parse("public class TestInnerClass {\n" + " public void foo() {\n" + " Statement statement = new Statement();\n" + " " + "}\n" + " static class Statement {\n" + " }\n" - + "}", "1.8"); + + "}"); ASTClassOrInterfaceType statement = acu.getFirstDescendantOfType(ASTClassOrInterfaceType.class); Assert.assertTrue(statement.isReferenceToClassSameCompilationUnit()); } @@ -262,7 +265,7 @@ public class ClassTypeResolverTest { @Test public void testAnonymousClassFromInterface() throws Exception { - Node acu = parseAndTypeResolveForClass(AnonymousClassFromInterface.class, "1.8"); + Node acu = java8.parseClass(AnonymousClassFromInterface.class); ASTAllocationExpression allocationExpression = acu.getFirstDescendantOfType(ASTAllocationExpression.class); TypeNode child = (TypeNode) allocationExpression.jjtGetChild(0); Assert.assertTrue(Comparator.class.isAssignableFrom(child.getType())); @@ -272,7 +275,7 @@ public class ClassTypeResolverTest { @Test public void testNestedAnonymousClass() throws Exception { - Node acu = parseAndTypeResolveForClass(NestedAnonymousClass.class, "1.8"); + Node acu = java8.parseClass(NestedAnonymousClass.class); ASTAllocationExpression allocationExpression = acu.getFirstDescendantOfType(ASTAllocationExpression.class); ASTAllocationExpression nestedAllocation = allocationExpression.getFirstDescendantOfType(ASTClassOrInterfaceBodyDeclaration.class) // get the declaration (boundary) @@ -285,7 +288,7 @@ public class ClassTypeResolverTest { @Test public void testAnonymousExtendingObject() throws Exception { - Node acu = parseAndTypeResolveForClass(AnoymousExtendingObject.class, "1.8"); + Node acu = java8.parseClass(AnoymousExtendingObject.class); ASTAllocationExpression allocationExpression = acu.getFirstDescendantOfType(ASTAllocationExpression.class); TypeNode child = (TypeNode) allocationExpression.jjtGetChild(0); Assert.assertTrue(Object.class.isAssignableFrom(child.getType())); @@ -294,7 +297,7 @@ public class ClassTypeResolverTest { @Test public void testAnonymousInnerClass() throws ClassNotFoundException { - ASTCompilationUnit acu = parseAndTypeResolveForClass15(AnonymousInnerClass.class); + ASTCompilationUnit acu = java5.parseClass(AnonymousInnerClass.class); Class theAnonymousInnerClass = Class .forName("net.sourceforge.pmd.typeresolution.testdata.AnonymousInnerClass$1"); // Outer class @@ -461,9 +464,12 @@ public class ClassTypeResolverTest { @Test public void testUnaryNumericPromotion() throws JaxenException { - List expressions = selectNodes(Promotion.class, ASTExpression.class, - "//Block[preceding-sibling::MethodDeclarator[@Image = " - + "'unaryNumericPromotion']]//Expression[UnaryExpression]"); + ASTCompilationUnit acu = java5.parseClass(Promotion.class); + List expressions = convertList( + acu.findChildNodesWithXPath( + "//Block[preceding-sibling::MethodDeclarator[@Image = " + + "'unaryNumericPromotion']]//Expression[UnaryExpression]"), + ASTExpression.class); int index = 0; assertEquals(Integer.TYPE, expressions.get(index++).getType()); @@ -481,9 +487,12 @@ public class ClassTypeResolverTest { @Test public void testBinaryNumericPromotion() throws JaxenException { - List expressions = selectNodes(Promotion.class, ASTExpression.class, - "//Block[preceding-sibling::MethodDeclarator[@Image = " - + "'binaryNumericPromotion']]//Expression[AdditiveExpression]"); + ASTCompilationUnit acu = java5.parseClass(Promotion.class); + List expressions = convertList( + acu.findChildNodesWithXPath( + "//Block[preceding-sibling::MethodDeclarator[@Image = " + + "'binaryNumericPromotion']]//Expression[AdditiveExpression]"), + ASTExpression.class); int index = 0; // LHS = byte @@ -550,8 +559,11 @@ public class ClassTypeResolverTest { @Test public void testBinaryStringPromotion() throws JaxenException { - List expressions = selectNodes(Promotion.class, ASTExpression.class, - "//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryStringPromotion']]//Expression"); + ASTCompilationUnit acu = java5.parseClass(Promotion.class); + List expressions = convertList( + acu.findChildNodesWithXPath( + "//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryStringPromotion']]//Expression"), + ASTExpression.class); int index = 0; assertEquals(String.class, expressions.get(index++).getType()); @@ -581,8 +593,11 @@ public class ClassTypeResolverTest { @Test public void testBinaryLogicalOperators() throws JaxenException { - List expressions = selectNodes(Operators.class, ASTExpression.class, - "//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryLogicalOperators']]//Expression"); + ASTCompilationUnit acu = java5.parseClass(Operators.class); + List expressions = convertList( + acu.findChildNodesWithXPath( + "//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryLogicalOperators']]//Expression"), + ASTExpression.class); int index = 0; assertEquals(Boolean.TYPE, expressions.get(index++).getType()); @@ -606,9 +621,13 @@ public class ClassTypeResolverTest { @Test public void testUnaryNumericOperators() throws JaxenException { - List expressions = selectNodes(Operators.class, TypeNode.class, - "//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]" - + "//*[self::Expression or self::PostfixExpression or self::PreIncrementExpression or self::PreDecrementExpression]"); + ASTCompilationUnit acu = java5.parseClass(Operators.class); + List expressions = new ArrayList<>(); + expressions.addAll(convertList( + acu.findChildNodesWithXPath( + "//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]" + + "//*[self::Expression or self::PostfixExpression or self::PreIncrementExpression or self::PreDecrementExpression]"), + TypeNode.class)); int index = 0; assertEquals(Integer.TYPE, expressions.get(index++).getType()); @@ -625,8 +644,11 @@ public class ClassTypeResolverTest { @Test public void testBinaryNumericOperators() throws JaxenException { - List expressions = selectNodes(Operators.class, ASTExpression.class, - "//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryNumericOperators']]//Expression"); + ASTCompilationUnit acu = java5.parseClass(Operators.class); + List expressions = convertList( + acu.findChildNodesWithXPath( + "//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryNumericOperators']]//Expression"), + ASTExpression.class); int index = 0; assertEquals(Integer.TYPE, expressions.get(index++).getType()); @@ -645,9 +667,12 @@ public class ClassTypeResolverTest { @Test public void testAssignmentOperators() throws JaxenException { - List expressions = selectNodes(Operators.class, ASTStatementExpression.class, - "//Block[preceding-sibling::MethodDeclarator[@Image = " - + "'assignmentOperators']]//StatementExpression"); + ASTCompilationUnit acu = java5.parseClass(Operators.class); + List expressions = convertList( + acu.findChildNodesWithXPath( + "//Block[preceding-sibling::MethodDeclarator[@Image = " + + "'assignmentOperators']]//StatementExpression"), + ASTStatementExpression.class); int index = 0; assertEquals(Long.TYPE, expressions.get(index++).getType()); @@ -678,7 +703,7 @@ public class ClassTypeResolverTest { + " java.util.StringTokenizer st = new StringTokenizer(\"a.b.c.d\", \".\");\n" + " while (st.hasMoreTokens()) {\n" + " System.out.println(st.nextToken());\n" + " }\n" + " }\n" + "}"; - ASTCompilationUnit acu = parseAndTypeResolveForString(source, "1.5"); + ASTCompilationUnit acu = java5.parse(source); List names = acu.findDescendantsOfType(ASTName.class); ASTName theStringTokenizer = null; for (ASTName name : names) { @@ -701,7 +726,7 @@ public class ClassTypeResolverTest { @Test public void testThisExpression() { - ASTCompilationUnit compilationUnit = parseAndTypeResolveForClass15(ThisExpression.class); + ASTCompilationUnit compilationUnit = java5.parseClass(ThisExpression.class); // need to cross borders, to find expressions of the nested classes List expressions = compilationUnit.findDescendantsOfType(ASTThisExpression.class, true); @@ -1827,7 +1852,7 @@ public class ClassTypeResolverTest { @Test public void testNestedAllocationExpressions() { - ASTCompilationUnit acu = parseAndTypeResolveForClass15(NestedAllocationExpressions.class); + ASTCompilationUnit acu = java5.parseClass(NestedAllocationExpressions.class); List allocs = acu.findDescendantsOfType(ASTAllocationExpression.class); assertFalse(allocs.get(0).isAnonymousClass()); @@ -1841,48 +1866,48 @@ public class ClassTypeResolverTest { @Test public void testAnnotatedTypeParams() { - parseAndTypeResolveForString("public class Foo { public static > T getEnum() { return null; } }", "1.8"); + java8.parse("public class Foo { public static > T getEnum() { return null; } }"); } @Test public void testMethodOverrides() throws Exception { - parseAndTypeResolveForClass(SubTypeUsage.class, "1.8"); + java8.parseClass(SubTypeUsage.class); } @Test public void testMethodWildcardParam() throws Exception { - parseAndTypeResolveForClass(MethodGenericParam.class, "1.8"); + java8.parseClass(MethodGenericParam.class); } @Test public void testAbstractMethodReturnType() throws Exception { - parseAndTypeResolveForClass(AbstractReturnTypeUseCase.class, "1.8"); + java8.parseClass(AbstractReturnTypeUseCase.class); } @Test public void testMethodOverloaded() throws Exception { - parseAndTypeResolveForClass(OverloadedMethodsUsage.class, "1.8"); + java8.parseClass(OverloadedMethodsUsage.class); } @Test public void testVarArgsMethodUseCase() throws Exception { - parseAndTypeResolveForClass(VarArgsMethodUseCase.class, "1.8"); + java8.parseClass(VarArgsMethodUseCase.class); } @Test public void testLocalGenericClass() throws Exception { - parseAndTypeResolveForClass(LocalGenericClass.class, "9"); + java9.parseClass(LocalGenericClass.class); } @Test public void testMethodCallExpressionTypes() throws Exception { - ASTCompilationUnit cu = parseAndTypeResolveForClass(MethodCallExpressionTypes.class, "11"); + ASTCompilationUnit cu = java11.parseClass(MethodCallExpressionTypes.class); ASTPrimaryExpression expr = cu.getFirstDescendantOfType(ASTPrimaryExpression.class); assertEquals(forClass(String.class), expr.getTypeDefinition()); assertEquals(forClass(Objects.class), expr.getFirstChildOfType(ASTPrimaryPrefix.class).getTypeDefinition()); @@ -1898,30 +1923,29 @@ public class ClassTypeResolverTest { } - private ASTCompilationUnit parseAndTypeResolveForClass15(Class clazz) { - return parseAndTypeResolveForClass(clazz, "1.5"); + private List selectNodes(String source, Class resultType, String xpath) throws JaxenException { + return selectNodes(source, "1.5", resultType, xpath); + } + + // This is the master overload, others just default the parameters + private List selectNodes(String source, String version, Class resultType, String xpath) throws JaxenException { + ASTCompilationUnit acu = java4.parse(source, version); + return convertList(acu.findChildNodesWithXPath(xpath), resultType); } - // Note: If you're using Eclipse or some other IDE to run this test, you - // _must_ have the src/test/java folder in - // the classpath. Normally the IDE doesn't put source directories themselves - // directly in the classpath, only - // the output directories are in the classpath. - private ASTCompilationUnit parseAndTypeResolveForClass(Class clazz, String version) { - return parseAndTypeResolveForString(ParserTstUtil.getSourceFromClass(clazz), version); + private List selectNodes(Class source, Class resultType) { + return java5.parseClass(source).findDescendantsOfType(resultType); + } + + private List selectNodes(Class source, Class resultType, String xpath) throws JaxenException { + return selectNodes(source, "1.5", resultType, xpath); } - private ASTCompilationUnit parseAndTypeResolveForString(String source, String version) { - LanguageVersionHandler languageVersionHandler = LanguageRegistry.getLanguage(JavaLanguageModule.NAME) - .getVersion(version).getLanguageVersionHandler(); - ASTCompilationUnit acu = (ASTCompilationUnit) languageVersionHandler - .getParser(languageVersionHandler.getDefaultParserOptions()).parse(null, new StringReader(source)); - languageVersionHandler.getQualifiedNameResolutionFacade(ClassTypeResolverTest.class.getClassLoader()).start(acu); - languageVersionHandler.getSymbolFacade().start(acu); - languageVersionHandler.getTypeResolutionFacade(ClassTypeResolverTest.class.getClassLoader()).start(acu); - return acu; + private List selectNodes(Class source, String version, Class resultType, String xpath) throws JaxenException { + ASTCompilationUnit acu = java4.parseClass(source, version); + return convertList(acu.findChildNodesWithXPath(xpath), resultType); } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTAdditiveExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTAdditiveExpressionTest.kt index ca43d4ae25..603fb2d8d3 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTAdditiveExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTAdditiveExpressionTest.kt @@ -5,7 +5,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.java.ast.BinaryOp.* -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx class ASTAdditiveExpressionTest : ParserTestSpec({ diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTest.kt index 8efcf64aaa..116a058ffd 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTest.kt @@ -7,7 +7,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.ast.test.shouldBe import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Earliest import net.sourceforge.pmd.lang.java.ast.JavaVersion.J1_3 -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.AnnotationParsingCtx /** * @author Clément Fournier diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTAssignmentExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTAssignmentExpressionTest.kt index 9aaf149224..c0ec3d7663 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTAssignmentExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTAssignmentExpressionTest.kt @@ -4,7 +4,6 @@ import net.sourceforge.pmd.lang.ast.test.shouldBe import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.AccessType.READ import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.AccessType.WRITE import net.sourceforge.pmd.lang.java.ast.AssignmentOp.* -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx /** * @author Clément Fournier diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTBinaryExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTBinaryExpressionTest.kt index bd5899b170..cd50b2d1b2 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTBinaryExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTBinaryExpressionTest.kt @@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.java.ast.BinaryOp.* -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx /* Tests for the rest of binary expressions diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTCastExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTCastExpressionTest.kt index 855b57ae60..6ede2a06c9 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTCastExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTCastExpressionTest.kt @@ -8,7 +8,6 @@ import net.sourceforge.pmd.lang.ast.test.shouldBe import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType.INT import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Earliest import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Latest -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx class ASTCastExpressionTest : ParserTestSpec({ diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTCatchClauseTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTCatchClauseTest.kt index 45af65f1ec..08d8a9afe7 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTCatchClauseTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTCatchClauseTest.kt @@ -1,6 +1,7 @@ package net.sourceforge.pmd.lang.java.ast import io.kotlintest.matchers.collections.shouldContainExactly +import io.kotlintest.matchers.string.shouldContain import io.kotlintest.shouldBe import net.sourceforge.pmd.lang.java.ast.JavaVersion.* import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Earliest @@ -12,10 +13,14 @@ class ASTCatchClauseTest : ParserTestSpec({ parserTest("Test crash on multicatch", javaVersions = Earliest..J1_6) { - expectParseException("Composite catch clauses are a feature of Java 1.7, you should select your language version accordingly") { - parseStatement("try { } catch (IOException | AssertionError e) { }") - } + inContext(StatementParsingCtx) { + + "try { } catch (IOException | AssertionError e) { }" should throwParseException { + it.message.shouldContain("Composite catch clauses are a feature of Java 1.7, you should select your language version accordingly") + } + + } } parserTest("Test single type", javaVersions = J1_5..Latest) { diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTClassLiteralTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTClassLiteralTest.kt index 7bf4f4ef9b..d7787ac847 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTClassLiteralTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTClassLiteralTest.kt @@ -2,7 +2,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.ast.test.shouldBe import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType.INT -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx /** * @author Clément Fournier diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclTest.kt index b7be4d1423..dcecd61f52 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclTest.kt @@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.ast.test.shouldBe -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.StatementParsingCtx // TODO merge the java ASTClassOrInterfaceDeclarationTest into this class ASTClassOrInterfaceDeclTest : ParserTestSpec({ diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclarationTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclarationTest.kt index e1e39c4cc3..c778667741 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclarationTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclarationTest.kt @@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.ast.test.shouldBe +import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType class ASTConstructorDeclarationTest : ParserTestSpec({ @@ -44,7 +45,7 @@ class ASTConstructorDeclarationTest : ParserTestSpec({ it::toList shouldBe listOf( child { - primitiveType(ASTPrimitiveType.PrimitiveType.INT) + primitiveType(PrimitiveType.INT) variableId("other") } ) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTEqualityExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTEqualityExpressionTest.kt index d6bb089001..175a0994f1 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTEqualityExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTEqualityExpressionTest.kt @@ -5,7 +5,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.java.ast.BinaryOp.* -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx class ASTEqualityExpressionTest : ParserTestSpec({ diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt index 222e07512c..c9e4efb322 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt @@ -7,7 +7,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.ast.test.shouldBe import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx class ASTInstanceOfExpressionTest : ParserTestSpec({ diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpressionTest.kt index 81ce9a5942..07cbe2230c 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpressionTest.kt @@ -8,8 +8,6 @@ import net.sourceforge.pmd.lang.ast.test.shouldBe import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType.INT import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Latest import net.sourceforge.pmd.lang.java.ast.JavaVersion.J1_8 -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.StatementParsingCtx class ASTLambdaExpressionTest : ParserTestSpec({ diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTLiteralTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTLiteralTest.kt index 1ae98dcfc2..ce5e58df79 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTLiteralTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTLiteralTest.kt @@ -8,7 +8,6 @@ import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType.* import net.sourceforge.pmd.lang.java.ast.JavaVersion.* import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Earliest import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Latest -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx import net.sourceforge.pmd.lang.java.ast.UnaryOp.UNARY_MINUS /** diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclarationTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclarationTest.kt index 99bf9b7cd6..61e6b1898e 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclarationTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclarationTest.kt @@ -6,7 +6,6 @@ import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Earliest import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Latest import net.sourceforge.pmd.lang.java.ast.JavaVersion.J1_8 import net.sourceforge.pmd.lang.java.ast.JavaVersion.J9 -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.EnclosedDeclarationParsingCtx class ASTMethodDeclarationTest : ParserTestSpec({ diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodReferenceTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodReferenceTest.kt index 35efaed73a..9471a72fd7 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodReferenceTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodReferenceTest.kt @@ -2,7 +2,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.ast.test.shouldBe import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType.INT -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx /** * Nodes that previously corresponded to ASTAllocationExpression. diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMultiplicativeExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMultiplicativeExpressionTest.kt index 954e2eddba..9fe9faf3d0 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMultiplicativeExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMultiplicativeExpressionTest.kt @@ -5,7 +5,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.java.ast.BinaryOp.* -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx import net.sourceforge.pmd.lang.java.ast.UnaryOp.UNARY_MINUS diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTRelationalExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTRelationalExpressionTest.kt index 008b1195e3..61983126b2 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTRelationalExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTRelationalExpressionTest.kt @@ -4,8 +4,6 @@ package net.sourceforge.pmd.lang.java.ast -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx - class ASTRelationalExpressionTest : ParserTestSpec({ diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTShiftExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTShiftExpressionTest.kt index 0e8668cc38..9a145a7def 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTShiftExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTShiftExpressionTest.kt @@ -5,7 +5,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.java.ast.BinaryOp.* -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx /** * Nodes that previously corresponded to ASTAllocationExpression. diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTStatementsTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTStatementsTest.kt index a53c1b59ce..fd85441346 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTStatementsTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTStatementsTest.kt @@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.ast.test.shouldBe -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.StatementParsingCtx class ASTStatementsTest : ParserTestSpec({ diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSuperExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSuperExpressionTest.kt index 9663f76296..4109995ffe 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSuperExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSuperExpressionTest.kt @@ -1,7 +1,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.ast.test.shouldBe -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx /** * @author Clément Fournier diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSwitchExpressionTests.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSwitchExpressionTests.kt index 1becc95870..c1446b43c7 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSwitchExpressionTests.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSwitchExpressionTests.kt @@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.ast.test.shouldBe import net.sourceforge.pmd.lang.java.ast.BinaryOp.* -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx import net.sourceforge.pmd.lang.java.ast.UnaryOp.UNARY_MINUS diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTThisExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTThisExpressionTest.kt index a6806b0c00..2fb03fc782 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTThisExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTThisExpressionTest.kt @@ -1,7 +1,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.ast.test.shouldBe -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx /** * @author Clément Fournier diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTTryStatementTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTTryStatementTest.kt index 75cea01780..7606035336 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTTryStatementTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTTryStatementTest.kt @@ -8,7 +8,6 @@ import net.sourceforge.pmd.lang.ast.test.shouldBe import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Latest import net.sourceforge.pmd.lang.java.ast.JavaVersion.J1_7 import net.sourceforge.pmd.lang.java.ast.JavaVersion.J9 -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.StatementParsingCtx /** * @author Clément Fournier diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTTypeParametersTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTTypeParametersTest.kt index 3a13e36337..433c53541c 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTTypeParametersTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTTypeParametersTest.kt @@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Latest import net.sourceforge.pmd.lang.java.ast.JavaVersion.J1_8 -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.TypeParametersParsingCtx /** * @author Clément Fournier diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTTypeTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTTypeTest.kt index fa56bd6989..d6389ad248 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTTypeTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTTypeTest.kt @@ -1,7 +1,6 @@ package net.sourceforge.pmd.lang.java.ast import net.sourceforge.pmd.lang.ast.test.shouldBe -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.TypeParsingCtx /** * @author Clément Fournier diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTUnaryExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTUnaryExpressionTest.kt index 5900063c87..db54fef25d 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTUnaryExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTUnaryExpressionTest.kt @@ -5,7 +5,6 @@ import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.AccessType.WRITE import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType import net.sourceforge.pmd.lang.java.ast.BinaryOp.ADD import net.sourceforge.pmd.lang.java.ast.BinaryOp.SUB -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx import net.sourceforge.pmd.lang.java.ast.UnaryOp.* class ASTUnaryExpressionTest : ParserTestSpec({ diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTWildcardTypeTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTWildcardTypeTest.kt index 4eddc8dded..2c8042e136 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTWildcardTypeTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTWildcardTypeTest.kt @@ -8,7 +8,6 @@ import net.sourceforge.pmd.lang.ast.test.shouldBe import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Latest import net.sourceforge.pmd.lang.java.ast.JavaVersion.J1_5 import net.sourceforge.pmd.lang.java.ast.JavaVersion.J1_8 -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.TypeParsingCtx /** * @author Clément Fournier diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/JavaTextAccessTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/JavaTextAccessTest.kt index 173878d2bd..1a5e31d638 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/JavaTextAccessTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/JavaTextAccessTest.kt @@ -8,7 +8,6 @@ import io.kotlintest.shouldBe import net.sourceforge.pmd.lang.ast.TextAvailableNode import net.sourceforge.pmd.lang.ast.test.shouldBe import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType.INT -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.StatementParsingCtx // Use a string for comparison because CharSequence are not necessarily // equatable to string diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt index 39083d2e39..8b3fd463e8 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt @@ -8,7 +8,7 @@ import io.kotlintest.matchers.string.shouldContain import io.kotlintest.shouldThrow import net.sourceforge.pmd.lang.ast.Node import net.sourceforge.pmd.lang.ast.test.* -import net.sourceforge.pmd.lang.java.ParserTstUtil +import net.sourceforge.pmd.lang.java.JavaParsingHelper import java.beans.PropertyDescriptor /** @@ -17,9 +17,10 @@ import java.beans.PropertyDescriptor enum class JavaVersion : Comparable { J1_3, J1_4, J1_5, J1_6, J1_7, J1_8, J9, J10, J11, J12, J12__PREVIEW, J13, J13__PREVIEW; - /** Name suitable for use with e.g. [ParserTstUtil.parseAndTypeResolveJava] */ + /** Name suitable for use with e.g. [JavaParsingHelper.parse] */ val pmdName: String = name.removePrefix("J").replaceFirst("__", "-").replace('_', '.').toLowerCase() + val parser: JavaParsingHelper = JavaParsingHelper.WITH_PROCESSING.withDefaultVersion(pmdName) operator fun not(): List = values().toList() - this @@ -150,8 +151,11 @@ inline fun JavaNode?.shouldMatchNode(ignoreChildren: Boolean open class ParserTestCtx(val javaVersion: JavaVersion = JavaVersion.Latest, val importedTypes: MutableList> = mutableListOf(), val otherImports: MutableList = mutableListOf(), + var packageName: String = "", var genClassHeader: String = "class Foo") { + var fullSource: String? = null + /** Imports to add to the top of the parsing contexts. */ internal val imports: List get() { @@ -159,6 +163,34 @@ open class ParserTestCtx(val javaVersion: JavaVersion = JavaVersion.Latest, return types + otherImports.map { "import $it;" } } + internal val packageDecl: String get() = if (packageName.isEmpty()) "" else "package $packageName;" + + /** + * Places all node parsing contexts inside the declaration of the given class + * of the given class. + * It's like you were writing eg expressions inside the class, with the method + * declarations around it and all. + * + * LIMITATIONS: + * - does not work for [TopLevelTypeDeclarationParsingCtx] + * - [klass] must be a toplevel class (not an enum, not an interface, not nested/local/anonymous) + */ + fun asIfIn(klass: Class<*>) { + assert(!klass.isArray && !klass.isPrimitive) { + "$klass has no class name" + } + + assert(!klass.isLocalClass + && !klass.isAnonymousClass + && klass.enclosingClass == null + && !klass.isEnum + && !klass.isInterface) { + "Unsupported class $klass" + } + + fullSource = javaVersion.parser.readClassSource(klass) + } + inline fun makeMatcher(nodeParsingCtx: NodeParsingCtx<*>, ignoreChildren: Boolean, noinline nodeSpec: NodeSpec) : Assertions = { nodeParsingCtx.parseAndFind(it, this).shouldMatchNode(ignoreChildren, nodeSpec) } @@ -168,7 +200,7 @@ open class ParserTestCtx(val javaVersion: JavaVersion = JavaVersion.Latest, * */ inline fun matchExpr(ignoreChildren: Boolean = false, - noinline nodeSpec: NodeSpec) = + noinline nodeSpec: NodeSpec) = makeMatcher(ExpressionParsingCtx, ignoreChildren, nodeSpec) /** @@ -214,10 +246,11 @@ open class ParserTestCtx(val javaVersion: JavaVersion = JavaVersion.Latest, ignoreChildren: Boolean = false, noinline nodeSpec: NodeSpec) = makeMatcher(EnclosedDeclarationParsingCtx, ignoreChildren, nodeSpec) - fun notParseIn(nodeParsingCtx: NodeParsingCtx<*>): Assertions = { - shouldThrow { + fun notParseIn(nodeParsingCtx: NodeParsingCtx<*>, expected: (ParseException) -> Unit = {}): Assertions = { + val e = shouldThrow { nodeParsingCtx.parseNode(it, this) } + expected(e) } fun parseIn(nodeParsingCtx: NodeParsingCtx<*>) = object : Matcher { @@ -269,174 +302,5 @@ open class ParserTestCtx(val javaVersion: JavaVersion = JavaVersion.Latest, inline fun parseDeclaration(decl: String): N = EnclosedDeclarationParsingCtx.parseNode(decl, this) as N - companion object { - - - /** - * Finds the first descendant of type [N] of [this] node which is - * accessible in a straight line. The descendant must be accessible - * from the [this] on a path where each node has a single child. - * - * If one node has another child, the search is aborted and the method - * returns null. - */ - fun Node.findFirstNodeOnStraightLine(klass: Class): N? { - return when { - klass.isInstance(this) -> klass.cast(this) - this.numChildren == 1 -> getChild(0).findFirstNodeOnStraightLine(klass) - else -> null - } - } - - /** - * Describes a kind of node that can be found commonly in the same contexts. - * This type defines some machinery to parse a string to this kind of node - * without much ado by placing it in a specific parsing context. - */ - abstract class NodeParsingCtx(val constructName: String) { - - abstract fun getTemplate(construct: String, ctx: ParserTestCtx): String - - abstract fun retrieveNode(acu: ASTCompilationUnit): T - - /** - * Parse the string in the context described by this object. The parsed node is usually - * the child of the returned [T] node. Note that [parseAndFind] can save you some keystrokes - * because it finds a descendant of the wanted type. - * - * @param construct The construct to parse - * - * @return A [T] whose child is the given statement - * - * @throws ParseException If the argument is no valid construct of this kind (mind the language version) - */ - fun parseNode(construct: String, ctx: ParserTestCtx): T { - val root = ParserTstUtil.parseAndTypeResolveJava(ctx.javaVersion.pmdName, getTemplate(construct, ctx)) - - return retrieveNode(root) - } - - /** - * Parse the string the context described by this object, and finds the first descendant of type [N]. - * The descendant is searched for by [findFirstNodeOnStraightLine], to prevent accidental - * mis-selection of a node. In such a case, a [NoSuchElementException] is thrown, and you - * should fix your test case. - * - * @param construct The construct to parse - * @param N The type of node to find - * - * @return The first descendant of type [N] found in the parsed expression - * - * @throws NoSuchElementException If no node of type [N] is found by [findFirstNodeOnStraightLine] - * @throws ParseException If the argument is no valid construct of this kind - * - */ - inline fun parseAndFind(construct: String, ctx: ParserTestCtx): N = - parseNode(construct, ctx).findFirstNodeOnStraightLine(N::class.java) - ?: throw NoSuchElementException("No node of type ${N::class.java.simpleName} in the given $constructName:\n\t$construct") - - - override fun toString(): String = "$constructName context" - } - - - object ExpressionParsingCtx : NodeParsingCtx("expression") { - - override fun getTemplate(construct: String, ctx: ParserTestCtx): String = - """ -${ctx.imports.joinToString(separator = "\n")} -${ctx.genClassHeader} { - { - Object o = $construct; - } -} - """ - - - override fun retrieveNode(acu: ASTCompilationUnit): ASTExpression = acu.getFirstDescendantOfType(ASTExpression::class.java)!! - } - - object StatementParsingCtx : NodeParsingCtx("statement") { - - override fun getTemplate(construct: String, ctx: ParserTestCtx): String = - """ - ${ctx.imports.joinToString(separator = "\n")} - ${ctx.genClassHeader} { - { - $construct - } - } - """.trimIndent() - - - override fun retrieveNode(acu: ASTCompilationUnit): ASTStatement = acu.getFirstDescendantOfType(ASTBlock::class.java).jjtGetChild(0) - } - - object EnclosedDeclarationParsingCtx : NodeParsingCtx("enclosed declaration") { - - override fun getTemplate(construct: String, ctx: ParserTestCtx): String = """ - ${ctx.imports.joinToString(separator = "\n")} - ${ctx.genClassHeader} { - $construct - } - """.trimIndent() - - override fun retrieveNode(acu: ASTCompilationUnit): JavaNode = - acu.getFirstDescendantOfType(ASTAnyTypeBodyDeclaration::class.java).declarationNode - } - - object TopLevelTypeDeclarationParsingCtx : NodeParsingCtx("top-level declaration") { - - override fun getTemplate(construct: String, ctx: ParserTestCtx): String = """ - ${ctx.imports.joinToString(separator = "\n")} - $construct - """.trimIndent() - - override fun retrieveNode(acu: ASTCompilationUnit): ASTAnyTypeDeclaration = acu.getFirstDescendantOfType(ASTAnyTypeDeclaration::class.java)!! - } - - object TypeParsingCtx : NodeParsingCtx("type") { - override fun getTemplate(construct: String, ctx: ParserTestCtx): String = - """ - ${ctx.imports.joinToString(separator = "\n")} - ${ctx.genClassHeader} { - Object f = ($construct) null; - } - """.trimIndent() - - override fun retrieveNode(acu: ASTCompilationUnit): ASTType = - acu.getFirstDescendantOfType(ASTCastExpression::class.java).castType - } - - object AnnotationParsingCtx : NodeParsingCtx("annotation") { - override fun getTemplate(construct: String, ctx: ParserTestCtx): String = - """ - ${ctx.imports.joinToString(separator = "\n")} - ${ctx.genClassHeader} { - Object f = ($construct Type) null; - } - """.trimIndent() - - override fun retrieveNode(acu: ASTCompilationUnit): ASTAnnotation = - acu.getFirstDescendantOfType(ASTCastExpression::class.java) - .getFirstDescendantOfType(ASTAnnotation::class.java) - } - - object TypeParametersParsingCtx : NodeParsingCtx("type parameters") { - override fun getTemplate(construct: String, ctx: ParserTestCtx): String = - """ - ${ctx.imports.joinToString(separator = "\n")} - ${ctx.genClassHeader} { - - - public $construct void f() {} - } - """.trimIndent() - - override fun retrieveNode(acu: ASTCompilationUnit): ASTTypeParameters = - acu.getFirstDescendantOfType(ASTMethodDeclaration::class.java).typeParameters!! - } - - } } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/LanguageLevelCheckTests.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/LanguageLevelCheckTests.kt new file mode 100644 index 0000000000..2ded24cb62 --- /dev/null +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/LanguageLevelCheckTests.kt @@ -0,0 +1,77 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast + +import io.kotlintest.matchers.string.shouldContain +import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Earliest +import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Latest +import net.sourceforge.pmd.lang.java.ast.JavaVersion.J10 +import net.sourceforge.pmd.lang.java.ast.JavaVersion.J9 + +/** + * @author Clément Fournier + */ +class LanguageLevelCheckTests : ParserTestSpec({ + + parserTestGroup("Reserved 'var' identifier") { + + onVersions(J10..Latest) { + + inContext(TopLevelTypeDeclarationParsingCtx) { + "/*Top*/ class var { }" should throwParseException { ex -> + ex.message.shouldContain("'var' is reserved and cannot be used as a type name") + } + } + + inContext(EnclosedDeclarationParsingCtx) { + + "public enum var { A }" should throwParseException { ex -> + ex.message.shouldContain("'var' is reserved and cannot be used as a type name") + } + + "public class var { }" should throwParseException { ex -> + ex.message.shouldContain("'var' is reserved and cannot be used as a type name") + } + + "public interface var { }" should throwParseException { ex -> + ex.message.shouldContain("'var' is reserved and cannot be used as a type name") + } + + "public @interface var { }" should throwParseException { ex -> + ex.message.shouldContain("'var' is reserved and cannot be used as a type name") + } + + "public void var() { return; }" should parse() + } + + inContext(StatementParsingCtx) { + "/*Local*/ class var { }" should throwParseException { ex -> + ex.message.shouldContain("'var' is reserved and cannot be used as a type name") + } + + "int var = 0;" should parse() // only fail on type decls + "var var = 0;" should parse() + } + + inContext(ExpressionParsingCtx) { + "(var) -> {}" should parse() // only fail on type decls + } + } + + onVersions(Earliest..J9) { + + inContext(TopLevelTypeDeclarationParsingCtx) { + "/*Top*/ class var { }" should parse() + } + + inContext(StatementParsingCtx) { + "/*Local*/ class var { }" should parse() + "int var = 0;" should parse() + } + } + } + + +}) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/NodeParsingCtx.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/NodeParsingCtx.kt new file mode 100644 index 0000000000..4192a43a07 --- /dev/null +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/NodeParsingCtx.kt @@ -0,0 +1,160 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast + +import net.sourceforge.pmd.lang.ast.Node +import net.sourceforge.pmd.lang.ast.test.getChild +import net.sourceforge.pmd.lang.ast.test.numChildren + +/** + * Describes a kind of node that can be found commonly in the same contexts. + * This type defines some machinery to parse a string to this kind of node + * without much ado by placing it in a specific parsing context. + */ +abstract class NodeParsingCtx(val constructName: String) { + + abstract fun getTemplate(construct: String, ctx: ParserTestCtx): String + + abstract fun retrieveNode(acu: ASTCompilationUnit): T + + /** + * Parse the string in the context described by this object. The parsed node is usually + * the child of the returned [T] node. Note that [parseAndFind] can save you some keystrokes + * because it finds a descendant of the wanted type. + * + * @param construct The construct to parse + * + * @return A [T] whose child is the given statement + * + * @throws ParseException If the argument is no valid construct of this kind (mind the language version) + */ + fun parseNode(construct: String, ctx: ParserTestCtx): T { + val root = ctx.javaVersion.parser.parse(getTemplate(construct, ctx)) + + return retrieveNode(root) + } + + /** + * Parse the string the context described by this object, and finds the first descendant of type [N]. + * The descendant is searched for by [findFirstNodeOnStraightLine], to prevent accidental + * mis-selection of a node. In such a case, a [NoSuchElementException] is thrown, and you + * should fix your test case. + * + * @param construct The construct to parse + * @param N The type of node to find + * + * @return The first descendant of type [N] found in the parsed expression + * + * @throws NoSuchElementException If no node of type [N] is found by [findFirstNodeOnStraightLine] + * @throws ParseException If the argument is no valid construct of this kind + * + */ + inline fun parseAndFind(construct: String, ctx: ParserTestCtx): N = + parseNode(construct, ctx).findFirstNodeOnStraightLine(N::class.java) + ?: throw NoSuchElementException("No node of type ${N::class.java.simpleName} in the given $constructName:\n\t$construct") + + + override fun toString(): String = "$constructName context" +} + + +/** + * Finds the first descendant of type [N] of [this] node which is + * accessible in a straight line. The descendant must be accessible + * from the [this] on a path where each node has a single child. + * + * If one node has another child, the search is aborted and the method + * returns null. + */ +fun Node.findFirstNodeOnStraightLine(klass: Class): N? { + return when { + klass.isInstance(this) -> klass.cast(this) + this.numChildren == 1 -> getChild(0).findFirstNodeOnStraightLine(klass) + else -> null + } +} + + +object ExpressionParsingCtx : NodeParsingCtx("expression") { + + override fun getTemplate(construct: String, ctx: ParserTestCtx): String = + StatementParsingCtx.getTemplate("Object o = $construct;", ctx) + + override fun retrieveNode(acu: ASTCompilationUnit): ASTExpression = + StatementParsingCtx.retrieveNode(acu) + .getFirstDescendantOfType(ASTExpression::class.java)!! +} + +object StatementParsingCtx : NodeParsingCtx("statement") { + + override fun getTemplate(construct: String, ctx: ParserTestCtx): String = + EnclosedDeclarationParsingCtx.getTemplate("{\n$construct}", ctx) + + + override fun retrieveNode(acu: ASTCompilationUnit): ASTStatement = + EnclosedDeclarationParsingCtx.retrieveNode(acu) + .getFirstDescendantOfType(ASTBlock::class.java).jjtGetChild(0) +} + +object EnclosedDeclarationParsingCtx : NodeParsingCtx("enclosed declaration") { + + override fun getTemplate(construct: String, ctx: ParserTestCtx): String { + val source = ctx.fullSource + return if (source != null) { + source.substringBefore('{') + "{" + construct + source.substringAfter('{') + } else """ +${ctx.packageDecl} +${ctx.imports.joinToString(separator = "\n")} +${ctx.genClassHeader} { +$construct +} + """ + } + + override fun retrieveNode(acu: ASTCompilationUnit): JavaNode = + acu.getFirstDescendantOfType(ASTAnyTypeBodyDeclaration::class.java).declarationNode +} + +object TopLevelTypeDeclarationParsingCtx : NodeParsingCtx("top-level declaration") { + + override fun getTemplate(construct: String, ctx: ParserTestCtx): String = """ + ${ctx.imports.joinToString(separator = "\n")} + $construct + """.trimIndent() + + override fun retrieveNode(acu: ASTCompilationUnit): ASTAnyTypeDeclaration = acu.getFirstDescendantOfType(ASTAnyTypeDeclaration::class.java)!! +} + +object TypeParsingCtx : NodeParsingCtx("type") { + override fun getTemplate(construct: String, ctx: ParserTestCtx): String = + StatementParsingCtx.getTemplate(" Object f = ($construct) null;", ctx) + + override fun retrieveNode(acu: ASTCompilationUnit): ASTType = + StatementParsingCtx.retrieveNode(acu) + .descendants(ASTCastExpression::class.java) + .first()!! + .children(ASTType::class.java) + .first()!! +} + +object AnnotationParsingCtx : NodeParsingCtx("annotation") { + override fun getTemplate(construct: String, ctx: ParserTestCtx): String = + StatementParsingCtx.getTemplate("$construct Object f = null;", ctx) + + override fun retrieveNode(acu: ASTCompilationUnit): ASTAnnotation = + StatementParsingCtx.retrieveNode(acu) + .getFirstDescendantOfType(ASTAnnotation::class.java)!! +} + +object TypeParametersParsingCtx : NodeParsingCtx("type parameters") { + override fun getTemplate(construct: String, ctx: ParserTestCtx): String = + EnclosedDeclarationParsingCtx.getTemplate("public $construct void f() {}", ctx) + + override fun retrieveNode(acu: ASTCompilationUnit): ASTTypeParameters = + EnclosedDeclarationParsingCtx.retrieveNode(acu) + .descendantsOrSelf() + .last(ASTMethodDeclaration::class.java)!! + .typeParameters!! +} diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ParenthesesTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ParenthesesTest.kt index 2cfa9ecc8d..d9c95dee40 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ParenthesesTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ParenthesesTest.kt @@ -7,8 +7,6 @@ package net.sourceforge.pmd.lang.java.ast import io.kotlintest.shouldBe import net.sourceforge.pmd.lang.ast.test.shouldBe import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType.INT -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.ExpressionParsingCtx -import net.sourceforge.pmd.lang.java.ast.ParserTestCtx.Companion.StatementParsingCtx /** * @author Clément Fournier diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ParserTestSpec.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ParserTestSpec.kt index bbdaedebc4..814997e2d0 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ParserTestSpec.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ParserTestSpec.kt @@ -1,6 +1,9 @@ package net.sourceforge.pmd.lang.java.ast -import io.kotlintest.* +import io.kotlintest.AbstractSpec +import io.kotlintest.Matcher +import io.kotlintest.TestContext +import io.kotlintest.TestType import io.kotlintest.specs.IntelliMarker import net.sourceforge.pmd.lang.ast.Node import net.sourceforge.pmd.lang.ast.test.* @@ -134,17 +137,24 @@ abstract class ParserTestSpec(body: ParserTestSpec.() -> Unit) : AbstractSpec(), infix fun String.shouldNot(matcher: Matcher) = should(matcher.invert()) - fun inContext(nodeParsingCtx: Companion.NodeParsingCtx<*>, assertions: ImplicitNodeParsingCtx.() -> Unit) { + fun inContext(nodeParsingCtx: NodeParsingCtx<*>, assertions: ImplicitNodeParsingCtx.() -> Unit) { ImplicitNodeParsingCtx(nodeParsingCtx).assertions() } - inner class ImplicitNodeParsingCtx(private val nodeParsingCtx: Companion.NodeParsingCtx<*>) { + inner class ImplicitNodeParsingCtx(private val nodeParsingCtx: NodeParsingCtx<*>) { /** * A matcher that succeeds if the string parses correctly. */ fun parse(): Matcher = this@VersionedTestCtx.parseIn(nodeParsingCtx) + /** + * A matcher that succeeds if parsing throws a ParseException. + */ + fun throwParseException(expected: (ParseException) -> Unit = {}): Assertions = + this@VersionedTestCtx.notParseIn(nodeParsingCtx, expected) + + fun parseAs(matcher: ValuedNodeSpec): Assertions = { str -> val node = nodeParsingCtx.parseNode(str, this@VersionedTestCtx) val idx = node.jjtGetChildIndex() diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/TestExtensions.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/TestExtensions.kt index 0cd92c12fc..ab071dbedf 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/TestExtensions.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/TestExtensions.kt @@ -7,6 +7,7 @@ import io.kotlintest.should import net.sourceforge.pmd.lang.ast.GenericToken import net.sourceforge.pmd.lang.ast.Node import net.sourceforge.pmd.lang.ast.test.* +import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType.* import java.util.* import kotlin.reflect.KCallable @@ -288,7 +289,7 @@ fun TreeNodeWrapper.arrayType(contents: NodeSpec = EmptyA } -fun TreeNodeWrapper.primitiveType(type: ASTPrimitiveType.PrimitiveType, assertions: NodeSpec = EmptyAssertions) = +fun TreeNodeWrapper.primitiveType(type: PrimitiveType, assertions: NodeSpec = EmptyAssertions) = child { it::getModelConstant shouldBe type it::getTypeImage shouldBe type.token @@ -424,7 +425,7 @@ fun TreeNodeWrapper.switchExpr(assertions: NodeSpec.number(primitiveType: ASTPrimitiveType.PrimitiveType? = null, assertions: NodeSpec = EmptyAssertions) = +fun TreeNodeWrapper.number(primitiveType: PrimitiveType? = null, assertions: NodeSpec = EmptyAssertions) = child { if (primitiveType != null) { it::getPrimitiveType shouldBe primitiveType diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/Utils.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/Utils.kt new file mode 100644 index 0000000000..6caca85b98 --- /dev/null +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/Utils.kt @@ -0,0 +1,127 @@ +package net.sourceforge.pmd.lang.java.symbols + +import io.kotlintest.matchers.haveSize +import io.kotlintest.properties.Gen +import io.kotlintest.should +import net.sourceforge.pmd.lang.java.JavaParsingHelper; +import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit +import net.sourceforge.pmd.lang.java.qname.QualifiedNameFactory +import net.sourceforge.pmd.lang.java.symbols.internal.impl.SymbolFactory +import net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect.ReflectionSymFactory +import java.io.File +import java.io.IOException +import java.util.* + +/** Testing utilities */ + +fun Class<*>.getAst(): ASTCompilationUnit = JavaParsingHelper.WITH_PROCESSING.parseClass(this) + +fun Class<*>.getTypeDeclaration(): ASTAnyTypeDeclaration = + JavaParsingHelper.WITH_PROCESSING.parseClass(this).let { acu -> + if (this.enclosingClass == null) { + acu.getFirstDescendantOfType(ASTAnyTypeDeclaration::class.java) + } else { + val qname = QualifiedNameFactory.ofClass(this) + acu.findDescendantsOfType(ASTAnyTypeDeclaration::class.java, true) + .stream().filter { it.qualifiedName == qname } + .findFirst() + .get() + } + } + +val testSymFactory = ReflectionSymFactory() +fun classSym(klass: Class<*>?) = testSymFactory.getClassSymbol(klass) + + +fun List.groupByUnique(keySelector: (T) -> K): Map = + groupBy(keySelector).mapValues { (_, vs) -> + vs should haveSize(1) + vs.first() + } + + +fun Gen.forAllEqual(test: (T) -> Pair) { + random().forEach { + val (t, r) = test(it) + if (t != r && r == t || t == r && r != t) { + throw AssertionError("Asymmetry in equals relation $t <=> $r") + } else if (t != r) { + throw AssertionError("Expected property of $it to be $r, got $t") + } + } +} + +/** Generator of test instances. */ +object TestClassesGen : Gen> { + override fun constants(): Iterable> = emptyList() + + override fun random(): Sequence> = + sequenceOf( + java.lang.Object::class.java, + IntArray::class.java, + Cloneable::class.java, + Integer.TYPE, + Array::class.java) + + getClassesInPackage(javaClass.`package`.name + ".internal.testdata").asSequence() + + /** + * Scans all classes accessible from the context class loader which belong to the given package and subpackages. + * + * @param packageName The base package + * @return The classes + * @throws ClassNotFoundException + * @throws IOException + */ + fun getClassesInPackage(packageName: String): List> { + + val result = ArrayList>() + + /** Recursive method side-effecting on the result list. */ + fun findClasses(directory: File, packageName: String) { + if (!directory.exists()) { + return + } + val files = directory.listFiles() + for (file in files) { + if (file.isDirectory) { + assert(!file.name.contains(".")) + findClasses(file, packageName + "." + file.name) + } else if (file.name.endsWith(".class")) { + result.add(Class.forName(packageName + '.' + file.name.substring(0, file.name.length - ".class".length))) + } + } + } + + val classLoader = Thread.currentThread().contextClassLoader!! + val path = packageName.replace('.', '/') + val resources = classLoader.getResources(path) + val dirs = generateSequence { + if (resources.hasMoreElements()) + File(resources.nextElement().file) + else null + } + + for (directory in dirs) { + findClasses(directory, packageName) + } + return result + } +} + +/** Generator of test instances. */ +object PrimitiveSymGen : Gen { + override fun constants() = listOf( + SymbolFactory.INT_SYM, + SymbolFactory.DOUBLE_SYM, + SymbolFactory.FLOAT_SYM, + SymbolFactory.VOID_SYM, + SymbolFactory.CHAR_SYM, + SymbolFactory.BYTE_SYM, + SymbolFactory.SHORT_SYM, + SymbolFactory.LONG_SYM, + SymbolFactory.BOOLEAN_SYM + ) + + override fun random() = emptySequence() +} diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ArraySymbolTests.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ArraySymbolTests.kt new file mode 100644 index 0000000000..ec5d4d1c7c --- /dev/null +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ArraySymbolTests.kt @@ -0,0 +1,130 @@ +package net.sourceforge.pmd.lang.java.symbols.internal + +import io.kotlintest.matchers.collections.shouldHaveSize +import io.kotlintest.specs.WordSpec +import net.sourceforge.pmd.lang.ast.test.shouldBe +import net.sourceforge.pmd.lang.ast.test.shouldBeA +import net.sourceforge.pmd.lang.java.ast.JavaNode +import net.sourceforge.pmd.lang.java.symbols.JAccessibleElementSymbol.PRIMITIVE_PACKAGE +import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol +import net.sourceforge.pmd.lang.java.symbols.JFieldSymbol +import net.sourceforge.pmd.lang.java.symbols.internal.impl.SymbolFactory +import net.sourceforge.pmd.lang.java.symbols.testSymFactory + +/** + * @author Clément Fournier + * @since 7.0.0 + */ +class ArraySymbolTests : WordSpec({ + + "An array symbol" should { + + "have a length field" { + val intArr = testSymFactory.makeArraySymbol(SymbolFactory.INT_SYM) + + intArr.getDeclaredField("length").shouldBeA { + it::isFinal shouldBe true + it::getSimpleName shouldBe "length" + it::getPackageName shouldBe PRIMITIVE_PACKAGE + it::getEnclosingClass shouldBe intArr + } + + + val javanodeArr = testSymFactory.makeArraySymbol(testSymFactory.getClassSymbol(JavaNode::class.java)) + + + javanodeArr.getDeclaredField("length").shouldBeA { + it::isFinal shouldBe true + it::getSimpleName shouldBe "length" + it::getPackageName shouldBe "net.sourceforge.pmd.lang.java.ast" + it::getEnclosingClass shouldBe javanodeArr + } + } + + "have a clone method" { + val intArr = testSymFactory.makeArraySymbol(SymbolFactory.INT_SYM) + + intArr.getDeclaredMethods("clone").single().also { + it::getSimpleName shouldBe "clone" + it::getPackageName shouldBe PRIMITIVE_PACKAGE + it::getEnclosingClass shouldBe intArr + } + + + val javanodeArr = testSymFactory.makeArraySymbol(testSymFactory.getClassSymbol(JavaNode::class.java)) + + javanodeArr.getDeclaredMethods("clone").single().also { + it::getSimpleName shouldBe "clone" + it::getPackageName shouldBe "net.sourceforge.pmd.lang.java.ast" + it::getEnclosingClass shouldBe javanodeArr + } + } + + "have a constructor method" { + val intArr = testSymFactory.makeArraySymbol(SymbolFactory.INT_SYM) + + intArr.constructors.single().also { + it::getSimpleName shouldBe JConstructorSymbol.CTOR_NAME + it::getPackageName shouldBe PRIMITIVE_PACKAGE + it::getEnclosingClass shouldBe intArr + it.formalParameters.shouldHaveSize(1) + } + + + val javanodeArr = testSymFactory.makeArraySymbol(testSymFactory.getClassSymbol(JavaNode::class.java)) + + javanodeArr.constructors.single().also { + it::getSimpleName shouldBe JConstructorSymbol.CTOR_NAME + it::getEnclosingClass shouldBe javanodeArr + it::getPackageName shouldBe "net.sourceforge.pmd.lang.java.ast" + it.formalParameters.shouldHaveSize(1) + } + } + + "reflect its simple name properly" { + + val stringArr = testSymFactory.makeArraySymbol(SymbolFactory.STRING_SYM) + + stringArr::getSimpleName shouldBe "String[]" + + val intArr = testSymFactory.makeArraySymbol(SymbolFactory.INT_SYM) + + intArr::getSimpleName shouldBe "int[]" + + val iiarr = testSymFactory.makeArraySymbol(intArr) + + iiarr::getSimpleName shouldBe "int[][]" + + } + + "reflect its binary name properly" { + + val stringArr = testSymFactory.makeArraySymbol(SymbolFactory.STRING_SYM) + + stringArr::getBinaryName shouldBe "java.lang.String[]" + + val intArr = testSymFactory.makeArraySymbol(SymbolFactory.INT_SYM) + + intArr::getBinaryName shouldBe "int[]" + + val iiarr = testSymFactory.makeArraySymbol(intArr) + + iiarr::getBinaryName shouldBe "int[][]" + + } + + "reflect its package name properly" { + + val stringArr = testSymFactory.makeArraySymbol(SymbolFactory.STRING_SYM) + + stringArr::getPackageName shouldBe "java.lang" + + val iarr = testSymFactory.makeArraySymbol(SymbolFactory.INT_SYM) + + iarr::getPackageName shouldBe PRIMITIVE_PACKAGE + + } + + } + +}) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ClassPathSymbolResolverTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ClassPathSymbolResolverTest.kt new file mode 100644 index 0000000000..6dab1bfc04 --- /dev/null +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ClassPathSymbolResolverTest.kt @@ -0,0 +1,50 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal + +import io.kotlintest.shouldBe +import io.kotlintest.specs.FunSpec +import javasymbols.testdata.impls.GenericClass +import javasymbols.testdata.impls.SomeInnerClasses +import net.sourceforge.pmd.lang.ast.test.shouldBe +import net.sourceforge.pmd.lang.java.symbols.classSym +import net.sourceforge.pmd.lang.java.symbols.internal.impl.reflect.ClasspathSymbolResolver +import net.sourceforge.pmd.lang.java.symbols.testSymFactory + +/** + * @author Clément Fournier + */ +class ClassPathSymbolResolverTest : FunSpec({ + + + val cl = Thread.currentThread().contextClassLoader + val resolver = ClasspathSymbolResolver(cl, testSymFactory) + + test("Test outer class") { + + resolver.resolveClassFromCanonicalName(GenericClass::class.java.canonicalName) shouldBe classSym(GenericClass::class.java) + } + + test("Test inner class") { + + resolver.resolveClassFromCanonicalName("javasymbols.testdata.impls.SomeInnerClasses.Inner") + .shouldBe(classSym(SomeInnerClasses.Inner::class.java)) + } + + test("Test inner class with dollar") { + + resolver.resolveClassFromCanonicalName("javasymbols.testdata.impls.SomeInnerClasses\$Inner") + .shouldBe(classSym(SomeInnerClasses.Inner::class.java)) + } + + test("Test default to unresolved") { + + val sym = resolver.resolveClassOrDefault("javasymbols.testdata.impls.This.Does.NotExist") + + sym::isUnresolved shouldBe true + sym::getSimpleName shouldBe "NotExist" + } + +}) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JTypeParameterSymbolTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JTypeParameterSymbolTest.kt new file mode 100644 index 0000000000..2385721e95 --- /dev/null +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JTypeParameterSymbolTest.kt @@ -0,0 +1,23 @@ +package net.sourceforge.pmd.lang.java.symbols.internal + +import io.kotlintest.shouldNotBe +import io.kotlintest.specs.WordSpec +import javasymbols.testdata.impls.GenericClass +import javasymbols.testdata.impls.GenericClassCopy +import net.sourceforge.pmd.lang.java.symbols.classSym + +/** + * @author Clément Fournier + * @since 7.0.0 + */ +class JTypeParameterSymbolTest : WordSpec({ + + "A type parameter symbol" should { + + "not be equal to type parameter symbols declared on any other entity" { + classSym(GenericClass::class.java)!!.typeParameters shouldNotBe classSym(GenericClassCopy::class.java)!!.typeParameters + } + + } + +}) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/PrimitiveSymbolTests.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/PrimitiveSymbolTests.kt new file mode 100644 index 0000000000..f08033cf5d --- /dev/null +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/PrimitiveSymbolTests.kt @@ -0,0 +1,58 @@ +package net.sourceforge.pmd.lang.java.symbols.internal + +import io.kotlintest.matchers.collections.shouldBeEmpty +import io.kotlintest.specs.WordSpec +import net.sourceforge.pmd.lang.ast.test.shouldBe +import net.sourceforge.pmd.lang.java.symbols.JAccessibleElementSymbol.PRIMITIVE_PACKAGE +import net.sourceforge.pmd.lang.java.symbols.PrimitiveSymGen + +/** + * @author Clément Fournier + * @since 7.0.0 + */ +class PrimitiveSymbolTests : WordSpec({ + + + + "A primitive symbol" should { + + "have no fields" { + PrimitiveSymGen.constants().forEach { + it.declaredFields.shouldBeEmpty() + } + } + + "have no methods" { + PrimitiveSymGen.constants().forEach { + it.declaredMethods.shouldBeEmpty() + } + } + + "have no constructors" { + PrimitiveSymGen.constants().forEach { + it.constructors.shouldBeEmpty() + } + } + + "have no superclass" { + PrimitiveSymGen.constants().forEach { + it::getSuperclass shouldBe null + } + } + + "have no superInterfaces" { + PrimitiveSymGen.constants().forEach { + it::getSuperInterfaces shouldBe emptyList() + } + } + + + "reflect its package name properly" { + PrimitiveSymGen.constants().forEach { + it::getPackageName shouldBe PRIMITIVE_PACKAGE + } + } + + } + +}) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ReflectedClassSymbolTests.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ReflectedClassSymbolTests.kt new file mode 100644 index 0000000000..601698a7f3 --- /dev/null +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ReflectedClassSymbolTests.kt @@ -0,0 +1,76 @@ +package net.sourceforge.pmd.lang.java.symbols.internal + +import io.kotlintest.shouldBe +import io.kotlintest.specs.WordSpec +import net.sourceforge.pmd.lang.ast.test.shouldBe +import net.sourceforge.pmd.lang.java.symbols.TestClassesGen +import net.sourceforge.pmd.lang.java.symbols.classSym +import net.sourceforge.pmd.lang.java.symbols.forAllEqual +import net.sourceforge.pmd.lang.java.symbols.internal.impl.SymbolFactory + +/** + * @author Clément Fournier + * @since 7.0.0 + */ +class ReflectedClassSymbolTests : WordSpec({ + + "A class symbol" should { + + "reflect its superclass correctly" { + TestClassesGen.forAllEqual { + classSym(it)!!.superclass to classSym(it.superclass) + } + } + + "reflect its type parameters correctly" { + TestClassesGen.random().forEach { clazz -> + val classSym = classSym(clazz)!! + classSym.typeParameters.map { it.simpleName } shouldBe clazz.typeParameters.toList().map { it.name } + classSym.typeParameters.forEach { + it.declaringSymbol shouldBe classSym + } + } + } + + "reflect its superinterfaces correctly" { + TestClassesGen.forAllEqual { + classSym(it)!!.superInterfaces to it.interfaces.toList().map { classSym(it) } + } + } + + "reflect its simple name properly" { + TestClassesGen.forAllEqual { + classSym(it)!!.simpleName to it.simpleName + } + } + + "reflect its canonical name properly" { + TestClassesGen.forAllEqual { + classSym(it)!!.canonicalName to it.canonicalName + } + } + + "reflect its modifiers properly" { + TestClassesGen.forAllEqual { + classSym(it)!!.modifiers to it.modifiers + } + } + + "reflect its component type when it is a primitive array" { + + val iarr = classSym(IntArray::class.java)!! + iarr::isArray shouldBe true + iarr::isInterface shouldBe false + iarr::getArrayComponent shouldBe SymbolFactory.INT_SYM + } + + "reflect its component type when it is a reference array" { + + val arr = classSym(Array::class.java)!! + arr::isArray shouldBe true + arr::isInterface shouldBe false + arr::getArrayComponent shouldBe classSym(String::class.java) + } + } + +}) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ReflectedFieldSymbolTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ReflectedFieldSymbolTest.kt new file mode 100644 index 0000000000..5144eecab6 --- /dev/null +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ReflectedFieldSymbolTest.kt @@ -0,0 +1,52 @@ +package net.sourceforge.pmd.lang.java.symbols.internal + +import io.kotlintest.shouldBe +import io.kotlintest.shouldNotBe +import io.kotlintest.specs.WordSpec +import javasymbols.testdata.impls.IdenticalToSomeFields +import javasymbols.testdata.impls.SomeFields +import net.sourceforge.pmd.lang.java.symbols.TestClassesGen +import net.sourceforge.pmd.lang.java.symbols.classSym +import net.sourceforge.pmd.lang.java.symbols.forAllEqual + +/** + * @author Clément Fournier + * @since 7.0.0 + */ +class ReflectedFieldSymbolTest : WordSpec({ + + "A field symbol" should { + + "reflect its name properly" { + classSym(SomeFields::class.java)!!.getDeclaredField("a")!!.simpleName shouldBe "a" + classSym(SomeFields::class.java)!!.getDeclaredField("bb")!!.simpleName shouldBe "bb" + } + + "be equal to itself" { + TestClassesGen.forAllEqual { + Pair( + // note: different class symbol instances + classSym(it)!!.declaredFields, + classSym(it)!!.declaredFields + ) + } + } + + "reflect its modifiers properly" { + TestClassesGen.filterNot { it.isArray }.forAllEqual { + Pair( + classSym(it)!!.declaredFields.map { it.simpleName to it.modifiers }, + it.declaredFields.map { it.name to it.modifiers } + ) + } + } + + + "not be equal to fields declared in other classes" { + classSym(SomeFields::class.java)!!.getDeclaredField("a")!! shouldNotBe classSym(IdenticalToSomeFields::class.java)!!.getDeclaredField("a")!! + classSym(SomeFields::class.java)!!.getDeclaredField("bb")!! shouldNotBe classSym(IdenticalToSomeFields::class.java)!!.getDeclaredField("bb")!! + } + + } + +}) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ReflectedMethodSymbolTests.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ReflectedMethodSymbolTests.kt new file mode 100644 index 0000000000..5f04a0efc5 --- /dev/null +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/ReflectedMethodSymbolTests.kt @@ -0,0 +1,29 @@ +package net.sourceforge.pmd.lang.java.symbols.internal + +import io.kotlintest.shouldNotBe +import io.kotlintest.specs.WordSpec +import net.sourceforge.pmd.lang.java.symbols.classSym +import javasymbols.testdata.impls.Overloads + +/** + * @author Clément Fournier + * @since 7.0.0 + */ +class ReflectedMethodSymbolTests : WordSpec({ + + "A method symbol" should { + + // note that this is still limited because parameter symbols + // don't yet have access to their type + "not be equal to its overloads" { + + val clazz = classSym(Overloads::class.java)!! + + val overloads = clazz.getDeclaredMethods("anOverload") + + overloads[0] shouldNotBe overloads[1] + } + + } + +}) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/UnresolvedClassTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/UnresolvedClassTest.kt new file mode 100644 index 0000000000..7a1f7efa4e --- /dev/null +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/UnresolvedClassTest.kt @@ -0,0 +1,33 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal + +import io.kotlintest.specs.FunSpec +import net.sourceforge.pmd.lang.ast.test.shouldBe +import net.sourceforge.pmd.lang.java.symbols.testSymFactory + +/** + * @author Clément Fournier + */ +class UnresolvedClassTest : FunSpec({ + + test("Test simple unresolved class") { + + val sym = testSymFactory.makeUnresolvedReference("some.pack.Class") + + sym::isUnresolved shouldBe true + sym::getSimpleName shouldBe "Class" + sym::getPackageName shouldBe "some.pack" + sym::getCanonicalName shouldBe "some.pack.Class" + sym::getBinaryName shouldBe "some.pack.Class" + + sym::isClass shouldBe true + sym::isArray shouldBe false + sym::isAnonymousClass shouldBe false + sym::isEnum shouldBe false + sym::isInterface shouldBe false + } + +}) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/ast/ParserCornerCases.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.java similarity index 100% rename from pmd-java/src/test/resources/net/sourceforge/pmd/ast/ParserCornerCases.java rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.java diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/ast/ParserCornerCases17.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.java similarity index 100% rename from pmd-java/src/test/resources/net/sourceforge/pmd/ast/ParserCornerCases17.java rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.java diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/ast/ParserCornerCases18.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.java similarity index 100% rename from pmd-java/src/test/resources/net/sourceforge/pmd/ast/ParserCornerCases18.java rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.java diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsAnnotationName.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsAnnotationName.java deleted file mode 100644 index b31f370d75..0000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsAnnotationName.java +++ /dev/null @@ -1,8 +0,0 @@ -public class LocalVariableTypeInference_varAsAnnotationName { - public static @interface var { } - public static void main(String... args) { - var var = 1; - - System.out.println("var = " + var); - } -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsEnumName.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsEnumName.java deleted file mode 100644 index 1cb91c604e..0000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsEnumName.java +++ /dev/null @@ -1,8 +0,0 @@ -public class LocalVariableTypeInference_varAsEnumName { - public enum var { A } - public static void main(String... args) { - var var = 1; - - System.out.println("var = " + var); - } -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsIdentifier.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsIdentifier.java deleted file mode 100644 index 275ab1c4ec..0000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsIdentifier.java +++ /dev/null @@ -1,7 +0,0 @@ -public class LocalVariableTypeInference_varAsIdentifier { - public static void main(String... args) { - var var = 1; - - System.out.println("var = " + var); - } -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsTypeIdentifier.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsTypeIdentifier.java deleted file mode 100644 index ffd2db6505..0000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsTypeIdentifier.java +++ /dev/null @@ -1,8 +0,0 @@ -public class LocalVariableTypeInference_varAsTypeIdentifier { - public static class var { } - public static void main(String... args) { - var var = 1; - - System.out.println("var = " + var); - } -} diff --git a/pmd-javascript/etc/grammar/es5.jj b/pmd-javascript/etc/grammar/es5.jj index 4878bc295f..688692d61d 100644 --- a/pmd-javascript/etc/grammar/es5.jj +++ b/pmd-javascript/etc/grammar/es5.jj @@ -15,7 +15,7 @@ options { PARSER_BEGIN(Ecmascript5Parser) package net.sourceforge.pmd.lang.ecmascript5.ast; -import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; +import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.TokenMgrError; public class Ecmascript5Parser { diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 7d7011d3da..74d7303482 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -96,5 +96,15 @@ pmd-test test + + org.junit.vintage + junit-vintage-engine + test + + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-javascript/src/main/ant/alljavacc.xml b/pmd-javascript/src/main/ant/alljavacc.xml index 8cbcad70bd..6f7a0a7bc4 100644 --- a/pmd-javascript/src/main/ant/alljavacc.xml +++ b/pmd-javascript/src/main/ant/alljavacc.xml @@ -36,7 +36,7 @@ javacchome="${javacc-home.path}" /> + value="class Ecmascript5ParserTokenManager extends net.sourceforge.pmd.lang.ast.AbstractTokenManager" /> diff --git a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript5/Ecmascript5TokenManager.java b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript5/Ecmascript5TokenManager.java index 292801dd6f..634a1283d1 100644 --- a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript5/Ecmascript5TokenManager.java +++ b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript5/Ecmascript5TokenManager.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.lang.ecmascript5; import java.io.Reader; import net.sourceforge.pmd.lang.TokenManager; -import net.sourceforge.pmd.lang.ast.impl.javacc.SimpleCharStream; +import net.sourceforge.pmd.lang.ast.impl.javacc.CharStreamFactory; import net.sourceforge.pmd.lang.ecmascript5.ast.Ecmascript5ParserTokenManager; /** @@ -23,7 +23,7 @@ public class Ecmascript5TokenManager implements TokenManager { * the source code */ public Ecmascript5TokenManager(Reader source) { - tokenManager = new Ecmascript5ParserTokenManager(new SimpleCharStream(source)); + tokenManager = new Ecmascript5ParserTokenManager(CharStreamFactory.simpleCharStream(source)); } @Override diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTFunctionNodeTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTFunctionNodeTest.java index ef040c68b2..40726ff26a 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTFunctionNodeTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTFunctionNodeTest.java @@ -11,7 +11,7 @@ public class ASTFunctionNodeTest extends EcmascriptParserTestBase { @Test public void testGetBody() { - ASTAstRoot node = parse("function foo() { var a = 'a'; }"); + ASTAstRoot node = js.parse("function foo() { var a = 'a'; }"); ASTFunctionNode fn = node.getFirstDescendantOfType(ASTFunctionNode.class); Assert.assertFalse(fn.isClosure()); EcmascriptNode body = fn.getBody(); @@ -20,7 +20,7 @@ public class ASTFunctionNodeTest extends EcmascriptParserTestBase { @Test public void testGetBodyFunctionClosureExpression() { - ASTAstRoot node = parse18("(function(x) x*x)"); + ASTAstRoot node = js18.parse("(function(x) x*x)"); ASTFunctionNode fn = node.getFirstDescendantOfType(ASTFunctionNode.class); Assert.assertTrue(fn.isClosure()); EcmascriptNode body = fn.getBody(); diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTTryStatementTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTTryStatementTest.java index 738676eabc..40dcb6c097 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTTryStatementTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTTryStatementTest.java @@ -17,7 +17,7 @@ import org.mozilla.javascript.ast.AstRoot; public class ASTTryStatementTest extends EcmascriptParserTestBase { private ASTTryStatement getTryStmt(String js) { - EcmascriptNode node = parse(js); + EcmascriptNode node = this.js.parse(js); List trys = node.findDescendantsOfType(ASTTryStatement.class); Assert.assertEquals(1, trys.size()); ASTTryStatement tryStmt = trys.get(0); diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTest.java index e4f3931c6e..8203c91007 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTest.java @@ -32,7 +32,7 @@ public class EcmascriptParserTest extends EcmascriptParserTestBase { @Test public void testLineNumbers() { final String SOURCE_CODE = "function a() {" + PMD.EOL + " alert('hello');" + PMD.EOL + "}" + PMD.EOL; - EcmascriptNode node = parse(SOURCE_CODE); + EcmascriptNode node = js.parse(SOURCE_CODE); assertEquals(1, node.getBeginLine()); assertEquals(1, node.getBeginColumn()); assertEquals(3, node.getEndLine()); @@ -69,7 +69,7 @@ public class EcmascriptParserTest extends EcmascriptParserTestBase { MyEcmascriptRule rule = new MyEcmascriptRule(); RuleContext ctx = new RuleContext(); - rule.apply(Arrays.asList(parse(source)), ctx); + rule.apply(Arrays.asList(js.parse(source)), ctx); assertEquals("Scope from 2 to 4", output.get(0)); assertEquals("Scope from 4 to 6", output.get(1)); @@ -80,7 +80,7 @@ public class EcmascriptParserTest extends EcmascriptParserTestBase { */ @Test public void testArrayAccess() { - EcmascriptNode node = parse("function a() { b['a'] = 1; c[1] = 2; }"); + EcmascriptNode node = js.parse("function a() { b['a'] = 1; c[1] = 2; }"); List arrays = node.findDescendantsOfType(ASTElementGet.class); assertEquals("b", arrays.get(0).getTarget().getImage()); assertEquals("a", arrays.get(0).getElement().getImage()); @@ -94,9 +94,9 @@ public class EcmascriptParserTest extends EcmascriptParserTestBase { */ @Test public void testArrayMethod() { - EcmascriptNode rootNode = parse( - "function test(){\n" + " a(); // OK\n" + " b.c(); // OK\n" + " d[0](); // OK\n" - + " e[0].f(); // OK\n" + " y.z[0](); // FAIL ==> java.lang.NullPointerException\n" + "}"); + EcmascriptNode rootNode = js.parse( + "function test(){\n" + " a(); // OK\n" + " b.c(); // OK\n" + " d[0](); // OK\n" + + " e[0].f(); // OK\n" + " y.z[0](); // FAIL ==> java.lang.NullPointerException\n" + "}"); List calls = rootNode.findDescendantsOfType(ASTFunctionCall.class); List results = new ArrayList<>(); @@ -129,7 +129,7 @@ public class EcmascriptParserTest extends EcmascriptParserTestBase { */ @Test public void testCaseAsIdentifier() { - ASTAstRoot rootNode = parse("function f(a){\n" + " a.case.flag = 1;\n" + " return;\n" + "}"); + ASTAstRoot rootNode = js.parse("function f(a){\n" + " a.case.flag = 1;\n" + " return;\n" + "}"); ASTBlock block = rootNode.getFirstDescendantOfType(ASTBlock.class); assertFalse(block.jjtGetChild(0) instanceof ASTEmptyExpression); assertTrue(block.jjtGetChild(0) instanceof ASTExpressionStatement); @@ -163,9 +163,9 @@ public class EcmascriptParserTest extends EcmascriptParserTestBase { */ @Test public void testVoidKeyword() { - ASTAstRoot rootNode = parse("function f(matchFn, fieldval, n){\n" - + " return (matchFn)?(matcharray = eval(matchFn+\"('\"+fieldval+\"','\"+n.id+\"')\")):void(0);\n" - + "}\n"); + ASTAstRoot rootNode = js.parse("function f(matchFn, fieldval, n){\n" + + " return (matchFn)?(matcharray = eval(matchFn+\"('\"+fieldval+\"','\"+n.id+\"')\")):void(0);\n" + + "}\n"); ASTUnaryExpression unary = rootNode.getFirstDescendantOfType(ASTUnaryExpression.class); assertEquals("void", unary.getImage()); } @@ -175,9 +175,9 @@ public class EcmascriptParserTest extends EcmascriptParserTestBase { */ @Test public void testXorAssignment() { - ASTAstRoot rootNode = parse("function f() { var x = 2; x ^= 2; x &= 2; x |= 2; " - + "x &&= true; x ||= false; x *= 2; x /= 2; x %= 2; x += 2; x -= 2; " - + "x <<= 2; x >>= 2; x >>>= 2; }"); + ASTAstRoot rootNode = js.parse("function f() { var x = 2; x ^= 2; x &= 2; x |= 2; " + + "x &&= true; x ||= false; x *= 2; x /= 2; x %= 2; x += 2; x -= 2; " + + "x <<= 2; x >>= 2; x >>>= 2; }"); ASTAssignment infix = rootNode.getFirstDescendantOfType(ASTAssignment.class); assertEquals("^=", infix.getImage()); } diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTestBase.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTestBase.java index ef46aae5e5..cf6eade47e 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTestBase.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTestBase.java @@ -4,24 +4,21 @@ package net.sourceforge.pmd.lang.ecmascript.ast; -import java.io.Reader; -import java.io.StringReader; - +import net.sourceforge.pmd.lang.ParserOptions; import net.sourceforge.pmd.lang.ecmascript.EcmascriptParserOptions; +import net.sourceforge.pmd.lang.ecmascript.EcmascriptParserOptions.Version; public abstract class EcmascriptParserTestBase { - public ASTAstRoot parse(String code) { - EcmascriptParser parser = new EcmascriptParser(new EcmascriptParserOptions()); - Reader sourceCode = new StringReader(code); - return (ASTAstRoot) parser.parse(sourceCode); - } - public ASTAstRoot parse18(String code) { + protected final JsParsingHelper js = JsParsingHelper.DEFAULT.withResourceContext(getClass()); + + protected final JsParsingHelper js18 = JsParsingHelper.DEFAULT.withResourceContext(getClass()) + .withParserOptions(parserVersion(Version.VERSION_1_8)); + + public ParserOptions parserVersion(EcmascriptParserOptions.Version version) { EcmascriptParserOptions parserOptions = new EcmascriptParserOptions(); - parserOptions.setRhinoLanguageVersion(EcmascriptParserOptions.Version.VERSION_1_8); - EcmascriptParser parser = new EcmascriptParser(parserOptions); - Reader sourceCode = new StringReader(code); - return (ASTAstRoot) parser.parse(sourceCode); + parserOptions.setRhinoLanguageVersion(version); + return parserOptions; } } diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/JsParsingHelper.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/JsParsingHelper.java new file mode 100644 index 0000000000..055891146a --- /dev/null +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/JsParsingHelper.java @@ -0,0 +1,22 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.ecmascript.ast; + +import net.sourceforge.pmd.lang.ast.test.BaseParsingHelper; +import net.sourceforge.pmd.lang.ecmascript.EcmascriptLanguageModule; + +public final class JsParsingHelper extends BaseParsingHelper { + + public static final JsParsingHelper DEFAULT = new JsParsingHelper(Params.getDefaultProcess()); + + private JsParsingHelper(Params params) { + super(EcmascriptLanguageModule.NAME, ASTAstRoot.class, params); + } + + @Override + protected JsParsingHelper clone(Params params) { + return new JsParsingHelper(params); + } +} diff --git a/pmd-jsp/etc/grammar/JspParser.jjt b/pmd-jsp/etc/grammar/JspParser.jjt index af2c3540e7..9e27e3550a 100644 --- a/pmd-jsp/etc/grammar/JspParser.jjt +++ b/pmd-jsp/etc/grammar/JspParser.jjt @@ -31,7 +31,7 @@ options { PARSER_BEGIN(JspParser) package net.sourceforge.pmd.lang.jsp.ast; -import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; +import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.TokenMgrError; /** diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index d1499f1c77..fa27b7982e 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -93,10 +93,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-jsp/src/main/ant/alljavacc.xml b/pmd-jsp/src/main/ant/alljavacc.xml index 87aaa7524e..34207aa4a6 100644 --- a/pmd-jsp/src/main/ant/alljavacc.xml +++ b/pmd-jsp/src/main/ant/alljavacc.xml @@ -45,7 +45,7 @@ + value="class JspParserTokenManager extends net.sourceforge.pmd.lang.ast.AbstractTokenManager" /> diff --git a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/JspParser.java b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/JspParser.java index 780670c391..976657d90d 100644 --- a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/JspParser.java +++ b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/JspParser.java @@ -9,10 +9,10 @@ import java.io.Reader; import net.sourceforge.pmd.lang.AbstractParser; import net.sourceforge.pmd.lang.ParserOptions; import net.sourceforge.pmd.lang.TokenManager; +import net.sourceforge.pmd.lang.ast.AbstractTokenManager; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.ParseException; -import net.sourceforge.pmd.lang.ast.impl.javacc.AbstractTokenManager; -import net.sourceforge.pmd.lang.ast.impl.javacc.SimpleCharStream; +import net.sourceforge.pmd.lang.ast.impl.javacc.CharStreamFactory; /** * Adapter for the JspParser. @@ -31,7 +31,7 @@ public class JspParser extends AbstractParser { @Override public Node parse(String fileName, Reader source) throws ParseException { AbstractTokenManager.setFileName(fileName); - return new net.sourceforge.pmd.lang.jsp.ast.JspParser(new SimpleCharStream(source)).CompilationUnit(); + return new net.sourceforge.pmd.lang.jsp.ast.JspParser(CharStreamFactory.simpleCharStream(source)).CompilationUnit(); } } diff --git a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/JspTokenManager.java b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/JspTokenManager.java index 1342951e4a..e10a66daf0 100644 --- a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/JspTokenManager.java +++ b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/JspTokenManager.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.lang.jsp; import java.io.Reader; import net.sourceforge.pmd.lang.TokenManager; -import net.sourceforge.pmd.lang.ast.impl.javacc.JavaCharStream; +import net.sourceforge.pmd.lang.ast.impl.javacc.CharStreamFactory; import net.sourceforge.pmd.lang.jsp.ast.JspParserTokenManager; /** @@ -17,7 +17,7 @@ public class JspTokenManager implements TokenManager { private final JspParserTokenManager tokenManager; public JspTokenManager(Reader source) { - tokenManager = new JspParserTokenManager(new JavaCharStream(source)); + tokenManager = new JspParserTokenManager(CharStreamFactory.javaCharStream(source)); } @Override diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNodesTst.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNodesTst.java index 52d3dbc75d..fd8c4082fb 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNodesTst.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNodesTst.java @@ -4,68 +4,8 @@ package net.sourceforge.pmd.lang.jsp.ast; -import static org.junit.Assert.assertEquals; - -import java.io.StringReader; -import java.util.HashSet; -import java.util.Set; - -import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.ast.impl.javacc.JavaCharStream; - public abstract class AbstractJspNodesTst { - public void assertNumberOfNodes(Class clazz, String source, int number) { - Set nodes = getNodes(clazz, source); - assertEquals("Exactly " + number + " element(s) expected", number, nodes.size()); - } - - /** - * Run the JSP parser on the source, and return the nodes of type clazz. - * - * @param clazz - * @param source - * @return Set - */ - public Set getNodes(Class clazz, String source) { - JspParser parser = new JspParser(new JavaCharStream(new StringReader(source))); - Node rootNode = parser.CompilationUnit(); - Set nodes = new HashSet<>(); - addNodeAndSubnodes(rootNode, nodes, clazz); - return nodes; - } - - /** - * Return a subset of allNodes, containing the items in allNodes that are of - * the given type. - * - * @param clazz - * @param allNodes - * @return Set - */ - public Set getNodesOfType(Class clazz, Set allNodes) { - Set result = new HashSet<>(); - for (Node node : allNodes) { - if (clazz.equals(node.getClass())) { - result.add((T) node); - } - } - return result; - } - - /** - * Add the given node and its subnodes to the set of nodes. If clazz is not - * null, only nodes of the given class are put in the set of nodes. - */ - private void addNodeAndSubnodes(Node node, Set nodes, Class clazz) { - if (null != node) { - if ((null == clazz) || (clazz.equals(node.getClass()))) { - nodes.add((T) node); - } - for (int i = 0; i < node.jjtGetNumChildren(); i++) { - addNodeAndSubnodes(node.jjtGetChild(i), nodes, clazz); - } - } - } + protected JspParsingHelper jsp = JspParsingHelper.DEFAULT.withResourceContext(getClass()); } diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java index c62d1fc5b5..26a54a3f8b 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java @@ -9,11 +9,11 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; -import java.util.Set; import org.junit.Ignore; import org.junit.Test; @@ -33,7 +33,8 @@ public class JspDocStyleTest extends AbstractJspNodesTst { */ @Test public void testSimplestJsp() { - assertNumberOfNodes(ASTElement.class, TEST_SIMPLEST_HTML, 1); + List nodes = jsp.getNodes(ASTElement.class, TEST_SIMPLEST_HTML); + assertEquals("Exactly " + 1 + " element(s) expected", 1, nodes.size()); } /** @@ -41,22 +42,22 @@ public class JspDocStyleTest extends AbstractJspNodesTst { */ @Test public void testElementAttributeAndNamespace() { - Set nodes = getNodes(null, TEST_ELEMENT_AND_NAMESPACE); + ASTCompilationUnit root = jsp.parse(TEST_ELEMENT_AND_NAMESPACE); - Set elementNodes = getNodesOfType(ASTElement.class, nodes); + List elementNodes = root.findDescendantsOfType(ASTElement.class); assertEquals("One element node expected!", 1, elementNodes.size()); - ASTElement element = elementNodes.iterator().next(); + ASTElement element = elementNodes.get(0); assertEquals("Correct name expected!", "h:html", element.getName()); - assertEquals("Has namespace prefix!", true, element.isHasNamespacePrefix()); - assertEquals("Element is empty!", true, element.isEmpty()); + assertTrue("Has namespace prefix!", element.isHasNamespacePrefix()); + assertTrue("Element is empty!", element.isEmpty()); assertEquals("Correct namespace prefix of element expected!", "h", element.getNamespacePrefix()); assertEquals("Correct local name of element expected!", "html", element.getLocalName()); - Set attributeNodes = getNodesOfType(ASTAttribute.class, nodes); + List attributeNodes = root.findDescendantsOfType(ASTAttribute.class); assertEquals("One attribute node expected!", 1, attributeNodes.size()); - ASTAttribute attribute = attributeNodes.iterator().next(); + ASTAttribute attribute = attributeNodes.get(0); assertEquals("Correct name expected!", "MyNsPrefix:MyAttr", attribute.getName()); - assertEquals("Has namespace prefix!", true, attribute.isHasNamespacePrefix()); + assertTrue("Has namespace prefix!", attribute.isHasNamespacePrefix()); assertEquals("Correct namespace prefix of element expected!", "MyNsPrefix", attribute.getNamespacePrefix()); assertEquals("Correct local name of element expected!", "MyAttr", attribute.getLocalName()); @@ -69,32 +70,26 @@ public class JspDocStyleTest extends AbstractJspNodesTst { */ @Test public void testAttributeValueContainingHash() { - Set nodes = getNodes(null, TEST_ATTRIBUTE_VALUE_CONTAINING_HASH); + ASTCompilationUnit root = jsp.parse(TEST_ATTRIBUTE_VALUE_CONTAINING_HASH); - Set attributes = getNodesOfType(ASTAttribute.class, nodes); - assertEquals("Three attributes expected!", 3, attributes.size()); - - List attrsList = new ArrayList<>(attributes); - Collections.sort(attrsList, new Comparator() { - public int compare(ASTAttribute arg0, ASTAttribute arg1) { - return arg0.getName().compareTo(arg1.getName()); - } - }); + List attrsList = root.findDescendantsOfType(ASTAttribute.class); + assertEquals("Three attributes expected!", 3, attrsList.size()); ASTAttribute attr = attrsList.get(0); - assertEquals("Correct attribute name expected!", "foo", attr.getName()); - assertEquals("Correct attribute value expected!", "CREATE", - attr.getFirstDescendantOfType(ASTAttributeValue.class).getImage()); - attr = attrsList.get(1); - assertEquals("Correct attribute name expected!", "href", attr.getName()); - assertEquals("Correct attribute value expected!", "#", - attr.getFirstDescendantOfType(ASTAttributeValue.class).getImage()); - - attr = attrsList.get(2); assertEquals("Correct attribute name expected!", "something", attr.getName()); assertEquals("Correct attribute value expected!", "#yes#", - attr.getFirstDescendantOfType(ASTAttributeValue.class).getImage()); + attr.getFirstDescendantOfType(ASTAttributeValue.class).getImage()); + + attr = attrsList.get(1); + assertEquals("Correct attribute name expected!", "foo", attr.getName()); + assertEquals("Correct attribute value expected!", "CREATE", + attr.getFirstDescendantOfType(ASTAttributeValue.class).getImage()); + + attr = attrsList.get(2); + assertEquals("Correct attribute name expected!", "href", attr.getName()); + assertEquals("Correct attribute value expected!", "#", + attr.getFirstDescendantOfType(ASTAttributeValue.class).getImage()); } /** @@ -102,10 +97,10 @@ public class JspDocStyleTest extends AbstractJspNodesTst { */ @Test public void testCData() { - Set cdataNodes = getNodes(ASTCData.class, TEST_CDATA); + List cdataNodes = jsp.getNodes(ASTCData.class, TEST_CDATA); assertEquals("One CDATA node expected!", 1, cdataNodes.size()); - ASTCData cdata = cdataNodes.iterator().next(); + ASTCData cdata = cdataNodes.get(0); assertEquals("Content incorrectly parsed!", " some ]] ]> ", cdata.getImage()); } @@ -114,14 +109,14 @@ public class JspDocStyleTest extends AbstractJspNodesTst { */ @Test public void testDoctype() { - Set nodes = getNodes(null, TEST_DOCTYPE); + ASTCompilationUnit root = jsp.parse(TEST_DOCTYPE); - Set docTypeDeclarations = getNodesOfType(ASTDoctypeDeclaration.class, nodes); + List docTypeDeclarations = root.findDescendantsOfType(ASTDoctypeDeclaration.class); assertEquals("One doctype declaration expected!", 1, docTypeDeclarations.size()); ASTDoctypeDeclaration docTypeDecl = docTypeDeclarations.iterator().next(); assertEquals("Correct doctype-name expected!", "html", docTypeDecl.getName()); - Set externalIds = getNodesOfType(ASTDoctypeExternalId.class, nodes); + List externalIds = root.findDescendantsOfType(ASTDoctypeExternalId.class); assertEquals("One doctype external id expected!", 1, externalIds.size()); ASTDoctypeExternalId externalId = externalIds.iterator().next(); assertEquals("Correct external public id expected!", "-//W3C//DTD XHTML 1.1//EN", externalId.getPublicId()); @@ -136,7 +131,7 @@ public class JspDocStyleTest extends AbstractJspNodesTst { */ @Test public void testComment() { - Set comments = getNodes(ASTCommentTag.class, TEST_COMMENT); + List comments = jsp.getNodes(ASTCommentTag.class, TEST_COMMENT); assertEquals("One comment expected!", 1, comments.size()); ASTCommentTag comment = comments.iterator().next(); assertEquals("Correct comment content expected!", "comment", comment.getImage()); @@ -147,7 +142,7 @@ public class JspDocStyleTest extends AbstractJspNodesTst { */ @Test public void testHtmlScript() { - Set scripts = getNodes(ASTHtmlScript.class, TEST_HTML_SCRIPT); + List scripts = jsp.getNodes(ASTHtmlScript.class, TEST_HTML_SCRIPT); assertEquals("One script expected!", 1, scripts.size()); ASTHtmlScript script = scripts.iterator().next(); assertEquals("Correct script content expected!", "Script!", script.getImage()); @@ -159,7 +154,7 @@ public class JspDocStyleTest extends AbstractJspNodesTst { */ @Test public void testImportHtmlScript() { - Set scripts = getNodes(ASTHtmlScript.class, TEST_IMPORT_JAVASCRIPT); + List scripts = jsp.getNodes(ASTHtmlScript.class, TEST_IMPORT_JAVASCRIPT); assertEquals("One script expected!", 1, scripts.size()); ASTHtmlScript script = scripts.iterator().next(); List value = script.findDescendantsOfType(ASTAttributeValue.class); @@ -171,7 +166,7 @@ public class JspDocStyleTest extends AbstractJspNodesTst { */ @Test public void testHtmlScriptWithAttribute() { - Set scripts = getNodes(ASTHtmlScript.class, TEST_HTML_SCRIPT_WITH_ATTRIBUTE); + List scripts = jsp.getNodes(ASTHtmlScript.class, TEST_HTML_SCRIPT_WITH_ATTRIBUTE); assertEquals("One script expected!", 1, scripts.size()); ASTHtmlScript script = scripts.iterator().next(); assertEquals("Correct script content expected!", "Script!", script.getImage()); @@ -184,11 +179,11 @@ public class JspDocStyleTest extends AbstractJspNodesTst { */ @Test public void testComplexHtmlScript() { - Set script = getNodes(ASTHtmlScript.class, TEST_COMPLEX_SCRIPT); + List script = jsp.getNodes(ASTHtmlScript.class, TEST_COMPLEX_SCRIPT); assertEquals("One script expected!", 1, script.size()); ASTHtmlScript next = script.iterator().next(); assertTrue(next.getImage().contains(" - + @@ -80,7 +79,7 @@ value="PLSQLNode" /> + value="class PLSQLParserTokenManager extends net.sourceforge.pmd.lang.ast.AbstractTokenManager" /> public class implements InvocationHandler { - private Class clazz = null; - private Collection collection; + protected final PlsqlParsingHelper plsql = PlsqlParsingHelper.WITH_PROCESSING.withResourceContext(getClass()); - Collector(Class clazz) { - this(clazz, new HashSet()); - } - - Collector(Class clazz, Collection coll) { - this.clazz = clazz; - this.collection = coll; - } - - public Collection getCollection() { - return collection; - } - - public Object invoke(Object proxy, Method method, Object[] params) throws NoSuchMethodException, - SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - if (method.getName().equals("visit")) { - if (clazz.isInstance(params[0])) { - collection.add((E) params[0]); - } - } - - Method childrenAccept = params[0].getClass().getMethod("childrenAccept", - new Class[] { PLSQLParserVisitor.class, Object.class }); - childrenAccept.invoke(params[0], new Object[] { proxy, null }); - return null; - } - } - - public Set getNodes(Class clazz, String plsqlCode) { - return getNodes(LanguageRegistry.getLanguage(PLSQLLanguageModule.NAME).getDefaultVersion(), clazz, plsqlCode); - } - - public Set getNodes(LanguageVersion languageVersion, Class clazz, String plsqlCode) { - Collector coll = new Collector<>(clazz); - LanguageVersionHandler languageVersionHandler = languageVersion.getLanguageVersionHandler(); - ASTInput cu = (ASTInput) languageVersionHandler.getParser(languageVersionHandler.getDefaultParserOptions()) - .parse(null, new StringReader(plsqlCode)); - PLSQLParserVisitor jpv = (PLSQLParserVisitor) Proxy.newProxyInstance(PLSQLParserVisitor.class.getClassLoader(), - new Class[] { PLSQLParserVisitor.class }, coll); - jpv.visit(cu, null); - return (Set) coll.getCollection(); - } - - public List getOrderedNodes(Class clazz, String plsqlCode) { - Collector coll = new Collector<>(clazz, new ArrayList()); - LanguageVersionHandler languageVersionHandler = LanguageRegistry.getLanguage(PLSQLLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); - ASTInput cu = (ASTInput) languageVersionHandler.getParser(languageVersionHandler.getDefaultParserOptions()) - .parse(null, new StringReader(plsqlCode)); - PLSQLParserVisitor jpv = (PLSQLParserVisitor) Proxy.newProxyInstance(PLSQLParserVisitor.class.getClassLoader(), - new Class[] { PLSQLParserVisitor.class }, coll); - jpv.visit(cu, null); - SymbolFacade sf = new SymbolFacade(); - sf.initializeWith(cu); - DataFlowFacade dff = new DataFlowFacade(); - dff.initializeWith(languageVersionHandler.getDataFlowHandler(), cu); - return (List) coll.getCollection(); - } - - public String dumpNodes(List list) { - StringBuilder sb = new StringBuilder(); - int index = 0; - for (E item : list) { - sb.append("\n node[").append(index).append(item.toString()); - index++; - } - return sb.toString(); - } - - public ASTInput buildDFA(String plsqlCode) { - LanguageVersionHandler languageVersionHandler = LanguageRegistry.getLanguage(PLSQLLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); - ASTInput cu = (ASTInput) languageVersionHandler.getParser(languageVersionHandler.getDefaultParserOptions()) - .parse(null, new StringReader(plsqlCode)); - PLSQLParserVisitor jpv = (PLSQLParserVisitor) Proxy.newProxyInstance(PLSQLParserVisitor.class.getClassLoader(), - new Class[] { PLSQLParserVisitor.class }, new Collector<>(ASTInput.class)); - jpv.visit(cu, null); - new SymbolFacade().initializeWith(cu); - new DataFlowFacade().initializeWith(languageVersionHandler.getDataFlowHandler(), cu); - return cu; - } - - public ASTInput parsePLSQL(LanguageVersion languageVersion, String code) { - LanguageVersionHandler languageVersionHandler = languageVersion.getLanguageVersionHandler(); - return (ASTInput) languageVersionHandler.getParser(languageVersionHandler.getDefaultParserOptions()).parse(null, - new StringReader(code)); - } - - public ASTInput parsePLSQL(String code) { - return parsePLSQL(LanguageRegistry.getLanguage(PLSQLLanguageModule.NAME).getDefaultVersion(), code); - } - - public Node parseLanguage(LanguageVersion languageVersion, String code) { - LanguageVersionHandler languageVersionHandler = languageVersion.getLanguageVersionHandler(); - return languageVersionHandler.getParser(languageVersionHandler.getDefaultParserOptions()).parse(null, - new StringReader(code)); - } - - public String loadTestResource(String name) { - try { - return IOUtils.toString(this.getClass().getResourceAsStream(name), StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException(e); - } - } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PLSQLParserTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PLSQLParserTest.java deleted file mode 100644 index afa641c06c..0000000000 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PLSQLParserTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.plsql; - -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Test; - -public class PLSQLParserTest extends AbstractPLSQLParserTst { - - @Test - public void testExceptions() { - parsePLSQL("CREATE OR REPLACE PROCEDURE bar IS BEGIN" + " doSomething;" + " EXCEPTION" - + " WHEN FooException THEN" + " doSomethingElse;" + " WHEN OTHERS THEN" - + " doSomethingElse;" + "END;"); - } - - /** - * See https://sourceforge.net/p/pmd/bugs/1167/ - */ - @Test - public void testBOM() { - parsePLSQL("\ufeff" + "CREATE OR REPLACE PROCEDURE bar IS BEGIN" + " doSomething;" + " EXCEPTION" - + " WHEN FooException THEN" + " doSomethingElse;" + " WHEN OTHERS THEN" - + " doSomethingElse;" + "END;"); - } - - @Test(timeout = 5000) - public void testBug1531() { - parsePLSQL("create or replace force view oxa.o_xa_function_role_types as\n" - + "select \"CFT_ID\",\"CFR_ID\",\"CFT_NAME\",\"TCN\",\"LOG_MODULE\",\"LOG_USER\",\"LOG_DATE\",\"LOG_TIME\" from crm_function_role_types\n" - + "/"); - } - - @Test - public void testBug1527() throws Exception { - parsePLSQL(IOUtils.toString(PLSQLParserTest.class.getResourceAsStream("ast/InlinePragmaProcError.pls"), StandardCharsets.UTF_8)); - } - - @Test - public void testBug1520IsOfType() throws Exception { - parsePLSQL(IOUtils.toString(PLSQLParserTest.class.getResourceAsStream("ast/IsOfType.pls"), StandardCharsets.UTF_8)); - } - - @Test - public void testBug1520Using() throws Exception { - parsePLSQL(IOUtils.toString(PLSQLParserTest.class.getResourceAsStream("ast/Using.pls"), StandardCharsets.UTF_8)); - } - - @Test - public void testSingleLineSelect() throws Exception { - parsePLSQL(IOUtils.toString(PLSQLParserTest.class.getResourceAsStream("ast/SingleLineSelect.pls"), StandardCharsets.UTF_8)); - } - - @Test - public void testMultiLineSelect() throws Exception { - parsePLSQL(IOUtils.toString(PLSQLParserTest.class.getResourceAsStream("ast/MultiLineSelect.pls"), StandardCharsets.UTF_8)); - } - - @Test - public void testIsNull() throws Exception { - parsePLSQL(IOUtils.toString(PLSQLParserTest.class.getResourceAsStream("ast/IsNull.pls"), StandardCharsets.UTF_8)); - } - - @Test - public void testCodingStyleExample() throws Exception { - parsePLSQL(IOUtils.toString(PLSQLParserTest.class.getResourceAsStream("ast/CodingStyleExample.pls"), StandardCharsets.UTF_8)); - } - - @Test - public void testCaseIssue1454() throws Exception { - parsePLSQL(IOUtils.toString(PLSQLParserTest.class.getResourceAsStream("ast/CaseIssue1454.pls"), StandardCharsets.UTF_8)); - } -} diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PLSQLXPathRuleTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PLSQLXPathRuleTest.java index fe3340396e..094edb08f4 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PLSQLXPathRuleTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PLSQLXPathRuleTest.java @@ -7,7 +7,6 @@ package net.sourceforge.pmd.lang.plsql; import java.util.Arrays; import org.junit.Assert; -import org.junit.Before; import org.junit.Test; import net.sourceforge.pmd.RuleContext; @@ -20,16 +19,15 @@ import net.sourceforge.pmd.lang.rule.XPathRule; */ public class PLSQLXPathRuleTest extends AbstractPLSQLParserTst { - private ASTInput node = parsePLSQL( - "create or replace\n" + "package pkg_xpath_problem\n" + "AS\n" + " PROCEDURE pkg_minimal\n" + " IS\n" - + " a_variable VARCHAR2(1);\n" + " BEGIN \n" + " --PRAGMA INLINE(output,'YES');\n" - + " a_variable := 'Y' ;\n" + " END ;\n" + "end pkg_xpath_problem;\n" + "/\n" + ""); + private ASTInput node = plsql.parse( + "create or replace\n" + "package pkg_xpath_problem\n" + "AS\n" + " PROCEDURE pkg_minimal\n" + " IS\n" + + " a_variable VARCHAR2(1);\n" + " BEGIN \n" + " --PRAGMA INLINE(output,'YES');\n" + + " a_variable := 'Y' ;\n" + " END ;\n" + "end pkg_xpath_problem;\n" + "/\n" + ""); private RuleContext ctx = new RuleContext(); - @Before - public void setup() { - ctx.setLanguageVersion(LanguageRegistry.getLanguage(PLSQLLanguageModule.NAME).getDefaultVersion()); + public PLSQLXPathRuleTest() { + ctx.setLanguageVersion(plsql.getDefaultVersion()); } /** diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PlsqlParsingHelper.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PlsqlParsingHelper.java new file mode 100644 index 0000000000..c340aabaad --- /dev/null +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PlsqlParsingHelper.java @@ -0,0 +1,27 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.plsql; + +import net.sourceforge.pmd.lang.ast.test.BaseParsingHelper; +import net.sourceforge.pmd.lang.plsql.ast.ASTInput; + +public class PlsqlParsingHelper extends BaseParsingHelper { + + /** This just runs the parser and no processing stages. */ + public static final PlsqlParsingHelper JUST_PARSE = new PlsqlParsingHelper(Params.getDefaultNoProcess()); + /** This runs all processing stages when parsing. */ + public static final PlsqlParsingHelper WITH_PROCESSING = new PlsqlParsingHelper(Params.getDefaultProcess()); + + private PlsqlParsingHelper(Params params) { + super(PLSQLLanguageModule.NAME, ASTInput.class, params); + } + + @Override + protected PlsqlParsingHelper clone(Params params) { + return new PlsqlParsingHelper(params); + } + +} + diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTComparisonConditionTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTComparisonConditionTest.java index 52b2681581..1425941012 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTComparisonConditionTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTComparisonConditionTest.java @@ -15,7 +15,7 @@ public class ASTComparisonConditionTest extends AbstractPLSQLParserTst { @Test public void testOperator() { - ASTInput input = parsePLSQL("BEGIN SELECT COUNT(1) INTO MY_TABLE FROM USERS_TABLE WHERE user_id = 1; END;"); + ASTInput input = plsql.parse("BEGIN SELECT COUNT(1) INTO MY_TABLE FROM USERS_TABLE WHERE user_id = 1; END;"); List conditions = input.findDescendantsOfType(ASTComparisonCondition.class); Assert.assertEquals(1, conditions.size()); Assert.assertEquals("=", conditions.get(0).getOperator()); diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTCompoundConditionTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTCompoundConditionTest.java index 2dd3a52456..ff13a04493 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTCompoundConditionTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTCompoundConditionTest.java @@ -16,7 +16,7 @@ public class ASTCompoundConditionTest extends AbstractPLSQLParserTst { @Test public void testParseType() { - ASTInput input = parsePLSQL("BEGIN SELECT COUNT(1) INTO MY_TABLE FROM USERS_TABLE WHERE user_id = 1 AnD user_id = 2; END;"); + ASTInput input = plsql.parse("BEGIN SELECT COUNT(1) INTO MY_TABLE FROM USERS_TABLE WHERE user_id = 1 AnD user_id = 2; END;"); List compoundConditions = input.findDescendantsOfType(ASTCompoundCondition.class); Assert.assertFalse(compoundConditions.isEmpty()); Assert.assertEquals("AND", compoundConditions.get(0).getType()); diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AnonymousBlockTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AnonymousBlockTest.java index 6c2d74afa2..bd5c9f1c60 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AnonymousBlockTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AnonymousBlockTest.java @@ -4,10 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -15,18 +11,12 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class AnonymousBlockTest extends AbstractPLSQLParserTst { @Test - public void parseCursorInsideProcAnonymousBlock() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("AnonymousBlock1.sql"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseCursorInsideProcAnonymousBlock() { + plsql.parseResource("AnonymousBlock1.sql"); } @Test - public void parseCursorInsideAnonymousBlock() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("AnonymousBlock2.sql"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseCursorInsideAnonymousBlock() { + plsql.parseResource("AnonymousBlock2.sql"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CreateTableTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CreateTableTest.java index 0052faf081..01c1fa0fd3 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CreateTableTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CreateTableTest.java @@ -4,9 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -15,11 +12,8 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class CreateTableTest extends AbstractPLSQLParserTst { @Test - public void parseCreateTable() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("CreateTable.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseCreateTable() { + ASTInput input = plsql.parseResource("CreateTable.pls"); // 5th column of first table statement has a inline constraint of type check ASTTableColumn columnStatus = input.findChildrenOfType(ASTTable.class).get(0).findChildrenOfType(ASTTableColumn.class).get(4); @@ -28,10 +22,7 @@ public class CreateTableTest extends AbstractPLSQLParserTst { } @Test - public void parseCreateOrganizedTable() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("CreateOrganizedTable.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseCreateOrganizedTable() { + plsql.parseResource("CreateOrganizedTable.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorAttributesTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorAttributesTest.java index a7e232484b..429d47b83e 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorAttributesTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorAttributesTest.java @@ -13,17 +13,14 @@ public class CursorAttributesTest extends AbstractPLSQLParserTst { @Test public void parseCursorWithAttribute() { - String code = loadTestResource("CursorAttributes.pls"); - ASTInput input = parsePLSQL(code); + ASTInput input = plsql.parseResource("CursorAttributes.pls"); ASTExpression exp = input.getFirstDescendantOfType(ASTIfStatement.class).getFirstChildOfType(ASTExpression.class); Assert.assertEquals("TestSearch%notfound", exp.getImage()); } @Test public void parseImplicitCursorAttributeBulkExceptions() { - String code = loadTestResource("CursorAttributesBulkExceptions.pls"); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + plsql.parseResource("CursorAttributesBulkExceptions.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorForLoopTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorForLoopTest.java index e3d0a77fc5..6b8b99e369 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorForLoopTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorForLoopTest.java @@ -13,8 +13,7 @@ public class CursorForLoopTest extends AbstractPLSQLParserTst { @Test public void parseCursorForLoopSimple() { - String code = loadTestResource("CursorForLoopSimple.pls"); - ASTInput input = parsePLSQL(code); + ASTInput input = plsql.parseResource("CursorForLoopSimple.pls"); ASTCursorForLoopStatement forloop = input.getFirstDescendantOfType(ASTCursorForLoopStatement.class); Assert.assertNotNull(forloop); ASTForIndex forindex = forloop.getFirstChildOfType(ASTForIndex.class); @@ -24,8 +23,7 @@ public class CursorForLoopTest extends AbstractPLSQLParserTst { @Test public void parseCursorForLoopNested() { - String code = loadTestResource("CursorForLoopNested.pls"); - ASTInput input = parsePLSQL(code); + ASTInput input = plsql.parseResource("CursorForLoopNested.pls"); ASTCursorForLoopStatement forloop = input.getFirstDescendantOfType(ASTCursorForLoopStatement.class); Assert.assertNotNull(forloop); ASTForIndex forindex = forloop.getFirstChildOfType(ASTForIndex.class); @@ -43,22 +41,19 @@ public class CursorForLoopTest extends AbstractPLSQLParserTst { @Test public void parseCursorForLoop1047a() { - String code = loadTestResource("CursorForLoop1047a.pls"); - ASTInput input = parsePLSQL(code); + ASTInput input = plsql.parseResource("CursorForLoop1047a.pls"); Assert.assertNotNull(input); } @Test public void parseCursorForLoop1047b() { - String code = loadTestResource("CursorForLoop1047b.pls"); - ASTInput input = parsePLSQL(code); + ASTInput input = plsql.parseResource("CursorForLoop1047b.pls"); Assert.assertNotNull(input); } @Test public void parseCursorForLoop681() { - String code = loadTestResource("CursorForLoop681.pls"); - ASTInput input = parsePLSQL(code); + ASTInput input = plsql.parseResource("CursorForLoop681.pls"); Assert.assertNotNull(input); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorWithWithTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorWithWithTest.java index cfbb601150..bf0d285e6e 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorWithWithTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorWithWithTest.java @@ -4,9 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -15,11 +12,8 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class CursorWithWithTest extends AbstractPLSQLParserTst { @Test - public void parseCursorWithWith() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("CursorWithWith.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseCursorWithWith() { + ASTInput input = plsql.parseResource("CursorWithWith.pls"); ASTCursorUnit cursor = input.getFirstDescendantOfType(ASTCursorUnit.class); ASTSelectStatement select = (ASTSelectStatement) cursor.jjtGetChild(1); ASTWithClause with = (ASTWithClause) select.jjtGetChild(0); diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/DeleteStatementTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/DeleteStatementTest.java index fa2196466b..e0f1edd28f 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/DeleteStatementTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/DeleteStatementTest.java @@ -4,10 +4,8 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -16,14 +14,12 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class DeleteStatementTest extends AbstractPLSQLParserTst { @Test - public void parseDeleteStatementExample() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("DeleteStatementExample.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void parseDeleteStatementExample() { + ASTInput input = plsql.parseResource("DeleteStatementExample.pls"); List deleteStatements = input.findDescendantsOfType(ASTDeleteStatement.class); Assert.assertEquals(3, deleteStatements.size()); Assert.assertEquals("product_descriptions", deleteStatements.get(0).jjtGetChild(0) - .getFirstChildOfType(ASTTableName.class).getImage()); + .getFirstChildOfType(ASTTableName.class).getImage()); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateTest.java index ff12b5d148..0e459ec1b2 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateTest.java @@ -4,10 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -15,18 +11,12 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class ExecuteImmediateTest extends AbstractPLSQLParserTst { @Test - public void parseExecuteImmediate1047a() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("ExecuteImmediate1047a.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseExecuteImmediate1047a() { + plsql.parseResource("ExecuteImmediate1047a.pls"); } @Test - public void parseExecuteImmediate1047b() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("ExecuteImmediate1047b.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseExecuteImmediate1047b() { + plsql.parseResource("ExecuteImmediate1047b.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/FunctionsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/FunctionsTest.java index ea78ede269..2f4b1bd2dd 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/FunctionsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/FunctionsTest.java @@ -4,10 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -15,18 +11,12 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class FunctionsTest extends AbstractPLSQLParserTst { @Test - public void parseTrimCall() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("TrimFunction.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseTrimCall() { + plsql.parseResource("TrimFunction.pls"); } @Test - public void parseSelectExtractExpression() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("ExtractExpressions.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseSelectExtractExpression() { + plsql.parseResource("ExtractExpressions.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/IfStatementTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/IfStatementTest.java index b5422b6a04..acb57a2a4f 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/IfStatementTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/IfStatementTest.java @@ -14,7 +14,7 @@ public class IfStatementTest extends AbstractPLSQLParserTst { @Test public void parseIfWithElseIf() throws Exception { String code = "BEGIN\nIF 1 = 1 THEN null;\nELSIF (2 = 2) THEN null;\nELSE null;\nEND IF;\nEND;\n/\n"; - ASTInput input = parsePLSQL(code); + ASTInput input = plsql.parse(code); Assert.assertNotNull(input); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/InsertIntoClauseTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/InsertIntoClauseTest.java index 16b8614eef..fd8bbbe7a3 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/InsertIntoClauseTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/InsertIntoClauseTest.java @@ -4,10 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -15,26 +11,17 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class InsertIntoClauseTest extends AbstractPLSQLParserTst { @Test - public void parseInsertInto() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("InsertIntoClause.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseInsertInto() { + plsql.parseResource("InsertIntoClause.pls"); } @Test - public void parseInsertIntoReturning() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("InsertIntoClauseReturning.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseInsertIntoReturning() { + plsql.parseResource("InsertIntoClauseReturning.pls"); } @Test - public void parseInsertIntoWithRecord() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("InsertIntoClauseRecord.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseInsertIntoWithRecord() { + plsql.parseResource("InsertIntoClauseRecord.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/JoinClauseTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/JoinClauseTest.java index a15ceaa7dd..8e2413ab38 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/JoinClauseTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/JoinClauseTest.java @@ -4,10 +4,8 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -16,10 +14,8 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class JoinClauseTest extends AbstractPLSQLParserTst { @Test - public void testInnerCrossJoin() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("InnerCrossJoin.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testInnerCrossJoin() { + ASTInput input = plsql.parseResource("InnerCrossJoin.pls"); List joins = input.findDescendantsOfType(ASTInnerCrossJoinClause.class); Assert.assertEquals(1, joins.size()); Assert.assertTrue(joins.get(0).isCross()); @@ -27,10 +23,8 @@ public class JoinClauseTest extends AbstractPLSQLParserTst { } @Test - public void testInnerNaturalJoin() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("InnerNaturalJoin.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testInnerNaturalJoin() { + ASTInput input = plsql.parseResource("InnerNaturalJoin.pls"); List joins = input.findDescendantsOfType(ASTInnerCrossJoinClause.class); Assert.assertEquals(2, joins.size()); Assert.assertFalse(joins.get(0).isCross()); @@ -38,10 +32,8 @@ public class JoinClauseTest extends AbstractPLSQLParserTst { } @Test - public void testInnerJoinUsing() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("InnerJoinUsing.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testInnerJoinUsing() { + ASTInput input = plsql.parseResource("InnerJoinUsing.pls"); List joins = input.findDescendantsOfType(ASTInnerCrossJoinClause.class); Assert.assertEquals(3, joins.size()); Assert.assertFalse(joins.get(0).isCross()); @@ -52,10 +44,8 @@ public class JoinClauseTest extends AbstractPLSQLParserTst { } @Test - public void testOuterJoinUsing() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("OuterJoinUsing.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testOuterJoinUsing() { + ASTInput input = plsql.parseResource("OuterJoinUsing.pls"); List joins = input.findDescendantsOfType(ASTOuterJoinClause.class); Assert.assertEquals(1, joins.size()); ASTOuterJoinType type = joins.get(0).getFirstChildOfType(ASTOuterJoinType.class); @@ -66,10 +56,8 @@ public class JoinClauseTest extends AbstractPLSQLParserTst { } @Test - public void testRightOuterJoin() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("RightOuterJoin.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testRightOuterJoin() { + ASTInput input = plsql.parseResource("RightOuterJoin.pls"); List joins = input.findDescendantsOfType(ASTOuterJoinClause.class); Assert.assertEquals(2, joins.size()); ASTOuterJoinType type = joins.get(0).getFirstChildOfType(ASTOuterJoinType.class); @@ -77,10 +65,8 @@ public class JoinClauseTest extends AbstractPLSQLParserTst { } @Test - public void testLeftOuterJoin() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("LeftOuterJoin.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testLeftOuterJoin() { + ASTInput input = plsql.parseResource("LeftOuterJoin.pls"); List joins = input.findDescendantsOfType(ASTOuterJoinClause.class); Assert.assertEquals(2, joins.size()); ASTOuterJoinType type = joins.get(0).getFirstChildOfType(ASTOuterJoinType.class); @@ -93,10 +79,8 @@ public class JoinClauseTest extends AbstractPLSQLParserTst { } @Test - public void testNaturalRightOuterJoin() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("NaturalRightOuterJoin.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testNaturalRightOuterJoin() { + ASTInput input = plsql.parseResource("NaturalRightOuterJoin.pls"); List joins = input.findDescendantsOfType(ASTOuterJoinClause.class); Assert.assertEquals(1, joins.size()); ASTOuterJoinType type = joins.get(0).getFirstChildOfType(ASTOuterJoinType.class); @@ -105,10 +89,8 @@ public class JoinClauseTest extends AbstractPLSQLParserTst { } @Test - public void testOuterJoinPartitioned() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("OuterJoinPartitioned.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testOuterJoinPartitioned() { + ASTInput input = plsql.parseResource("OuterJoinPartitioned.pls"); List joins = input.findDescendantsOfType(ASTOuterJoinClause.class); Assert.assertEquals(1, joins.size()); ASTOuterJoinType type = joins.get(0).getFirstChildOfType(ASTOuterJoinType.class); @@ -117,24 +99,18 @@ public class JoinClauseTest extends AbstractPLSQLParserTst { } @Test - public void testFullOuterJoin() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("FullOuterJoin.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testFullOuterJoin() { + plsql.parseResource("FullOuterJoin.pls"); } @Test - public void testInnerJoinSubquery() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("InnerJoinSubquery.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testInnerJoinSubquery() { + plsql.parseResource("InnerJoinSubquery.pls"); } @Test - public void testJoinOperator() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("JoinOperator.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testJoinOperator() { + ASTInput input = plsql.parseResource("JoinOperator.pls"); List expressions = input.findDescendantsOfType(ASTOuterJoinExpression.class); Assert.assertEquals(4, expressions.size()); Assert.assertEquals("h.opp_id", expressions.get(3).getImage()); diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/MultipleDDLStatementsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/MultipleDDLStatementsTest.java index cbd5a74497..d318911662 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/MultipleDDLStatementsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/MultipleDDLStatementsTest.java @@ -4,10 +4,8 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -17,9 +15,7 @@ public class MultipleDDLStatementsTest extends AbstractPLSQLParserTst { @Test public void parseDDLCommands() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("DDLCommands.sql"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + ASTInput input = plsql.parseResource("DDLCommands.sql"); List ddlcommands = input.findDescendantsOfType(ASTDDLCommand.class); Assert.assertEquals(4, ddlcommands.size()); List comments = input.findDescendantsOfType(ASTComment.class); diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/OrderByExpressionsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/OrderByExpressionsTest.java index 05055fed04..8c729df6dc 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/OrderByExpressionsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/OrderByExpressionsTest.java @@ -4,10 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -15,10 +11,7 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class OrderByExpressionsTest extends AbstractPLSQLParserTst { @Test - public void parseOrderByExpression() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("OrderByExpression.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseOrderByExpression() { + plsql.parseResource("OrderByExpression.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParserTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParserTest.java new file mode 100644 index 0000000000..0caea6b6f7 --- /dev/null +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParserTest.java @@ -0,0 +1,76 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.plsql.ast; + +import org.junit.Test; + +import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; + +public class PLSQLParserTest extends AbstractPLSQLParserTst { + + @Test + public void testExceptions() { + plsql.parse("CREATE OR REPLACE PROCEDURE bar IS BEGIN" + " doSomething;" + " EXCEPTION" + + " WHEN FooException THEN" + " doSomethingElse;" + " WHEN OTHERS THEN" + + " doSomethingElse;" + "END;"); + } + + /** + * See https://sourceforge.net/p/pmd/bugs/1167/ + */ + @Test + public void testBOM() { + plsql.parse("\ufeff" + "CREATE OR REPLACE PROCEDURE bar IS BEGIN" + " doSomething;" + " EXCEPTION" + + " WHEN FooException THEN" + " doSomethingElse;" + " WHEN OTHERS THEN" + + " doSomethingElse;" + "END;"); + } + + @Test(timeout = 5000) + public void testBug1531() { + plsql.parse("create or replace force view oxa.o_xa_function_role_types as\n" + + "select \"CFT_ID\",\"CFR_ID\",\"CFT_NAME\",\"TCN\",\"LOG_MODULE\",\"LOG_USER\",\"LOG_DATE\",\"LOG_TIME\" from crm_function_role_types\n" + + "/"); + } + + @Test + public void testBug1527() { + plsql.parseResource("InlinePragmaProcError.pls"); + } + + @Test + public void testBug1520IsOfType() { + plsql.parseResource("IsOfType.pls"); + } + + @Test + public void testBug1520Using() { + plsql.parseResource("Using.pls"); + } + + @Test + public void testSingleLineSelect() { + plsql.parseResource("SingleLineSelect.pls"); + } + + @Test + public void testMultiLineSelect() { + plsql.parseResource("MultiLineSelect.pls"); + } + + @Test + public void testIsNull() { + plsql.parseResource("IsNull.pls"); + } + + @Test + public void testCodingStyleExample() { + plsql.parseResource("CodingStyleExample.pls"); + } + + @Test + public void testCaseIssue1454() { + plsql.parseResource("CaseIssue1454.pls"); + } +} diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/RecordTypeTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/RecordTypeTest.java index 1b0a3f4e06..0d8235820d 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/RecordTypeTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/RecordTypeTest.java @@ -4,10 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -15,10 +11,7 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class RecordTypeTest extends AbstractPLSQLParserTst { @Test - public void parseRecordType() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("RecordType.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseRecordType() { + plsql.parseResource("RecordType.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectExpressionsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectExpressionsTest.java index 16a10d9c73..53737bbd97 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectExpressionsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectExpressionsTest.java @@ -4,10 +4,8 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -16,18 +14,13 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class SelectExpressionsTest extends AbstractPLSQLParserTst { @Test - public void parseSelectExpression() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectExpressions.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseSelectExpression() { + plsql.parseResource("SelectExpressions.pls"); } @Test - public void parseSelectSimpleExpression() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectSimpleExpression.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void parseSelectSimpleExpression() { + ASTInput input = plsql.parseResource("SelectSimpleExpression.pls"); Assert.assertNotNull(input); List simpleExpressions = input.findDescendantsOfType(ASTSimpleExpression.class); @@ -40,18 +33,12 @@ public class SelectExpressionsTest extends AbstractPLSQLParserTst { } @Test - public void parseSelectCount() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectCount.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseSelectCount() { + plsql.parseResource("SelectCount.pls"); } @Test - public void parseSelectSubqueryExpression() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectSubqueryExpressions.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseSelectSubqueryExpression() { + plsql.parseResource("SelectSubqueryExpressions.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateTest.java index 7b655488f6..125483aa07 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateTest.java @@ -4,10 +4,8 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -16,19 +14,15 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class SelectForUpdateTest extends AbstractPLSQLParserTst { @Test - public void parseSelectForUpdateWait() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectForUpdateWait.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void parseSelectForUpdateWait() { + ASTInput input = plsql.parseResource("SelectForUpdateWait.pls"); Assert.assertNotNull(input); Assert.assertEquals(5, input.findDescendantsOfType(ASTForUpdateClause.class).size()); } @Test - public void parseSelectForUpdate() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectForUpdate.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void parseSelectForUpdate() { + ASTInput input = plsql.parseResource("SelectForUpdate.pls"); Assert.assertNotNull(input); List forUpdateClauses = input.findDescendantsOfType(ASTForUpdateClause.class); Assert.assertEquals(2, forUpdateClauses.size()); diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchicalTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchicalTest.java index f2809c982a..7af37055ca 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchicalTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchicalTest.java @@ -4,10 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -15,10 +11,7 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class SelectHierarchicalTest extends AbstractPLSQLParserTst { @Test - public void parseSelectHierarchicalQueries() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectHierarchical.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseSelectHierarchicalQueries() { + plsql.parseResource("SelectHierarchical.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementTest.java index 61b192fc2d..cd414650ac 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementTest.java @@ -4,9 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; import org.junit.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -14,58 +11,42 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class SelectIntoStatementTest extends AbstractPLSQLParserTst { @Test - public void testParsingComplex() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectIntoStatement.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testParsingComplex() { + plsql.parseResource("SelectIntoStatement.pls"); } @Test - public void testParsingExample1() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectIntoStatementExample1.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testParsingExample1() { + plsql.parseResource("SelectIntoStatementExample1.pls"); } @Test - public void testParsingExample2() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectIntoStatementExample2.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testParsingExample2() { + plsql.parseResource("SelectIntoStatementExample2.pls"); } @Test - public void testParsingExample3() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectIntoStatementExample3.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testParsingExample3() { + plsql.parseResource("SelectIntoStatementExample3.pls"); } @Test - public void testParsingExample4() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectIntoStatementExample4.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testParsingExample4() { + plsql.parseResource("SelectIntoStatementExample4.pls"); } @Test - public void testParsingExample5() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectIntoStatementExample5.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testParsingExample5() { + plsql.parseResource("SelectIntoStatementExample5.pls"); } @Test - public void testParsingWithFunctionCall() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectIntoStatementFunctionCall.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testParsingWithFunctionCall() { + plsql.parseResource("SelectIntoStatementFunctionCall.pls"); } @Test - public void testParsingIntoRecordField() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectIntoStatementRecordField.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testParsingIntoRecordField() { + plsql.parseResource("SelectIntoStatementRecordField.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupByTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupByTest.java index 3eeeec46cd..76225c466c 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupByTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupByTest.java @@ -4,10 +4,8 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -16,38 +14,30 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class SelectIntoWithGroupByTest extends AbstractPLSQLParserTst { @Test - public void testExample1() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectIntoWithGroupBy1.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testExample1() { + ASTInput input = plsql.parseResource("SelectIntoWithGroupBy1.pls"); ASTGroupByClause groupByClause = input.getFirstDescendantOfType(ASTGroupByClause.class); Assert.assertNotNull(groupByClause); } @Test - public void testExample2() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectIntoWithGroupBy2.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testExample2() { + ASTInput input = plsql.parseResource("SelectIntoWithGroupBy2.pls"); ASTGroupByClause groupByClause = input.getFirstDescendantOfType(ASTGroupByClause.class); Assert.assertNotNull(groupByClause); } @Test - public void testExample3WithCube() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectIntoWithGroupBy3.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testExample3WithCube() { + ASTInput input = plsql.parseResource("SelectIntoWithGroupBy3.pls"); ASTRollupCubeClause cubeClause = input.getFirstDescendantOfType(ASTRollupCubeClause.class); Assert.assertNotNull(cubeClause); Assert.assertEquals("CUBE", cubeClause.getImage()); } @Test - public void testExample4WithGroupingSets() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectIntoWithGroupBy4.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testExample4WithGroupingSets() { + ASTInput input = plsql.parseResource("SelectIntoWithGroupBy4.pls"); ASTGroupingSetsClause groupingSetsClause = input.getFirstDescendantOfType(ASTGroupingSetsClause.class); Assert.assertNotNull(groupingSetsClause); diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectUnionTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectUnionTest.java index 5118f00574..d213f4883c 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectUnionTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectUnionTest.java @@ -4,10 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -15,11 +11,8 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class SelectUnionTest extends AbstractPLSQLParserTst { @Test - public void parseSelectUnion() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("SelectUnion.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseSelectUnion() { + plsql.parseResource("SelectUnion.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/StringLiteralsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/StringLiteralsTest.java index fcc7777e03..9a23c02b56 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/StringLiteralsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/StringLiteralsTest.java @@ -4,10 +4,8 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -18,9 +16,7 @@ public class StringLiteralsTest extends AbstractPLSQLParserTst { @Test public void parseStringLiterals() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("StringLiterals.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + ASTInput input = plsql.parseResource("StringLiterals.pls"); List strings = input.findDescendantsOfType(ASTStringLiteral.class); Assert.assertEquals(20, strings.size()); @@ -35,9 +31,7 @@ public class StringLiteralsTest extends AbstractPLSQLParserTst { @Test public void parseMultilineVarchar() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("MultilineVarchar.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + ASTInput input = plsql.parseResource("MultilineVarchar.pls"); List strings = input.findDescendantsOfType(ASTStringLiteral.class); Assert.assertEquals(1, strings.size()); Assert.assertTrue(normalizeEol(strings.get(0).getString()).startsWith("\ncreate or replace and")); diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TableCollectionExpressionTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TableCollectionExpressionTest.java index 1daad5882a..51172989cf 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TableCollectionExpressionTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TableCollectionExpressionTest.java @@ -4,10 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -15,18 +11,12 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class TableCollectionExpressionTest extends AbstractPLSQLParserTst { @Test - public void testExamples() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("TableCollectionExpressionExamples.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void testExamples() { + plsql.parseResource("TableCollectionExpressionExamples.pls"); } @Test - public void testIssue1526() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("TableCollectionExpressionIssue1526.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void testIssue1526() { + plsql.parseResource("TableCollectionExpressionIssue1526.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordTypeTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordTypeTest.java index 8f92db5209..9715fa9918 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordTypeTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordTypeTest.java @@ -4,10 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -15,10 +11,7 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class TrimWithRecordTypeTest extends AbstractPLSQLParserTst { @Test - public void parseTrimWithRecordType() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("TrimWithRecordType.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseTrimWithRecordType() { + plsql.parseResource("TrimWithRecordType.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/UpdateStatementTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/UpdateStatementTest.java index f5abafb4f6..9a56a576ec 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/UpdateStatementTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/UpdateStatementTest.java @@ -14,8 +14,7 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class UpdateStatementTest extends AbstractPLSQLParserTst { @Test public void parseUpdateStatementExample() { - String code = loadTestResource("UpdateStatementExample.pls"); - ASTInput input = parsePLSQL(code); + ASTInput input = plsql.parseResource("UpdateStatementExample.pls"); List updateStatements = input.findDescendantsOfType(ASTUpdateStatement.class); Assert.assertEquals(2, updateStatements.size()); Assert.assertEquals(2, updateStatements.get(1).getFirstChildOfType(ASTUpdateSetClause.class) @@ -24,13 +23,13 @@ public class UpdateStatementTest extends AbstractPLSQLParserTst { @Test public void parseUpdateStatementExample2() { - ASTInput input = parsePLSQL(loadTestResource("UpdateStatementExample2.pls")); + ASTInput input = plsql.parseResource("UpdateStatementExample2.pls"); Assert.assertNotNull(input); } @Test public void parseUpdateStatementRef() { - ASTInput input = parsePLSQL(loadTestResource("UpdateStatementRef.pls")); + ASTInput input = plsql.parseResource("UpdateStatementRef.pls"); Assert.assertNotNull(input); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ViewTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ViewTest.java index a00f2f8710..e62509f89b 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ViewTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ViewTest.java @@ -4,10 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -15,26 +11,17 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class ViewTest extends AbstractPLSQLParserTst { @Test - public void parseCreateViewIssue981() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("ViewIssue981.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseCreateViewIssue981() { + plsql.parseResource("ViewIssue981.pls"); } @Test - public void parseCreateView() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("CreateViewWithSubquery.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseCreateView() { + plsql.parseResource("CreateViewWithSubquery.pls"); } @Test - public void parseCreateViewWithoutSemicolon() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("QueryWithoutSemicolon.sql"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); - Assert.assertNotNull(input); + public void parseCreateViewWithoutSemicolon() { + plsql.parseResource("QueryWithoutSemicolon.sql"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WhereClauseTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WhereClauseTest.java index 038fa3e5e6..96440c0b15 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WhereClauseTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WhereClauseTest.java @@ -4,10 +4,8 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -16,10 +14,8 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class WhereClauseTest extends AbstractPLSQLParserTst { @Test - public void testFunctionCall() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseFunctionCall.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testFunctionCall() { + ASTInput input = plsql.parseResource("WhereClauseFunctionCall.pls"); List selectStatements = input.findDescendantsOfType(ASTSelectIntoStatement.class); Assert.assertEquals(4, selectStatements.size()); @@ -31,66 +27,48 @@ public class WhereClauseTest extends AbstractPLSQLParserTst { } @Test - public void testLikeCondition() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseLike.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testLikeCondition() { + plsql.parseResource("WhereClauseLike.pls"); } @Test - public void testNullCondition() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseIsNull.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testNullCondition() { + plsql.parseResource("WhereClauseIsNull.pls"); } @Test - public void testBetweenCondition() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseBetween.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testBetweenCondition() { + plsql.parseResource("WhereClauseBetween.pls"); } @Test - public void testInCondition() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseIn.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testInCondition() { + plsql.parseResource("WhereClauseIn.pls"); } @Test - public void testIsOfTypeCondition() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseIsOfType.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testIsOfTypeCondition() { + plsql.parseResource("WhereClauseIsOfType.pls"); } @Test - public void testConcatenationOperator() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseConcatenation.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testConcatenationOperator() { + plsql.parseResource("WhereClauseConcatenation.pls"); } @Test - public void testExistsCondition() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseExists.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testExistsCondition() { + plsql.parseResource("WhereClauseExists.pls"); } @Test - public void testMultisetCondition() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseMultiset.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testMultisetCondition() { + plsql.parseResource("WhereClauseMultiset.pls"); } @Test - public void testRegexpLikeCondition() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseRegexpLike.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testRegexpLikeCondition() { + ASTInput input = plsql.parseResource("WhereClauseRegexpLike.pls"); List regexps = input.findDescendantsOfType(ASTRegexpLikeCondition.class); Assert.assertEquals(3, regexps.size()); Assert.assertEquals("last_name", regexps.get(1).getSourceChar().getImage()); @@ -99,16 +77,12 @@ public class WhereClauseTest extends AbstractPLSQLParserTst { } @Test - public void testSubqueries() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseSubqueries.pls"), - StandardCharsets.UTF_8); - ASTInput input = parsePLSQL(code); + public void testSubqueries() { + plsql.parseResource("WhereClauseSubqueries.pls"); } @Test - public void testParentheses() throws Exception { - String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseParens.pls"), - StandardCharsets.UTF_8); - parsePLSQL(code); + public void testParentheses() { + plsql.parseResource("WhereClauseParens.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/XMLElementTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/XMLElementTest.java index 31781cb261..32f8d1b555 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/XMLElementTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/XMLElementTest.java @@ -4,10 +4,8 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -16,10 +14,8 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class XMLElementTest extends AbstractPLSQLParserTst { @Test - public void testParseXMLElement() throws Exception { - ASTInput input = parsePLSQL(IOUtils.toString(this.getClass().getResourceAsStream("XMLElement.pls"), - StandardCharsets.UTF_8)); - Assert.assertNotNull(input); + public void testParseXMLElement() { + ASTInput input = plsql.parseResource("XMLElement.pls"); List xmlelements = input.findDescendantsOfType(ASTXMLElement.class); Assert.assertEquals(10, xmlelements.size()); Assert.assertEquals("\"Emp\"", xmlelements.get(0).getFirstChildOfType(ASTID.class).getImage()); diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/XMLTableTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/XMLTableTest.java index 476a35e29a..25d129b1fd 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/XMLTableTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/XMLTableTest.java @@ -4,10 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -15,9 +11,7 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; public class XMLTableTest extends AbstractPLSQLParserTst { @Test - public void testParseXMLTable() throws Exception { - ASTInput input = parsePLSQL(IOUtils.toString(this.getClass().getResourceAsStream("XMLTable.pls"), - StandardCharsets.UTF_8)); - Assert.assertNotNull(input); + public void testParseXMLTable() { + plsql.parseResource("XMLTable.pls"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/dfa/StatementAndBraceFinderTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/dfa/StatementAndBraceFinderTest.java index 91ce778b57..d75ce4985b 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/dfa/StatementAndBraceFinderTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/dfa/StatementAndBraceFinderTest.java @@ -12,13 +12,12 @@ import java.util.List; import org.junit.Test; import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.lang.LanguageRegistry; import net.sourceforge.pmd.lang.ast.AbstractNode; import net.sourceforge.pmd.lang.dfa.DataFlowNode; import net.sourceforge.pmd.lang.dfa.NodeType; import net.sourceforge.pmd.lang.dfa.StartOrEndDataFlowNode; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; -import net.sourceforge.pmd.lang.plsql.PLSQLLanguageModule; +import net.sourceforge.pmd.lang.plsql.PlsqlParsingHelper; import net.sourceforge.pmd.lang.plsql.ast.ASTExpression; import net.sourceforge.pmd.lang.plsql.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.plsql.ast.ASTProgramUnit; @@ -27,13 +26,19 @@ import net.sourceforge.pmd.lang.plsql.ast.PLSQLNode; public class StatementAndBraceFinderTest extends AbstractPLSQLParserTst { + private final PlsqlParsingHelper plsql = PlsqlParsingHelper.WITH_PROCESSING.withResourceContext(StatementAndBraceFinderTest.class); + + private ASTExpression getExpr(String test1) { + return plsql.parse(test1).getFirstDescendantOfType(ASTExpression.class); + } + /** * Java ASTStatementExpression equivalent is inferred as an Expression() * which has an UnlabelledStatement as a parent. */ @Test public void testExpressionParentChildLinks() { - ASTExpression ex = getOrderedNodes(ASTExpression.class, TEST1).get(0); + ASTExpression ex = getExpr(TEST1); DataFlowNode dfn = ex.getDataFlowNode(); assertEquals(3, dfn.getLine()); assertTrue(dfn.getNode() instanceof ASTExpression); @@ -48,9 +53,10 @@ public class StatementAndBraceFinderTest extends AbstractPLSQLParserTst { assertEquals(exParent, ex.getDataFlowNode().getParents().get(0).getNode()); } + @Test public void testVariableOrConstantDeclaratorParentChildLinks() { - ASTVariableOrConstantDeclarator vd = getOrderedNodes(ASTVariableOrConstantDeclarator.class, TEST2).get(0); + ASTVariableOrConstantDeclarator vd = plsql.getNodes(ASTVariableOrConstantDeclarator.class, TEST2).get(0); // ASTMethodDeclaration vdParent = (ASTMethodDeclaration) // ((DataFlowNode) vd.getDataFlowNode().getParents().get(0)).getNode(); ASTProgramUnit vdParent = (ASTProgramUnit) vd.getDataFlowNode().getParents().get(0).getNode(); @@ -61,7 +67,7 @@ public class StatementAndBraceFinderTest extends AbstractPLSQLParserTst { @Test public void testIfStmtHasCorrectTypes() { - ASTExpression exp = getOrderedNodes(ASTExpression.class, TEST3).get(0); + ASTExpression exp = getExpr(TEST3); assertEquals(5, exp.getDataFlowNode().getFlow().size()); DataFlowNode dfn = exp.getDataFlowNode().getFlow().get(2); assertTrue(dfn.isType(NodeType.IF_EXPR)); @@ -73,7 +79,7 @@ public class StatementAndBraceFinderTest extends AbstractPLSQLParserTst { @Test public void testWhileStmtHasCorrectTypes() { - ASTExpression exp = getOrderedNodes(ASTExpression.class, TEST4).get(0); + ASTExpression exp = getExpr(TEST4); DataFlowNode dfn = exp.getDataFlowNode().getFlow().get(2); assertTrue(dfn.isType(NodeType.WHILE_EXPR)); dfn = exp.getDataFlowNode().getFlow().get(3); @@ -82,7 +88,7 @@ public class StatementAndBraceFinderTest extends AbstractPLSQLParserTst { @Test public void testForStmtHasCorrectTypes() { - ASTExpression exp = getOrderedNodes(ASTExpression.class, TEST5).get(0); + ASTExpression exp = getExpr(TEST5); DataFlowNode dfn = null; dfn = exp.getDataFlowNode().getFlow().get(0); assertTrue(dfn instanceof StartOrEndDataFlowNode); @@ -100,7 +106,7 @@ public class StatementAndBraceFinderTest extends AbstractPLSQLParserTst { @Test public void testSimpleCaseStmtHasCorrectTypes() { - ASTExpression exp = getOrderedNodes(ASTExpression.class, TEST6).get(0); + ASTExpression exp = getExpr(TEST6); DataFlowNode dfn = null; dfn = exp.getDataFlowNode().getFlow().get(0); assertTrue(dfn instanceof StartOrEndDataFlowNode); @@ -129,25 +135,25 @@ public class StatementAndBraceFinderTest extends AbstractPLSQLParserTst { * { List statements = getOrderedNodes(ASTStatement.class, * TEST7); List expressions = * getOrderedNodes(ASTExpression.class, TEST7); - * + * * ASTStatement st = statements.get(0); ASTStatement st1 = * statements.get(1); ASTStatement st2 = statements.get(2); ASTStatement st3 * = statements.get(3); * System.err.println("testSearchedCaseStmtHasCorrectTypes-st(0)="+st. * getBeginLine()); - * + * * ASTExpression ex = expressions.get(0); ASTExpression ex1 = * expressions.get(1); ASTExpression ex2 = expressions.get(2); ASTExpression * ex3 = expressions.get(3); ASTExpression ex4 = expressions.get(4); * System.err.println("ASTExpression="+ex ); - * + * * DataFlowNode dfn = null; //dfn = ex.getDataFlowNode().getFlow().get(0); * //dfn = st.getDataFlowNode().getFlow().get(0); dfn = (DataFlowNode) * st.getDataFlowNode(); System.err.println("DataFlowNode(st-0)="+dfn ) ; * System.err.println("DataFlowNode(st-1)="+st1.getDataFlowNode() ) ; * System.err.println("DataFlowNode(st-2)="+st2.getDataFlowNode() ) ; * System.err.println("DataFlowNode(st-3)="+st3.getDataFlowNode() ) ; - * + * * System.err.println("DataFlowNode(ex-0)="+ex.getDataFlowNode() ) ; * System.err.println("DataFlowNode(ex-1)="+ex1.getDataFlowNode() ) ; * System.err.println("DataFlowNode(ex-2)="+ex2.getDataFlowNode() ) ; @@ -178,7 +184,7 @@ public class StatementAndBraceFinderTest extends AbstractPLSQLParserTst { */ @Test public void testLabelledStmtHasCorrectTypes() { - ASTExpression exp = getOrderedNodes(ASTExpression.class, TEST8).get(0); + ASTExpression exp = getExpr(TEST8); DataFlowNode dfn = exp.getDataFlowNode().getFlow().get(2); assertEquals(3, dfn.getLine()); assertTrue(dfn.isType(NodeType.LABEL_STATEMENT)); @@ -186,8 +192,7 @@ public class StatementAndBraceFinderTest extends AbstractPLSQLParserTst { @Test public void testOnlyWorksForMethodsAndConstructors() { - StatementAndBraceFinder sbf = new StatementAndBraceFinder(LanguageRegistry.getLanguage(PLSQLLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler().getDataFlowHandler()); + StatementAndBraceFinder sbf = new StatementAndBraceFinder(plsql.getDefaultHandler().getDataFlowHandler()); PLSQLNode node = new ASTMethodDeclaration(1); ((AbstractNode) node).testingOnlySetBeginColumn(1); sbf.buildDataFlowFor(node); diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/StringLiterals.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/StringLiterals.pls index 66118495ad..7d1f68bc3d 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/StringLiterals.pls +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/StringLiterals.pls @@ -25,8 +25,8 @@ declare qliteral1 clob := q'!name LIKE '%DBMS_%%'!'; qliteral2 clob := Q'{SELECT * FROM employees WHERE last_name = 'Smith';}'; - qliteral1a clob := q'! test !'; - qliteral2a clob := q'{ + qliteral2a clob := q'! test !'; + qliteral2b clob := q'{ also multiple lines }'; diff --git a/pmd-python/etc/grammar/python.jj b/pmd-python/etc/grammar/python.jj index a7ae02074c..e17cb57801 100644 --- a/pmd-python/etc/grammar/python.jj +++ b/pmd-python/etc/grammar/python.jj @@ -17,7 +17,7 @@ PARSER_BEGIN(PythonParser) package net.sourceforge.pmd.lang.python.ast; -import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; +import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.TokenMgrError; public class PythonParser { diff --git a/pmd-python/src/main/ant/alljavacc.xml b/pmd-python/src/main/ant/alljavacc.xml index af8ab888f0..b876617263 100644 --- a/pmd-python/src/main/ant/alljavacc.xml +++ b/pmd-python/src/main/ant/alljavacc.xml @@ -36,7 +36,7 @@ javacchome="${javacc-home.path}" /> + value="class PythonParserTokenManager extends net.sourceforge.pmd.lang.ast.AbstractTokenManager" /> diff --git a/pmd-python/src/main/java/net/sourceforge/pmd/lang/python/PythonTokenManager.java b/pmd-python/src/main/java/net/sourceforge/pmd/lang/python/PythonTokenManager.java index c80b6be501..881c190b57 100644 --- a/pmd-python/src/main/java/net/sourceforge/pmd/lang/python/PythonTokenManager.java +++ b/pmd-python/src/main/java/net/sourceforge/pmd/lang/python/PythonTokenManager.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.lang.python; import java.io.Reader; import net.sourceforge.pmd.lang.TokenManager; -import net.sourceforge.pmd.lang.ast.impl.javacc.SimpleCharStream; +import net.sourceforge.pmd.lang.ast.impl.javacc.CharStreamFactory; import net.sourceforge.pmd.lang.python.ast.PythonParserTokenManager; /** @@ -23,7 +23,7 @@ public class PythonTokenManager implements TokenManager { * the source code */ public PythonTokenManager(Reader source) { - tokenManager = new PythonParserTokenManager(new SimpleCharStream(source)); + tokenManager = new PythonParserTokenManager(CharStreamFactory.simpleCharStream(source)); } @Override diff --git a/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/ast/BaseScalaTest.java b/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/ast/BaseScalaTest.java new file mode 100644 index 0000000000..6b96899084 --- /dev/null +++ b/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/ast/BaseScalaTest.java @@ -0,0 +1,14 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.scala.ast; + +/** + * @author Clément Fournier + */ +public abstract class BaseScalaTest { + + protected final ScalaParsingHelper scala = ScalaParsingHelper.DEFAULT.withResourceContext(getClass()); + +} diff --git a/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/ast/ScalaParsingHelper.java b/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/ast/ScalaParsingHelper.java new file mode 100644 index 0000000000..1f37f484c7 --- /dev/null +++ b/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/ast/ScalaParsingHelper.java @@ -0,0 +1,53 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.scala.ast; + +import java.io.File; +import java.io.StringReader; + +import net.sourceforge.pmd.PMD; +import net.sourceforge.pmd.PMDException; +import net.sourceforge.pmd.Report; +import net.sourceforge.pmd.Rule; +import net.sourceforge.pmd.RuleContext; +import net.sourceforge.pmd.RuleSet; +import net.sourceforge.pmd.RuleSetFactory; +import net.sourceforge.pmd.RuleSets; +import net.sourceforge.pmd.lang.ast.test.BaseParsingHelper; +import net.sourceforge.pmd.lang.scala.ScalaLanguageModule; + +public final class ScalaParsingHelper extends BaseParsingHelper { + + public static final ScalaParsingHelper DEFAULT = new ScalaParsingHelper(Params.getDefaultProcess()); + + private ScalaParsingHelper(Params params) { + super(ScalaLanguageModule.NAME, ASTSource.class, params); + } + + @Override + protected ScalaParsingHelper clone(Params params) { + return new ScalaParsingHelper(params); + } + + + public Report getReportForTestString(Rule rule, String testSourceCode) { + PMD p = new PMD(); + RuleContext ctx = new RuleContext(); + Report report = new Report(); + ctx.setReport(report); + ctx.setSourceCodeFile(new File("test.scala")); + RuleSet rules = new RuleSetFactory().createSingleRuleRuleSet(rule); + try { + p.getSourceCodeProcessor().processSourceCode(new StringReader(testSourceCode), new RuleSets(rules), ctx); + } catch (PMDException e) { + throw new AssertionError(e); + } + return report; + } + + public Report getReportForResource(Rule rule, String resourcePath) { + return getReportForTestString(rule, readResource(resourcePath)); + } +} diff --git a/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/rule/ScalaRuleTest.java b/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/rule/ScalaRuleTest.java index 8c7cc39599..d3920f0e83 100644 --- a/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/rule/ScalaRuleTest.java +++ b/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/rule/ScalaRuleTest.java @@ -4,42 +4,27 @@ package net.sourceforge.pmd.lang.scala.rule; -import java.io.File; -import java.io.StringReader; -import java.util.Arrays; +import java.util.Collections; import java.util.concurrent.atomic.AtomicInteger; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; -import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.PMDException; import net.sourceforge.pmd.Report; -import net.sourceforge.pmd.Rule; import net.sourceforge.pmd.RuleContext; -import net.sourceforge.pmd.RuleSet; -import net.sourceforge.pmd.RuleSets; -import net.sourceforge.pmd.RulesetsFactoryUtils; import net.sourceforge.pmd.internal.util.IteratorUtil; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.LanguageVersionHandler; -import net.sourceforge.pmd.lang.Parser; -import net.sourceforge.pmd.lang.scala.ScalaLanguageModule; +import net.sourceforge.pmd.lang.scala.ast.ASTSource; import net.sourceforge.pmd.lang.scala.ast.ASTTermApply; import net.sourceforge.pmd.lang.scala.ast.ASTTermName; +import net.sourceforge.pmd.lang.scala.ast.BaseScalaTest; import net.sourceforge.pmd.lang.scala.ast.ScalaNode; -public class ScalaRuleTest { +public class ScalaRuleTest extends BaseScalaTest { + private static final String SCALA_TEST = "/parserFiles/helloworld.scala"; @Test - public void testRuleVisits() throws Exception { - LanguageVersionHandler scalaVersionHandler = LanguageRegistry.getLanguage(ScalaLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); - Parser parser = scalaVersionHandler.getParser(scalaVersionHandler.getDefaultParserOptions()); - ScalaNode root = (ScalaNode) parser.parse(null, - new StringReader(IOUtils.toString(getClass().getResourceAsStream(SCALA_TEST), "UTF-8"))); + public void testRuleVisits() { final AtomicInteger visited = new AtomicInteger(); ScalaRule rule = new ScalaRule() { @@ -49,12 +34,13 @@ public class ScalaRuleTest { return super.visit(node, data); } }; - rule.apply(Arrays.asList(root), null); + ASTSource root = scala.parseResource(SCALA_TEST); + rule.apply(Collections.singletonList(root), null); Assert.assertEquals(12, visited.get()); } @Test - public void testDummyRule() throws Exception { + public void testDummyRule() { ScalaRule rule = new ScalaRule() { @Override public RuleContext visit(ASTTermApply node, RuleContext data) { @@ -65,21 +51,8 @@ public class ScalaRuleTest { return data; } }; - Report report = getReportForTestString(rule, - IOUtils.toString(getClass().getResourceAsStream(SCALA_TEST), "UTF-8")); + Report report = scala.getReportForResource(rule, SCALA_TEST); Assert.assertEquals(1, IteratorUtil.count(report.iterator())); } - - private static Report getReportForTestString(Rule r, String test) throws PMDException { - PMD p = new PMD(); - RuleContext ctx = new RuleContext(); - Report report = new Report(); - ctx.setReport(report); - ctx.setSourceCodeFile(new File("test.scala")); - RuleSet rules = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(r); - p.getSourceCodeProcessor().processSourceCode(new StringReader(test), new RuleSets(rules), ctx); - return report; - } - } diff --git a/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/rule/XPathRuleTest.java b/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/rule/XPathRuleTest.java index 5c64d291df..aefa9ee487 100644 --- a/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/rule/XPathRuleTest.java +++ b/pmd-scala/src/test/java/net/sourceforge/pmd/lang/scala/rule/XPathRuleTest.java @@ -6,29 +6,19 @@ package net.sourceforge.pmd.lang.scala.rule; import static org.junit.Assert.assertEquals; -import java.io.File; -import java.io.StringReader; - -import org.apache.commons.io.IOUtils; import org.junit.Before; import org.junit.Test; -import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.PMDException; import net.sourceforge.pmd.Report; -import net.sourceforge.pmd.Rule; -import net.sourceforge.pmd.RuleContext; -import net.sourceforge.pmd.RuleSet; -import net.sourceforge.pmd.RuleSets; import net.sourceforge.pmd.RuleViolation; -import net.sourceforge.pmd.RulesetsFactoryUtils; import net.sourceforge.pmd.lang.LanguageRegistry; import net.sourceforge.pmd.lang.rule.XPathRule; import net.sourceforge.pmd.lang.rule.xpath.XPathRuleQuery; import net.sourceforge.pmd.lang.scala.ScalaLanguageModule; -import net.sourceforge.pmd.testframework.RuleTst; +import net.sourceforge.pmd.lang.scala.ast.BaseScalaTest; + +public class XPathRuleTest extends BaseScalaTest { -public class XPathRuleTest extends RuleTst { private static final String SCALA_TEST = "/parserFiles/helloworld.scala"; XPathRule rule; @@ -41,24 +31,12 @@ public class XPathRuleTest extends RuleTst { } @Test - public void testPrintHelloWorld() throws Exception { + public void testPrintHelloWorld() { String xpath = "//TermApply/TermName[@Image=\"println\"]"; rule.setXPath(xpath); rule.setVersion(XPathRuleQuery.XPATH_2_0); - Report report = getReportForTestString(rule, - IOUtils.toString(getClass().getResourceAsStream(SCALA_TEST), "UTF-8")); + Report report = scala.getReportForResource(rule, SCALA_TEST); RuleViolation rv = report.iterator().next(); assertEquals(2, rv.getBeginLine()); } - - private static Report getReportForTestString(Rule r, String test) throws PMDException { - PMD p = new PMD(); - RuleContext ctx = new RuleContext(); - Report report = new Report(); - ctx.setReport(report); - ctx.setSourceCodeFile(new File("test.scala")); - RuleSet rules = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(r); - p.getSourceCodeProcessor().processSourceCode(new StringReader(test), new RuleSets(rules), ctx); - return report; - } } diff --git a/pmd-visualforce/etc/grammar/VfParser.jjt b/pmd-visualforce/etc/grammar/VfParser.jjt index f1ae19b8f3..5e1bbf20d1 100644 --- a/pmd-visualforce/etc/grammar/VfParser.jjt +++ b/pmd-visualforce/etc/grammar/VfParser.jjt @@ -14,7 +14,7 @@ options { PARSER_BEGIN(VfParser) package net.sourceforge.pmd.lang.vf.ast; -import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; +import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.TokenMgrError; public class VfParser { diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 3a00d97ae3..04ffc69700 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -93,10 +93,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-visualforce/src/main/ant/alljavacc.xml b/pmd-visualforce/src/main/ant/alljavacc.xml index f3e8198e2f..c3650bdc0e 100644 --- a/pmd-visualforce/src/main/ant/alljavacc.xml +++ b/pmd-visualforce/src/main/ant/alljavacc.xml @@ -46,7 +46,7 @@ + value="class VfParserTokenManager extends net.sourceforge.pmd.lang.ast.AbstractTokenManager" /> diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfParser.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfParser.java index b23c992d87..79cd8f5e01 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfParser.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfParser.java @@ -9,9 +9,10 @@ import java.io.Reader; import net.sourceforge.pmd.lang.AbstractParser; import net.sourceforge.pmd.lang.ParserOptions; import net.sourceforge.pmd.lang.TokenManager; +import net.sourceforge.pmd.lang.ast.AbstractTokenManager; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.ParseException; -import net.sourceforge.pmd.lang.ast.impl.javacc.AbstractTokenManager; +import net.sourceforge.pmd.lang.ast.impl.javacc.CharStreamFactory; /** * Adapter for the VfParser. @@ -30,7 +31,7 @@ public class VfParser extends AbstractParser { @Override public Node parse(String fileName, Reader source) throws ParseException { AbstractTokenManager.setFileName(fileName); - return new net.sourceforge.pmd.lang.vf.ast.VfParser(new VfSimpleCharStream(source)).CompilationUnit(); + return new net.sourceforge.pmd.lang.vf.ast.VfParser(CharStreamFactory.simpleCharStream(source)).CompilationUnit(); } } diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfSimpleCharStream.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfSimpleCharStream.java deleted file mode 100644 index b3b1bda907..0000000000 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfSimpleCharStream.java +++ /dev/null @@ -1,22 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.vf; - -import java.io.Reader; - -import net.sourceforge.pmd.lang.ast.impl.javacc.SimpleCharStream; - -/** - * @author sergey.gorbaty - * - */ -public class VfSimpleCharStream extends SimpleCharStream { - - public VfSimpleCharStream(Reader dstream) { - super(dstream); - tabSize = 4; - } - -} diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfTokenManager.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfTokenManager.java index 9d531d4f1c..42b55f3ba6 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfTokenManager.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfTokenManager.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.lang.vf; import java.io.Reader; import net.sourceforge.pmd.lang.TokenManager; -import net.sourceforge.pmd.lang.ast.impl.javacc.JavaCharStream; +import net.sourceforge.pmd.lang.ast.impl.javacc.CharStreamFactory; import net.sourceforge.pmd.lang.vf.ast.VfParserTokenManager; /** @@ -17,7 +17,7 @@ public class VfTokenManager implements TokenManager { private final VfParserTokenManager tokenManager; public VfTokenManager(Reader source) { - tokenManager = new VfParserTokenManager(new JavaCharStream(source)); + tokenManager = new VfParserTokenManager(CharStreamFactory.javaCharStream(source)); } @Override diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/VfParserTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/VfParserTest.java deleted file mode 100644 index 3e40cc7e44..0000000000 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/VfParserTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.vf; - -import java.io.StringReader; - -import org.junit.Assert; -import org.junit.Test; - -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.LanguageVersionHandler; -import net.sourceforge.pmd.lang.Parser; -import net.sourceforge.pmd.lang.ast.Node; - -/** - * @author sergey.gorbaty - * - */ -public class VfParserTest { - - @Test - public void testSingleDoubleQuoteAndEL() { - Node node = parse("${!'yes'}"); - Assert.assertNotNull(node); - } - - @Test - public void testSingleDoubleQuoteAndELFunction() { - Node node = parse("${!method}"); - Assert.assertNotNull(node); - } - - @Test - public void testSingleDoubleQuote() { - Node node = parse("${\"yes\"}"); - Assert.assertNotNull(node); - } - - private Node parse(String code) { - LanguageVersionHandler vfLang = LanguageRegistry.getLanguage(VfLanguageModule.NAME).getDefaultVersion() - .getLanguageVersionHandler(); - Parser parser = vfLang.getParser(vfLang.getDefaultParserOptions()); - Node node = parser.parse(null, new StringReader(code)); - return node; - } -} diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/AbstractVfNodesTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/AbstractVfNodesTest.java index e846ceeb05..d905a3817a 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/AbstractVfNodesTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/AbstractVfNodesTest.java @@ -4,70 +4,8 @@ package net.sourceforge.pmd.lang.vf.ast; -import static org.junit.Assert.assertEquals; - -import java.io.StringReader; -import java.util.HashSet; -import java.util.Set; - -import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.ast.impl.javacc.JavaCharStream; - public abstract class AbstractVfNodesTest { - public void assertNumberOfNodes(Class clazz, String source, int number) { - Set nodes = getNodes(clazz, source); - assertEquals("Exactly " + number + " element(s) expected", number, nodes.size()); - } - - /** - * Run the VF parser on the source, and return the nodes of type clazz. - * - * @param clazz - * @param source - * @return Set - */ - public Set getNodes(Class clazz, String source) { - VfParser parser = new VfParser(new JavaCharStream(new StringReader(source))); - Node rootNode = parser.CompilationUnit(); - Set nodes = new HashSet<>(); - addNodeAndSubnodes(rootNode, nodes, clazz); - return nodes; - } - - /** - * Return a subset of allNodes, containing the items in allNodes that are of - * the given type. - * - * @param clazz - * @param allNodes - * @return Set - */ - @SuppressWarnings("unchecked") - public Set getNodesOfType(Class clazz, Set allNodes) { - Set result = new HashSet<>(); - for (Node node : allNodes) { - if (clazz.equals(node.getClass())) { - result.add((T) node); - } - } - return result; - } - - /** - * Add the given node and its subnodes to the set of nodes. If clazz is not - * null, only nodes of the given class are put in the set of nodes. - */ - @SuppressWarnings("unchecked") - private void addNodeAndSubnodes(Node node, Set nodes, Class clazz) { - if (null != node) { - if ((null == clazz) || (clazz.equals(node.getClass()))) { - nodes.add((T) node); - } - for (int i = 0; i < node.jjtGetNumChildren(); i++) { - addNodeAndSubnodes(node.jjtGetChild(i), nodes, clazz); - } - } - } + protected final VfParsingHelper vf = VfParsingHelper.DEFAULT.withResourceContext(getClass()); } diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfDocStyleTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfDocStyleTest.java index 004cafddf2..17609b05fe 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfDocStyleTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfDocStyleTest.java @@ -6,14 +6,13 @@ package net.sourceforge.pmd.lang.vf.ast; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; -import java.util.Set; import org.junit.Test; @@ -21,7 +20,7 @@ import org.junit.Test; * Test parsing of a VF in document style, by checking the generated AST. * Original @author pieter_van_raemdonck - Application Engineers NV/SA - * www.ae.be - * + * * @author sergey.gorbaty - VF adaptation * */ @@ -32,7 +31,8 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testSimplestVf() { - assertNumberOfNodes(ASTElement.class, TEST_SIMPLEST_HTML, 1); + List nodes = vf.getNodes(ASTElement.class, TEST_SIMPLEST_HTML); + assertEquals("Exactly " + 1 + " element(s) expected", 1, nodes.size()); } /** @@ -40,22 +40,23 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testElementAttributeAndNamespace() { - Set nodes = getNodes(null, TEST_ELEMENT_AND_NAMESPACE); + ASTCompilationUnit root = vf.parse(TEST_ELEMENT_AND_NAMESPACE); - Set elementNodes = getNodesOfType(ASTElement.class, nodes); + + List elementNodes = root.findDescendantsOfType(ASTElement.class); assertEquals("One element node expected!", 1, elementNodes.size()); ASTElement element = elementNodes.iterator().next(); assertEquals("Correct name expected!", "h:html", element.getName()); - assertEquals("Has namespace prefix!", true, element.isHasNamespacePrefix()); - assertEquals("Element is empty!", true, element.isEmpty()); + assertTrue("Has namespace prefix!", element.isHasNamespacePrefix()); + assertTrue("Element is empty!", element.isEmpty()); assertEquals("Correct namespace prefix of element expected!", "h", element.getNamespacePrefix()); assertEquals("Correct local name of element expected!", "html", element.getLocalName()); - Set attributeNodes = getNodesOfType(ASTAttribute.class, nodes); + List attributeNodes = root.findDescendantsOfType(ASTAttribute.class); assertEquals("One attribute node expected!", 1, attributeNodes.size()); ASTAttribute attribute = attributeNodes.iterator().next(); assertEquals("Correct name expected!", "MyNsPrefix:MyAttr", attribute.getName()); - assertEquals("Has namespace prefix!", true, attribute.isHasNamespacePrefix()); + assertTrue("Has namespace prefix!", attribute.isHasNamespacePrefix()); assertEquals("Correct namespace prefix of element expected!", "MyNsPrefix", attribute.getNamespacePrefix()); assertEquals("Correct local name of element expected!", "MyAttr", attribute.getLocalName()); @@ -68,31 +69,24 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testAttributeValueContainingHash() { - Set nodes = getNodes(null, TEST_ATTRIBUTE_VALUE_CONTAINING_HASH); - Set attributes = getNodesOfType(ASTAttribute.class, nodes); + List attributes = vf.getNodes(ASTAttribute.class, TEST_ATTRIBUTE_VALUE_CONTAINING_HASH); assertEquals("Three attributes expected!", 3, attributes.size()); - List attrsList = new ArrayList<>(attributes); - Collections.sort(attrsList, new Comparator() { - public int compare(ASTAttribute arg0, ASTAttribute arg1) { - return arg0.getName().compareTo(arg1.getName()); - } - }); + ASTAttribute attr = attributes.get(0); + assertEquals("Correct attribute name expected!", "something", attr.getName()); + assertEquals("Correct attribute value expected!", "#yes#", + attr.getFirstDescendantOfType(ASTText.class).getImage()); - ASTAttribute attr = attrsList.get(0); + attr = attributes.get(1); assertEquals("Correct attribute name expected!", "foo", attr.getName()); assertEquals("Correct attribute value expected!", "CREATE", attr.getFirstDescendantOfType(ASTText.class).getImage()); - attr = attrsList.get(1); + attr = attributes.get(2); assertEquals("Correct attribute name expected!", "href", attr.getName()); assertEquals("Correct attribute value expected!", "#", attr.getFirstDescendantOfType(ASTText.class).getImage()); - attr = attrsList.get(2); - assertEquals("Correct attribute name expected!", "something", attr.getName()); - assertEquals("Correct attribute value expected!", "#yes#", - attr.getFirstDescendantOfType(ASTText.class).getImage()); } /** @@ -100,7 +94,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testCData() { - Set cdataNodes = getNodes(ASTCData.class, TEST_CDATA); + List cdataNodes = vf.getNodes(ASTCData.class, TEST_CDATA); assertEquals("One CDATA node expected!", 1, cdataNodes.size()); ASTCData cdata = cdataNodes.iterator().next(); @@ -112,14 +106,14 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testDoctype() { - Set nodes = getNodes(null, TEST_DOCTYPE); + ASTCompilationUnit root = vf.parse(TEST_DOCTYPE); - Set docTypeDeclarations = getNodesOfType(ASTDoctypeDeclaration.class, nodes); + List docTypeDeclarations = root.findDescendantsOfType(ASTDoctypeDeclaration.class); assertEquals("One doctype declaration expected!", 1, docTypeDeclarations.size()); ASTDoctypeDeclaration docTypeDecl = docTypeDeclarations.iterator().next(); assertEquals("Correct doctype-name expected!", "html", docTypeDecl.getName()); - Set externalIds = getNodesOfType(ASTDoctypeExternalId.class, nodes); + List externalIds = root.findDescendantsOfType(ASTDoctypeExternalId.class); assertEquals("One doctype external id expected!", 1, externalIds.size()); ASTDoctypeExternalId externalId = externalIds.iterator().next(); assertEquals("Correct external public id expected!", "-//W3C//DTD XHTML 1.1//EN", externalId.getPublicId()); @@ -133,7 +127,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testHtmlScript() { - Set scripts = getNodes(ASTHtmlScript.class, TEST_HTML_SCRIPT); + List scripts = vf.getNodes(ASTHtmlScript.class, TEST_HTML_SCRIPT); assertEquals("One script expected!", 1, scripts.size()); ASTHtmlScript script = scripts.iterator().next(); ASTText text = script.getFirstChildOfType(ASTText.class); @@ -145,7 +139,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testELInTagValue() { - Set elememts = getNodes(ASTElement.class, TEST_EL_IN_TAG_ATTRIBUTE); + List elememts = vf.getNodes(ASTElement.class, TEST_EL_IN_TAG_ATTRIBUTE); assertEquals("One element expected!", 1, elememts.size()); ASTElement element = elememts.iterator().next(); ASTAttributeValue attribute = element.getFirstDescendantOfType(ASTAttributeValue.class); @@ -159,7 +153,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testELInTagValueWithCommentDQ() { - Set elememts = getNodes(ASTElement.class, TEST_EL_IN_TAG_ATTRIBUTE_WITH_COMMENT); + List elememts = vf.getNodes(ASTElement.class, TEST_EL_IN_TAG_ATTRIBUTE_WITH_COMMENT); assertEquals("One element expected!", 1, elememts.size()); ASTElement element = elememts.iterator().next(); ASTElExpression elExpr = element.getFirstDescendantOfType(ASTElExpression.class); @@ -172,7 +166,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testELInTagValueWithCommentSQ() { - Set elememts = getNodes(ASTElement.class, TEST_EL_IN_TAG_ATTRIBUTE_WITH_COMMENT_SQ); + List elememts = vf.getNodes(ASTElement.class, TEST_EL_IN_TAG_ATTRIBUTE_WITH_COMMENT_SQ); assertEquals("One element expected!", 1, elememts.size()); ASTElement element = elememts.iterator().next(); ASTElExpression elExpr = element.getFirstDescendantOfType(ASTElExpression.class); @@ -186,7 +180,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testELInHtmlScript() { - Set scripts = getNodes(ASTHtmlScript.class, TEST_EL_IN_HTML_SCRIPT); + List scripts = vf.getNodes(ASTHtmlScript.class, TEST_EL_IN_HTML_SCRIPT); assertEquals("One script expected!", 1, scripts.size()); ASTHtmlScript script = scripts.iterator().next(); ASTText text = script.getFirstChildOfType(ASTText.class); @@ -201,7 +195,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testInlineCommentInEL() { - Set scripts = getNodes(ASTHtmlScript.class, TEST_EL_IN_HTML_SCRIPT_WITH_COMMENT); + List scripts = vf.getNodes(ASTHtmlScript.class, TEST_EL_IN_HTML_SCRIPT_WITH_COMMENT); assertEquals("One script expected!", 1, scripts.size()); ASTHtmlScript script = scripts.iterator().next(); ASTText text = script.getFirstChildOfType(ASTText.class); @@ -216,7 +210,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testQuotedELInHtmlScript() { - Set scripts = getNodes(ASTHtmlScript.class, TEST_QUOTED_EL_IN_HTML_SCRIPT); + List scripts = vf.getNodes(ASTHtmlScript.class, TEST_QUOTED_EL_IN_HTML_SCRIPT); assertEquals("One script expected!", 1, scripts.size()); ASTHtmlScript script = scripts.iterator().next(); ASTText text = script.getFirstChildOfType(ASTText.class); @@ -232,7 +226,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testImportHtmlScript() { - Set scripts = getNodes(ASTHtmlScript.class, TEST_IMPORT_JAVASCRIPT); + List scripts = vf.getNodes(ASTHtmlScript.class, TEST_IMPORT_JAVASCRIPT); assertEquals("One script expected!", 1, scripts.size()); ASTHtmlScript script = scripts.iterator().next(); List attr = script.findDescendantsOfType(ASTAttribute.class); @@ -248,13 +242,13 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testHtmlScriptWithAttribute() { - Set scripts = getNodes(ASTHtmlScript.class, TEST_HTML_SCRIPT_WITH_ATTRIBUTE); + List scripts = vf.getNodes(ASTHtmlScript.class, TEST_HTML_SCRIPT_WITH_ATTRIBUTE); assertEquals("One script expected!", 1, scripts.size()); ASTHtmlScript script = scripts.iterator().next(); ASTText text = script.getFirstChildOfType(ASTText.class); assertEquals("Correct script content expected!", "Script!", text.getImage()); List attrs = script.findDescendantsOfType(ASTText.class); - assertTrue("text/javascript".equals(attrs.get(0).getImage())); + assertEquals("text/javascript", attrs.get(0).getImage()); } /** @@ -262,7 +256,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testComplexHtmlScript() { - Set script = getNodes(ASTHtmlScript.class, TEST_COMPLEX_SCRIPT); + List script = vf.getNodes(ASTHtmlScript.class, TEST_COMPLEX_SCRIPT); assertEquals("One script expected!", 1, script.size()); ASTHtmlScript next = script.iterator().next(); ASTText text = next.getFirstChildOfType(ASTText.class); @@ -275,7 +269,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testInlineCss() { - Set elements = getNodes(ASTElement.class, TEST_INLINE_STYLE); + List elements = vf.getNodes(ASTElement.class, TEST_INLINE_STYLE); assertEquals("Two elements expected!", 3, elements.size()); } @@ -284,7 +278,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void testTextInTag() { - Set scripts = getNodes(ASTText.class, TEST_TEXT_IN_TAG); + List scripts = vf.getNodes(ASTText.class, TEST_TEXT_IN_TAG); assertEquals("One text chunk expected!", 1, scripts.size()); ASTText script = scripts.iterator().next(); assertEquals("Correct content expected!", " some text ", script.getImage()); @@ -296,10 +290,9 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void noSpacesBetweenTags() { - Set scripts = getNodes(ASTElement.class, TEST_TAGS_NO_SPACE); + List scripts = vf.getNodes(ASTElement.class, TEST_TAGS_NO_SPACE); assertEquals("Two tags expected!", 2, scripts.size()); - List elmts = sortNodesByName(scripts); - Iterator iterator = elmts.iterator(); + Iterator iterator = scripts.iterator(); ASTElement script = iterator.next(); assertEquals("Correct content expected!", "a", script.getName()); script = iterator.next(); @@ -312,7 +305,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void unclosedTagsWithDollar() { - Set scripts = getNodes(ASTText.class, TEST_TAGS_WITH_DOLLAR); + List scripts = vf.getNodes(ASTText.class, TEST_TAGS_WITH_DOLLAR); assertEquals("Two text chunks expected!", 2, scripts.size()); ASTText script = scripts.iterator().next(); assertEquals("Correct content expected!", " $ ", script.getImage()); @@ -324,7 +317,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void unclosedTagsWithELWithin() { - Set element = getNodes(ASTElement.class, TEST_TAGS_WITH_EL_WITHIN); + List element = vf.getNodes(ASTElement.class, TEST_TAGS_WITH_EL_WITHIN); assertEquals("One element expected!", 1, element.size()); for (ASTElement elem : element) { @@ -347,21 +340,20 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void textAfterOpenAndClosedTag() { - Set nodes = getNodes(ASTElement.class, TEST_TEXT_AFTER_OPEN_AND_CLOSED_TAG); + List nodes = vf.getNodes(ASTElement.class, TEST_TEXT_AFTER_OPEN_AND_CLOSED_TAG); assertEquals("Two elements expected!", 2, nodes.size()); - List elmts = sortNodesByName(nodes); - assertEquals("First element should be a", "a", elmts.get(0).getName()); - assertFalse("first element should be closed", elmts.get(0).isUnclosed()); - assertEquals("Second element should be b", "b", elmts.get(1).getName()); - assertTrue("Second element should not be closed", elmts.get(1).isUnclosed()); + assertEquals("First element should be a", "a", nodes.get(0).getName()); + assertFalse("first element should be closed", nodes.get(0).isUnclosed()); + assertEquals("Second element should be b", "b", nodes.get(1).getName()); + assertTrue("Second element should not be closed", nodes.get(1).isUnclosed()); - Set text = getNodes(ASTText.class, TEST_TEXT_AFTER_OPEN_AND_CLOSED_TAG); + List text = vf.getNodes(ASTText.class, TEST_TEXT_AFTER_OPEN_AND_CLOSED_TAG); assertEquals("Two text chunks expected!", 2, text.size()); } @Test public void quoteEL() { - Set attributes = getNodes(ASTAttributeValue.class, TEST_QUOTE_EL); + List attributes = vf.getNodes(ASTAttributeValue.class, TEST_QUOTE_EL); assertEquals("One attribute expected!", 1, attributes.size()); ASTAttributeValue attr = attributes.iterator().next(); List els = attr.findChildrenOfType(ASTElExpression.class); @@ -376,7 +368,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void quoteAttrValue() { - Set attributes = getNodes(ASTAttributeValue.class, TEST_ATTR); + List attributes = vf.getNodes(ASTAttributeValue.class, TEST_ATTR); assertEquals("One attribute expected!", 1, attributes.size()); ASTAttributeValue attr = attributes.iterator().next(); ASTText text = attr.getFirstChildOfType(ASTText.class); @@ -388,7 +380,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void noQuoteAttrEmpty() { - Set attributes = getNodes(ASTAttributeValue.class, TEST_EMPTY_ATTR); + List attributes = vf.getNodes(ASTAttributeValue.class, TEST_EMPTY_ATTR); assertEquals("two attributes expected!", 2, attributes.size()); Iterator iterator = attributes.iterator(); ASTAttributeValue attr = iterator.next(); @@ -397,7 +389,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { // in order to ensure that we check the proper attribute attr = iterator.next(); } - assertEquals("Expected to detect proper value for attribute!", null, attr.getImage()); + assertNull("Expected to detect proper value for attribute!", attr.getImage()); } /** @@ -405,7 +397,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void singleQuoteAttrTab() { - Set attributes = getNodes(ASTAttributeValue.class, TEST_TAB_ATTR); + List attributes = vf.getNodes(ASTAttributeValue.class, TEST_TAB_ATTR); assertEquals("One attribute expected!", 1, attributes.size()); Iterator iterator = attributes.iterator(); ASTAttributeValue attr = iterator.next(); @@ -416,35 +408,33 @@ public class VfDocStyleTest extends AbstractVfNodesTest { @Test public void unclosedTag() { - Set elements = getNodes(ASTElement.class, TEST_UNCLOSED_SIMPLE); - List sortedElmnts = sortNodesByName(elements); + List elements = vf.getNodes(ASTElement.class, TEST_UNCLOSED_SIMPLE); assertEquals("2 tags expected", 2, elements.size()); - assertEquals("First element should be sorted tag:if", "tag:if", sortedElmnts.get(0).getName()); - assertEquals("Second element should be tag:someTag", "tag:someTag", sortedElmnts.get(1).getName()); + assertEquals("Second element should be tag:someTag", "tag:someTag", elements.get(0).getName()); + assertEquals("First element should be sorted tag:if", "tag:if", elements.get(1).getName()); - assertTrue(sortedElmnts.get(0).isEmpty()); - assertTrue(sortedElmnts.get(0).isUnclosed()); - assertFalse(sortedElmnts.get(1).isEmpty()); - assertFalse(sortedElmnts.get(1).isUnclosed()); + assertTrue(elements.get(1).isEmpty()); + assertTrue(elements.get(1).isUnclosed()); + assertFalse(elements.get(0).isEmpty()); + assertFalse(elements.get(0).isUnclosed()); } @Test public void unclosedTagAndNoQuotesForAttribute() { - Set elements = getNodes(ASTElement.class, TEST_UNCLOSED_ATTR); - List sortedElmnts = sortNodesByName(elements); + List elements = vf.getNodes(ASTElement.class, TEST_UNCLOSED_ATTR); assertEquals("2 tags expected", 2, elements.size()); - assertEquals("First element should be sorted tag:if", "tag:if", sortedElmnts.get(0).getName()); - assertEquals("Second element should be tag:someTag", "tag:someTag", sortedElmnts.get(1).getName()); + assertEquals("Second element should be tag:someTag", "tag:someTag", elements.get(0).getName()); + assertEquals("First element should be sorted tag:if", "tag:if", elements.get(1).getName()); - assertTrue(sortedElmnts.get(0).isEmpty()); - assertTrue(sortedElmnts.get(0).isUnclosed()); - assertFalse(sortedElmnts.get(1).isEmpty()); - assertFalse(sortedElmnts.get(1).isUnclosed()); + assertTrue(elements.get(1).isEmpty()); + assertTrue(elements.get(1).isUnclosed()); + assertFalse(elements.get(0).isEmpty()); + assertFalse(elements.get(0).isUnclosed()); } @Test public void unclosedTagMultipleLevels() { - Set elements = getNodes(ASTElement.class, TEST_UNCLOSED_MULTIPLE_LEVELS); + List elements = vf.getNodes(ASTElement.class, TEST_UNCLOSED_MULTIPLE_LEVELS); List sortedElmnts = sortNodesByName(elements); assertEquals("3 tags expected", 3, elements.size()); assertEquals("First element should be sorted tag:someTag", "tag:someTag", sortedElmnts.get(0).getName()); @@ -466,7 +456,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void nestedEmptyTags() { - Set elements = getNodes(ASTElement.class, TEST_MULTIPLE_EMPTY_TAGS); + List elements = vf.getNodes(ASTElement.class, TEST_MULTIPLE_EMPTY_TAGS); List sortedElmnts = sortNodesByName(elements); assertEquals("4 tags expected", 4, elements.size()); assertEquals("First element should a1", "a1", sortedElmnts.get(0).getName()); @@ -498,7 +488,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void nestedMultipleTags() { - Set elements = getNodes(ASTElement.class, TEST_MULTIPLE_NESTED_TAGS); + List elements = vf.getNodes(ASTElement.class, TEST_MULTIPLE_NESTED_TAGS); List sortedElmnts = sortNodesByName(elements); assertEquals("4 tags expected", 6, elements.size()); assertEquals("First element should a1", "a1", sortedElmnts.get(0).getName()); @@ -541,7 +531,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void unclosedParentTagClosedBeforeChild() { - Set elements = getNodes(ASTElement.class, TEST_UNCLOSED_END_AFTER_PARENT_CLOSE); + List elements = vf.getNodes(ASTElement.class, TEST_UNCLOSED_END_AFTER_PARENT_CLOSE); List sortedElmnts = sortNodesByName(elements); assertEquals("4 tags expected", 4, elements.size()); assertEquals("First element should be 'a'", "a", sortedElmnts.get(0).getName()); @@ -575,7 +565,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void unmatchedTagDoesNotInfluenceStructure() { - Set elements = getNodes(ASTElement.class, TEST_UNCLOSED_UNMATCHED_CLOSING_TAG); + List elements = vf.getNodes(ASTElement.class, TEST_UNCLOSED_UNMATCHED_CLOSING_TAG); List sortedElmnts = sortNodesByName(elements); assertEquals("4 tags expected", 4, elements.size()); assertEquals("First element should be 'a'", "a", sortedElmnts.get(0).getName()); @@ -609,7 +599,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { */ @Test public void unclosedStartTagWithUnmatchedCloseOfDifferentTag() { - Set elements = getNodes(ASTElement.class, TEST_UNCLOSED_START_TAG_WITH_UNMATCHED_CLOSE); + List elements = vf.getNodes(ASTElement.class, TEST_UNCLOSED_START_TAG_WITH_UNMATCHED_CLOSE); List sortedElmnts = sortNodesByName(elements); assertEquals("5 tags expected", 5, elements.size()); assertEquals("First element should be 'a'", "a", sortedElmnts.get(0).getName()); @@ -644,14 +634,13 @@ public class VfDocStyleTest extends AbstractVfNodesTest { * is the same it will sort against o1.getBeginColumn() +""+ * o1.getBeginLine(). so first criteria is the name, then the second is the * column +""+line string. - * + * * @param elements * @return */ - private List sortNodesByName(Set elements) { - List list = new ArrayList<>(); - list.addAll(elements); - Collections.sort(list, new Comparator() { + private List sortNodesByName(List elements) { + Collections.sort(elements, new Comparator() { + @Override public int compare(ASTElement o1, ASTElement o2) { if (o1.getName() == null) { return Integer.MIN_VALUE; @@ -667,12 +656,12 @@ public class VfDocStyleTest extends AbstractVfNodesTest { return o1.getName().compareTo(o2.getName()); } }); - return list; + return elements; } @Test public void noQuoteAttrWithJspEL() { - Set attributes = getNodes(ASTAttributeValue.class, TEST_NO_QUOTE_ATTR_WITH_EL); + List attributes = vf.getNodes(ASTAttributeValue.class, TEST_NO_QUOTE_ATTR_WITH_EL); assertEquals("One attribute expected!", 1, attributes.size()); Iterator iterator = attributes.iterator(); ASTAttributeValue attr = iterator.next(); diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfPageStyleTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfPageStyleTest.java index 9295a8945d..77287f6e42 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfPageStyleTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfPageStyleTest.java @@ -6,7 +6,7 @@ package net.sourceforge.pmd.lang.vf.ast; import static org.junit.Assert.assertEquals; -import java.util.Set; +import java.util.List; import org.junit.Test; @@ -17,7 +17,7 @@ public class VfPageStyleTest extends AbstractVfNodesTest { */ @Test public void testElExpression() { - Set expressions = getNodes(ASTElExpression.class, VF_EL_EXPRESSION); + List expressions = vf.getNodes(ASTElExpression.class, VF_EL_EXPRESSION); assertEquals("One expression expected!", 1, expressions.size()); ASTElExpression expression = expressions.iterator().next(); ASTExpression exp = expression.getFirstChildOfType(ASTExpression.class); @@ -25,7 +25,7 @@ public class VfPageStyleTest extends AbstractVfNodesTest { assertEquals("Correct expression content expected!", "myBean", id.getImage()); ASTDotExpression dot = exp.getFirstChildOfType(ASTDotExpression.class); ASTIdentifier dotid = dot.getFirstChildOfType(ASTIdentifier.class); - assertEquals("Correct expression content expected!", "get", dotid.getImage()); + assertEquals("Correct expression content expected!", "get", dotid.getImage()); ASTArguments arguments = exp.getFirstChildOfType(ASTArguments.class); ASTExpression innerExpression = arguments.getFirstChildOfType(ASTExpression.class); ASTLiteral literal = innerExpression.getFirstChildOfType(ASTLiteral.class); @@ -37,7 +37,7 @@ public class VfPageStyleTest extends AbstractVfNodesTest { */ @Test public void testElExpressionInAttribute() { - Set expressions = getNodes(ASTElExpression.class, VF_EL_EXPRESSION_IN_ATTRIBUTE); + List expressions = vf.getNodes(ASTElExpression.class, VF_EL_EXPRESSION_IN_ATTRIBUTE); assertEquals("One expression expected!", 1, expressions.size()); ASTElExpression expression = expressions.iterator().next(); ASTExpression exp = expression.getFirstChildOfType(ASTExpression.class); diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfParserTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfParserTest.java new file mode 100644 index 0000000000..f425470314 --- /dev/null +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfParserTest.java @@ -0,0 +1,29 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.vf.ast; + +import org.junit.Test; + +/** + * @author sergey.gorbaty + */ +public class VfParserTest extends AbstractVfNodesTest { + + @Test + public void testSingleDoubleQuoteAndEL() { + vf.parse("${!'yes'}"); + } + + @Test + public void testSingleDoubleQuoteAndELFunction() { + vf.parse("${!method}"); + } + + @Test + public void testSingleDoubleQuote() { + vf.parse("${\"yes\"}"); + } + +} diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfParsingHelper.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfParsingHelper.java new file mode 100644 index 0000000000..bcb97098f5 --- /dev/null +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfParsingHelper.java @@ -0,0 +1,22 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.vf.ast; + +import net.sourceforge.pmd.lang.ast.test.BaseParsingHelper; +import net.sourceforge.pmd.lang.vf.VfLanguageModule; + +public final class VfParsingHelper extends BaseParsingHelper { + + public static final VfParsingHelper DEFAULT = new VfParsingHelper(Params.getDefaultProcess()); + + private VfParsingHelper(Params params) { + super(VfLanguageModule.NAME, ASTCompilationUnit.class, params); + } + + @Override + protected VfParsingHelper clone(Params params) { + return new VfParsingHelper(params); + } +} diff --git a/pmd-vm/etc/grammar/VmParser.jjt b/pmd-vm/etc/grammar/VmParser.jjt index 497449a2c8..4fab39c65a 100644 --- a/pmd-vm/etc/grammar/VmParser.jjt +++ b/pmd-vm/etc/grammar/VmParser.jjt @@ -93,7 +93,7 @@ import java.util.List; import java.util.HashMap; import java.util.Map; -import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; +import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.vm.directive.Directive; import net.sourceforge.pmd.lang.vm.util.VelocityCharStream; import net.sourceforge.pmd.lang.vm.util.DirectiveMapper; diff --git a/pmd-vm/src/main/ant/alljavacc.xml b/pmd-vm/src/main/ant/alljavacc.xml index d71ec6bbfb..845e8da6f7 100644 --- a/pmd-vm/src/main/ant/alljavacc.xml +++ b/pmd-vm/src/main/ant/alljavacc.xml @@ -46,7 +46,7 @@ + value="class VmParserTokenManager extends net.sourceforge.pmd.lang.ast.AbstractTokenManager" /> diff --git a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/VmParser.java b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/VmParser.java index c124a87ba3..812d924b86 100644 --- a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/VmParser.java +++ b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/VmParser.java @@ -9,9 +9,9 @@ import java.io.Reader; import net.sourceforge.pmd.lang.AbstractParser; import net.sourceforge.pmd.lang.ParserOptions; import net.sourceforge.pmd.lang.TokenManager; +import net.sourceforge.pmd.lang.ast.AbstractTokenManager; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.ParseException; -import net.sourceforge.pmd.lang.ast.impl.javacc.AbstractTokenManager; import net.sourceforge.pmd.lang.vm.util.VelocityCharStream; /** diff --git a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/VmTokenManager.java b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/VmTokenManager.java index 228bbabbfc..4d8f01e46c 100644 --- a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/VmTokenManager.java +++ b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/VmTokenManager.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.lang.vm; import java.io.Reader; import net.sourceforge.pmd.lang.TokenManager; -import net.sourceforge.pmd.lang.ast.impl.javacc.AbstractTokenManager; +import net.sourceforge.pmd.lang.ast.AbstractTokenManager; import net.sourceforge.pmd.lang.vm.ast.VmParserTokenManager; import net.sourceforge.pmd.lang.vm.util.VelocityCharStream; diff --git a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/util/VelocityCharStream.java b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/util/VelocityCharStream.java index cd6b536ec6..78a3e91fa3 100644 --- a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/util/VelocityCharStream.java +++ b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/util/VelocityCharStream.java @@ -1,7 +1,7 @@ package net.sourceforge.pmd.lang.vm.util; -import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; +import net.sourceforge.pmd.lang.ast.CharStream; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 8680d44c18..c588a93bed 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -55,10 +55,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/internal/XmlParserImpl.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/internal/XmlParserImpl.java index cab0908204..aaa17c9fd3 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/internal/XmlParserImpl.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/internal/XmlParserImpl.java @@ -95,7 +95,7 @@ public class XmlParserImpl { /** * The root should implement {@link RootNode}. */ - static class RootXmlNode extends XmlNodeWrapper implements RootNode { + public static class RootXmlNode extends XmlNodeWrapper implements RootNode { RootXmlNode(XmlParserImpl parser, Node domNode) { super(parser, domNode); } diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/XmlParserOptionsTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/XmlParserOptionsTest.java index 2e07a3e966..f9c9f2529c 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/XmlParserOptionsTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/XmlParserOptionsTest.java @@ -19,7 +19,7 @@ import net.sourceforge.pmd.properties.BooleanProperty; public class XmlParserOptionsTest { @Test - public void testDefaults() throws Exception { + public void testDefaults() { XmlParserOptions options = new XmlParserOptions(); assertFalse(options.isCoalescing()); assertTrue(options.isExpandEntityReferences()); @@ -41,7 +41,7 @@ public class XmlParserOptionsTest { } @Test - public void testConstructor() throws Exception { + public void testConstructor() { MyRule rule = new MyRule(); rule.setProperty(XmlParserOptions.COALESCING_DESCRIPTOR, true); diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/XmlParserTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/XmlParserTest.java index 02c9defc47..341892941f 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/XmlParserTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/XmlParserTest.java @@ -4,17 +4,15 @@ package net.sourceforge.pmd.lang.xml; -import static org.junit.Assert.assertNotNull; +import static net.sourceforge.pmd.lang.xml.XmlParsingHelper.XML; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.io.StringReader; import java.io.UnsupportedEncodingException; -import java.nio.charset.StandardCharsets; import java.util.Iterator; import java.util.Locale; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -51,16 +49,11 @@ public class XmlParserTest { /** * See bug #1054: XML Rules ever report a line -1 and not the line/column * where the error occurs - * - * @throws Exception - * any error + * */ @Test - public void testLineNumbers() throws Exception { - LanguageVersionHandler xmlVersionHandler = LanguageRegistry.getLanguage(XmlLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); - Parser parser = xmlVersionHandler.getParser(xmlVersionHandler.getDefaultParserOptions()); - Node document = parser.parse(null, new StringReader(XML_TEST)); + public void testLineNumbers() { + Node document = XML.parse(XML_TEST); assertNode(document, "document", 2); assertLineNumbers(document, 1, 1, 19, 14); @@ -101,10 +94,7 @@ public class XmlParserTest { */ @Test public void testDefaultParsing() { - LanguageVersionHandler xmlVersionHandler = LanguageRegistry.getLanguage(XmlLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); - Parser parser = xmlVersionHandler.getParser(xmlVersionHandler.getDefaultParserOptions()); - Node document = parser.parse(null, new StringReader(XML_TEST)); + Node document = XML.parse(XML_TEST); assertNode(document, "document", 2); Node dtdElement = document.jjtGetChild(0); @@ -131,12 +121,9 @@ public class XmlParserTest { */ @Test public void testParsingCoalescingEnabled() { - LanguageVersionHandler xmlVersionHandler = LanguageRegistry.getLanguage(XmlLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); XmlParserOptions parserOptions = new XmlParserOptions(); parserOptions.setCoalescing(true); - Parser parser = xmlVersionHandler.getParser(parserOptions); - Node document = parser.parse(null, new StringReader(XML_TEST)); + Node document = XML.withParserOptions(parserOptions).parse(XML_TEST); assertNode(document, "document", 2); Node dtdElement = document.jjtGetChild(0); @@ -162,12 +149,9 @@ public class XmlParserTest { */ @Test public void testParsingDoNotExpandEntities() { - LanguageVersionHandler xmlVersionHandler = LanguageRegistry.getLanguage(XmlLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); XmlParserOptions parserOptions = new XmlParserOptions(); parserOptions.setExpandEntityReferences(false); - Parser parser = xmlVersionHandler.getParser(parserOptions); - Node document = parser.parse(null, new StringReader(XML_TEST)); + Node document = XML.withParserOptions(parserOptions).parse(XML_TEST); assertNode(document, "document", 2); Node dtdElement = document.jjtGetChild(0); @@ -204,12 +188,9 @@ public class XmlParserTest { */ @Test public void testParsingIgnoreComments() { - LanguageVersionHandler xmlVersionHandler = LanguageRegistry.getLanguage(XmlLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); XmlParserOptions parserOptions = new XmlParserOptions(); parserOptions.setIgnoringComments(true); - Parser parser = xmlVersionHandler.getParser(parserOptions); - Node document = parser.parse(null, new StringReader(XML_TEST)); + Node document = XML.withParserOptions(parserOptions).parse(XML_TEST); assertNode(document, "document", 2); Node dtdElement = document.jjtGetChild(0); @@ -235,12 +216,9 @@ public class XmlParserTest { */ @Test public void testParsingIgnoreElementContentWhitespace() { - LanguageVersionHandler xmlVersionHandler = LanguageRegistry.getLanguage(XmlLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); XmlParserOptions parserOptions = new XmlParserOptions(); parserOptions.setIgnoringElementContentWhitespace(true); - Parser parser = xmlVersionHandler.getParser(parserOptions); - Node document = parser.parse(null, new StringReader(XML_TEST)); + Node document = XML.withParserOptions(parserOptions).parse(XML_TEST); assertNode(document, "document", 2); Node dtdElement = document.jjtGetChild(0); @@ -263,10 +241,7 @@ public class XmlParserTest { */ @Test public void testDefaultParsingNamespaces() { - LanguageVersionHandler xmlVersionHandler = LanguageRegistry.getLanguage(XmlLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); - Parser parser = xmlVersionHandler.getParser(xmlVersionHandler.getDefaultParserOptions()); - Node document = parser.parse(null, new StringReader(XML_NAMESPACE_TEST)); + Node document = XML.parse(XML_NAMESPACE_TEST); assertNode(document, "document", 1); Node rootElement = document.jjtGetChild(0); @@ -296,12 +271,9 @@ public class XmlParserTest { */ @Test public void testParsingNotNamespaceAware() { - LanguageVersionHandler xmlVersionHandler = LanguageRegistry.getLanguage(XmlLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); XmlParserOptions parserOptions = new XmlParserOptions(); parserOptions.setNamespaceAware(false); - Parser parser = xmlVersionHandler.getParser(parserOptions); - Node document = parser.parse(null, new StringReader(XML_NAMESPACE_TEST)); + Node document = XML.withParserOptions(parserOptions).parse(XML_NAMESPACE_TEST); assertNode(document, "document", 1); Node rootElement = document.jjtGetChild(0); @@ -327,24 +299,21 @@ public class XmlParserTest { /** * Verifies the parsing behavior of the XML parser with validation on. - * + * * @throws UnsupportedEncodingException * error */ @Test public void testParsingWithValidation() throws UnsupportedEncodingException { - LanguageVersionHandler xmlVersionHandler = LanguageRegistry.getLanguage(XmlLanguageModule.NAME) - .getDefaultVersion().getLanguageVersionHandler(); XmlParserOptions parserOptions = new XmlParserOptions(); parserOptions.setValidating(true); - Parser parser = xmlVersionHandler.getParser(parserOptions); PrintStream oldErr = System.err; Locale oldLocale = Locale.getDefault(); try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); System.setErr(new PrintStream(bos)); Locale.setDefault(Locale.ENGLISH); - Node document = parser.parse(null, new StringReader(XML_INVALID_WITH_DTD)); + Node document = XML.withParserOptions(parserOptions).parse(XML_INVALID_WITH_DTD); Assert.assertNotNull(document); String output = bos.toString("UTF-8"); Assert.assertTrue(output.contains("Element type \"invalidChild\" must be declared.")); @@ -371,30 +340,20 @@ public class XmlParserTest { assertLineNumbers(document.jjtGetChild(0), 1, 22, 1, 29); } - private Node parseXml(String xml) { - LanguageVersionHandler xmlVersionHandler = LanguageRegistry.getLanguage(XmlLanguageModule.NAME).getDefaultVersion().getLanguageVersionHandler(); - XmlParserOptions options = (XmlParserOptions) xmlVersionHandler.getDefaultParserOptions(); - Parser parser = xmlVersionHandler.getParser(options); - return parser.parse(null, new StringReader(xml)); - } - @Test public void testBug1518() throws Exception { - String xml = IOUtils.toString(XmlParserTest.class.getResourceAsStream("parsertests/bug1518.xml"), - StandardCharsets.UTF_8); - Node document = parseXml(xml); - assertNotNull(document); + XML.parseResource("parsertests/bug1518.xml"); } @Test public void testAutoclosingElementLength() { final String xml = ""; - assertLineNumbers(parseXml(xml), 1, 1, 1, xml.length()); + assertLineNumbers(XML.parse(xml), 1, 1, 1, xml.length()); } /** * Asserts a single node inclusive attributes. - * + * * @param node * the node * @param toString @@ -424,7 +383,7 @@ public class XmlParserTest { /** * Assert a single text node. - * + * * @param node * the node to check * @param text diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/XmlParsingHelper.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/XmlParsingHelper.java new file mode 100644 index 0000000000..8faa47e547 --- /dev/null +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/XmlParsingHelper.java @@ -0,0 +1,30 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.xml; + +import net.sourceforge.pmd.lang.ast.test.BaseParsingHelper; +import net.sourceforge.pmd.lang.pom.PomLanguageModule; +import net.sourceforge.pmd.lang.wsdl.WsdlLanguageModule; +import net.sourceforge.pmd.lang.xml.ast.internal.XmlParserImpl.RootXmlNode; + +/** + * @author Clément Fournier + */ +public final class XmlParsingHelper extends BaseParsingHelper { + + public static final XmlParsingHelper XML = new XmlParsingHelper(XmlLanguageModule.NAME, Params.getDefaultProcess()); + public static final XmlParsingHelper WSDL = new XmlParsingHelper(WsdlLanguageModule.NAME, Params.getDefaultProcess()); + public static final XmlParsingHelper POM = new XmlParsingHelper(PomLanguageModule.NAME, Params.getDefaultProcess()); + + + private XmlParsingHelper(String langName, Params params) { + super(langName, RootXmlNode.class, params); + } + + @Override + protected XmlParsingHelper clone(Params params) { + return new XmlParsingHelper(this.getLangName(), params); + } +}