diff --git a/docs/_includes/custom/xpath_fun_doc.html b/docs/_includes/custom/xpath_fun_doc.html index d66bae0483..1ae4d12079 100644 --- a/docs/_includes/custom/xpath_fun_doc.html +++ b/docs/_includes/custom/xpath_fun_doc.html @@ -1,6 +1,6 @@ {% for lang in site.data.xpath_funs.langs %} - + ### {{ lang.name }} diff --git a/docs/images/userdocs/designer-overview-with-nums.png b/docs/images/userdocs/designer-overview-with-nums.png index 2851fd8ae6..1a8e139918 100644 Binary files a/docs/images/userdocs/designer-overview-with-nums.png and b/docs/images/userdocs/designer-overview-with-nums.png differ diff --git a/docs/images/userdocs/designer-overview.png b/docs/images/userdocs/designer-overview.png index 8cbda3c4d5..53c0a4a167 100644 Binary files a/docs/images/userdocs/designer-overview.png and b/docs/images/userdocs/designer-overview.png differ diff --git a/docs/pages/pmd/userdocs/extending/writing_rules_intro.md b/docs/pages/pmd/userdocs/extending/writing_rules_intro.md index 2c0b4dc478..2831e1eb0f 100644 --- a/docs/pages/pmd/userdocs/extending/writing_rules_intro.md +++ b/docs/pages/pmd/userdocs/extending/writing_rules_intro.md @@ -2,7 +2,7 @@ title: Introduction to writing PMD rules tags: [extending, userdocs, getting_started] summary: "Writing your own PMD rules" -last_updated: February 2020 (6.22.0) +last_updated: December 2023 (7.0.0) permalink: pmd_userdocs_extending_writing_rules_intro.html author: Clément Fournier --- @@ -14,19 +14,16 @@ team. ## How rules work: the AST Before running rules, PMD parses the source file into a data structure called an -**abstract syntax tree (AST)**. This tree represents the syntactic structure of the +**[abstract syntax tree (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree)**. +This tree represents the syntactic structure of the code, and encodes syntactic relations between source code elements. For instance, in Java, method declarations belong to a class: in the AST, the nodes representing method declarations will be descendants of a node representing the declaration of their enclosing class. This representation is thus much richer than the original source code (which, for a program, is just a chain of characters), or the token -chain produced by a lexer (which is e.g. what Checkstyle works on). For example: +chain produced by a lexer. For example: ---- @@ -48,11 +45,11 @@ class Foo extends Object { ```java └─ CompilationUnit - └─ TypeDeclaration - └─ ClassOrInterfaceDeclaration "Foo" - ├─ ExtendsList - │ └─ ClassOrInterfaceType "Object" - └─ ClassOrInterfaceBody + └─ ClassOrInterfaceDeclaration "Foo" + ├─ ModifierList + ├─ ExtendsList + │ └─ ClassOrInterfaceType "Object" + └─ ClassOrInterfaceBody ``` @@ -95,6 +92,8 @@ complicated processing, to which an XPath rule couldn't scale. In the end, choosing one strategy or the other depends on the difficulty of what your rule does. I'd advise to keep to XPath unless you have no other choice. +Note: Despite that fact, the Java rules are written in Java, any language that PMD supports +can be analyzed. E.g. you can write a Java rule to analyze Apex source code. ## XML rule definition @@ -103,16 +102,18 @@ case for both XPath and Java rules. To do this, the `rule` element is used, but instead of mentioning the `ref` attribute, it mentions the `class` attribute, with the implementation class of your rule. -* **For Java rules:** this is the class extending AbstractRule (transitively) -* **For XPath rules:** this is `net.sourceforge.pmd.lang.rule.XPathRule` +* **For Java rules:** this is the concrete class extending AbstractRule (transitively) +* **For XPath rules:** this is `net.sourceforge.pmd.lang.rule.XPathRule`. +* **For XPath rules analyzing XML-based languages:** this is `net.sourceforge.pmd.lang.xml.rule.DomXPathRule`. + See [XPath rules in XML](pmd_languages_xml.html#xpath-rules-in-xml) for more info. -Example: +Example for Java rule: ```xml + class="com.me.MyJavaRule"> Description @@ -120,11 +121,31 @@ Example: ``` -{% include note.html content="In PMD 7, the `language` attribute will be required on all `rule` - elements that declare a new rule. Some base rule classes set the language implicitly in their - constructor, and so this is not required in all cases for the rule to work. But this - behavior will be discontinued in PMD 7, so missing `language` attributes are - reported beginning with PMD 6.27.0 as a forward compatibility warning." %} +Example for XPath rule: + +```xml + + + Description + + 3 + + + + + + +``` + + +{% include note.html content="Since PMD 7, the `language` attribute is required on all `rule` + elements that declare a new rule. In PMD 6, this was optional, as the base rule classes sometimes set + the language implicitly in their constructor." %} ## Resource index diff --git a/docs/pages/pmd/userdocs/extending/writing_xpath_rules.md b/docs/pages/pmd/userdocs/extending/writing_xpath_rules.md index 23e0c5be0c..c8bccc167a 100644 --- a/docs/pages/pmd/userdocs/extending/writing_xpath_rules.md +++ b/docs/pages/pmd/userdocs/extending/writing_xpath_rules.md @@ -2,7 +2,7 @@ title: Writing XPath rules tags: [extending, userdocs] summary: "This page describes XPath rule support in more details" -last_updated: February 2020 (6.22.0) +last_updated: December 2023 (7.0.0) permalink: pmd_userdocs_extending_writing_xpath_rules.html author: Miguel Griffa , Clément Fournier --- @@ -15,17 +15,19 @@ author: Miguel Griffa , Clément Fournier ## XPath version -PMD uses XPath 3.1 for its XPath rules since PMD 7. Before then, the default version was XPath 1.0, with opt-in support for XPath 2.0. +PMD uses XPath 3.1 for its XPath rules since PMD 7. Before then, the default version was XPath 1.0, +with opt-in support for XPath 2.0. -See [the Saxonica documentation](https://www.saxonica.com/html/documentation/expressions/xpath31new.html) for an introduction to new features in XPath 3.1. +See [the Saxonica documentation](https://www.saxonica.com/html/documentation/expressions/xpath31new.html) +for an introduction to new features in XPath 3.1. -The property `version` of XPathRule is deprecated and will be removed. +The property `version` of {% jdoc core::lang.rule.XPathRule %} is deprecated and will be removed. ## DOM representation of ASTs @@ -38,11 +40,13 @@ defined on. Concretely, this means: * Some Java getters are exposed as XML attributes on those elements * This means, that documentation for attributes can be found in our Javadocs. For example, the attribute `@SimpleName` of the Java node `EnumDeclaration` is backed - by the Java getter {% jdoc java::lang.java.ast.ASTAnyTypeDeclaration#getSimpleName() %}. + by the Java getter {% jdoc java::lang.java.ast.AbstractAnyTypeDeclaration#getSimpleName() %}. ### Value conversion -To represent attributes, we must map Java values to [XPath Data Model (XDM)](https://www.w3.org/TR/xpath-datamodel/) values. In the following table we refer to the type conversion function as `conv`, a function from Java types to XDM types. +To represent attributes, we must map Java values to [XPath Data Model (XDM)](https://www.w3.org/TR/xpath-datamodel/) +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)` | |---------------|---------------------------------------| @@ -73,14 +77,9 @@ The same `conv` function is used to translate rule property values to XDM values PMD provides some language-specific XPath functions to access semantic information from the AST. -On XPath 2.0, the namespace of custom PMD function must be explicitly mentioned. +The namespace of custom PMD functions must be explicitly mentioned. {% render %} {% include custom/xpath_fun_doc.html %} {% endrender %} -{% include note.html content='There is also a `typeOf` function which is -deprecated and whose usages should be replaced with uses of `typeIs` or -`typeIsExactly`. That one will be removed with PMD 7.0.0.' %} - - diff --git a/docs/pages/pmd/userdocs/extending/your_first_rule.md b/docs/pages/pmd/userdocs/extending/your_first_rule.md index d9ff74802b..eeb2e064c8 100644 --- a/docs/pages/pmd/userdocs/extending/your_first_rule.md +++ b/docs/pages/pmd/userdocs/extending/your_first_rule.md @@ -1,8 +1,8 @@ --- -title: Your first rule XPath +title: Your first rule tags: [extending, userdocs] -summary: "Introduction to rule writing through an example." -last_updated: February 2020 (6.22.0) +summary: "Introduction to rule writing through an example for a XPath rule." +last_updated: December 2023 (7.0.0) permalink: pmd_userdocs_extending_your_first_rule.html author: Miguel Griffa , Clément Fournier --- @@ -11,7 +11,7 @@ This page is a gentle introduction to rule writing, and the Rule Designer. Using the designer is useful both to write Java rules and XPath rules, but it's more specifically geared towards XPath rules. -This page uses a simple XPath rule to illustrate the common workflow. We assume +This page uses a **simple XPath rule** to illustrate the common workflow. We assume here that you already know what XPath is and how to read basic XPath queries. W3C has a good tutorial [here](https://www.w3schools.com/xml/xpath_syntax.asp) if you don't (in the context of XML only), and [the Saxon documentation](https://www.saxonica.com/documentation/index.html#!expressions) @@ -35,11 +35,11 @@ The interface looks like the following: {% include image.html file="userdocs/designer-overview-with-nums.png" alt="Designer overview" %} The zone (2) is the **main editor**. When you write a code snippet in the - code area to the left, you'll see that the tree to the right will be updated - automatically: it's the AST of the code. - Note that the code snippet must be a syntactically valid compilation unit for the - language you've chosen, e.g. for Java, a compilation unit necessarily has a top-level - type declaration. +code area to the left, you'll see that the tree to the right will be updated +automatically: it's the AST of the code. +Note that the code snippet must be a syntactically valid compilation unit for the +language you've chosen, e.g. for Java, a compilation unit necessarily has a top-level +type declaration. If you select a node in the AST, its specific properties will also be displayed in the panel (1): they're the XPath attributes of the node. More on that later. @@ -57,7 +57,7 @@ The basic development process is straightforward: 2. Examine the AST and determine what node the violation should be reported on 3. Write an XPath expression matching that node in the XPath editor 4. Refine the XPath expression iteratively using different code snippets, so that - it matches violation cases, but no other node + it matches violation cases, but no other nodes 5. Export your XPath expression to an XML rule element, and place it in your ruleset Each time you test your rule against a different snippet, it's a good idea to @@ -84,10 +84,10 @@ public class KeepingItSerious { ``` Examining the AST, you find out that the LocalVariableDeclaration has a VariableDeclaratorId -descendant, whose `Image` XPath attribute is exactly `bill`. You thus write your first attempt +descendant, whose `Name` XPath attribute is exactly `bill`. You thus write your first attempt in the XPath editor: ```xpath -//VariableDeclaratorId[@Image = "bill"] +//VariableDeclaratorId[@Name = "bill"] ``` You can see the XPath result list is updated with the variable declarator. @@ -112,13 +112,14 @@ based on your examination of the Type node of the field and local variable declaration nodes. ```xpath -//VariableDeclaratorId[@Image = "bill" and ../../Type[@TypeImage = "short"]] +//VariableDeclaratorId[@Image = "bill"][../../PrimitiveType[@Kind = "short"]] ``` ### Exporting to XML You estimate that your rule is now production ready, and you'd like to use it in your ruleset. -The `File > Export XPath to rule...` allows you to do that in a few clicks: just enter some +The second button in the toolbar above the XPath editor (Tooltip: `Export XPath to rule...`) +allows you to do that in a few clicks: just enter some additional metadata for your rule, and the popup will generate an XML element that you can copy-paste into your ruleset XML. The resulting element looks like so: @@ -126,16 +127,16 @@ copy-paste into your ruleset XML. The resulting element looks like so: + class="net.sourceforge.pmd.lang.rule.XPathRule"> -TODO + TODO 3 - diff --git a/docs/pages/pmd/userdocs/migrating_to_pmd7.md b/docs/pages/pmd/userdocs/migrating_to_pmd7.md index 64b2a4f93d..a78f4224ad 100644 --- a/docs/pages/pmd/userdocs/migrating_to_pmd7.md +++ b/docs/pages/pmd/userdocs/migrating_to_pmd7.md @@ -83,6 +83,10 @@ Once you have reviewed your ruleset(s), you can switch to PMD 7. Ideally, you have written good tests already for your custom rules - see [Testing your rules](pmd_userdocs_extending_testing.html). This helps to identify problems early on. +#### Ruleset XML +The `` tag, that defines your custom rule, is required to have a `language` attribute now. This was always the +case for XPath rules, but is now a requirement for Java rules. + #### XPath rules If you have **XPath based** rules, the first step will be to migrate to XPath 2.0 and then to XPath 3.1. XPath 2.0 is available in PMD 6 already and can be used right away. PMD 7 will use by default XPath 3.1 and @@ -93,6 +97,12 @@ After you have migrated your XPath rules to XPath 2.0, remove the "version" prop with PMD 7. PMD 7 by default uses XPath 3.1. See below [XPath](#xpath-migrating-from-10-to-20) for details. +Additional infos: +* The custom XPath function `typeOf` has been removed (deprecated since 6.4.0). + Use the function `pmd-java:typeIs` or `pmd-java:typeIsExactly` instead. + See [PMD extension functions](pmd_userdocs_extending_writing_xpath_rules.html#pmd-extension-functions) for available + functions. + #### Java rules If you have **Java based rules**, and you are using rulechain, this works a bit different now. The RuleChain API has changed, see [[core] Simplify the rulechain (#2490)](https://github.com/pmd/pmd/pull/2490) for the full details.
Sample code (Java)