forked from phoedos/pmd
Merge branch 'master' into cli-exit-codes-processing-errors
This commit is contained in:
commit
2d9385f462
26
README.md
26
README.md
@ -5,28 +5,26 @@
|
||||
[![Join the chat](https://img.shields.io/gitter/room/pmd/pmd)](https://app.gitter.im/#/room/#pmd_pmd:gitter.im?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[![Build Status](https://github.com/pmd/pmd/workflows/build/badge.svg?branch=master)](https://github.com/pmd/pmd/actions)
|
||||
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd)
|
||||
[![Reproducible Builds](https://img.shields.io/badge/Reproducible_Builds-ok-green?labelColor=blue)](https://github.com/jvm-repo-rebuild/reproducible-central#net.sourceforge.pmd:pmd)
|
||||
[![Reproducible Builds](https://img.shields.io/badge/Reproducible_Builds-ok-green?labelColor=blue)](https://github.com/jvm-repo-rebuild/reproducible-central/tree/master/content/net/sourceforge/pmd#readme)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/pmd/pmd/badge.svg)](https://coveralls.io/github/pmd/pmd)
|
||||
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/ea550046a02344ec850553476c4aa2ca)](https://www.codacy.com/gh/pmd/pmd/dashboard?utm_source=github.com&utm_medium=referral&utm_content=pmd/pmd&utm_campaign=Badge_Grade)
|
||||
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/ea550046a02344ec850553476c4aa2ca)](https://app.codacy.com/organizations/gh/pmd/dashboard)
|
||||
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](code_of_conduct.md)
|
||||
[![Documentation (latest)](https://img.shields.io/badge/docs-latest-green)](https://docs.pmd-code.org/latest/)
|
||||
|
||||
**PMD** is a source code analyzer. It finds common programming flaws like unused variables, empty catch blocks,
|
||||
unnecessary object creation, and so forth. It supports many languages. It can be extended with custom rules.
|
||||
It uses JavaCC and Antlr to parse source files into abstract syntax trees (AST) and runs rules against them to find violations.
|
||||
Rules can be written in Java or using a XPath query.
|
||||
**PMD** is an extensible multilanguage static code analyzer. It finds common programming flaws like unused variables,
|
||||
empty catch blocks, unnecessary object creation, and so forth. It's mainly concerned with **Java and
|
||||
Apex**, but **supports 16 other languages**. It comes with **400+ built-in rules**. It can be
|
||||
extended with custom rules. It uses JavaCC and Antlr to parse source files into abstract syntax trees
|
||||
(AST) and runs rules against them to find violations. Rules can be written in Java or using a XPath query.
|
||||
|
||||
It supports Java, JavaScript, Salesforce.com Apex and Visualforce,
|
||||
Modelica, PLSQL, Apache Velocity, HTML, XML and XSL.
|
||||
Currently, PMD supports Java, JavaScript, Salesforce.com Apex and Visualforce,
|
||||
Kotlin, Swift, Modelica, PLSQL, Apache Velocity, JSP, WSDL, Maven POM, HTML, XML and XSL.
|
||||
Scala is supported, but there are currently no Scala rules available.
|
||||
|
||||
Additionally, it includes **CPD**, the copy-paste-detector. CPD finds duplicated code in
|
||||
C/C++, C#, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Kotlin, Lua, Matlab, Modelica,
|
||||
Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex and Visualforce, Scala, Swift, T-SQL,
|
||||
Apache Velocity, and XML.
|
||||
|
||||
In the future we hope to add support for data/control flow analysis and automatic (quick) fixes where
|
||||
it makes sense.
|
||||
Coco, C/C++, C#, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Julia, Kotlin,
|
||||
Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex and
|
||||
Visualforce, Scala, Swift, T-SQL, Typescript, Apache Velocity, WSDL, XML and XSL.
|
||||
|
||||
## 🚀 Installation and Usage
|
||||
|
||||
|
@ -24,10 +24,20 @@ additional_js:
|
||||
<!-- You can link to an individual panel, the id is determined from the title of the panel -->
|
||||
<!-- See custom/shuffle_panel.html for the details -->
|
||||
|
||||
**PMD** is a static source code analyzer. It finds common programming flaws like
|
||||
unused variables, empty catch blocks, unnecessary object creation, and
|
||||
so forth. It's mainly concerned with **Java and Apex**, but **supports 16 other
|
||||
languages**.
|
||||
**PMD** is an extensible multilanguage static code analyzer. It finds common programming flaws like unused variables,
|
||||
empty catch blocks, unnecessary object creation, and so forth. It's mainly concerned with **Java and
|
||||
Apex**, but **supports 16 other languages**. It comes with **400+ built-in rules**. It can be
|
||||
extended with custom rules. It uses JavaCC and Antlr to parse source files into abstract syntax trees
|
||||
(AST) and runs rules against them to find violations. Rules can be written in Java or using a XPath query.
|
||||
|
||||
Currently, PMD supports Java, JavaScript, Salesforce.com Apex and Visualforce,
|
||||
Kotlin, Swift, Modelica, PLSQL, Apache Velocity, JSP, WSDL, Maven POM, HTML, XML and XSL.
|
||||
Scala is supported, but there are currently no Scala rules available.
|
||||
|
||||
Additionally, it includes **CPD**, the copy-paste-detector. CPD finds duplicated code in
|
||||
Coco, C/C++, C#, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Julia, Kotlin,
|
||||
Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex and
|
||||
Visualforce, Scala, Swift, T-SQL, Typescript, Apache Velocity, WSDL, XML and XSL.
|
||||
|
||||
PMD features many **built-in checks** (in PMD lingo, *rules*), which are documented
|
||||
for each language in our [Rule references](#shuffle-panel-rule-references). We
|
||||
@ -43,7 +53,7 @@ things, PMD can be run:
|
||||
* As a [bld operation](pmd_userdocs_tools_bld.html)
|
||||
* From [command-line](pmd_userdocs_installation.html#running-pmd-via-command-line)
|
||||
|
||||
**CPD**, the **copy-paste detector**, is also distributed with PMD. You can also use it
|
||||
**CPD**, the **copy-paste detector**, is also distributed with PMD. You can use it
|
||||
in a variety of ways, which are [documented here](pmd_userdocs_cpd.html).
|
||||
|
||||
## 💾 Download
|
||||
|
@ -49,23 +49,21 @@ To represent attributes, we must map Java values to [XPath Data Model (XDM)](htt
|
||||
values. In the following table we refer to the type conversion function as `conv`, a function from Java types
|
||||
to XDM types.
|
||||
|
||||
| Java type `T` | XSD type `conv(T)` |
|
||||
|---------------|---------------------------------------|
|
||||
| `int` | `xs:integer` |
|
||||
| `long` | `xs:integer` |
|
||||
| `double` | `xs:decimal` |
|
||||
| `float` | `xs:decimal` |
|
||||
| `boolean` | `xs:boolean` |
|
||||
| `String` | `xs:string` |
|
||||
| `Character` | `xs:string` |
|
||||
| `Enum<E>` | `xs:string` (uses `Object::toString`) |
|
||||
| `List<E>` | `conv(E)*` (a sequence type) |
|
||||
| Java type `T` | XSD type `conv(T)` |
|
||||
|-------------------|---------------------------------------|
|
||||
| `int` | `xs:integer` |
|
||||
| `long` | `xs:integer` |
|
||||
| `double` | `xs:decimal` |
|
||||
| `float` | `xs:decimal` |
|
||||
| `boolean` | `xs:boolean` |
|
||||
| `String` | `xs:string` |
|
||||
| `Character` | `xs:string` |
|
||||
| `Enum<E>` | `xs:string` (uses `Object::toString`) |
|
||||
| `Collection<E>` | `conv(E)*` (a sequence type) |
|
||||
|
||||
The same `conv` function is used to translate rule property values to XDM values.
|
||||
|
||||
{% include warning.html content="Lists are only supported for rule properties, not attributes." %}
|
||||
|
||||
|
||||
Additionaly, PMD's own `net.sourceforge.pmd.lang.document.Chars` is also translated to a `xs:string`
|
||||
|
||||
|
||||
## Rule properties
|
||||
|
@ -14,17 +14,29 @@ This is a {{ site.pmd.release_type }} release.
|
||||
|
||||
### 🚀 New and noteworthy
|
||||
|
||||
### 🐛 Fixed Issues
|
||||
#### Collections exposed as XPath attributes
|
||||
|
||||
Up to now, all AST node getters would be exposed to XPath, as long as the return type was a primitive (boxed or unboxed), String or Enum. That meant that collections, even of these basic types, were not exposed, so for instance accessing Apex's `ASTUserClass.getInterfaceNames()` to list the interfaces implemented by a class was impossible from XPath, and would require writing a Java rule to check it.
|
||||
|
||||
Since this release, PMD will also expose any getter returning a collection of any supported type as a sequence through an XPath attribute. They would require to use apropriate XQuery functions to manipulate the sequence. So for instance, to detect any given `ASTUserClass` in Apex that implements `Queueable`, it is now possible to write:
|
||||
|
||||
```xml
|
||||
/UserClass[@InterfaceNames = 'Queueable']
|
||||
```
|
||||
|
||||
### 🐛 Fixed Issues
|
||||
* cli
|
||||
* [#2827](https://github.com/pmd/pmd/issues/2827): \[cli] Consider processing errors in exit status
|
||||
* core
|
||||
* [#4467](https://github.com/pmd/pmd/issues/4467): \[core] Expose collections from getters as XPath sequence attributes
|
||||
* [#4978](https://github.com/pmd/pmd/issues/4978): \[core] Referenced Rulesets do not emit details on validation errors
|
||||
* [#4983](https://github.com/pmd/pmd/pull/4983): \[cpd] Fix CPD crashes about unicode escapes
|
||||
* java
|
||||
* [#4912](https://github.com/pmd/pmd/issues/4912): \[java] Unable to parse some Java9+ resource references
|
||||
* [#4973](https://github.com/pmd/pmd/pull/4973): \[java] Stop parsing Java for CPD
|
||||
* [#4980](https://github.com/pmd/pmd/issues/4980): \[java] Bad intersection, unrelated class types java.lang.Object\[] and java.lang.Number
|
||||
* [#4988](https://github.com/pmd/pmd/pull/4988): \[java] Fix impl of ASTVariableId::isResourceDeclaration / VariableId/@<!-- -->ResourceDeclaration
|
||||
* [#5006](https://github.com/pmd/pmd/issues/5006): \[java] Bad intersection, unrelated class types Child and Parent<? extends Child>
|
||||
* java-bestpractices
|
||||
* [#4278](https://github.com/pmd/pmd/issues/4278): \[java] UnusedPrivateMethod FP with Junit 5 @MethodSource and default factory method name
|
||||
* [#4852](https://github.com/pmd/pmd/issues/4852): \[java] ReplaceVectorWithList false-positive (neither Vector nor List usage)
|
||||
@ -32,6 +44,10 @@ This is a {{ site.pmd.release_type }} release.
|
||||
* [#4985](https://github.com/pmd/pmd/issues/4985): \[java] UnusedPrivateMethod false-positive / method reference in combination with custom object
|
||||
* java-codestyle
|
||||
* [#4930](https://github.com/pmd/pmd/issues/4930): \[java] EmptyControlStatement should not allow empty try with concise resources
|
||||
* java-errorprone
|
||||
* [#4042](https://github.com/pmd/pmd/issues/4042): \[java] A false negative about the rule StringBufferInstantiationWithChar
|
||||
* java-multithreading
|
||||
* [#2368](https://github.com/pmd/pmd/issues/2368): \[java] False positive UnsynchronizedStaticFormatter in static initializer
|
||||
|
||||
### 🚨 API Changes
|
||||
|
||||
|
@ -7,6 +7,8 @@ package net.sourceforge.pmd.lang.apex.ast;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.sourceforge.pmd.lang.rule.xpath.NoAttribute;
|
||||
|
||||
import com.google.summit.ast.Identifier;
|
||||
|
||||
public final class ASTReferenceExpression extends AbstractApexNode.Many<Identifier> {
|
||||
@ -38,6 +40,7 @@ public final class ASTReferenceExpression extends AbstractApexNode.Many<Identifi
|
||||
return "";
|
||||
}
|
||||
|
||||
@NoAttribute
|
||||
public List<String> getNames() {
|
||||
return nodes.stream().map(Identifier::getString).collect(Collectors.toList());
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
+- ApexFile[@DefiningType = "InnerClassLocations", @RealLoc = true]
|
||||
+- UserClass[@DefiningType = "InnerClassLocations", @Image = "InnerClassLocations", @RealLoc = true, @SimpleName = "InnerClassLocations", @SuperClassName = ""]
|
||||
+- UserClass[@DefiningType = "InnerClassLocations", @Image = "InnerClassLocations", @InterfaceNames = (), @RealLoc = true, @SimpleName = "InnerClassLocations", @SuperClassName = ""]
|
||||
+- ModifierNode[@Abstract = false, @DefiningType = "InnerClassLocations", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
+- UserClass[@DefiningType = "InnerClassLocations.bar1", @Image = "bar1", @RealLoc = true, @SimpleName = "bar1", @SuperClassName = ""]
|
||||
+- UserClass[@DefiningType = "InnerClassLocations.bar1", @Image = "bar1", @InterfaceNames = (), @RealLoc = true, @SimpleName = "bar1", @SuperClassName = ""]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "InnerClassLocations.bar1", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- Method[@Arity = 0, @CanonicalName = "m", @Constructor = false, @DefiningType = "InnerClassLocations.bar1", @Image = "m", @RealLoc = true, @ReturnType = "void", @StaticInitializer = false]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "InnerClassLocations.bar1", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
@ -14,7 +14,7 @@
|
||||
| +- MethodCallExpression[@DefiningType = "InnerClassLocations.bar1", @FullMethodName = "System.out.println", @InputParametersSize = 1, @MethodName = "println", @RealLoc = true]
|
||||
| +- ReferenceExpression[@DefiningType = "InnerClassLocations.bar1", @Image = "System", @RealLoc = true, @ReferenceType = ReferenceType.METHOD, @SObjectType = false, @SafeNav = false]
|
||||
| +- LiteralExpression[@Boolean = false, @Decimal = false, @DefiningType = "InnerClassLocations.bar1", @Double = false, @Image = "foo", @Integer = false, @LiteralType = LiteralType.STRING, @Long = false, @Name = null, @Null = false, @RealLoc = true, @String = true]
|
||||
+- UserClass[@DefiningType = "InnerClassLocations.bar2", @Image = "bar2", @RealLoc = true, @SimpleName = "bar2", @SuperClassName = ""]
|
||||
+- UserClass[@DefiningType = "InnerClassLocations.bar2", @Image = "bar2", @InterfaceNames = (), @RealLoc = true, @SimpleName = "bar2", @SuperClassName = ""]
|
||||
+- ModifierNode[@Abstract = false, @DefiningType = "InnerClassLocations.bar2", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
+- Method[@Arity = 0, @CanonicalName = "m", @Constructor = false, @DefiningType = "InnerClassLocations.bar2", @Image = "m", @RealLoc = true, @ReturnType = "void", @StaticInitializer = false]
|
||||
+- ModifierNode[@Abstract = false, @DefiningType = "InnerClassLocations.bar2", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
|
@ -1,5 +1,5 @@
|
||||
+- ApexFile[@DefiningType = "NullCoalescingOperator", @RealLoc = true]
|
||||
+- UserClass[@DefiningType = "NullCoalescingOperator", @Image = "NullCoalescingOperator", @RealLoc = true, @SimpleName = "NullCoalescingOperator", @SuperClassName = ""]
|
||||
+- UserClass[@DefiningType = "NullCoalescingOperator", @Image = "NullCoalescingOperator", @InterfaceNames = (), @RealLoc = true, @SimpleName = "NullCoalescingOperator", @SuperClassName = ""]
|
||||
+- ModifierNode[@Abstract = false, @DefiningType = "NullCoalescingOperator", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
+- Method[@Arity = 2, @CanonicalName = "leftOrRight", @Constructor = false, @DefiningType = "NullCoalescingOperator", @Image = "leftOrRight", @RealLoc = true, @ReturnType = "String", @StaticInitializer = false]
|
||||
+- ModifierNode[@Abstract = false, @DefiningType = "NullCoalescingOperator", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
|
@ -1,11 +1,11 @@
|
||||
+- ApexFile[@DefiningType = "Foo", @RealLoc = true]
|
||||
+- UserClass[@DefiningType = "Foo", @Image = "Foo", @RealLoc = true, @SimpleName = "Foo", @SuperClassName = ""]
|
||||
+- UserClass[@DefiningType = "Foo", @Image = "Foo", @InterfaceNames = (), @RealLoc = true, @SimpleName = "Foo", @SuperClassName = ""]
|
||||
+- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
+- Field[@DefiningType = "Foo", @Image = "x", @Name = "x", @RealLoc = true, @Type = "Integer", @Value = null]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
+- Field[@DefiningType = "Foo", @Image = "profileUrl", @Name = "profileUrl", @RealLoc = true, @Type = "String", @Value = null]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
+- FieldDeclarationStatements[@DefiningType = "Foo", @RealLoc = true, @TypeName = "Integer"]
|
||||
+- FieldDeclarationStatements[@DefiningType = "Foo", @RealLoc = true, @TypeArguments = (), @TypeName = "Integer"]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- FieldDeclaration[@DefiningType = "Foo", @Image = "x", @Name = "x", @RealLoc = true]
|
||||
| +- VariableExpression[@DefiningType = "Foo", @Image = "anIntegerField", @RealLoc = true]
|
||||
@ -14,7 +14,7 @@
|
||||
| | +- EmptyReferenceExpression[@DefiningType = null, @RealLoc = false]
|
||||
| +- VariableExpression[@DefiningType = "Foo", @Image = "x", @RealLoc = true]
|
||||
| +- EmptyReferenceExpression[@DefiningType = null, @RealLoc = false]
|
||||
+- FieldDeclarationStatements[@DefiningType = "Foo", @RealLoc = true, @TypeName = "String"]
|
||||
+- FieldDeclarationStatements[@DefiningType = "Foo", @RealLoc = true, @TypeArguments = (), @TypeName = "String"]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- FieldDeclaration[@DefiningType = "Foo", @Image = "profileUrl", @Name = "profileUrl", @RealLoc = true]
|
||||
| +- MethodCallExpression[@DefiningType = "Foo", @FullMethodName = "toExternalForm", @InputParametersSize = 0, @MethodName = "toExternalForm", @RealLoc = true]
|
||||
|
@ -31,9 +31,9 @@ class TreeExportCliTest extends BaseCliTest {
|
||||
final CliExecutionResult output = runCliSuccessfully("-i", "-f", "xml", "-PlineSeparator=LF");
|
||||
|
||||
output.checkStdOut(equalTo("<?xml version='1.0' encoding='UTF-8' ?>\n"
|
||||
+ "<dummyRootNode Image=''>\n"
|
||||
+ " <dummyNode Image='a'>\n"
|
||||
+ " <dummyNode Image='b' />\n"
|
||||
+ "<dummyRootNode Image='' Lines='[, , ]'>\n"
|
||||
+ " <dummyNode Image='a' Lines='[a, a, a]'>\n"
|
||||
+ " <dummyNode Image='b' Lines='[b, b, b]' />\n"
|
||||
+ " </dummyNode>\n"
|
||||
+ "</dummyRootNode>\n"));
|
||||
});
|
||||
@ -44,9 +44,9 @@ class TreeExportCliTest extends BaseCliTest {
|
||||
File file = newFileWithContents("(a(b))");
|
||||
final CliExecutionResult result = runCliSuccessfully("--file", file.getAbsolutePath(), "-f", "xml", "-PlineSeparator=LF");
|
||||
result.checkStdOut(equalTo("<?xml version='1.0' encoding='UTF-8' ?>\n"
|
||||
+ "<dummyRootNode Image=''>\n"
|
||||
+ " <dummyNode Image='a'>\n"
|
||||
+ " <dummyNode Image='b' />\n"
|
||||
+ "<dummyRootNode Image='' Lines='[, , ]'>\n"
|
||||
+ " <dummyNode Image='a' Lines='[a, a, a]'>\n"
|
||||
+ " <dummyNode Image='b' Lines='[b, b, b]' />\n"
|
||||
+ " </dummyNode>\n"
|
||||
+ "</dummyRootNode>\n"));
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ package net.sourceforge.pmd.lang.rule.xpath;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
@ -106,16 +105,11 @@ public final class Attribute {
|
||||
return null;
|
||||
} else {
|
||||
DeprecatedAttribute annot = method.getAnnotation(DeprecatedAttribute.class);
|
||||
String result = annot != null
|
||||
return annot != null
|
||||
? annot.replaceWith()
|
||||
: method.isAnnotationPresent(Deprecated.class)
|
||||
? DeprecatedAttribute.NO_REPLACEMENT
|
||||
: null;
|
||||
if (result == null && List.class.isAssignableFrom(method.getReturnType())) {
|
||||
// Lists are generally deprecated, see #2451
|
||||
result = DeprecatedAttribute.NO_REPLACEMENT;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,11 @@ import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -119,7 +123,27 @@ public class AttributeAxisIterator implements Iterator<Attribute> {
|
||||
|
||||
private boolean isConsideredReturnType(Method method) {
|
||||
Class<?> klass = method.getReturnType();
|
||||
return CONSIDERED_RETURN_TYPES.contains(klass) || klass.isEnum();
|
||||
if (CONSIDERED_RETURN_TYPES.contains(klass) || klass.isEnum()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Collection.class.isAssignableFrom(klass)) {
|
||||
Type t = method.getGenericReturnType();
|
||||
if (t instanceof ParameterizedType) {
|
||||
try {
|
||||
// ignore type variables, such as List<N>… we could check all bounds, but probably it's overkill
|
||||
Type actualTypeArgument = ((ParameterizedType) t).getActualTypeArguments()[0];
|
||||
if (!TypeVariable.class.isAssignableFrom(actualTypeArgument.getClass())) {
|
||||
Class<?> elementKlass = Class.forName(actualTypeArgument.getTypeName());
|
||||
return CONSIDERED_RETURN_TYPES.contains(elementKlass) || elementKlass.isEnum();
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw AssertionUtil.shouldNotReachHere("Method '" + method + "' should return a known type, but: " + e, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isIgnored(Class<?> nodeClass, Method method) {
|
||||
|
@ -68,6 +68,7 @@ class AstAttributeNode extends BaseNodeInfo implements SiblingCountingNode {
|
||||
|
||||
@Override
|
||||
public AtomicSequence atomize() {
|
||||
getTreeInfo().getLogger().recordUsageOf(attribute);
|
||||
if (value == null) {
|
||||
value = DomainConversion.convert(attribute.getValue());
|
||||
}
|
||||
|
@ -258,13 +258,14 @@ public class SaxonXPathRuleQuery {
|
||||
return NAME_POOL;
|
||||
}
|
||||
|
||||
|
||||
final class StaticContextWithProperties extends IndependentContext {
|
||||
|
||||
private final Map<StructuredQName, PropertyDescriptor<?>> propertiesByName = new HashMap<>();
|
||||
|
||||
StaticContextWithProperties(Configuration config) {
|
||||
super(config);
|
||||
// This statement is necessary for Saxon to support sequence-valued attributes
|
||||
getPackageData().setSchemaAware(true);
|
||||
}
|
||||
|
||||
public void declareProperty(PropertyDescriptor<?> prop) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
package net.sourceforge.pmd.lang.ast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -125,6 +126,11 @@ public class DummyNode extends AbstractNode<DummyNode, DummyNode> {
|
||||
return attributes.iterator();
|
||||
}
|
||||
|
||||
// phony attribute that repeats the image 3 times
|
||||
public List<String> getLines() {
|
||||
return Arrays.asList(getImage(), getImage(), getImage());
|
||||
}
|
||||
|
||||
public static class DummyRootNode extends DummyNode implements RootNode, GenericNode<DummyNode> {
|
||||
|
||||
// FIXME remove this
|
||||
|
@ -41,7 +41,9 @@ class AttributeAxisIteratorTest {
|
||||
|
||||
AttributeAxisIterator it = new AttributeAxisIterator(dummyNode);
|
||||
|
||||
assertEquals(DEFAULT_ATTRS, toMap(it).keySet());
|
||||
Set<String> expected = CollectionUtil.setUnion(DEFAULT_ATTRS, "Lines");
|
||||
|
||||
assertEquals(expected, toMap(it).keySet());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -50,7 +52,7 @@ class AttributeAxisIteratorTest {
|
||||
|
||||
AttributeAxisIterator it = new AttributeAxisIterator(dummyNode);
|
||||
|
||||
Set<String> expected = CollectionUtil.setUnion(DEFAULT_ATTRS, "Enum");
|
||||
Set<String> expected = CollectionUtil.setUnion(DEFAULT_ATTRS, "Enum", "Lines");
|
||||
|
||||
assertEquals(expected, toMap(it).keySet());
|
||||
}
|
||||
@ -62,7 +64,9 @@ class AttributeAxisIteratorTest {
|
||||
|
||||
AttributeAxisIterator it = new AttributeAxisIterator(dummyNode);
|
||||
|
||||
assertEquals(DEFAULT_ATTRS, toMap(it).keySet());
|
||||
Set<String> expected = CollectionUtil.setUnion(DEFAULT_ATTRS, "List", "Lines");
|
||||
|
||||
assertEquals(expected, toMap(it).keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -134,6 +134,15 @@ class SaxonXPathRuleQueryTest {
|
||||
assertQuery(0, "(/)[self::document-node(element(DummyNodeX))]", dummy);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testListAttributes() {
|
||||
DummyRootNode dummy = helper.parse("(a(b))");
|
||||
List<Node> result = assertQuery(1,
|
||||
"//dummyNode[count(distinct-values(@Lines)) > 0 and not(empty(index-of(@Lines, 'a')))]", dummy);
|
||||
|
||||
assertEquals(dummy.getChild(0), result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void ruleChainVisits() {
|
||||
SaxonXPathRuleQuery query = createQuery("//dummyNode[@Image='baz']/foo | //bar[@Public = 'true'] | //dummyNode[@Public = false()] | //dummyNode");
|
||||
@ -143,11 +152,11 @@ class SaxonXPathRuleQueryTest {
|
||||
assertTrue(ruleChainVisits.contains("bar"));
|
||||
|
||||
assertEquals(3, query.nodeNameToXPaths.size());
|
||||
assertExpression("(self::node()[(string(data(@Image))) eq baz])/child::element(foo)", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("self::node()[(boolean(data(@Public))) eq false]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(1));
|
||||
assertExpression("(self::node()[(data(attribute::attribute(Image))) = baz])/child::element(foo)", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("self::node()[(data(attribute::attribute(Public))) = false]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(1));
|
||||
assertExpression("self::node()", query.getExpressionsForLocalNameOrDefault("dummyNode").get(2));
|
||||
assertExpression("self::node()[(string(data(@Public))) eq true]", query.getExpressionsForLocalNameOrDefault("bar").get(0));
|
||||
assertExpression("(((docOrder((((/)/descendant::element(dummyNode))[(string(data(@Image))) eq baz])/child::element(foo))) | (((/)/descendant::element(bar))[(string(data(@Public))) eq true])) | (((/)/descendant::element(dummyNode))[(boolean(data(@Public))) eq false])) | ((/)/descendant::element(dummyNode))", query.getFallbackExpr());
|
||||
assertExpression("self::node()[(data(attribute::attribute(Public))) = true]", query.getExpressionsForLocalNameOrDefault("bar").get(0));
|
||||
assertExpression("(((docOrder((((/)/descendant::element(dummyNode))[(data(attribute::attribute(Image))) = baz])/child::element(foo))) | (((/)/descendant::element(bar))[(data(attribute::attribute(Public))) = true])) | (((/)/descendant::element(dummyNode))[(data(attribute::attribute(Public))) = false])) | ((/)/descendant::element(dummyNode))", query.getFallbackExpr());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -157,8 +166,8 @@ class SaxonXPathRuleQueryTest {
|
||||
assertEquals(1, ruleChainVisits.size());
|
||||
assertTrue(ruleChainVisits.contains("dummyNode"));
|
||||
assertEquals(2, query.nodeNameToXPaths.size());
|
||||
assertExpression("(self::node()[(boolean(data(@Test1))) eq false])[(boolean(data(@Test2))) eq true]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("(((/)/descendant::element(dummyNode))[(boolean(data(@Test1))) eq false])[(boolean(data(@Test2))) eq true]", query.getFallbackExpr());
|
||||
assertExpression("(self::node()[(data(attribute::attribute(Test1))) = false])[(data(attribute::attribute(Test2))) = true]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("(((/)/descendant::element(dummyNode))[(data(attribute::attribute(Test1))) = false])[(data(attribute::attribute(Test2))) = true]", query.getFallbackExpr());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -168,8 +177,8 @@ class SaxonXPathRuleQueryTest {
|
||||
assertEquals(1, ruleChainVisits.size());
|
||||
assertTrue(ruleChainVisits.contains("dummyNode"));
|
||||
assertEquals(2, query.nodeNameToXPaths.size());
|
||||
assertExpression("self::node()[Q{http://pmd.sourceforge.net/pmd-dummy}imageIs(exactly-one(convertTo_xs:string(data(@Image))))]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("((/)/descendant::element(Q{}dummyNode))[Q{http://pmd.sourceforge.net/pmd-dummy}imageIs(exactly-one(convertTo_xs:string(data(@Image))))]", query.getFallbackExpr());
|
||||
assertExpression("self::node()[Q{http://pmd.sourceforge.net/pmd-dummy}imageIs(exactly-one(convertTo_xs:string(data(attribute::attribute(Image)))))]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("((/)/descendant::element(Q{}dummyNode))[Q{http://pmd.sourceforge.net/pmd-dummy}imageIs(exactly-one(convertTo_xs:string(data(attribute::attribute(Image)))))]", query.getFallbackExpr());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -206,8 +215,8 @@ class SaxonXPathRuleQueryTest {
|
||||
assertEquals(1, ruleChainVisits.size());
|
||||
assertTrue(ruleChainVisits.contains("dummyNode"));
|
||||
assertEquals(2, query.nodeNameToXPaths.size());
|
||||
assertExpression("(((self::node()/child::element(foo))/child::element())/child::element(bar))[(string(data(@Test))) eq false]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("docOrder(((docOrder((((/)/descendant::element(dummyNode))/child::element(foo))/child::element()))/child::element(bar))[(string(data(@Test))) eq false])", query.getFallbackExpr());
|
||||
assertExpression("(((self::node()/child::element(foo))/child::element())/child::element(bar))[(data(attribute::attribute(Test))) = false]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("docOrder(((docOrder((((/)/descendant::element(dummyNode))/child::element(foo))/child::element()))/child::element(bar))[(data(attribute::attribute(Test))) = false])", query.getFallbackExpr());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -217,8 +226,8 @@ class SaxonXPathRuleQueryTest {
|
||||
assertEquals(1, ruleChainVisits.size());
|
||||
assertTrue(ruleChainVisits.contains("dummyNode"));
|
||||
assertEquals(2, query.nodeNameToXPaths.size());
|
||||
assertExpression("((((self::node()/child::element(foo))[(string(data(@Baz))) eq a])/child::element())/child::element(bar))[(string(data(@Test))) eq false]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("docOrder(((docOrder(((((/)/descendant::element(dummyNode))/child::element(foo))[(string(data(@Baz))) eq a])/child::element()))/child::element(bar))[(string(data(@Test))) eq false])", query.getFallbackExpr());
|
||||
assertExpression("((((self::node()/child::element(foo))[(data(attribute::attribute(Baz))) = a])/child::element())/child::element(bar))[(data(attribute::attribute(Test))) = false]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("docOrder(((docOrder(((((/)/descendant::element(dummyNode))/child::element(foo))[(data(attribute::attribute(Baz))) = a])/child::element()))/child::element(bar))[(data(attribute::attribute(Test))) = false])", query.getFallbackExpr());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -240,7 +249,7 @@ class SaxonXPathRuleQueryTest {
|
||||
assertEquals(followPath(tree, "10"), results.get(0));
|
||||
});
|
||||
|
||||
assertExpression("docOrder((((/)/descendant::(element(dummyNode) | element(dummyNodeB)))/child::element(dummyNode))[(string(data(@Image))) eq 10])", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("docOrder((((/)/descendant::(element(dummyNode) | element(dummyNodeB)))/child::element(dummyNode))[(data(attribute::attribute(Image))) = 10])", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -257,7 +266,7 @@ class SaxonXPathRuleQueryTest {
|
||||
));
|
||||
|
||||
assertEquals(0, query.getRuleChainVisits().size());
|
||||
assertExpression("docOrder((((((/)/descendant::element(dummyNode))[(string(data(@Image))) eq 0]) | (((/)/descendant::element(dummyNodeB))[(string(data(@Image))) eq 1]))/child::element(dummyNode))[(string(data(@Image))) eq 10])", query.getFallbackExpr());
|
||||
assertExpression("docOrder((((((/)/descendant::element(dummyNode))[(data(attribute::attribute(Image))) = 0]) | (((/)/descendant::element(dummyNodeB))[(data(attribute::attribute(Image))) = 1]))/child::element(dummyNode))[(data(attribute::attribute(Image))) = 10])", query.getFallbackExpr());
|
||||
|
||||
tree.descendantsOrSelf().forEach(n -> {
|
||||
List<Node> results = query.evaluate(n);
|
||||
@ -299,8 +308,8 @@ class SaxonXPathRuleQueryTest {
|
||||
assertEquals(1, ruleChainVisits.size());
|
||||
assertTrue(ruleChainVisits.contains("dummyNode"));
|
||||
assertEquals(2, query.nodeNameToXPaths.size());
|
||||
assertExpression("self::node()[matches(convertTo_xs:string(data(@SimpleName)), a, )]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("((/)/descendant::element(Q{}dummyNode))[matches(convertTo_xs:string(data(@SimpleName)), a, )]", query.getFallbackExpr());
|
||||
assertExpression("self::node()[matches(zero-or-one(convertTo_xs:string(data(attribute::attribute(SimpleName)))), a, )]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("((/)/descendant::element(Q{}dummyNode))[matches(zero-or-one(convertTo_xs:string(data(attribute::attribute(SimpleName)))), a, )]", query.getFallbackExpr());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -311,8 +320,8 @@ class SaxonXPathRuleQueryTest {
|
||||
assertEquals(1, ruleChainVisits.size());
|
||||
assertTrue(ruleChainVisits.contains("dummyNode"));
|
||||
assertEquals(2, query.nodeNameToXPaths.size());
|
||||
assertExpression("(self::node()[matches(convertTo_xs:string(data(@SimpleName)), a, )])/child::element(Q{}foo)", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("docOrder((((/)/descendant::element(Q{}dummyNode))[matches(convertTo_xs:string(data(@SimpleName)), a, )])/child::element(Q{}foo))", query.getFallbackExpr());
|
||||
assertExpression("(self::node()[matches(zero-or-one(convertTo_xs:string(data(attribute::attribute(SimpleName)))), a, )])/child::element(Q{}foo)", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0));
|
||||
assertExpression("docOrder((((/)/descendant::element(Q{}dummyNode))[matches(zero-or-one(convertTo_xs:string(data(attribute::attribute(SimpleName)))), a, )])/child::element(Q{}foo))", query.getFallbackExpr());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -322,7 +331,7 @@ class SaxonXPathRuleQueryTest {
|
||||
assertEquals(1, ruleChainVisits.size());
|
||||
assertTrue(ruleChainVisits.contains("dummyNode"));
|
||||
assertEquals(2, query.nodeNameToXPaths.size());
|
||||
assertExpression("let $v0 := imageIs(bar) return ((self::node()[ends-with(convertTo_xs:string(data(@Image)), foo)])[$v0])", query.nodeNameToXPaths.get("dummyNode").get(0));
|
||||
assertExpression("let $v0 := imageIs(bar) return ((self::node()[ends-with(zero-or-one(convertTo_xs:string(data(attribute::attribute(Image)))), foo)])[$v0])", query.nodeNameToXPaths.get("dummyNode").get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -364,7 +373,7 @@ class SaxonXPathRuleQueryTest {
|
||||
assertTrue(ruleChainVisits.contains("WhileStatement"));
|
||||
assertTrue(ruleChainVisits.contains("DoStatement"));
|
||||
|
||||
final String expectedSubexpression = "(self::node()/descendant::element(dummyNode))[imageIs(exactly-one(convertTo_xs:string(data(@Image))))]";
|
||||
final String expectedSubexpression = "(self::node()/descendant::element(dummyNode))[imageIs(exactly-one(convertTo_xs:string(data(attribute::attribute(Image)))))]";
|
||||
assertExpression(expectedSubexpression, query.nodeNameToXPaths.get("ForStatement").get(0));
|
||||
assertExpression(expectedSubexpression, query.nodeNameToXPaths.get("WhileStatement").get(0));
|
||||
assertExpression(expectedSubexpression, query.nodeNameToXPaths.get("DoStatement").get(0));
|
||||
|
@ -21,7 +21,7 @@ import net.sourceforge.pmd.lang.java.types.JClassType;
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTAnnotation extends AbstractJavaTypeNode implements TypeNode, ASTMemberValue, Iterable<ASTMemberValuePair> {
|
||||
public final class ASTAnnotation extends AbstractJavaTypeNode implements ASTMemberValue, Iterable<ASTMemberValuePair> {
|
||||
|
||||
ASTAnnotation(int id) {
|
||||
super(id);
|
||||
|
@ -17,7 +17,7 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTArrayDimExpr extends ASTArrayTypeDim implements Annotatable {
|
||||
public final class ASTArrayDimExpr extends ASTArrayTypeDim {
|
||||
|
||||
ASTArrayDimExpr(int id) {
|
||||
super(id);
|
||||
|
@ -22,7 +22,7 @@ import java.util.Iterator;
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public final class ASTArrayInitializer extends AbstractJavaExpr implements ASTExpression, Iterable<ASTExpression> {
|
||||
public final class ASTArrayInitializer extends AbstractJavaExpr implements Iterable<ASTExpression> {
|
||||
|
||||
ASTArrayInitializer(int id) {
|
||||
super(id);
|
||||
|
@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTList.ASTMaybeEmptyListOf;
|
||||
import net.sourceforge.pmd.lang.java.ast.InternalInterfaces.AllChildrenAreOfType;
|
||||
|
||||
/**
|
||||
* A block of code. This is a {@linkplain ASTStatement statement} that
|
||||
@ -19,7 +18,7 @@ import net.sourceforge.pmd.lang.java.ast.InternalInterfaces.AllChildrenAreOfType
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTBlock extends ASTMaybeEmptyListOf<ASTStatement>
|
||||
implements ASTSwitchArrowRHS, ASTStatement, AllChildrenAreOfType<ASTStatement> {
|
||||
implements ASTSwitchArrowRHS, ASTStatement {
|
||||
|
||||
ASTBlock(int id) {
|
||||
super(id, ASTStatement.class);
|
||||
|
@ -9,7 +9,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
/**
|
||||
* The boolean literal, either "true" or "false".
|
||||
*/
|
||||
public final class ASTBooleanLiteral extends AbstractLiteral implements ASTLiteral {
|
||||
public final class ASTBooleanLiteral extends AbstractLiteral {
|
||||
|
||||
private boolean isTrue;
|
||||
|
||||
|
@ -14,7 +14,7 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTCastExpression extends AbstractJavaExpr implements ASTExpression {
|
||||
public final class ASTCastExpression extends AbstractJavaExpr {
|
||||
|
||||
ASTCastExpression(int id) {
|
||||
super(id);
|
||||
|
@ -15,7 +15,7 @@ import net.sourceforge.pmd.lang.document.Chars;
|
||||
* retrieve the actual runtime value. Use {@link #getLiteralText()} to
|
||||
* retrieve the text.
|
||||
*/
|
||||
public final class ASTCharLiteral extends AbstractLiteral implements ASTLiteral {
|
||||
public final class ASTCharLiteral extends AbstractLiteral {
|
||||
|
||||
|
||||
ASTCharLiteral(int id) {
|
||||
|
@ -13,7 +13,6 @@ import net.sourceforge.pmd.annotation.Experimental;
|
||||
import net.sourceforge.pmd.lang.ast.AstInfo;
|
||||
import net.sourceforge.pmd.lang.ast.NodeStream;
|
||||
import net.sourceforge.pmd.lang.ast.RootNode;
|
||||
import net.sourceforge.pmd.lang.ast.impl.GenericNode;
|
||||
import net.sourceforge.pmd.lang.java.symbols.table.JSymbolTable;
|
||||
import net.sourceforge.pmd.lang.java.types.TypeSystem;
|
||||
import net.sourceforge.pmd.lang.java.types.ast.internal.LazyTypeResolver;
|
||||
@ -49,7 +48,7 @@ import net.sourceforge.pmd.lang.rule.xpath.NoAttribute;
|
||||
* @see <a href="https://openjdk.org/jeps/445">JEP 445: Unnamed Classes and Instance Main Methods (Preview)</a> (Java 21)
|
||||
* @see #isUnnamedClass()
|
||||
*/
|
||||
public final class ASTCompilationUnit extends AbstractJavaNode implements JavaNode, GenericNode<JavaNode>, RootNode {
|
||||
public final class ASTCompilationUnit extends AbstractJavaNode implements RootNode {
|
||||
|
||||
private LazyTypeResolver lazyTypeResolver;
|
||||
private List<JavaComment> comments;
|
||||
|
@ -22,11 +22,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTConstructorCall extends AbstractInvocationExpr
|
||||
implements ASTPrimaryExpression,
|
||||
QualifiableExpression,
|
||||
LeftRecursiveNode,
|
||||
InvocationNode {
|
||||
public final class ASTConstructorCall extends AbstractInvocationExpr implements QualifiableExpression, LeftRecursiveNode {
|
||||
|
||||
ASTConstructorCall(int id) {
|
||||
super(id);
|
||||
|
@ -19,9 +19,8 @@ import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult;
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTEnumConstant extends AbstractJavaTypeNode
|
||||
implements Annotatable,
|
||||
InvocationNode,
|
||||
ModifierOwner,
|
||||
implements InvocationNode,
|
||||
ModifierOwner,
|
||||
ASTBodyDeclaration,
|
||||
InternalInterfaces.VariableIdOwner,
|
||||
JavadocCommentOwner {
|
||||
|
@ -7,7 +7,6 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.impl.GenericNode;
|
||||
import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol;
|
||||
import net.sourceforge.pmd.lang.java.types.JClassType;
|
||||
import net.sourceforge.pmd.lang.java.types.JMethodSig;
|
||||
@ -32,7 +31,6 @@ public interface ASTExecutableDeclaration
|
||||
extends ModifierOwner,
|
||||
ASTBodyDeclaration,
|
||||
TypeParamOwnerNode,
|
||||
GenericNode<JavaNode>,
|
||||
JavadocCommentOwner {
|
||||
|
||||
|
||||
|
@ -39,11 +39,7 @@ import net.sourceforge.pmd.lang.java.types.ast.ExprContext;
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public interface ASTExpression
|
||||
extends JavaNode,
|
||||
TypeNode,
|
||||
ASTMemberValue,
|
||||
ASTSwitchArrowRHS {
|
||||
public interface ASTExpression extends TypeNode, ASTMemberValue, ASTSwitchArrowRHS {
|
||||
|
||||
/**
|
||||
* Always returns true. This is to allow XPath queries
|
||||
|
@ -22,9 +22,7 @@ import net.sourceforge.pmd.lang.rule.xpath.DeprecatedAttribute;
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTFieldDeclaration extends AbstractJavaNode
|
||||
implements Iterable<ASTVariableId>,
|
||||
LeftRecursiveNode,
|
||||
ModifierOwner,
|
||||
implements LeftRecursiveNode,
|
||||
ASTBodyDeclaration,
|
||||
InternalInterfaces.MultiVariableIdOwner,
|
||||
JavadocCommentOwner {
|
||||
|
@ -25,10 +25,7 @@ import net.sourceforge.pmd.lang.java.types.TypingContext;
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTFormalParameter extends AbstractJavaNode
|
||||
implements ModifierOwner,
|
||||
TypeNode,
|
||||
Annotatable,
|
||||
VariableIdOwner {
|
||||
implements ModifierOwner, TypeNode, VariableIdOwner {
|
||||
|
||||
ASTFormalParameter(int id) {
|
||||
super(id);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user