Merge branch 'master' into pmd/7.0.x

This commit is contained in:
Andreas Dangel
2020-03-12 14:03:20 +01:00
114 changed files with 1007 additions and 457 deletions

View File

@ -9,7 +9,9 @@ author: Tom Copeland <tom@infoether.org>
### Salesforce / Apex Language Module
* July 2019 - [Apex PMD | Static code analysis - Apex Hours](https://youtu.be/34PxAHtAavU)
* March 2020 - [Helping Salesforce developers create readable and maintainable Apex code](https://gearset.com/blog/helping-sf-developers-create-readable-and-maintainable-apex-code)
* July 2019 - [Apex PMD | Static code analysis - Apex Hours](https://youtu.be/34PxAHtAavU)
* June 2019 - [Pluralsight](https://www.pluralsight.com/authors/don-robins) Course about leveraging PMD usage for Salesforce by [Robert Sösemann](https://github.com/rsoesemann) (Apex Language Module Contributor) [Play by Play: Automated Code Analysis in Salesforce - a Tools Deep-Dive](https://www.pluralsight.com/courses/play-by-play-automated-code-analysis-in-salesforce)

View File

@ -57,7 +57,7 @@ The examples below won't repeat this taskdef element, as this is always required
<tr>
<td>rulesetfiles</td>
<td>
A comma delimited list of ruleset files ('rulesets/java/basic.xml,rulesets/java/design.xml').
A comma delimited list of ruleset files ('rulesets/java/quickstart.xml,config/my-ruleset.xml').
If you write your own ruleset files, you can put them on the classpath and plug them in here.
</td>
<td>Yes, unless the ruleset nested element is used</td>
@ -153,9 +153,10 @@ configure multiple formatters.
<dt>encoding</dt>
<dd>Specifies the encoding to be used in the generated report (only honored when used with `toFile`). When rendering `toConsole` PMD will automatically detect the terminal's encoding and use it, unless the output is being redirected / piped, in which case `file.encoding` is used. See example below.</dd>
<dt>linkPrefix</dt>
<dd>Used for linking to online HTMLized source (like <a href="https://maven.apache.org/plugins/maven-pmd-plugin/xref/org/apache/maven/plugins/pmd/PmdReport.html">this</a>). See example below. Note, this only works with [maven-jxr-plugin](https://maven.apache.org/jxr/maven-jxr-plugin/index.html).</dd>
<dd>Used for linking to online HTMLized source (like <a href="https://maven.apache.org/plugins/maven-pmd-plugin/xref/org/apache/maven/plugins/pmd/PmdReport.html">this</a>). See example below. Note, this only works with
<a href="https://maven.apache.org/jxr/maven-jxr-plugin/index.html">maven-jxr-plugin</a>.</dd>
<dt>linePrefix</dt>
<dd>Used for linking to online HTMLized source (like <a href="https://maven.apache.org/plugins/maven-pmd-plugin/xref/org/apache/maven/plugins/pmd/PmdReport.html#L375">this</a>). See example below. Note, this only works with [maven-jxr-plugin](https://maven.apache.org/jxr/maven-jxr-plugin/index.html).</dd>
<dd>Used for linking to online HTMLized source (like <a href="https://maven.apache.org/plugins/maven-pmd-plugin/xref/org/apache/maven/plugins/pmd/PmdReport.html#L375">this</a>). See example below. Note, this only works with <a href="https://maven.apache.org/jxr/maven-jxr-plugin/index.html">maven-jxr-plugin</a>.</dd>
</dl>
</td>
</tr>
@ -179,8 +180,8 @@ automatically and the latest language version is used.
<target name="pmd">
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask"/>
<pmd shortFilenames="true">
<ruleset>rulesets/java/design.xml</ruleset>
<ruleset>java-basic</ruleset>
<ruleset>rulesets/java/quickstart.xml</ruleset>
<ruleset>config/my-ruleset.xml</ruleset>
<fileset dir="/usr/local/j2sdk1.4.1_01/src/">
<include name="java/lang/*.java"/>
</fileset>
@ -261,7 +262,7 @@ Then, after the end of the PMD task, do this:
Running one ruleset to produce a HTML report (and printing the report to the console as well) using a file cache
<target name="pmd">
<pmd rulesetfiles="java-imports" cacheLocation="build/pmd/pmd.cache">
<pmd rulesetfiles="rulesets/java/quickstart.xml" cacheLocation="build/pmd/pmd.cache">
<formatter type="html" toFile="pmd_report.html" toConsole="true"/>
<fileset dir="C:\j2sdk1.4.1_01\src\java\lang\">
<include name="**/*.java"/>
@ -274,7 +275,7 @@ Running one ruleset to produce a HTML report (and printing the report to the con
Running multiple rulesets to produce an XML report with the same analysis cache
<target name="pmd">
<pmd rulesetfiles="rulesets/java/imports.xml,java-unusedcode" cacheLocation="build/pmd/pmd.cache">
<pmd rulesetfiles="rulesets/java/quickstart.xml,config/my-ruleset.xml" cacheLocation="build/pmd/pmd.cache">
<formatter type="xml" toFile="c:\pmd_report.xml"/>
<fileset dir="C:\j2sdk1.4.1_01\src\java\lang\">
<include name="**/*.java"/>
@ -297,7 +298,7 @@ need to be configured when defining the task:
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpathref="pmd.classpath" />
<target name="pmd">
<pmd rulesetfiles="rulesets/java/design.xml">
<pmd rulesetfiles="rulesets/java/quickstart.xml">
<formatter type="com.mycompany.MyRenderer" toFile="foo.html"/>
<fileset dir="/path/to/java/src">
<include name="**/*.java"/>
@ -370,11 +371,13 @@ You can run pmd then with `ant pmd`.
pmd:
[pmd] Using the normal ClassLoader
[pmd] Using these rulesets: rulesets/java/imports.xml
[pmd] Using rule DontImportJavaLang
[pmd] Using rule UnusedImports
[pmd] Using rule ImportFromSamePackage
[pmd] Using rule DuplicateImports
[pmd] Using these rulesets: rulesets/java/quickstart.xml
[pmd] Using rule AvoidMessageDigestField
[pmd] Using rule AvoidStringBufferField
[pmd] Using rule AvoidUsingHardCodedIP
[pmd] Using rule CheckResultSet
[pmd] Using rule ConstantsInInterface
...
[pmd] Processing file /usr/local/java/src/java/lang/ref/Finalizer.java
[pmd] Processing file /usr/local/java/src/java/lang/ref/FinalReference.java
[pmd] Processing file /usr/local/java/src/java/lang/ref/PhantomReference.java
@ -394,7 +397,7 @@ An HTML report with the "linkPrefix" and "linePrefix" properties:
<target name="pmd">
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask"/>
<pmd rulesetfiles="java-basic" shortFilenames="true">
<pmd rulesetfiles="rulesets/java/quickstart.xml" shortFilenames="true">
<formatter type="html" toFile="pmd_report.html">
<param name="linkPrefix" value="https://maven.apache.org/plugins/maven-pmd-plugin/xref/"/>
<param name="linePrefix" value="L"/>

View File

@ -94,9 +94,8 @@ To specify a ruleset, simply edit the previous configuration:
<artifactId>maven-pmd-plugin</artifactId>
<configuration>
<rulesets>
<ruleset>/rulesets/java/braces.xml</ruleset>
<ruleset>/rulesets/java/naming.xml</ruleset>
<ruleset>d:\rulesets\strings.xml</ruleset>
<ruleset>/rulesets/java/quickstart.xml</ruleset>
<ruleset>d:\rulesets\my-ruleset.xml</ruleset>
<ruleset>http://localhost/design.xml</ruleset>
</rulesets>
</configuration>

View File

@ -96,6 +96,13 @@ should give more accurate results and especially fixes the problems with the usi
* [#2255](https://github.com/pmd/pmd/issues/2255): \[java] InvalidLogMessageFormat false-positive for a lambda argument
* java-performance
* [#2275](https://github.com/pmd/pmd/issues/2275): \[java] AppendCharacterWithChar flags literals in an expression
* plsql
* [#2325](https://github.com/pmd/pmd/issues/2325): \[plsql] NullPointerException while running parsing test for CREATE TRIGGER
* [#2327](https://github.com/pmd/pmd/pull/2327): \[plsql] Parsing of WHERE CURRENT OF
* [#2328](https://github.com/pmd/pmd/issues/2328): \[plsql] Support XMLROOT
* [#2331](https://github.com/pmd/pmd/pull/2331): \[plsql] Fix in Comment statement
* [#2332](https://github.com/pmd/pmd/pull/2332): \[plsql] Fixed Execute Immediate statement parsing
* [#2340](https://github.com/pmd/pmd/pull/2340): \[plsql] Fixed parsing / as divide or execute
### API Changes
@ -173,6 +180,59 @@ methods on {% jdoc apex::lang.apex.ast.ApexParserVisitor %} and its implementati
* pmd-apex
* {% jdoc apex::lang.apex.metrics.ApexMetrics %}, {% jdoc apex::lang.apex.metrics.ApexMetricsComputer %}
##### In ASTs (JSP)
As part of the changes we'd like to do to AST classes for 7.0.0, we would like to
hide some methods and constructors that rule writers should not have access to.
The following usages are now deprecated **in the JSP AST** (with other languages to come):
* Manual instantiation of nodes. **Constructors of node classes are deprecated** and
marked {% jdoc core::annotation.InternalApi %}. Nodes should only be obtained from the parser,
which for rules, means that they never need to instantiate node themselves.
Those constructors will be made package private with 7.0.0.
* **Subclassing of abstract node classes, or usage of their type**. The base classes are internal API
and will be hidden in version 7.0.0. You should not couple your code to them.
* In the meantime you should use interfaces like {% jdoc jsp::lang.jsp.ast.JspNode %} or
{% jdoc core::lang.ast.Node %}, or the other published interfaces in this package,
to refer to nodes generically.
* Concrete node classes will **be made final** with 7.0.0.
* Setters found in any node class or interface. **Rules should consider the AST immutable**.
We will make those setters package private with 7.0.0.
* The class {% jdoc jsp::lang.jsp.JspParser %} is deprecated and should not be used directly.
Use {% jdoc !!core::lang.LanguageVersionHandler#getParser(ParserOptions) %} instead.
Please look at {% jdoc_package jsp::lang.jsp.ast %} to find out the full list of deprecations.
##### In ASTs (Velocity)
As part of the changes we'd like to do to AST classes for 7.0.0, we would like to
hide some methods and constructors that rule writers should not have access to.
The following usages are now deprecated **in the VM AST** (with other languages to come):
* Manual instantiation of nodes. **Constructors of node classes are deprecated** and
marked {% jdoc core::annotation.InternalApi %}. Nodes should only be obtained from the parser,
which for rules, means that they never need to instantiate node themselves.
Those constructors will be made package private with 7.0.0.
* **Subclassing of abstract node classes, or usage of their type**. The base classes are internal API
and will be hidden in version 7.0.0. You should not couple your code to them.
* In the meantime you should use interfaces like {% jdoc vm::lang.vm.ast.VmNode %} or
{% jdoc core::lang.ast.Node %}, or the other published interfaces in this package,
to refer to nodes generically.
* Concrete node classes will **be made final** with 7.0.0.
* Setters found in any node class or interface. **Rules should consider the AST immutable**.
We will make those setters package private with 7.0.0.
* The package {% jdoc_package vm::lang.vm.directive %} as well as the classes
{% jdoc vm::lang.vm.util.DirectiveMapper %} and {% jdoc vm::lang.vm.util.LogUtil %} are deprecated
for removal. They were only used internally during parsing.
* The class {% jdoc vm::lang.vm.VmParser %} is deprecated and should not be used directly.
Use {% jdoc !!core::lang.LanguageVersionHandler#getParser(ParserOptions) %} instead.
Please look at {% jdoc_package vm::lang.vm.ast %} to find out the full list of deprecations.
#### PLSQL AST
The production and node `ASTCursorBody` was unnecessary, not used and has been removed. Cursors have been already
parsed as `ASTCursorSpecification`.
### External Contributions
@ -186,6 +246,16 @@ methods on {% jdoc apex::lang.apex.ast.ApexParserVisitor %} and its implementati
* [#2297](https://github.com/pmd/pmd/pull/2297): \[apex] Cognitive complexity metrics - [Gwilym Kuiper](https://github.com/gwilymatgearset)
* [#2317](https://github.com/pmd/pmd/pull/2317): \[apex] New Rule - Test Methods Must Be In Test Classes - [Brian Nørremark](https://github.com/noerremark)
* [#2321](https://github.com/pmd/pmd/pull/2321): \[apex] Support switch statements correctly in Cognitive Complexity - [Gwilym Kuiper](https://github.com/gwilymatgearset)
* [#2326](https://github.com/pmd/pmd/pull/2326): \[plsql] Added XML functions to parser: extract(xml), xml_root and fixed xml_forest - [Piotr Szymanski](https://github.com/szyman23)
* [#2327](https://github.com/pmd/pmd/pull/2327): \[plsql] Parsing of WHERE CURRENT OF added - [Piotr Szymanski](https://github.com/szyman23)
* [#2331](https://github.com/pmd/pmd/pull/2331): \[plsql] Fix in Comment statement - [Piotr Szymanski](https://github.com/szyman23)
* [#2332](https://github.com/pmd/pmd/pull/2332): \[plsql] Fixed Execute Immediate statement parsing - [Piotr Szymanski](https://github.com/szyman23)
* [#2338](https://github.com/pmd/pmd/pull/2338): \[cs] CPD: fixes in filtering of using directives - [Maikel Steneker](https://github.com/maikelsteneker)
* [#2339](https://github.com/pmd/pmd/pull/2339): \[cs] CPD: Fixed CPD --ignore-usings option - [Maikel Steneker](https://github.com/maikelsteneker)
* [#2340](https://github.com/pmd/pmd/pull/2340): \[plsql] fix for parsing / as divide or execute - [Piotr Szymanski](https://github.com/szyman23)
* [#2342](https://github.com/pmd/pmd/pull/2342): \[xml] Update property used in example - [Piotrek Żygieło](https://github.com/pzygielo)
* [#2344](https://github.com/pmd/pmd/pull/2344): \[doc] Update ruleset examples for ant - [Piotrek Żygieło](https://github.com/pzygielo)
* [#2343](https://github.com/pmd/pmd/pull/2343): \[ci] Disable checking for snapshots in jcenter - [Piotrek Żygieło](https://github.com/pzygielo)
{% endtocmaker %}

View File

@ -41,9 +41,9 @@ public abstract class BaseTokenFilter<T extends GenericToken> implements TokenFi
currentToken = null;
if (!unprocessedTokens.isEmpty()) {
currentToken = unprocessedTokens.poll();
return currentToken;
} else {
currentToken = (T) tokenManager.getNextToken();
}
currentToken = (T) tokenManager.getNextToken();
while (!shouldStopProcessing(currentToken)) {
analyzeToken(currentToken);
analyzeTokens(currentToken, remainingTokens);
@ -53,7 +53,11 @@ public abstract class BaseTokenFilter<T extends GenericToken> implements TokenFi
return currentToken;
}
currentToken = (T) tokenManager.getNextToken();
if (!unprocessedTokens.isEmpty()) {
currentToken = unprocessedTokens.poll();
} else {
currentToken = (T) tokenManager.getNextToken();
}
}
return null;

View File

@ -1,4 +1,4 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/

View File

@ -59,6 +59,7 @@ public class CsTokenizer extends AntlrTokenizer {
private final boolean ignoreUsings;
private boolean discardingUsings = false;
private boolean discardingNL = false;
private boolean discardCurrent = false;
CsTokenFilter(final AntlrTokenManager tokenManager, boolean ignoreUsings) {
super(tokenManager);
@ -72,15 +73,19 @@ public class CsTokenizer extends AntlrTokenizer {
@Override
protected void analyzeTokens(final AntlrToken currentToken, final Iterable<AntlrToken> remainingTokens) {
discardCurrent = false;
skipUsingDirectives(currentToken, remainingTokens);
}
private void skipUsingDirectives(final AntlrToken currentToken, final Iterable<AntlrToken> remainingTokens) {
final int type = currentToken.getType();
if (type == CSharpLexer.USING && isUsingDirective(remainingTokens)) {
discardingUsings = true;
} else if (type == CSharpLexer.SEMICOLON) {
discardingUsings = false;
if (ignoreUsings) {
final int type = currentToken.getType();
if (type == CSharpLexer.USING && isUsingDirective(remainingTokens)) {
discardingUsings = true;
} else if (type == CSharpLexer.SEMICOLON && discardingUsings) {
discardingUsings = false;
discardCurrent = true;
}
}
}
@ -148,7 +153,7 @@ public class CsTokenizer extends AntlrTokenizer {
@Override
protected boolean isLanguageSpecificDiscarding() {
return discardingUsings || discardingNL;
return discardingUsings || discardingNL || discardCurrent;
}
}
}

View File

@ -116,6 +116,14 @@ public class CsTokenizerTest {
assertEquals(8, tokens.getTokens().get(14).getBeginLine());
}
@Test
public void testDoNotIgnoreUsingDirectives() {
tokenizer.setIgnoreUsings(false);
tokenizer.tokenize(toSourceCode("using System.Text;\n"), tokens);
assertEquals(6, tokens.size());
assertEquals("using", tokens.getTokens().get(0).toString());
}
@Test
public void testIgnoreUsingDirectives() {
tokenizer.setIgnoreUsings(true);
@ -125,6 +133,17 @@ public class CsTokenizerTest {
assertEquals(TokenEntry.EOF, tokens.getTokens().get(0));
}
@Test
public void testStatementsAfterUsingDirectivesAreNotIgnored() {
tokenizer.setIgnoreUsings(true);
tokenizer.tokenize(toSourceCode(
"using System;\n"
+ "public class MyClass {\n"
+ "}\n"),
tokens);
assertEquals(6, tokens.size());
}
@Test
public void testUsingStatementsAreNotIgnored() {
tokenizer.setIgnoreUsings(true);

View File

@ -59,6 +59,8 @@ public interface ASTAnyTypeBodyDeclaration extends JavaNode {
ANNOTATION,
/** No child, {@link #getDeclarationNode()} will return null. */
EMPTY,
/** See {@link ASTRecordDeclaration}. */
RECORD,
/** See {@link ASTRecordConstructorDeclaration}. */
RECORD_CONSTRUCTOR
}

View File

@ -59,6 +59,9 @@ public class ASTVariableDeclaratorId extends AbstractJavaTypeNode implements Dim
}
/**
* Note: this might be <code>null</code> in certain cases.
*/
public VariableNameDeclaration getNameDeclaration() {
return nameDeclaration;
}

View File

@ -14,6 +14,7 @@ import static net.sourceforge.pmd.lang.java.ast.ASTAnyTypeBodyDeclaration.Declar
import static net.sourceforge.pmd.lang.java.ast.ASTAnyTypeBodyDeclaration.DeclarationKind.INITIALIZER;
import static net.sourceforge.pmd.lang.java.ast.ASTAnyTypeBodyDeclaration.DeclarationKind.INTERFACE;
import static net.sourceforge.pmd.lang.java.ast.ASTAnyTypeBodyDeclaration.DeclarationKind.METHOD;
import static net.sourceforge.pmd.lang.java.ast.ASTAnyTypeBodyDeclaration.DeclarationKind.RECORD;
import net.sourceforge.pmd.annotation.InternalApi;
@ -72,6 +73,8 @@ abstract class AbstractTypeBodyDeclaration extends AbstractJavaNode implements A
return ANNOTATION;
} else if (node instanceof ASTEnumDeclaration) {
return ENUM;
} else if (node instanceof ASTRecordDeclaration) {
return RECORD;
}
throw new IllegalStateException("Declaration node types should all be known");

View File

@ -60,6 +60,7 @@ public abstract class AbstractInefficientZeroCheck extends AbstractJavaRule {
public Object visit(ASTVariableDeclaratorId node, Object data) {
Node nameNode = node.getTypeNameNode();
if (nameNode == null || nameNode instanceof ASTPrimitiveType
|| node.getNameDeclaration() == null
|| !appliesToClassName(node.getNameDeclaration().getTypeImage())) {
return data;
}

View File

@ -92,7 +92,7 @@ public abstract class AbstractPoorMethodCall extends AbstractJavaRule {
*/
@Override
public Object visit(ASTVariableDeclaratorId node, Object data) {
if (!targetTypename().equals(node.getNameDeclaration().getTypeImage())) {
if (node.getNameDeclaration() == null || !targetTypename().equals(node.getNameDeclaration().getTypeImage())) {
return data;
}

View File

@ -209,7 +209,7 @@ public class MissingOverrideRule extends AbstractJavaRule {
@Override
public Object visit(ASTMethodDeclaration node, Object data) {
if (currentLookup.peek() == null) {
if (currentLookup.isEmpty() || currentLookup.peek() == null) {
return super.visit(node, data);
}

View File

@ -55,7 +55,8 @@ public class InsufficientStringBufferDeclarationRule extends AbstractJavaRule {
@Override
public Object visit(ASTVariableDeclaratorId node, Object data) {
if (!TypeHelper.isExactlyAny(node.getNameDeclaration(), StringBuffer.class, StringBuilder.class)) {
if (node.getNameDeclaration() == null
|| !TypeHelper.isExactlyAny(node.getNameDeclaration(), StringBuffer.class, StringBuilder.class)) {
return data;
}
Node rootNode = node;

View File

@ -18,7 +18,8 @@ public class StringToStringRule extends AbstractJavaRule {
@Override
public Object visit(ASTVariableDeclaratorId node, Object data) {
if (!TypeHelper.isExactlyAny(node.getNameDeclaration(), String.class)
if (node.getNameDeclaration() == null
|| !TypeHelper.isExactlyAny(node.getNameDeclaration(), String.class)
&& !TypeHelper.isExactlyAny(node.getNameDeclaration(), String[].class)) {
return data;
}

View File

@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.java.symboltable;
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression;
import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType;
import net.sourceforge.pmd.lang.java.ast.ASTRecordComponent;
import net.sourceforge.pmd.lang.java.ast.ASTReferenceType;
import net.sourceforge.pmd.lang.java.ast.ASTType;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
@ -91,7 +92,15 @@ public class VariableNameDeclaration extends AbstractNameDeclaration implements
&& getAccessNodeParent().getFirstChildOfType(ASTType.class).getChild(0) instanceof ASTReferenceType;
}
private boolean isRecordComponent() {
return node.getParent() instanceof ASTRecordComponent;
}
public AccessNode getAccessNodeParent() {
if (isRecordComponent()) {
return null;
}
if (node.getParent() instanceof ASTFormalParameter || node.getParent() instanceof ASTLambdaExpression) {
return (AccessNode) node.getParent();
}
@ -103,6 +112,9 @@ public class VariableNameDeclaration extends AbstractNameDeclaration implements
}
private TypeNode getTypeNode() {
if (isRecordComponent()) {
return (TypeNode) node.getParent().getFirstChildOfType(ASTType.class).getChild(0);
}
if (isPrimitiveType()) {
return (TypeNode) getAccessNodeParent().getFirstChildOfType(ASTType.class).getChild(0);
}

View File

@ -13,6 +13,7 @@ import org.junit.Test;
import net.sourceforge.pmd.lang.ast.ParseException;
import net.sourceforge.pmd.lang.java.JavaParsingHelper;
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeBodyDeclaration.DeclarationKind;
/**
* Tests new java14 preview features.
@ -83,6 +84,9 @@ public class Java14PreviewTest {
Assert.assertEquals("s", variable.getVariableName());
Assert.assertTrue(variable.isPatternBinding());
Assert.assertTrue(variable.isFinal());
// Note: these variables are not part of the symbol table
// See ScopeAndDeclarationFinder#visit(ASTVariableDeclaratorId, Object)
Assert.assertNull(variable.getNameDeclaration());
}
}
@ -102,6 +106,9 @@ public class Java14PreviewTest {
Assert.assertEquals(2, components.size());
Assert.assertEquals("x", components.get(0).getVarId().getImage());
Assert.assertEquals("y", components.get(1).getVarId().getImage());
Assert.assertNull(components.get(0).getVarId().getNameDeclaration().getAccessNodeParent());
Assert.assertEquals(Integer.TYPE, components.get(0).getVarId().getNameDeclaration().getType());
Assert.assertEquals("int", components.get(0).getVarId().getNameDeclaration().getTypeImage());
}
@Test(expected = ParseException.class)
@ -130,6 +137,10 @@ public class Java14PreviewTest {
Assert.assertEquals(2, complex.getDeclarations().size());
Assert.assertTrue(complex.getDeclarations().get(0).getChild(1) instanceof ASTConstructorDeclaration);
Assert.assertTrue(complex.getDeclarations().get(1).getChild(0) instanceof ASTRecordDeclaration);
Assert.assertTrue(complex.getParent() instanceof ASTClassOrInterfaceBodyDeclaration);
ASTClassOrInterfaceBodyDeclaration complexParent = complex.getFirstParentOfType(ASTClassOrInterfaceBodyDeclaration.class);
Assert.assertEquals(DeclarationKind.RECORD, complexParent.getKind());
Assert.assertSame(complex, complexParent.getDeclarationNode());
ASTRecordDeclaration nested = recordDecls.get(1);
Assert.assertEquals("Nested", nested.getSimpleName());

View File

@ -582,5 +582,18 @@
</code>
</test-code>
<test-code>
<description>EmptyStackException with record top level</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public record Point(int x, int y) {
public static void main(String[] args) {
Point p = new Point(1, 2);
System.out.println("p = " + p);
}
}
]]></code>
<source-type>java 14-preview</source-type>
</test-code>
</test-data>

View File

@ -196,4 +196,22 @@ public class Foo {
}
]]></code>
</test-code>
<test-code>
<description>Avoid NPE for pattern matching instanceof</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class PatternMatchingInstanceof {
private String s = "other string";
public void test() {
Object obj = "abc";
if (obj instanceof String s) {
System.out.println("a) obj == s: " + (obj == s)); // true
}
}
}
]]></code>
<source-type>java 14-preview</source-type>
</test-code>
</test-data>

View File

@ -120,17 +120,17 @@ public class Token implements GenericToken, java.io.Serializable]]></replacevalu
<replaceregexp>
<regexp pattern="class|interface" />
<substitution expression="@Deprecated @net.sourceforge.pmd.annotation.InternalApi \0" />
<regexp pattern="public (?:class|interface)" />
<substitution expression="@Deprecated${line.separator}@net.sourceforge.pmd.annotation.InternalApi${line.separator}\0" />
<fileset dir="${target}/net/sourceforge/pmd/lang/jsp/ast">
<exclude name="AST*.java" />
<exclude name="ParseException.java" />
</fileset>
</replaceregexp>
<replaceregexp>
<regexp pattern="public class ParseException " />
<substitution expression=" /** @deprecated Use superclass {@link net.sourceforge.pmd.lang.ast.ParseException} */
@Deprecated @net.sourceforge.pmd.annotation.InternalApi \0" />
<regexp pattern="(?m)\*/\s+(public class ParseException )" />
<substitution expression="*${line.separator} * @deprecated Use superclass {@link net.sourceforge.pmd.lang.ast.ParseException}${line.separator} */${line.separator}@Deprecated${line.separator}@net.sourceforge.pmd.annotation.InternalApi${line.separator}\1" />
<fileset file="${target}/net/sourceforge/pmd/lang/jsp/ast/ParseException.java"/>
</replaceregexp>
</target>

View File

@ -6,7 +6,9 @@ package net.sourceforge.pmd.lang.jsp;
import java.io.Reader;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.AbstractParser;
import net.sourceforge.pmd.lang.LanguageVersionHandler;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.TokenManager;
import net.sourceforge.pmd.lang.ast.AbstractTokenManager;
@ -16,7 +18,11 @@ import net.sourceforge.pmd.lang.ast.impl.javacc.CharStreamFactory;
/**
* Adapter for the JspParser.
*
* @deprecated This is internal API, use {@link LanguageVersionHandler#getParser(ParserOptions)}.
*/
@InternalApi
@Deprecated
public class JspParser extends AbstractParser {
public JspParser(ParserOptions parserOptions) {

View File

@ -1,33 +1,33 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
/* Generated By:JJTree: Do not edit this line. ASTAttribute.java */
package net.sourceforge.pmd.lang.jsp.ast;
import net.sourceforge.pmd.annotation.InternalApi;
public class ASTAttribute extends AbstractJspNode {
private String name;
@InternalApi
@Deprecated
public ASTAttribute(int id) {
super(id);
}
@InternalApi
@Deprecated
public ASTAttribute(JspParser p, int id) {
super(p, id);
}
/**
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param name
* The name to set.
*/
@InternalApi
@Deprecated
public void setName(String name) {
this.name = name;
}
@ -59,9 +59,6 @@ public class ASTAttribute extends AbstractJspNode {
return colonIndex >= 0 ? name.substring(colonIndex + 1) : name;
}
/**
* Accept the visitor. *
*/
@Override
public Object jjtAccept(JspParserVisitor visitor, Object data) {
return visitor.visit(this, data);

View File

@ -1,22 +1,24 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
/* Generated By:JJTree: Do not edit this line. ASTAttributeValue.java */
package net.sourceforge.pmd.lang.jsp.ast;
import net.sourceforge.pmd.annotation.InternalApi;
public class ASTAttributeValue extends AbstractJspNode {
@InternalApi
@Deprecated
public ASTAttributeValue(int id) {
super(id);
}
@InternalApi
@Deprecated
public ASTAttributeValue(JspParser p, int id) {
super(p, id);
}
/**
* Accept the visitor. *
*/
@Override
public Object jjtAccept(JspParserVisitor visitor, Object data) {
return visitor.visit(this, data);

View File

@ -1,22 +1,24 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
/* Generated By:JJTree: Do not edit this line. ASTCData.java */
package net.sourceforge.pmd.lang.jsp.ast;
import net.sourceforge.pmd.annotation.InternalApi;
public class ASTCData extends AbstractJspNode {
@InternalApi
@Deprecated
public ASTCData(int id) {
super(id);
}
@InternalApi
@Deprecated
public ASTCData(JspParser p, int id) {
super(p, id);
}
/**
* Accept the visitor. *
*/
@Override
public Object jjtAccept(JspParserVisitor visitor, Object data) {
return visitor.visit(this, data);

View File

@ -1,22 +1,24 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
/* Generated By:JJTree: Do not edit this line. ASTCommentTag.java */
package net.sourceforge.pmd.lang.jsp.ast;
import net.sourceforge.pmd.annotation.InternalApi;
public class ASTCommentTag extends AbstractJspNode {
@InternalApi
@Deprecated
public ASTCommentTag(int id) {
super(id);
}
@InternalApi
@Deprecated
public ASTCommentTag(JspParser p, int id) {
super(p, id);
}
/**
* Accept the visitor. *
*/
@Override
public Object jjtAccept(JspParserVisitor visitor, Object data) {
return visitor.visit(this, data);

View File

@ -1,24 +1,25 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
/* Generated By:JJTree: Do not edit this line. ASTCompilationUnit.java */
package net.sourceforge.pmd.lang.jsp.ast;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.RootNode;
public class ASTCompilationUnit extends AbstractJspNode implements RootNode {
@InternalApi
@Deprecated
public ASTCompilationUnit(int id) {
super(id);
}
@InternalApi
@Deprecated
public ASTCompilationUnit(JspParser p, int id) {
super(p, id);
}
/**
* Accept the visitor. *
*/
@Override
public Object jjtAccept(JspParserVisitor visitor, Object data) {
return visitor.visit(this, data);

View File

@ -1,22 +1,24 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
/* Generated By:JJTree: Do not edit this line. ASTContent.java */
package net.sourceforge.pmd.lang.jsp.ast;
import net.sourceforge.pmd.annotation.InternalApi;
public class ASTContent extends AbstractJspNode {
@InternalApi
@Deprecated
public ASTContent(int id) {
super(id);
}
@InternalApi
@Deprecated
public ASTContent(JspParser p, int id) {
super(p, id);
}
/**
* Accept the visitor. *
*/
@Override
public Object jjtAccept(JspParserVisitor visitor, Object data) {
return visitor.visit(this, data);

View File

@ -1,40 +1,37 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
/* Generated By:JJTree: Do not edit this line. ASTDeclaration.java */
package net.sourceforge.pmd.lang.jsp.ast;
import net.sourceforge.pmd.annotation.InternalApi;
public class ASTDeclaration extends AbstractJspNode {
private String name;
@InternalApi
@Deprecated
public ASTDeclaration(int id) {
super(id);
}
@InternalApi
@Deprecated
public ASTDeclaration(JspParser p, int id) {
super(p, id);
}
/**
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param name
* The name to set.
*/
@InternalApi
@Deprecated
public void setName(String name) {
this.name = name;
}
/**
* Accept the visitor. *
*/
@Override
public Object jjtAccept(JspParserVisitor visitor, Object data) {
return visitor.visit(this, data);

View File

@ -1,10 +1,11 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
/* Generated By:JJTree: Do not edit this line. ASTDoctypeDeclaration.java */
package net.sourceforge.pmd.lang.jsp.ast;
import net.sourceforge.pmd.annotation.InternalApi;
public class ASTDoctypeDeclaration extends AbstractJspNode {
/**
@ -12,32 +13,28 @@ public class ASTDoctypeDeclaration extends AbstractJspNode {
*/
private String name;
@InternalApi
@Deprecated
public ASTDoctypeDeclaration(int id) {
super(id);
}
@InternalApi
@Deprecated
public ASTDoctypeDeclaration(JspParser p, int id) {
super(p, id);
}
/**
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param name
* The name to set.
*/
@InternalApi
@Deprecated
public void setName(String name) {
this.name = name;
}
/**
* Accept the visitor. *
*/
@Override
public Object jjtAccept(JspParserVisitor visitor, Object data) {
return visitor.visit(this, data);

Some files were not shown because too many files have changed in this diff Show More