pmd/pmd_userdocs_extending_designer_reference.html

2302 lines
61 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Learn about the usage and features of the rule designer.">
<meta name="keywords" content="extendinguserdocs, ">
<title>The rule designer | PMD Source Code Analyzer</title>
<link rel="stylesheet" type="text/css" href="assets/fontawesome-free-5.15.4-web/css/all.min.css">
<link rel="stylesheet" type="text/css" href="assets/bootstrap-4.5.2-dist/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/syntax.css">
<link rel="stylesheet" type="text/css" href="css/modern-business.css">
<link rel="stylesheet" type="text/css" href="css/customstyles.css">
<link rel="stylesheet" type="text/css" href="css/theme-green.css">
<link rel="stylesheet" type="text/css" href="css/pmd-customstyles.css">
<link rel="shortcut icon" href="images/logo/favicon.ico" type="image/x-icon">
<link rel="icon" href="images/logo/favicon.ico" type="image/x-icon">
<link rel="alternate" type="application/rss+xml" title="" href="feed.xml">
</head>
<body>
<!-- Content is offset by the height of the topnav bar. -->
<!-- There's already a padding-top rule in modern-business.css, but it apparently doesn't work on Firefox 60 and Chrome 67 -->
<div id="topbar-content-offset">
<!-- Navigation -->
<nav class="navbar navbar-expand-lg fixed-top navbar-dark">
<div class="container topnavlinks">
<a class="navbar-brand fas fa-home fa-lg" href="index.html">&nbsp;<span class="projectTitle"> PMD Source Code Analyzer Project</span></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto mt-2 mt-lg-0"></ul>
<ul class="navbar-nav">
<!-- toggle sidebar button -->
<li class="nav-item"><a id="tg-sb-link" class="nav-link" href="#"><i id="tg-sb-icon" class="fas fa-toggle-on"></i> Nav</a></li>
<!-- entries without drop-downs appear here -->
<li class="nav-item"><a class="nav-link" href="https://github.com/pmd/pmd/releases/latest" target="_blank">Download</a></li>
<li class="nav-item"><a class="nav-link" href="https://github.com/pmd/pmd" target="_blank">Fork us on github</a></li>
<!-- entries with drop-downs appear here -->
<!-- conditional logic to control which topnav appears for the audience defined in the configuration file.-->
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="search..." id="search-input">
<ul id="results-container"></ul>
</form>
</div>
</div>
</nav>
<!-- Page Content -->
<div class="container-toc-wrapper">
<div class="container">
<div class="col-lg-12">&nbsp;</div>
<!-- Content Row -->
<div class="row">
<!-- Sidebar Column -->
<div class="col-md-3" id="tg-sb-sidebar">
<ul id="mysidebar" class="nav">
<li class="sidebarTitle">PMD 7.8.0-SNAPSHOT</li>
<div class="sidebarTitleDate">Release date: 29-November-2024</div>
<li>
<a href="#">About</a>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="pmd_release_notes.html">Release notes</a></li>
<li><a href="pmd_release_notes_pmd7.html">Release notes (PMD 7)</a></li>
<li><a href="pmd_about_help.html">Getting help</a></li>
<li><a href="pmd_about_release_policies.html">Release policies</a></li>
<li><a href="pmd_about_support_lifecycle.html">Support lifecycle</a></li>
</ul>
</li>
<li>
<a href="#">User Documentation</a>
<ul>
<li><a href="pmd_userdocs_migrating_to_pmd7.html">Migration Guide for PMD 7</a></li>
<li><a href="pmd_userdocs_installation.html">Installation and basic CLI usage</a></li>
<li><a href="pmd_userdocs_making_rulesets.html">Making rulesets</a></li>
<li><a href="pmd_userdocs_configuring_rules.html">Configuring rules</a></li>
<li><a href="pmd_userdocs_best_practices.html">Best practices</a></li>
<li><a href="pmd_userdocs_suppressing_warnings.html">Suppressing warnings</a></li>
<li><a href="pmd_userdocs_incremental_analysis.html">Incremental analysis</a></li>
<li><a href="pmd_userdocs_cli_reference.html">PMD CLI reference</a></li>
<li><a href="pmd_userdocs_report_formats.html">PMD Report formats</a></li>
<li><a href="pmd_userdocs_3rdpartyrulesets.html">3rd party rulesets</a></li>
<li class="subfolders">
<a href="#">CPD reference</a>
<ul>
<li><a href="pmd_userdocs_cpd.html">Copy-paste detection</a></li>
<li><a href="pmd_userdocs_cpd_report_formats.html">CPD Report formats</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Extending PMD</a>
<ul>
<li><a href="pmd_userdocs_extending_writing_rules_intro.html">Introduction to writing rules</a></li>
<li><a href="pmd_userdocs_extending_your_first_rule.html">Your first rule</a></li>
<li><a href="pmd_userdocs_extending_writing_xpath_rules.html">XPath rules</a></li>
<li><a href="pmd_userdocs_extending_writing_java_rules.html">Java rules</a></li>
<li class="active"><a href="pmd_userdocs_extending_designer_reference.html">Rule designer reference</a></li>
<li><a href="pmd_userdocs_extending_defining_properties.html">Defining rule properties</a></li>
<li><a href="pmd_userdocs_extending_rule_guidelines.html">Rule guidelines</a></li>
<li><a href="pmd_userdocs_extending_testing.html">Testing your rules</a></li>
<li><a href="pmd_userdocs_extending_ast_dump.html">Creating (XML) dump of the AST</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Tools / Integrations</a>
<ul>
<li><a href="pmd_userdocs_tools_maven.html">Maven PMD Plugin</a></li>
<li><a href="pmd_userdocs_tools_gradle.html">Gradle</a></li>
<li><a href="pmd_userdocs_tools_ant.html">Ant</a></li>
<li><a href="pmd_userdocs_tools_java_api.html">PMD Java API</a></li>
<li><a href="pmd_userdocs_tools_bld.html">bld PMD Extension</a></li>
<li><a href="pmd_userdocs_tools_ci.html">CI integrations</a></li>
<li><a href="pmd_userdocs_tools.html">Other Tools / Integrations</a></li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#">Rule Reference</a>
<ul>
<li class="subfolders">
<a href="#">Apex Rules</a>
<ul>
<li><a href="pmd_rules_apex.html">Index</a></li>
<li><a href="pmd_rules_apex_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_apex_codestyle.html">Code Style</a></li>
<li><a href="pmd_rules_apex_design.html">Design</a></li>
<li><a href="pmd_rules_apex_documentation.html">Documentation</a></li>
<li><a href="pmd_rules_apex_errorprone.html">Error Prone</a></li>
<li><a href="pmd_rules_apex_performance.html">Performance</a></li>
<li><a href="pmd_rules_apex_security.html">Security</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">HTML Rules</a>
<ul>
<li><a href="pmd_rules_html.html">Index</a></li>
<li><a href="pmd_rules_html_bestpractices.html">Best Practices</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Java Rules</a>
<ul>
<li><a href="pmd_rules_java.html">Index</a></li>
<li><a href="pmd_rules_java_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_java_codestyle.html">Code Style</a></li>
<li><a href="pmd_rules_java_design.html">Design</a></li>
<li><a href="pmd_rules_java_documentation.html">Documentation</a></li>
<li><a href="pmd_rules_java_errorprone.html">Error Prone</a></li>
<li><a href="pmd_rules_java_multithreading.html">Multithreading</a></li>
<li><a href="pmd_rules_java_performance.html">Performance</a></li>
<li><a href="pmd_rules_java_security.html">Security</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Java Server Pages Rules</a>
<ul>
<li><a href="pmd_rules_jsp.html">Index</a></li>
<li><a href="pmd_rules_jsp_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_jsp_codestyle.html">Code Style</a></li>
<li><a href="pmd_rules_jsp_design.html">Design</a></li>
<li><a href="pmd_rules_jsp_errorprone.html">Error Prone</a></li>
<li><a href="pmd_rules_jsp_security.html">Security</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">JavaScript Rules</a>
<ul>
<li><a href="pmd_rules_ecmascript.html">Index</a></li>
<li><a href="pmd_rules_ecmascript_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_ecmascript_codestyle.html">Code Style</a></li>
<li><a href="pmd_rules_ecmascript_errorprone.html">Error Prone</a></li>
<li><a href="pmd_rules_ecmascript_performance.html">Performance</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Kotlin Rules</a>
<ul>
<li><a href="pmd_rules_kotlin.html">Index</a></li>
<li><a href="pmd_rules_kotlin_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_kotlin_errorprone.html">Error Prone</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Maven POM Rules</a>
<ul>
<li><a href="pmd_rules_pom.html">Index</a></li>
<li><a href="pmd_rules_pom_errorprone.html">Error Prone</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Modelica Rules</a>
<ul>
<li><a href="pmd_rules_modelica.html">Index</a></li>
<li><a href="pmd_rules_modelica_bestpractices.html">Best Practices</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">PLSQL Rules</a>
<ul>
<li><a href="pmd_rules_plsql.html">Index</a></li>
<li><a href="pmd_rules_plsql_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_plsql_codestyle.html">Code Style</a></li>
<li><a href="pmd_rules_plsql_design.html">Design</a></li>
<li><a href="pmd_rules_plsql_errorprone.html">Error Prone</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Salesforce Visualforce Rules</a>
<ul>
<li><a href="pmd_rules_visualforce.html">Index</a></li>
<li><a href="pmd_rules_visualforce_security.html">Security</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Scala Rules</a>
<ul>
<li><a href="pmd_rules_scala.html">Index</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Swift Rules</a>
<ul>
<li><a href="pmd_rules_swift.html">Index</a></li>
<li><a href="pmd_rules_swift_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_swift_errorprone.html">Error Prone</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Velocity Template Language (VTL) Rules</a>
<ul>
<li><a href="pmd_rules_velocity.html">Index</a></li>
<li><a href="pmd_rules_velocity_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_velocity_design.html">Design</a></li>
<li><a href="pmd_rules_velocity_errorprone.html">Error Prone</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">WSDL Rules</a>
<ul>
<li><a href="pmd_rules_wsdl.html">Index</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">XML Rules</a>
<ul>
<li><a href="pmd_rules_xml.html">Index</a></li>
<li><a href="pmd_rules_xml_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_xml_errorprone.html">Error Prone</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">XSL Rules</a>
<ul>
<li><a href="pmd_rules_xsl.html">Index</a></li>
<li><a href="pmd_rules_xsl_codestyle.html">Code Style</a></li>
<li><a href="pmd_rules_xsl_performance.html">Performance</a></li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#">Language-Specific Documentation</a>
<ul>
<li><a href="pmd_languages_index.html">Overview</a></li>
<li><a href="pmd_languages_configuration.html">Language configuration</a></li>
<li><a href="pmd_languages_apex.html">Apex</a></li>
<li><a href="pmd_languages_cpp.html">C/C++</a></li>
<li><a href="pmd_languages_cs.html">C#</a></li>
<li><a href="pmd_languages_coco.html">Coco</a></li>
<li><a href="pmd_languages_dart.html">Dart</a></li>
<li><a href="pmd_languages_fortran.html">Fortran</a></li>
<li><a href="pmd_languages_gherkin.html">Gherkin</a></li>
<li><a href="pmd_languages_go.html">Go</a></li>
<li><a href="pmd_languages_html.html">HTML</a></li>
<li><a href="pmd_languages_java.html">Java</a></li>
<li><a href="pmd_languages_js_ts.html">JavaScript / TypeScript</a></li>
<li><a href="pmd_languages_jsp.html">JSP</a></li>
<li><a href="pmd_languages_julia.html">Julia</a></li>
<li><a href="pmd_languages_kotlin.html">Kotlin</a></li>
<li><a href="pmd_languages_lua.html">Lua</a></li>
<li><a href="pmd_languages_matlab.html">Matlab</a></li>
<li><a href="pmd_languages_modelica.html">Modelica</a></li>
<li><a href="pmd_languages_objectivec.html">Objective-C</a></li>
<li><a href="pmd_languages_perl.html">Perl</a></li>
<li><a href="pmd_languages_php.html">PHP</a></li>
<li><a href="pmd_languages_plsql.html">PLSQL</a></li>
<li><a href="pmd_languages_python.html">Python</a></li>
<li><a href="pmd_languages_ruby.html">Ruby</a></li>
<li><a href="pmd_languages_scala.html">Scala</a></li>
<li><a href="pmd_languages_swift.html">Swift</a></li>
<li><a href="pmd_languages_tsql.html">T-SQL</a></li>
<li><a href="pmd_languages_visualforce.html">Visualforce</a></li>
<li><a href="pmd_languages_velocity.html">Velocity Template Language (VTL)</a></li>
<li><a href="pmd_languages_xml.html">XML and XML dialects</a></li>
</ul>
</li>
<li>
<a href="#">Developer Documentation</a>
<ul>
<li><a href="pmd_devdocs_development.html">Developer resources</a></li>
<li><a href="pmd_devdocs_building.html">Building PMD from source</a></li>
<li><a href="https://github.com/pmd/pmd/blob/main/CONTRIBUTING.md" target="_blank">Contributing</a></li>
<li><a href="pmd_devdocs_writing_documentation.html">Writing documentation</a></li>
<li><a href="pmd_devdocs_roadmap.html">Roadmap</a></li>
<li><a href="pmd_devdocs_how_pmd_works.html">How PMD works</a></li>
<li><a href="pmd_devdocs_pmdtester.html">Pmdtester</a></li>
<li><a href="pmd_devdocs_rule_deprecation_policy.html">Rule Deprecation Policy</a></li>
<li class="subfolders">
<a href="#">Major contributions</a>
<ul>
<li><a href="pmd_devdocs_major_rule_guidelines.html">Rule Guidelines</a></li>
<li><a href="pmd_devdocs_major_adding_new_language_javacc.html">Adding a new language (JavaCC)</a></li>
<li><a href="pmd_devdocs_major_adding_new_language_antlr.html">Adding a new language (ANTLR)</a></li>
<li><a href="pmd_devdocs_major_adding_new_cpd_language.html">Adding a new CPD language</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Experimental features</a>
<ul>
<li><a href="tag_experimental.html">List of experimental Features</a></li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#">Project documentation</a>
<ul>
<li class="subfolders">
<a href="#">Trivia about PMD</a>
<ul>
<li><a href="pmd_projectdocs_trivia_news.html">PMD in the press</a></li>
<li><a href="pmd_projectdocs_trivia_products.html">Products & books related to PMD</a></li>
<li><a href="pmd_projectdocs_trivia_similarprojects.html">Similar projects</a></li>
<li><a href="pmd_projectdocs_trivia_meaning.html">What does 'PMD' mean?</a></li>
</ul>
</li>
<li><a href="pmd_projectdocs_logo.html">Logo</a></li>
<li><a href="pmd_projectdocs_faq.html">FAQ</a></li>
<li><a href="license.html">License</a></li>
<li><a href="pmd_projectdocs_credits.html">Credits</a></li>
<li><a href="pmd_release_notes_old.html">Old release notes</a></li>
<li><a href="pmd_projectdocs_decisions.html">Decisions</a></li>
<li class="subfolders">
<a href="#">Project management</a>
<ul>
<li><a href="pmd_projectdocs_committers_infrastructure.html">Infrastructure</a></li>
<li><a href="pmd_projectdocs_committers_releasing.html">Release process</a></li>
<li><a href="pmd_projectdocs_committers_merging_pull_requests.html">Merging pull requests</a></li>
<li><a href="pmd_projectdocs_committers_main_landing_page.html">Main Landing page</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<!-- Content Column -->
<div class="col-md-9" id="tg-sb-content">
<header>
<div class="row">
<div class="col-lg-12">
<a href="./" role="button"
><i class="fa fa-home fa-lg"></i
></a>
» The rule designer
<a
target="_blank"
href="https://github.com/pmd/pmd/blob/main/docs/pages/pmd/userdocs/extending/designer_reference.md"
class="float-right"
role="button"
><i class="fab fa-github fa-lg"></i> Edit on GitHub</a
>
</div>
</div>
<hr />
</header>
<div class="post-header">
<h1 class="post-title-main">The rule designer</h1>
</div>
<div class="post-content" data-github-edit-url="https://github.com/pmd/pmd/blob/main/docs/pages/pmd/userdocs/extending/designer_reference.md">
<div class="summary">Learn about the usage and features of the rule designer.</div>
<details id="inline-toc-details">
<summary>Table of Contents</summary>
<div id="inline-toc"><!-- empty, move TOC here when screen size too small --></div>
</details>
<h2 id="installing-running-updating">Installing, running, updating</h2>
<p>The designer is part of PMDs binary distributions. To <strong>install a distribution</strong>, see the
<a href="pmd_userdocs_installation.html">documentation page about installing PMD</a>.</p>
<p>The designer still works with Java 8 from Oracle, which includes JavaFX. If you use this Java version, then
all is set. However, it is recommended to use OpenJDK along with OpenJFX. The recommended Java Runtime is
Java 11 (or later) with OpenJFX 17 (or later).</p>
<p>You can get OpenJDK from <a href="https://adoptium.net">Adoptium</a>, <a href="https://www.azul.com/downloads/#zulu">Azul</a>,
<a href="https://learn.microsoft.com/en-us/java/openjdk/download">Microsoft</a>, <a href="https://sap.github.io/SapMachine/">SAP</a>,
<a href="https://downloads.corretto.aws/#/overview">Amazon</a> and other OpenJDK vendors.
Note: Azul provides a JDK which includes JavaFX - this variant is currently not supported. You always need
to install OpenJFX separately.</p>
<p><a href="https://openjfx.io/">OpenJFX</a> is available from <a href="https://gluonhq.com/products/javafx/">JavaFX download page</a>.
You need the SDK. Extract the zip file, and set the <code class="language-plaintext highlighter-rouge">JAVAFX_HOME</code> environment variable to the extracted
directory. It should be the directory, that contain the sub-folder “lib” in it.</p>
<p>Example (for linux x64 only, with Java 21 and OpenJFX 21):</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">mkdir</span> <span class="nv">$HOME</span>/openjdk
<span class="nv">$ </span><span class="nb">cd</span> <span class="nv">$HOME</span>/openjdk
<span class="nv">$ </span>wget https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.2%2B13/OpenJDK21U-jdk_x64_linux_hotspot_21.0.2_13.tar.gz
<span class="nv">$ </span><span class="nb">tar </span>xfz OpenJDK21U-jdk_x64_linux_hotspot_21.0.2_13.tar.gz
<span class="nv">$ </span><span class="nb">export </span><span class="nv">JAVA_HOME</span><span class="o">=</span><span class="nv">$HOME</span>/openjdk/jdk-21.0.2+13
<span class="nv">$ </span><span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span><span class="nv">$JAVA_HOME</span>/bin:<span class="nv">$PATH</span>
<span class="nv">$ </span>wget https://download2.gluonhq.com/openjfx/21.0.2/openjfx-21.0.2_linux-x64_bin-sdk.zip
<span class="nv">$ </span>unzip <span class="nt">-q</span> openjfx-21.0.2_linux-x64_bin-sdk.zip
<span class="nv">$ </span><span class="nb">export </span><span class="nv">JAVAFX_HOME</span><span class="o">=</span><span class="nv">$HOME</span>/openjdk/javafx-sdk-21.0.2
</code></pre></div></div>
<p>If the bin directory of your PMD distribution is on your shells path, then you can then <strong>launch the app</strong> with</p>
<div class="text-left">
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item" role="presentation">
<a class="nav-link active" id="linux-tab-pmd" data-toggle="tab" href="#linux-pmd" role="tab" aria-controls="linux" aria-selected="true">Linux / macOS</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link" id="windows-tab-pmd" data-toggle="tab" href="#windows-pmd" role="tab" aria-controls="windows" aria-selected="false">Windows</a>
</li>
</ul>
<div class="tab-content border">
<div class="tab-pane fade show active" id="linux-pmd" role="tabpanel" aria-labelledby="linux-tab">
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="gp">~ $ </span><span class="s2">pmd</span> designer
</code></pre></figure>
</div>
<div class="tab-pane fade" id="windows-pmd" role="tabpanel" aria-labelledby="windows-tab">
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="gp">C:\&gt; </span><span class="s2">pmd.bat</span> designer
</code></pre></figure>
</div>
</div>
</div>
<div class="alert alert-info" role="alert"><i class="fas fa-info-circle"></i> <b>Note:</b> pmd-designer.jar is not a runnable jar, because it doesnt include any PMD language module, or PMD Core. </div>
<p>This is to allow easy updating, and let you choose the dependencies youre interested in.
The available language modules are those on the classpath of the apps JVM. Thats why its recommended to use the
standard PMD startup scripts, which setups the classpath with the available PMD libraries.</p>
<h3 id="updating">Updating</h3>
<p>The latest version of the designer currently <strong>works with PMD 7.0.0 and above</strong>. You can simply replace
pmd-designer-7.X.Y.jar with the <a href="https://github.com/pmd/pmd-designer/releases">latest build</a> in the installation
folder of your PMD distribution, and run it normally. Note that updating may cause some persisted state
to get lost, for example the code snippet.</p>
<h1 id="usage-reference">Usage reference</h1>
<p>The rule designer is both a tool to inspect the tree on which PMD rules run on, and to write XPath rules
in an integrated manner. This page describes the features that enable this.</p>
<h2 id="ast-inspection">AST inspection</h2>
<p><img src="images/designer/designer-top.png" alt="Designer top UI" /></p>
<p>You can enter source code in the middle zone.</p>
<ul>
<li>Make sure to select the correct language and version for your source code:
<ul>
<li>Language is set app-wide with the blue button in the menu-bar</li>
<li>If the language has several language versions, you can select a specific one with the choicebox just above the code area</li>
</ul>
</li>
<li>If the source is valid using this setting, the tree to the right will update to display the AST of the code</li>
<li>When selecting a node, the left panel updates with information about a node</li>
</ul>
<h3 id="selecting-nodes">Selecting nodes</h3>
<p>There are several ways to focus a node for inspection:</p>
<ul>
<li><strong>From the tree view:</strong> just click on an item
<ul>
<li>Since 6.16.0, the tree view is also searchable: press <kbd>Ctlr</kbd>+<kbd>F</kbd> when its focused,
or click on the <code class="language-plaintext highlighter-rouge">Search</code> button and enter a search query. You can cycle through results with
<kbd>Ctrl</kbd>+<kbd>Tab</kbd> or <kbd>Ctrl</kbd>+<kbd>F3</kbd>, and cycle back with
<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Tab</kbd> or <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>F3</kbd>.</li>
</ul>
</li>
<li><strong>From the crumb bar:</strong> the crumb bar below the code area shows the ancestors of the currently selected node,
and is empty if you have no selection:</li>
</ul>
<details><summary>Ancestor crumb bar demo</summary>
<p><img src="images/designer/parents-bar.gif" alt="Ancestor crumb bar demo" /></p>
</details>
<ul>
<li><strong>From the source code:</strong> maintain <kbd>Ctrl</kbd> for a second until the code area becomes mostly blue.
Then, each node you hover over on the code area will be selected automatically. Example:</li>
</ul>
<details><summary>Ctrl-hover selection demo</summary>
<p><img src="images/designer/hover-selection.gif" alt="CTRL-hover selection demo" /></p>
</details>
<h3 id="node-inspection">Node inspection</h3>
<p>The left panel displays the following information:</p>
<ul>
<li><strong>XPath attributes:</strong> this basically are all the attributes available in XPath queries. Those attributes are
wrappers around a Java getter, so you can obtain documentation on the relevant Javadoc (thats not yet
integrated into the designer)</li>
<li><strong>Metrics:</strong> for nodes that support it, the values of metrics are displayed in this panel</li>
<li><strong>Scopes:</strong> This is java specific and displays some representation of the symbol table. You mostly dont need
it. If you select e.g. a variable id, its usages are already highlighted automatically without opening the panel:</li>
</ul>
<p><img src="images/designer/usages.gif" alt="Usages highlight example" /></p>
<h2 id="xpath-rule-design">XPath rule design</h2>
<p>The bottom part of the UI is dedicated to designing XPath rules:</p>
<p><img src="images/designer/bottom-ui.png" alt="Bottom UI" /></p>
<p>The center is an XPath expression. As you type it, the matched nodes are updated on the right, and highlighted
on the code area. Autocompletion is available on some languages.</p>
<p>Note: you can keep several rules in the editor (theres a tab for each of them).</p>
<h3 id="rule-properties">Rule properties</h3>
<p>Above the XPath expression area, the <strong>“Properties”</strong> button allows you to
<a href="pmd_userdocs_extending_defining_properties.html#for-xpath-rules">define new properties</a> for your prototype rule.
You can also edit the existing properties.</p>
<p>When you click on it, a small popup appears:</p>
<p><img src="images/designer/property-defs.png" alt="Property definition popup" /></p>
<p>The popup contains in the center a list of currently defined properties, displaying their name and expected type.</p>
<ul>
<li><strong>Adding</strong>: the “Add property” button adds a row to the table</li>
<li><strong>Deleting</strong>: each item has a “Trash” button to delete the property</li>
<li><strong>Editing</strong>: each property can be further edited by clicking on the “Ellipsis” button on the right</li>
</ul>
<h4 id="editing-properties">Editing properties</h4>
<p>The edit menu of a property looks like the following:</p>
<p><img src="images/designer/property-edit.png" alt="Property edition popup" /></p>
<ul>
<li>You can edit the name, description, expected type, and default value of the property</li>
<li>All this information is exported with the rule definition (see <a href="#exporting-to-an-xml-rule">Exporting to an XML rule</a>)</li>
<li>The default value is used unless youre editing a test case, and you set a custom value for the test case
(see <a href="#testing-a-rule">Testing a rule</a>)</li>
</ul>
<h3 id="exporting-to-an-xml-rule">Exporting to an XML rule</h3>
<p>The little <strong>export icon</strong> next to the gear icon opens a menu to export your rule. This menu lets you fill-in the
metadata necessary for an XPath rule to be included in a ruleset.</p>
<details><summary>Rule export demo</summary>
<p><img src="images/designer/export-example.gif" alt="Rule export demo" /></p>
</details>
<h2 id="testing-a-rule">Testing a rule</h2>
<p>PMD has its own XML format to describe rule tests and execute them using our test framework. The designer includes
a test editor, which allows you to edit such files or create a new one directly as you edit the rule.
This is what the panel left of the XPath expression area is for.</p>
<p>See also <a href="pmd_userdocs_extending_testing.html">the test framework documentation</a>.</p>
<h3 id="testing-model">Testing model</h3>
<p>A rule test describes</p>
<ul>
<li>the configuration of the rule</li>
<li>the source on which to run</li>
<li>the expected violations</li>
<li>a description (to name the test)</li>
</ul>
<p>When executing a test, the rule is run on the source with the given configuration, then the violations it finds
are compared to the expected ones.</p>
<h3 id="adding-tests">Adding tests</h3>
<p>Tests can be added in one of four ways:</p>
<ul>
<li><strong>From an XML file:</strong> if you already have a test XML file for your tests, you can load all the tests it defines easily.</li>
</ul>
<details><summary>Test import demo</summary>
<p><img src="images/designer/tests/import.gif" alt="Test import example" /></p>
</details>
<ul>
<li>
<p><strong>From the current source:</strong> A new test case with a default configuration is created, with the source that is
currently in the editor</p>
</li>
<li>
<p><strong>With an empty source:</strong> A new test case with a default configuration is created, with an empty source file.
You must edit the source yourself then.</p>
</li>
<li>
<p><strong>From an existing test case:</strong> Each test case list item has a “Copy” button which duplicates the test and loads
the new one.</p>
</li>
</ul>
<h3 id="test-status">Test status</h3>
<p>In the designer, the test panel is a list of test cases. Their status (passing, failing, error, unknown) is color coded.</p>
<details><summary>Test status color coding examples</summary>
<p>All tests passing (green):</p>
<p><img src="images/designer/tests/all-green.png" alt="All green" /></p>
<p>A failing test (orange):</p>
<p><img src="images/designer/tests/failing.png" alt="Failing" /></p>
</details>
<h3 id="loading-a-test-case">Loading a test case</h3>
<p>Each test has a piece of source, which you can edit independently of the others, when the test is
<strong>loaded in the editor</strong>. Additional rule configuration options can be chosen when the test is loaded.</p>
<p>Loading is done with the <strong>Load</strong> button:</p>
<details><summary>Test loading demo</summary>
<p><img src="images/designer/tests/load.gif" alt="Test loading demo" /></p>
</details>
<p>Only one test case may be loaded at a time. If the loaded test is unloaded, the editor reverts back to the state
it had before the first test case was loaded.</p>
<h3 id="editing-a-loaded-test-case">Editing a loaded test case</h3>
<p>When a test is loaded, <em>the source you edit in the code area is the source of the test</em>. Changes are independent
from other tests, and from the piece of source that was previously in the editor.</p>
<p>When a test is loaded, an additional toolbar shows up at the top of the code area:</p>
<p><img src="images/designer/tests/toolbar.png" alt="Failing" /></p>
<h4 id="expected-violations">Expected violations</h4>
<p>The <strong>“Expected violations”</strong> button is used to add or edit the expected violations.</p>
<p>Initially the list of violations is empty. You can add violations by <strong>dragging and dropping nodes</strong> onto the
button or its popup, from any control that displays nodes. For example:</p>
<details><summary>Adding a violation demo</summary>
<p><img src="images/designer/tests/add-violation.gif" alt="Add violation gif" /></p>
</details>
<h4 id="test-case-rule-configuration">Test case rule configuration</h4>
<p>Rule properties can be configured for each test case independently using the <strong>“Property mapping”</strong> button. For example:</p>
<details><summary>Test rule property demo</summary>
<p><img src="images/designer/tests/property.gif" alt="Configure properties demo" /></p>
</details>
<p>This configuration will be used when executing the test to check its status.</p>
<h3 id="exporting-tests">Exporting tests</h3>
<p>When youre done editing tests, its a good idea to save the test file to an XML file. Exporting is done using
the <strong>“Export”</strong> button above the list of test cases:</p>
<details><summary>Test export demo</summary>
<p><img src="images/designer/tests/export.gif" alt="Test export demo" /></p>
</details>
<p>Note that the exported file does not contain any information about the rule. The rule must be in a ruleset file
somewhere else.</p>
<p>If you want to use PMDs test framework to use the test file in your build, please refer to the conventions
explained in <a href="pmd_userdocs_extending_testing.html#where-to-place-the-test-code">the test framework documentation</a>.</p>
<div class="tags">
<b>Tags: </b>
<a href="tag_extending.html" class="btn btn-outline-secondary navbar-btn cursorNorm" role="button">extending</a>
<a href="tag_userdocs.html" class="btn btn-outline-secondary navbar-btn cursorNorm" role="button">userdocs</a>
</div>
</div>
<footer>
<hr />
<div>
This documentation is written in markdown. <br />
If there is something missing or can be improved, edit this page on
github and create a PR:
<a
target="_blank"
href="https://github.com/pmd/pmd/blob/main/docs/pages/pmd/userdocs/extending/designer_reference.md"
role="button"
><i class="fab fa-github fa-lg"></i> Edit on GitHub</a
>
</div>
<hr />
<div class="row">
<div class="col-lg-12 footer">
&copy;2024 PMD Open Source Project. All rights
reserved. <br />
<span>Page last updated:</span>
March 2024 (7.0.0)<br /> Site last generated: Nov 21, 2024 <br />
<p>
<img src="images/logo/pmd-logo-70px.png" alt="PMD
logo"/>
</p>
</div>
</div>
</footer>
</div>
<!-- /.row -->
</div>
<!-- /.container -->
</div>
<!-- Sticky TOC column -->
<div class="toc-col">
<div id="toc"></div>
</div>
<!-- /.toc-container-wrapper -->
</div>
</div>
<script type="application/javascript" src="assets/jquery-3.5.1/jquery-3.5.1.min.js"></script>
<script type="application/javascript" src="assets/anchorjs-4.2.2/anchor.min.js"></script>
<script type="application/javascript" src="assets/navgoco-0.2.1/src/jquery.navgoco.min.js"></script>
<script type="application/javascript" src="assets/bootstrap-4.5.2-dist/js/bootstrap.bundle.min.js"></script>
<script type="application/javascript" src="assets/Simple-Jekyll-Search-1.0.8/dest/jekyll-search.js"></script>
<script type="application/javascript" src="assets/jekyll-table-of-contents/toc.js"></script>
<script type="application/javascript" src="js/tabstate.js"></script>
<script type="application/javascript" src="js/customscripts.js"></script>
</body>
</html>