forked from phoedos/pmd
5545 lines
386 KiB
HTML
5545 lines
386 KiB
HTML
<!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="Migrating to PMD 7 from PMD 6.x">
|
||
<meta name="keywords" content="pmduserdocs, ">
|
||
<title>Migration Guide for PMD 7 | 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"> <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"> </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.3.0-SNAPSHOT</li>
|
||
<div class="sidebarTitleDate">Release date: 28-June-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 class="active"><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><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>
|
||
|
||
|
||
|
||
</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/master/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>
|
||
» Migration Guide for PMD 7
|
||
<a
|
||
target="_blank"
|
||
href="https://github.com/pmd/pmd/blob/master/docs/pages/pmd/userdocs/migrating_to_pmd7.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">Migration Guide for PMD 7</h1>
|
||
</div>
|
||
|
||
<div class="post-content" data-github-edit-url="https://github.com/pmd/pmd/blob/master/docs/pages/pmd/userdocs/migrating_to_pmd7.md">
|
||
|
||
|
||
<div class="summary">Migrating to PMD 7 from PMD 6.x</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>
|
||
|
||
<div class="alert alert-warning" role="alert"><i class="fas fa-warning"></i> <b>Important:</b>
|
||
This document might be incomplete and doesn’t answer all questions. In that case please reach out to us
|
||
by opening a <a href="https://github.com/pmd/pmd/discussions">discussion</a> so that we can improve this guide.
|
||
</div>
|
||
|
||
<h2 id="before-you-update">Before you update</h2>
|
||
|
||
<p>Before updating to PMD 7, you should first update to the latest PMD 6 version 6.55.0 and try to fix all
|
||
deprecation warnings.</p>
|
||
|
||
<p>There are a couple of deprecated things in PMD 6, you might encounter:</p>
|
||
|
||
<ul>
|
||
<li>
|
||
<p>Properties: In order to define property descriptors, you should use <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/properties/PropertyFactory.html#"><code>PropertyFactory</code></a> now.
|
||
This factory can create properties of any type. E.g. instead of <code class="language-plaintext highlighter-rouge">StringProperty.named(...)</code> use
|
||
<code class="language-plaintext highlighter-rouge">PropertyFactory.stringProperty(...)</code>.</p>
|
||
|
||
<p>Also note, that <code class="language-plaintext highlighter-rouge">uiOrder</code> is gone. You can just remove it.</p>
|
||
|
||
<p>See also <a href="pmd_userdocs_extending_defining_properties.html">Defining rule properties</a></p>
|
||
</li>
|
||
<li>
|
||
<p>When reporting a violation, you might see a deprecation of the <code class="language-plaintext highlighter-rouge">addViolation</code> methods. These methods have been moved
|
||
to <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/reporting/RuleContext.html#"><code>RuleContext</code></a>. E.g. instead of <code class="language-plaintext highlighter-rouge">addViolation(data, node, ...)</code> use <code class="language-plaintext highlighter-rouge">asCtx(data).addViolation(node, ...)</code>.</p>
|
||
</li>
|
||
<li>When you are calling PMD from CLI, you need to stop using deprecated CLI params, e.g.
|
||
<ul>
|
||
<li><code class="language-plaintext highlighter-rouge">-no-cache</code> ➡️ <code class="language-plaintext highlighter-rouge">--no-cache</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">-failOnViolation</code> ➡️ <code class="language-plaintext highlighter-rouge">--fail-on-violation</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">-reportfile</code> ➡️ <code class="language-plaintext highlighter-rouge">--report-file</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">-language</code> ➡️ <code class="language-plaintext highlighter-rouge">--use-version</code></li>
|
||
</ul>
|
||
</li>
|
||
<li>If you have written custom XPath rule, look out for warnings about deprecated XPath attributes. These warnings
|
||
might look like
|
||
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>WARNING: Use of deprecated attribute 'VariableId/@Image' by XPath rule 'VariableNaming' (in ruleset 'VariableNamingRule'), please use @Name instead
|
||
</code></pre></div> </div>
|
||
<p>and often already suggest an alternative.</p>
|
||
</li>
|
||
<li>If you still reference rulesets or rules the old way which has been deprecated since 6.46.0:
|
||
<ul>
|
||
<li><code class="language-plaintext highlighter-rouge"><lang-name>-<ruleset-name></code>, eg <code class="language-plaintext highlighter-rouge">java-basic</code>, which resolves to <code class="language-plaintext highlighter-rouge">rulesets/java/basic.xml</code></li>
|
||
<li>the internal release number, eg <code class="language-plaintext highlighter-rouge">600</code>, which resolves to <code class="language-plaintext highlighter-rouge">rulesets/releases/600.xml</code></li>
|
||
</ul>
|
||
|
||
<p>Such usages produce deprecation warnings that should be easy to spot, e.g.</p>
|
||
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Ruleset reference 'java-basic' uses a deprecated form, use 'rulesets/java/basic.xml' instead
|
||
</code></pre></div> </div>
|
||
|
||
<p>Use the explicit forms of these references to be compatible with PMD 7.</p>
|
||
|
||
<p>Note: Since PMD 6, all rules are sorted into categories (such as “Best Practices”, “Design”, “Error Prone”)
|
||
and the old rulesets like <code class="language-plaintext highlighter-rouge">basic.xml</code> have been deprecated and have been removed with PMD 7.
|
||
It is about time to create a <a href="pmd_userdocs_making_rulesets.html">custom ruleset</a>.</p>
|
||
</li>
|
||
</ul>
|
||
|
||
<h2 id="approaching-700">Approaching 7.0.0</h2>
|
||
|
||
<p>After that, migrate to the release candidates, and fix any problems you encounter. Start with 7.0.0-rc1 via
|
||
7.0.0-rc2, 7.0.0-rc3 and 7.0.0-rc4 until you finally use 7.0.0.</p>
|
||
|
||
<p>You might encounter additionally the following types of problems:</p>
|
||
|
||
<ul>
|
||
<li>If you use any programmatic API of PMD, first avoid any usage of deprecated or internal classes/methods. These
|
||
are marked with one of these annotations: <code class="language-plaintext highlighter-rouge">@Deprecated</code>, <code class="language-plaintext highlighter-rouge">@DeprecatedUtil700</code>, <code class="language-plaintext highlighter-rouge">@InternalApi</code>.
|
||
<ul>
|
||
<li>Some of these classes are available until 7.0.0-rc4 but are finally removed with 7.0.0.</li>
|
||
<li>See <a href="pmd_release_notes_pmd7.html#api-changes">API changes</a> for details.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Some rules have been removed, because they have been deprecated. See <a href="pmd_release_notes_pmd7.html#removed-rules">Removed Rules</a>.</li>
|
||
<li>Some rule properties have been removed or changed. See <a href="pmd_release_notes_pmd7.html#changed-rules">Changed Rules</a>.</li>
|
||
<li>The filenames of the assets of a release (the “binary distribution zip file”) have changed,
|
||
see <a href="#release-downloads">Release downloads</a>.</li>
|
||
<li>Some CLI options have been removed, because they have been deprecated. See <a href="#cli-changes">CLI Changes</a> for details.</li>
|
||
<li>If you call CPD programmatically, the API has changed, see <a href="pmd_release_notes_pmd7.html#new-programmatic-api-for-cpd">New Programmatic API for CPD</a>.</li>
|
||
<li>If you use Visualforce, then you need to change “vf” to “visualforce”, e.g. <code class="language-plaintext highlighter-rouge">category/vf/security.xml</code> ➡️ <code class="language-plaintext highlighter-rouge">category/visualforce/security.xml</code></li>
|
||
<li>If you use Velocity, then you need to change “vm” to “velocity”, e.g. <code class="language-plaintext highlighter-rouge">category/vm/...</code> ➡️ <code class="language-plaintext highlighter-rouge">category/velocity/...</code></li>
|
||
</ul>
|
||
|
||
<p>The following topics describe well known migration challenges in more detail.</p>
|
||
|
||
<h2 id="use-cases">Use cases</h2>
|
||
|
||
<h3 id="im-using-only-built-in-rules">I’m using only built-in rules</h3>
|
||
|
||
<p>When you are using only built-in rules, then you should check, whether you use any deprecated rule. With PMD 7
|
||
many deprecated rules are finally removed. You can see a complete list of the <a href="pmd_release_notes_pmd7.html#removed-rules">removed rules</a>
|
||
in the release notes for PMD 7.
|
||
The release notes also mention the replacement rule, that should be used instead. For some rules, there is no
|
||
replacement.</p>
|
||
|
||
<p>Then many rules have been changed or improved. New properties have been added to make them more versatile or
|
||
properties have been removed, if they are not necessary anymore. See <a href="pmd_release_notes_pmd7.html#changed-rules">changed rules</a>
|
||
in the release notes for PMD 7.</p>
|
||
|
||
<p>All properties which accept multiple values now use a comma (<code class="language-plaintext highlighter-rouge">,</code>) as a delimiter. The previous default was a
|
||
pipe character (<code class="language-plaintext highlighter-rouge">|</code>). The delimiter is not configurable anymore. If needed, the comma can be escaped
|
||
with a backslash. This affects the following rules:
|
||
<a href="pmd_rules_java_bestpractices.html#avoidusinghardcodedip"><code class="language-plaintext highlighter-rouge">AvoidUsingHardCodedIP</code></a>,
|
||
<a href="pmd_rules_java_bestpractices.html#loosecoupling"><code class="language-plaintext highlighter-rouge">LooseCoupling</code></a>,
|
||
<a href="pmd_rules_java_bestpractices.html#unusedprivatefield"><code class="language-plaintext highlighter-rouge">UnusedPrivateField</code></a>,
|
||
<a href="pmd_rules_java_bestpractices.html#unusedprivatemethod"><code class="language-plaintext highlighter-rouge">UnusedPrivateMethod</code></a>,
|
||
<a href="pmd_rules_java_codestyle.html#atleastoneconstructor"><code class="language-plaintext highlighter-rouge">AtLeastOneConstructor</code></a>,
|
||
<a href="pmd_rules_java_codestyle.html#commentdefaultaccessmodifier"><code class="language-plaintext highlighter-rouge">CommentDefaultAccessModifier</code></a>,
|
||
<a href="pmd_rules_java_codestyle.html#fieldnamingconventions"><code class="language-plaintext highlighter-rouge">FieldNamingConventions</code></a>,
|
||
<a href="pmd_rules_java_codestyle.html#linguisticnaming"><code class="language-plaintext highlighter-rouge">LinguisticNaming</code></a>,
|
||
<a href="pmd_rules_java_codestyle.html#unnecessaryconstructor"><code class="language-plaintext highlighter-rouge">UnnecessaryConstructor</code></a>,
|
||
<a href="pmd_rules_java_design.html#cyclomaticcomplexity"><code class="language-plaintext highlighter-rouge">CyclomaticComplexity</code></a>,
|
||
<a href="pmd_rules_java_design.html#ncsscount"><code class="language-plaintext highlighter-rouge">NcssCount</code></a>,
|
||
<a href="pmd_rules_java_design.html#singularfield"><code class="language-plaintext highlighter-rouge">SingularField</code></a>,
|
||
<a href="pmd_rules_java_errorprone.html#avoidbranchingstatementaslastinloop"><code class="language-plaintext highlighter-rouge">AvoidBranchingStatementAsLastInLoop</code></a>,
|
||
<a href="pmd_rules_java_errorprone.html#closeresource"><code class="language-plaintext highlighter-rouge">CloseResource</code></a>.</p>
|
||
|
||
<p>A handful of rules are new to PMD 7. You might want to check these out: <a href="pmd_release_notes_pmd7.html#new-rules">new rules</a>.</p>
|
||
|
||
<p>Once you have reviewed your ruleset(s), you can switch to PMD 7.</p>
|
||
|
||
<h3 id="im-using-custom-rules">I’m using custom rules</h3>
|
||
|
||
<h4 id="testing">Testing</h4>
|
||
<p>Ideally, you have written good tests already for your custom rules - see <a href="pmd_userdocs_extending_testing.html">Testing your rules</a>.
|
||
This helps to identify problems early on.</p>
|
||
|
||
<p>The base test classes <a href="https://docs.pmd-code.org/apidocs/pmd-test/7.3.0-SNAPSHOT/net/sourceforge/pmd/test/PmdRuleTst.html#"><code>PmdRuleTst</code></a> and <a href="https://docs.pmd-code.org/apidocs/pmd-test/7.3.0-SNAPSHOT/net/sourceforge/pmd/test/SimpleAggregatorTst.html#"><code>SimpleAggregatorTst</code></a> have been moved out
|
||
of package <code class="language-plaintext highlighter-rouge">net.sourceforge.pmd.testframework</code>. You’ll need to adjust your imports.</p>
|
||
|
||
<h4 id="ruleset-xml">Ruleset XML</h4>
|
||
<p>The <code class="language-plaintext highlighter-rouge"><rule></code> tag, that defines your custom rule, is required to have a <code class="language-plaintext highlighter-rouge">language</code> attribute now. This was always the
|
||
case for XPath rules, but is now a requirement for Java rules.</p>
|
||
|
||
<h4 id="xpath-rules">XPath rules</h4>
|
||
<p>If you have <strong>XPath based</strong> 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
|
||
won’t support XPath 1.0 anymore. The difference between XPath 2.0 and XPath 3.1 is not big, so your XPath 2.0
|
||
can be expected to work in PMD 7 without any further changes. So the migration path is to simply migrate to XPath 2.0.</p>
|
||
|
||
<p>After you have migrated your XPath rules to XPath 2.0, remove the “version” property, since that has been removed
|
||
with PMD 7. PMD 7 by default uses XPath 3.1. See below <a href="#xpath-migrating-from-10-to-20">XPath</a> for details.</p>
|
||
|
||
<p>Then change the <code class="language-plaintext highlighter-rouge">class</code> attribute of your rule to <code class="language-plaintext highlighter-rouge">net.sourceforge.pmd.lang.rule.xpath.XPathRule</code> - because the
|
||
class <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/rule/xpath/XPathRule.html#"><code>XPathRule</code></a> has been moved into subpackage <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/rule/xpath/package-summary.html#"><code>net.sourceforge.pmd.lang.rule.xpath</code></a>.</p>
|
||
|
||
<p>There are some general changes for AST nodes regarding the <code class="language-plaintext highlighter-rouge">@Image</code> attribute.
|
||
See below <a href="#general-ast-changes-to-avoid-image">General AST Changes to avoid @Image</a>.</p>
|
||
|
||
<p>Additional infos:</p>
|
||
<ul>
|
||
<li>The custom XPath function <code class="language-plaintext highlighter-rouge">typeOf</code> has been removed (deprecated since 6.4.0).
|
||
Use the function <code class="language-plaintext highlighter-rouge">pmd-java:typeIs</code> or <code class="language-plaintext highlighter-rouge">pmd-java:typeIsExactly</code> instead.
|
||
See <a href="pmd_userdocs_extending_writing_xpath_rules.html#pmd-extension-functions">PMD extension functions</a> for available
|
||
functions.</li>
|
||
</ul>
|
||
|
||
<h4 id="java-rules">Java rules</h4>
|
||
<p>If you have <strong>Java based rules</strong>, and you are using rulechain, this works a bit different now. The RuleChain API
|
||
has changed, see <a href="https://github.com/pmd/pmd/pull/2490">[core] Simplify the rulechain (#2490)</a> for the full details.
|
||
But in short, you don’t call <code class="language-plaintext highlighter-rouge">addRuleChainVisit(...)</code> in the rule’s constructor anymore. Instead, you
|
||
override the method <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/rule/AbstractRule.html#buildTargetSelector"><code>buildTargetSelector</code></a>:</p>
|
||
|
||
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">protected</span> <span class="nc">RuleTargetSelector</span> <span class="nf">buildTargetSelector</span><span class="o">()</span> <span class="o">{</span>
|
||
<span class="k">return</span> <span class="nc">RuleTargetSelector</span><span class="o">.</span><span class="na">forTypes</span><span class="o">(</span><span class="nc">ASTVariableId</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
|
||
<span class="o">}</span>
|
||
</code></pre></div></div>
|
||
|
||
<h4 id="java-ast-changes">Java AST changes</h4>
|
||
<p>The API to <strong>navigate the AST</strong> also changed significantly:</p>
|
||
<ul>
|
||
<li>Tree traversal using <a href="#node-api">Node API</a></li>
|
||
<li>Consider using the new <a href="#nodestream-api">NodeStream API</a> to navigate with null-safety. This is optional.</li>
|
||
</ul>
|
||
|
||
<p>Additionally, if you have created rules for <strong>Java</strong> - regardless whether it is a XPath based rule or a Java based
|
||
rule - you might need to adjust your queries or visitor methods. The Java AST has been refactored substantially.
|
||
The easiest way is to use the <a href="pmd_userdocs_extending_designer_reference.html">PMD Rule Designer</a> to see the structure
|
||
of the AST. See the section <a href="#java-ast">Java AST</a> below for details.</p>
|
||
|
||
<h3 id="ive-extended-pmd-with-a-custom-language">I’ve extended PMD with a custom language…</h3>
|
||
|
||
<p>The guides for <a href="pmd_devdocs_major_adding_new_language_javacc.html">Adding a new language with JavaCC</a> and
|
||
<a href="pmd_devdocs_major_adding_new_cpd_language.html">Adding a new CPD language</a> have been updated.</p>
|
||
|
||
<p>Most notable changes are:</p>
|
||
|
||
<ul>
|
||
<li>As an alternative, PMD 7 now supports ANTLR in addition to JavaCC:
|
||
<a href="pmd_devdocs_major_adding_new_language_antlr.html">Adding a new language with ANTLR</a>.</li>
|
||
<li>There is a shared ant script that wraps the calls to javacc: <code class="language-plaintext highlighter-rouge">javacc-wrapper.xml</code>. This should be used now.</li>
|
||
<li>PMD’s parser adapter for JavaCC generated parsers is called now
|
||
<a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.html#"><code>JjtreeParserAdapter</code></a>. This is the class that needs to be implemented now.</li>
|
||
<li>There is no need anymore to write a custom <code class="language-plaintext highlighter-rouge">TokenManager</code> - we have now a common base class for JavaCC generated
|
||
token managers. This base class is <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractTokenManager.html#"><code>AbstractTokenManager</code></a>.</li>
|
||
<li>A rule violation factory is not needed anymore. For language specific information on rule violations, there is
|
||
now a <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/reporting/ViolationDecorator.html#"><code>ViolationDecorator</code></a> that a language can implement. These ViolationDecorators
|
||
are called when a violation is reported and they can provide the additional information. This information can be
|
||
used by renderers via <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/reporting/RuleViolation.html#getAdditionalInfo()"><code>RuleViolation#getAdditionalInfo</code></a>.</li>
|
||
<li>A parser visitor adapter is not needed anymore. The visitor interface now provides a default implementation.
|
||
Instead, a base visitor for the language should be created, which extends <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/AstVisitorBase.html#"><code>AstVisitorBase</code></a>.</li>
|
||
<li>A rule chain visitor is not needed anymore. PMD provides a common implementation that fits all languages.</li>
|
||
</ul>
|
||
|
||
<h3 id="ive-extended-pmd-with-a-custom-feature">I’ve extended PMD with a custom feature…</h3>
|
||
|
||
<p>In that case we can’t provide a general guide unless we know the specific custom feature. If you are having difficulties
|
||
finding your way around the PMD source code and javadocs and you don’t see the aspect of PMD documented you are
|
||
using, we are probably missing documentation. Please reach out to us by opening a
|
||
<a href="https://github.com/pmd/pmd/discussions">discussion</a>. We then can enhance the documentation and/or the PMD API.</p>
|
||
|
||
<h2 id="special-topics">Special topics</h2>
|
||
|
||
<h3 id="release-downloads">Release downloads</h3>
|
||
|
||
<ul>
|
||
<li>The asset filenames of PMD on <a href="https://github.com/pmd/pmd/releases">GitHub Releases</a> are
|
||
now <code class="language-plaintext highlighter-rouge">pmd-dist-<version>-bin.zip</code>, <code class="language-plaintext highlighter-rouge">pmd-dist-<version>-src.zip</code> and <code class="language-plaintext highlighter-rouge">pmd-dist-<version>-doc.zip</code>.
|
||
Keep that in mind, if you have an automated download script.</li>
|
||
<li>The structure inside the ZIP files stay the same, e.g. we still provide inside the binary distribution
|
||
ZIP file the base directory <code class="language-plaintext highlighter-rouge">pmd-bin-<version></code>.</li>
|
||
</ul>
|
||
|
||
<h3 id="cli-changes">CLI Changes</h3>
|
||
|
||
<p>The CLI has been revamped completely
|
||
(see <a href="pmd_release_notes_pmd7.html#revamped-command-line-interface">Release Notes: Revamped Command Line Interface</a>).</p>
|
||
|
||
<p>Most notable changes:</p>
|
||
|
||
<ul>
|
||
<li>Unified start script on all platforms for all commands (PMD, CPD, Designer). Instead of <code class="language-plaintext highlighter-rouge">run.sh</code> and <code class="language-plaintext highlighter-rouge">pmd.bat</code>,
|
||
we now have <code class="language-plaintext highlighter-rouge">pmd</code> only (technically on Windows, there is still a <code class="language-plaintext highlighter-rouge">pmd.bat</code>, but it behaves the same).
|
||
<ul>
|
||
<li>Executing PMD from CLI now means: <code class="language-plaintext highlighter-rouge">run.sh pmd</code> / <code class="language-plaintext highlighter-rouge">pmd.bat</code> ➡️ <code class="language-plaintext highlighter-rouge">pmd check</code></li>
|
||
<li>Executing CPD: <code class="language-plaintext highlighter-rouge">run.sh cpd</code> / <code class="language-plaintext highlighter-rouge">cpd.bat</code> ➡️ <code class="language-plaintext highlighter-rouge">pmd cpd</code></li>
|
||
<li>Executing Designer: <code class="language-plaintext highlighter-rouge">run.sh designer</code> / <code class="language-plaintext highlighter-rouge">designer.bat</code> ➡️ <code class="language-plaintext highlighter-rouge">pmd designer</code></li>
|
||
<li>Executing CPD GUI: <code class="language-plaintext highlighter-rouge">run.sh cpd-gui</code> / <code class="language-plaintext highlighter-rouge">cpdgui.bat</code> ➡️ <code class="language-plaintext highlighter-rouge">pmd cpd-gui</code></li>
|
||
</ul>
|
||
</li>
|
||
<li>There are some changes to the CLI arguments:
|
||
<ul>
|
||
<li>
|
||
<p><code class="language-plaintext highlighter-rouge">--fail-on-violation false</code> ➡️ <code class="language-plaintext highlighter-rouge">--no-fail-on-violation</code></p>
|
||
|
||
<p>If you don’t replace this argument, then “false” will be interpreted as a file to analyze. You might see then
|
||
an error message such as <code class="language-plaintext highlighter-rouge">[main] ERROR net.sourceforge.pmd.cli.commands.internal.PmdCommand - No such file false</code>.</p>
|
||
</li>
|
||
<li>PMD tries to display a progress bar. If you don’t want this (e.g. on a CI build server), you can disable this
|
||
with <code class="language-plaintext highlighter-rouge">--no-progress</code>.</li>
|
||
<li><code class="language-plaintext highlighter-rouge">--no-ruleset-compatibility</code> has been removed without replacement.</li>
|
||
<li><code class="language-plaintext highlighter-rouge">--stress</code> (or <code class="language-plaintext highlighter-rouge">-stress</code>) has been removed without replacement.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 id="custom-distribution-packages">Custom distribution packages</h3>
|
||
|
||
<p>When creating a custom distribution which only integrates the languages you need, there are some changes to apply:</p>
|
||
|
||
<ul>
|
||
<li>In addition to the language dependencies you want, you also need add a dependency to
|
||
<code class="language-plaintext highlighter-rouge">net.sourceforge.pmd:pmd-cli</code> in order to get the CLI classes.</li>
|
||
<li>When fetching the scripts for the CLI with “maven-dependency-plugin”, you need to additionally fetch the
|
||
logging configuration. That means, the line
|
||
<code class="language-plaintext highlighter-rouge"><includes>scripts/**,LICENSE</includes></code> needs to be changed to <code class="language-plaintext highlighter-rouge"><includes>scripts/**,LICENSE,conf/**</includes></code>.</li>
|
||
<li>Since the assembly descriptor <code class="language-plaintext highlighter-rouge">pmd-bin</code> includes now optionally also a BOM (bill of material). If you want to
|
||
create this for your custom distribution, simply add the following plugin configuration:
|
||
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nt"><plugin></span>
|
||
<span class="nt"><groupId></span>org.cyclonedx<span class="nt"></groupId></span>
|
||
<span class="nt"><artifactId></span>cyclonedx-maven-plugin<span class="nt"></artifactId></span>
|
||
<span class="nt"><version></span>2.7.11<span class="nt"></version></span>
|
||
<span class="nt"><configuration></span>
|
||
<span class="nt"><outputName></span>pmd-${project.version}-cyclonedx<span class="nt"></outputName></span>
|
||
<span class="nt"></configuration></span>
|
||
<span class="nt"><executions></span>
|
||
<span class="nt"><execution></span>
|
||
<span class="nt"><phase></span>package<span class="nt"></phase></span>
|
||
<span class="nt"><goals></span>
|
||
<span class="nt"><goal></span>makeAggregateBom<span class="nt"></goal></span>
|
||
<span class="nt"></goals></span>
|
||
<span class="nt"></execution></span>
|
||
<span class="nt"></executions></span>
|
||
<span class="nt"></plugin></span>
|
||
</code></pre></div> </div>
|
||
</li>
|
||
<li>The artifact name for PMD Designer has been renamed, you need to use now <code class="language-plaintext highlighter-rouge">net.sourceforge.pmd:pmd-designer</code>
|
||
instead of “pmd-ui”.</li>
|
||
</ul>
|
||
|
||
<div class="alert alert-info" role="alert"><i class="fas fa-info-circle"></i> <b>Note:</b>
|
||
The examples on <a href="https://github.com/pmd/pmd-examples">https://github.com/pmd/pmd-examples</a> have been updated.
|
||
</div>
|
||
|
||
<h3 id="rule-tests-are-now-using-junit5">Rule tests are now using JUnit5</h3>
|
||
|
||
<p>When you have custom rules, and you have written rule tests according to the guide
|
||
<a href="pmd_userdocs_extending_testing.html">Testing your rules</a>, you might want to consider upgrading your other tests to
|
||
<a href="https://junit.org/junit5/">JUnit 5</a>. The tests in PMD 7 have been migrated to JUnit5 - including the rule tests
|
||
for the built-in rules.</p>
|
||
|
||
<p>When executing the rule tests, you need to make sure to have JUnit5 on the classpath - which you automatically
|
||
get when you depend on <code class="language-plaintext highlighter-rouge">net.sourceforge.pmd:pmd-test</code>. If you also have JUnit4 tests, you need to make sure
|
||
to have a <a href="https://junit.org/junit5/docs/current/user-guide/#migrating-from-junit4-running">junit-vintage-engine</a>
|
||
as well on the test classpath, so that all tests are executed. That means, you might
|
||
need to add now a dependency to JUnit4 explicitly if needed.</p>
|
||
|
||
<h3 id="cpd-reported-endcolumn-is-now-exclusive">CPD: Reported endcolumn is now exclusive</h3>
|
||
|
||
<p>In PMD 6, the reported position of the duplicated tokens in CPD where always including, e.g. the following
|
||
described a duplication of length 4 in PMD 6: beginLine=1, endLine=1, beginColumn=1, endColumn=4 - these are
|
||
the first 4 character in the first line. With PMD 7, the endColumn is now <strong>excluding</strong>. The same duplication
|
||
will be reported in PMD 7 as: beginLine=1, endLine=1, beginColumn=1, endColumn=5.</p>
|
||
|
||
<p>The reported positions in a file follow now the usual meaning: line numbering starts from 1, begin line and end line
|
||
are inclusive, begin column is inclusive and end column is exclusive. This is the usual behavior of the most
|
||
common text editors and the PMD part already used that meaning in RuleViolations for a long time in PMD 6 already.</p>
|
||
|
||
<p>This only affects the XML report format as the others don’t provide column information.</p>
|
||
|
||
<h3 id="node-api">Node API</h3>
|
||
|
||
<p>Starting from one node in the AST, you can navigate to children or parents with the following methods. This is
|
||
the “traditional” way for simple cases. For more complex cases, consider to use the new <a href="#nodestream-api">NodeStream API</a>.</p>
|
||
|
||
<p>Many methods available in PMD 6 have been deprecated and removed for a slicker API with consistent naming,
|
||
that also integrates tightly with the NodeStream API.</p>
|
||
|
||
<ul>
|
||
<li><code class="language-plaintext highlighter-rouge">getNthParent(n)</code> ➡️ <code class="language-plaintext highlighter-rouge">ancestors().get(n - 1)</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">getFirstParentOfType(parentType)</code> ➡️ <code class="language-plaintext highlighter-rouge">ancestors(parentType).first()</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">getParentsOfType(parentType)</code> ➡️ <code class="language-plaintext highlighter-rouge">ancestors(parentType).toList()</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">findChildrenOfType(childType)</code> ➡️ <code class="language-plaintext highlighter-rouge">children(childType).toList()</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">findDescendantsOfType(targetType)</code> ➡️ <code class="language-plaintext highlighter-rouge">descendants(targetType).toList()</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">getFirstChildOfType(childType)</code> ➡️ <code class="language-plaintext highlighter-rouge">firstChild(childType)</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">getFirstDescendantOfType(descendantType)</code> ➡️ <code class="language-plaintext highlighter-rouge">descendants(descendantType).first()</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">hasDescendantOfType(type)</code> ➡️ <code class="language-plaintext highlighter-rouge">descendants(type).nonEmpty()</code></li>
|
||
</ul>
|
||
|
||
<div class="alert alert-success" role="alert"><i class="fas fa-check-square-o"></i> <b>Tip:</b> First use PMD 7.0.0-rc3, which still has these methods. These methods are marked as
|
||
deprecated, so you can then start to change them. The replacement method is usually provided in the javadocs.
|
||
That way you avoid being confronted with just compile errors.</div>
|
||
|
||
<p>Unchanged methods that work as before:</p>
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#getParent()"><code>getParent</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#getChild(int)"><code>getChild</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#getNumChildren()"><code>getNumChildren</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#getIndexInParent()"><code>getIndexInParent</code></a></li>
|
||
</ul>
|
||
|
||
<p>New methods:</p>
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#getFirstChild()"><code>getFirstChild</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#getLastChild()"><code>getLastChild</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#getPreviousSibling()"><code>getPreviousSibling</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#getNextSibling()"><code>getNextSibling</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#getRoot()"><code>getRoot</code></a></li>
|
||
</ul>
|
||
|
||
<p>New methods that integrate with NodeStream:</p>
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#children()"><code>children</code></a> - returns a NodeStream containing all the children of this node.
|
||
Note: in PMD 6, this method returned an <code class="language-plaintext highlighter-rouge">Iterable</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#descendants()"><code>descendants</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#descendantsOrSelf()"><code>descendantsOrSelf</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#ancestors()"><code>ancestors</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#ancestorsOrSelf()"><code>ancestorsOrSelf</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#children(java.lang.Class)"><code>children</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#firstChild(java.lang.Class)"><code>firstChild</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#descendants(java.lang.Class)"><code>descendants</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#ancestors(java.lang.Class)"><code>ancestors</code></a></li>
|
||
</ul>
|
||
|
||
<p>Methods removed completely:</p>
|
||
<ul>
|
||
<li><code class="language-plaintext highlighter-rouge">getFirstParentOfAnyType(parentTypes)</code>:️ There is no direct replacement, but something along the lines:
|
||
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="n">ancestors</span><span class="o">()</span>
|
||
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="n">n</span> <span class="o">-></span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">stream</span><span class="o">(</span><span class="n">classes</span><span class="o">)</span>
|
||
<span class="o">.</span><span class="na">anyMatch</span><span class="o">(</span><span class="n">c</span> <span class="o">-></span> <span class="n">c</span><span class="o">.</span><span class="na">isInstance</span><span class="o">(</span><span class="n">n</span><span class="o">)))</span>
|
||
<span class="o">.</span><span class="na">first</span><span class="o">();</span>
|
||
</code></pre></div> </div>
|
||
</li>
|
||
<li><code class="language-plaintext highlighter-rouge">findChildNodesWithXPath</code>: Has been removed, because it is very inefficient. Use NodeStream instead.</li>
|
||
<li><code class="language-plaintext highlighter-rouge">hasDescendantMatchingXPath</code>: Has been removed, because it is very inefficient. Use NodeStream instead.</li>
|
||
<li><code class="language-plaintext highlighter-rouge">jjt*</code> like <code class="language-plaintext highlighter-rouge">jjtGetParent</code>. These methods were implementation specific. Use the equivalent methods like <code class="language-plaintext highlighter-rouge">getParent()</code>.</li>
|
||
</ul>
|
||
|
||
<p>See <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#"><code>Node</code></a> for the details.</p>
|
||
|
||
<h3 id="nodestream-api">NodeStream API</h3>
|
||
|
||
<p>In java rule implementations, you often need to navigate the AST to find the interesting nodes. In PMD 6, this
|
||
was often done by calling <code class="language-plaintext highlighter-rouge">jjtGetChild(int)</code> or <code class="language-plaintext highlighter-rouge">jjtGetParent(int)</code> and then checking the node type
|
||
with <code class="language-plaintext highlighter-rouge">instanceof</code>. There are also helper methods available, like <code class="language-plaintext highlighter-rouge">getFirstChildOfType(Class)</code> or
|
||
<code class="language-plaintext highlighter-rouge">findDescendantsOfType(Class)</code>. These methods might return <code class="language-plaintext highlighter-rouge">null</code> and you need to check this for every
|
||
level.</p>
|
||
|
||
<p>The new <strong>NodeStream API</strong> provides easy to use methods that follow the Java Stream API (<code class="language-plaintext highlighter-rouge">java.util.stream</code>).</p>
|
||
|
||
<p>Many complex predicates about nodes can be expressed by testing the emptiness of a node stream.
|
||
E.g. the following tests if the node is a variable declarator id initialized to the value <code class="language-plaintext highlighter-rouge">0</code>:</p>
|
||
|
||
<p>Example:</p>
|
||
|
||
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nc">NodeStream</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="n">someNode</span><span class="o">)</span> <span class="c1">// the stream here is empty if the node is null</span>
|
||
<span class="o">.</span><span class="na">filterIs</span><span class="o">(</span><span class="nc">ASTVariableId</span><span class="o">.</span><span class="na">class</span><span class="o">)</span> <span class="c1">// the stream here is empty if the node was not a variable id</span>
|
||
<span class="o">.</span><span class="na">followingSiblings</span><span class="o">()</span> <span class="c1">// the stream here contains only the siblings, not the original node</span>
|
||
<span class="o">.</span><span class="na">children</span><span class="o">(</span><span class="nc">ASTNumericLiteral</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
|
||
<span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="nl">ASTNumericLiteral:</span><span class="o">:</span><span class="n">isIntLiteral</span><span class="o">)</span>
|
||
<span class="o">.</span><span class="na">filterMatching</span><span class="o">(</span><span class="nl">ASTNumericLiteral:</span><span class="o">:</span><span class="n">getValueAsInt</span><span class="o">,</span> <span class="mi">0</span><span class="o">)</span>
|
||
<span class="o">.</span><span class="na">nonEmpty</span><span class="o">();</span> <span class="c1">// If the stream is non empty here, then all the pipeline matched</span>
|
||
</code></pre></div></div>
|
||
|
||
<p>See <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/NodeStream.html#"><code>NodeStream</code></a> for the details.
|
||
Note: This was implemented via <a href="https://github.com/pmd/pmd/pull/1622">PR #1622 [core] NodeStream API</a></p>
|
||
|
||
<h3 id="xpath-migrating-from-10-to-20">XPath: Migrating from 1.0 to 2.0</h3>
|
||
|
||
<p>XPath 1.0 and 2.0 have some incompatibilities. The <a href="https://www.w3.org/TR/xpath20/#id-incompat-in-false-mode">XPath 2.0 specification</a>
|
||
describes them precisely. Those are however mostly corner cases and XPath
|
||
rules usually don’t feature any of them.</p>
|
||
|
||
<p>The incompatibilities that are most relevant to migrating your rules are not
|
||
caused by the specification, but by the different engines we use to run
|
||
XPath 1.0 and 2.0 queries. Here’s a list of known incompatibilities:</p>
|
||
|
||
<ul>
|
||
<li>The namespace prefixes <code class="language-plaintext highlighter-rouge">fn:</code> and <code class="language-plaintext highlighter-rouge">string:</code> should not be mentioned explicitly.
|
||
In XPath 2.0 mode, the engine will complain about an undeclared namespace, but
|
||
the functions are in the default namespace. Removing the namespace prefixes fixes it.
|
||
<ul>
|
||
<li><code><b style="color:red">fn:</b>substring("Foo", 1)</code> → <code class="language-plaintext highlighter-rouge">substring("Foo", 1)</code></li>
|
||
</ul>
|
||
</li>
|
||
<li>Conversely, calls to custom PMD functions like <code class="language-plaintext highlighter-rouge">typeIs</code> <em>must</em> be prefixed
|
||
with the namespace of the declaring module (<code class="language-plaintext highlighter-rouge">pmd-java</code>).
|
||
<ul>
|
||
<li><code class="language-plaintext highlighter-rouge">typeIs("Foo")</code> → <code><b style="color:green">pmd-java:</b>typeIs("Foo")</code></li>
|
||
</ul>
|
||
</li>
|
||
<li>Boolean attribute values on our 1.0 engine are represented as the string values
|
||
<code class="language-plaintext highlighter-rouge">"true"</code> and <code class="language-plaintext highlighter-rouge">"false"</code>. In 2.0 mode though, boolean values are truly represented
|
||
as boolean values, which in XPath may only be obtained through the functions
|
||
<code class="language-plaintext highlighter-rouge">true()</code> and <code class="language-plaintext highlighter-rouge">false()</code>.
|
||
If your XPath 1.0 rule tests an attribute like <code class="language-plaintext highlighter-rouge">@Private="true"</code>, then it just
|
||
needs to be changed to <code class="language-plaintext highlighter-rouge">@Private=true()</code> when migrating. A type error will warn
|
||
you that you must update the comparison. More is explained on <a href="https://github.com/pmd/pmd/issues/1244">issue #1244</a>.
|
||
<ul>
|
||
<li><code class="language-plaintext highlighter-rouge">"true"</code>, <code class="language-plaintext highlighter-rouge">'true'</code> → <code class="language-plaintext highlighter-rouge">true()</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">"false"</code>, <code class="language-plaintext highlighter-rouge">'false'</code> → <code class="language-plaintext highlighter-rouge">false()</code></li>
|
||
</ul>
|
||
</li>
|
||
<li>In XPath 1.0, comparing a number to a string coerces the string to a number.
|
||
In XPath 2.0, a type error occurs. Like for boolean values, numeric values are
|
||
represented by our 1.0 implementation as strings, meaning that <code class="language-plaintext highlighter-rouge">@BeginLine > "1"</code>
|
||
worked —that’s not the case in 2.0 mode.
|
||
<ul>
|
||
<li><code>@ArgumentCount > <b style="color:red">'</b>1<b style="color:red">'</b></code> → <code class="language-plaintext highlighter-rouge">@ArgumentCount > 1</code></li>
|
||
</ul>
|
||
</li>
|
||
<li>In XPath 1.0, the expression <code class="language-plaintext highlighter-rouge">/Foo</code> matches the <em>children</em> of the root named <code class="language-plaintext highlighter-rouge">Foo</code>.
|
||
In XPath 2.0, that expression matches the root, if it is named <code class="language-plaintext highlighter-rouge">Foo</code>. Consider the following tree:
|
||
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Foo</span>
|
||
<span class="err">└─</span> <span class="nc">Foo</span>
|
||
<span class="err">└─</span> <span class="nc">Foo</span>
|
||
</code></pre></div> </div>
|
||
<p>Then <code class="language-plaintext highlighter-rouge">/Foo</code> will match the root in XPath 2.0, and the other nodes (but not the root) in XPath 1.0.
|
||
See e.g. <a href="https://github.com/pmd/pmd/issues/1919#issuecomment-512865434">an issue caused by this</a> in Apex,
|
||
with nested classes.</p>
|
||
</li>
|
||
<li>The custom function “pmd:matches” which checks a regular expression against a string has been removed,
|
||
since there is a built-in function available since XPath 2.0 which can be used instead. If you use “pmd:matches”
|
||
simply remove the “pmd:” prefix.</li>
|
||
</ul>
|
||
|
||
<h3 id="general-ast-changes-to-avoid-image">General AST Changes to avoid @Image</h3>
|
||
|
||
<p>An abstract syntax tree should be abstract, but in the same time, should not be too abstract. One of the
|
||
base interfaces for PMD’s AST for all languages is <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#"><code>Node</code></a>, which provides
|
||
the methods <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#getImage()"><code>getImage</code></a> and <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ast/Node.html#hasImageEqualTo(java.lang.String)"><code>hasImageEqualTo</code></a>.
|
||
However, these methods don’t necessarily make sense for all nodes in all contexts. That’s why <code class="language-plaintext highlighter-rouge">getImage()</code>
|
||
often returns just <code class="language-plaintext highlighter-rouge">null</code>. Also, the name is not very describing. AST nodes should try to use more specific
|
||
names, such as <code class="language-plaintext highlighter-rouge">getValue()</code> or <code class="language-plaintext highlighter-rouge">getName()</code>.</p>
|
||
|
||
<p>For PMD 7, most languages have been adapted. And when writing XPath rules, you need to replace <code class="language-plaintext highlighter-rouge">@Image</code> with
|
||
whatever is appropriate now (e.g. <code class="language-plaintext highlighter-rouge">@Name</code>). See below for details.</p>
|
||
|
||
<h4 id="apex-and-visualforce">Apex and Visualforce</h4>
|
||
|
||
<p>There are many usages of <code class="language-plaintext highlighter-rouge">@Image</code>. These will be refactored after PMD 7 is released
|
||
by deprecating the attribute and providing alternatives.</p>
|
||
|
||
<p>See also issue <a href="https://github.com/pmd/pmd/issues/4787">Deprecate getImage/@Image #4787</a>.</p>
|
||
|
||
<h4 id="html">Html</h4>
|
||
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-html/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/html/ast/ASTHtmlTextNode.html#"><code>ASTHtmlTextNode</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Text</code>, <code class="language-plaintext highlighter-rouge">@NormalizedText</code> ➡️ <code class="language-plaintext highlighter-rouge">@Text</code>, <code class="language-plaintext highlighter-rouge">@Text</code> ➡️ <code class="language-plaintext highlighter-rouge">@WholeText</code>.</li>
|
||
</ul>
|
||
|
||
<h4 id="java">Java</h4>
|
||
|
||
<p>There are still many usages of <code class="language-plaintext highlighter-rouge">@Image</code> which are not refactored yet. This will be done after PMD 7 is released
|
||
by deprecating the attribute and providing alternatives.</p>
|
||
|
||
<p>See also issue <a href="https://github.com/pmd/pmd/issues/4787">Deprecate getImage/@Image #4787</a>.</p>
|
||
|
||
<p>Some nodes have already the image attribute (and others) deprecated. These deprecated attributes are removed now:</p>
|
||
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTypeDeclaration.html#"><code>ASTAnnotationTypeDeclaration</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@SimpleName</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTAnonymousClassDeclaration.html#"><code>ASTAnonymousClassDeclaration</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@SimpleName</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.html#"><code>ASTClassDeclaration</code></a> (previously “ASTClassOrInterfaceDeclaration”): <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@SimpleName</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTEnumDeclaration.html#"><code>ASTEnumDeclaration</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@SimpleName</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.html#"><code>ASTFieldDeclaration</code></a>: <code class="language-plaintext highlighter-rouge">@VariableName</code> ➡️ <code class="language-plaintext highlighter-rouge">VariableId/@Name</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.html#"><code>ASTMethodDeclaration</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Name</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.html#"><code>ASTMethodDeclaration</code></a>: <code class="language-plaintext highlighter-rouge">@MethodName</code> ➡️ <code class="language-plaintext highlighter-rouge">@Name</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTRecordDeclaration.html#"><code>ASTRecordDeclaration</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@SimpleName</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTVariableId.html#"><code>ASTVariableId</code></a> (previously “ASTVariableDeclaratorId”): <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Name</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTVariableId.html#"><code>ASTVariableId</code></a> (previously “ASTVariableDeclaratorId”): <code class="language-plaintext highlighter-rouge">@VariableName</code> ➡️ <code class="language-plaintext highlighter-rouge">@Name</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTVariableId.html#"><code>ASTVariableId</code></a> (previously “ASTVariableDeclaratorId”): <code class="language-plaintext highlighter-rouge">@Array</code> ➡️ <code class="language-plaintext highlighter-rouge">@ArrayType</code></li>
|
||
</ul>
|
||
|
||
<h4 id="javascript">JavaScript</h4>
|
||
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTAssignment.html#"><code>ASTAssignment</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Operator</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTBigIntLiteral.html#"><code>ASTBigIntLiteral</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTBreakStatement.html#"><code>ASTBreakStatement</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">Name/@Identifier</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTContinueStatement.html#"><code>ASTContinueStatement</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">Name/@Identifier</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTErrorNode.html#"><code>ASTErrorNode</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Message</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTFunctionNode.html#"><code>ASTFunctionNode</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">Name/@Identifier</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTInfixExpression.html#"><code>ASTInfixExpression</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Operator</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTKeywordLiteral.html#"><code>ASTKeywordLiteral</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Literal</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTLabel.html#"><code>ASTLabel</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Name</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTName.html#"><code>ASTName</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Identifier</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTNumberLiteral.html#"><code>ASTNumberLiteral</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTObjectProperty.html#"><code>ASTObjectProperty</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Operator</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTPropertyGet.html#"><code>ASTPropertyGet</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Operator</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTRegExpLiteral.html#"><code>ASTRegExpLiteral</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTStringLiteral.html#"><code>ASTStringLiteral</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTUnaryExpression.html#"><code>ASTUnaryExpression</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Operator</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTUpdateExpression.html#"><code>ASTUpdateExpression</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Operator</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTXmlDotQuery.html#"><code>ASTXmlDotQuery</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Operator</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTXmlMemberGet.html#"><code>ASTXmlMemberGet</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Operator</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTXmlPropRef.html#"><code>ASTXmlPropRef</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">Name[last()]/@Identifier</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-javascript/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/ecmascript/ast/ASTXmlString.html#"><code>ASTXmlString</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Xml</code></li>
|
||
</ul>
|
||
|
||
<h4 id="jsp">JSP</h4>
|
||
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-jsp/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/jsp/ast/ASTAttributeValue.html#"><code>ASTAttributeValue</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-jsp/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/jsp/ast/ASTCData.html#"><code>ASTCData</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Content</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-jsp/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/jsp/ast/ASTCommentTag.html#"><code>ASTCommentTag</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Content</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-jsp/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/jsp/ast/ASTElExpression.html#"><code>ASTElExpression</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Content</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-jsp/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/jsp/ast/ASTHtmlScript.html#"><code>ASTHtmlScript</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Content</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-jsp/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/jsp/ast/ASTJspComment.html#"><code>ASTJspComment</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Content</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-jsp/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/jsp/ast/ASTJspDeclaration.html#"><code>ASTJspDeclaration</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Content</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-jsp/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/jsp/ast/ASTJspExpression.html#"><code>ASTJspExpression</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Content</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-jsp/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/jsp/ast/ASTJspExpressionInAttribute.html#"><code>ASTJspExpressionInAttribute</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Content</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-jsp/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/jsp/ast/ASTJspScriptlet.html#"><code>ASTJspScriptlet</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Content</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-jsp/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/jsp/ast/ASTText.html#"><code>ASTText</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Content</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-jsp/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/jsp/ast/ASTUnparsedText.html#"><code>ASTUnparsedText</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Content</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-jsp/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/jsp/ast/ASTValueBinding.html#"><code>ASTValueBinding</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Content</code></li>
|
||
</ul>
|
||
|
||
<h4 id="modelica">Modelica</h4>
|
||
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTAddOp.html#"><code>ASTAddOp</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Operator</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTDerClassSpecifier.html#"><code>ASTDerClassSpecifier</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@SimpleClassName</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTEnumerationShortClassSpecifier.html#"><code>ASTEnumerationShortClassSpecifier</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@SimpleClassName</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTExtendingLongClassSpecifier.html#"><code>ASTExtendingLongClassSpecifier</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@SimpleClassName</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTFactor.html#"><code>ASTFactor</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Operator</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTLanguageSpecification.html#"><code>ASTLanguageSpecification</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@ExternalLanguage</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTMulOp.html#"><code>ASTMulOp</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Operator</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTName.html#"><code>ASTName</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Name</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTNumberLiteral.html#"><code>ASTNumberLiteral</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTRelOp.html#"><code>ASTRelOp</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Operator</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTSimpleLongClassSpecifier.html#"><code>ASTSimpleLongClassSpecifier</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@SimpleClassName</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTSimpleName.html#"><code>ASTSimpleName</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Name</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTSimpleShortClassSpecifier.html#"><code>ASTSimpleShortClassSpecifier</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@SimpleClassName</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTStoredDefinition.html#"><code>ASTStoredDefinition</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Name</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTStringComment.html#"><code>ASTStringComment</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Comment</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTStringLiteral.html#"><code>ASTStringLiteral</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-modelica/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/modelica/ast/ASTWithinClause.html#"><code>ASTWithinClause</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Name</code></li>
|
||
</ul>
|
||
|
||
<h4 id="plsql">PLSQL</h4>
|
||
|
||
<p>There are many usages of <code class="language-plaintext highlighter-rouge">@Image</code>. These will be refactored after PMD 7 is released
|
||
by deprecating the attribute and providing alternatives.</p>
|
||
|
||
<p>See also issue <a href="https://github.com/pmd/pmd/issues/4787">Deprecate getImage/@Image #4787</a>.</p>
|
||
|
||
<h4 id="scala">Scala</h4>
|
||
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTLitBoolean.html#"><code>ASTLitBoolean</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTLitByte.html#"><code>ASTLitByte</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTLitChar.html#"><code>ASTLitChar</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTLitDouble.html#"><code>ASTLitDouble</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTLitFloat.html#"><code>ASTLitFloat</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTLitInt.html#"><code>ASTLitInt</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTLitLong.html#"><code>ASTLitLong</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTLitNull.html#"><code>ASTLitNull</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTLitShort.html#"><code>ASTLitShort</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTLitString.html#"><code>ASTLitString</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTLitSymbol.html#"><code>ASTLitSymbol</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTLitUnit.html#"><code>ASTLitUnit</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTNameAnonymous.html#"><code>ASTNameAnonymous</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTNameIndeterminate.html#"><code>ASTNameIndeterminate</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTTermName.html#"><code>ASTTermName</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-scala_2.13/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/scala/ast/ASTTypeName.html#"><code>ASTTypeName</code></a>: <code class="language-plaintext highlighter-rouge">@Image</code> ➡️ <code class="language-plaintext highlighter-rouge">@Value</code></li>
|
||
</ul>
|
||
|
||
<h4 id="xml-and-pom">XML (and POM)</h4>
|
||
|
||
<p>When using <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/rule/xpath/XPathRule.html#"><code>XPathRule</code></a>, text of text nodes was exposed as <code class="language-plaintext highlighter-rouge">@Image</code> of
|
||
normal element type nodes. Now the attribute is called <code class="language-plaintext highlighter-rouge">@Text</code>.</p>
|
||
|
||
<p>Note: In general, it is recommended to use <a href="https://docs.pmd-code.org/apidocs/pmd-xml/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/xml/rule/DomXPathRule.html#"><code>DomXPathRule</code></a> instead,
|
||
which exposes text nodes as real XPath/XML text nodes which conforms to the XPath spec.
|
||
There is no difference, text of text nodes can be selected using <code class="language-plaintext highlighter-rouge">text()</code>.</p>
|
||
|
||
<h3 id="java-ast">Java AST</h3>
|
||
|
||
<p>The Java grammar has been refactored substantially in order to make it easier to maintain and more correct
|
||
regarding the Java Language Specification.</p>
|
||
|
||
<p>Here you can see the most important changes as a comparison between the PMD 6 AST (“Old AST”) and
|
||
PMD 7 AST (“New AST”) and with some background info about the changes.</p>
|
||
|
||
<p>When in doubt, it is recommended to use the <a href="pmd_userdocs_extending_designer_reference.html">PMD Designer</a>
|
||
which can also display the AST.</p>
|
||
|
||
<h4 id="renamed-classes--interfaces">Renamed classes / interfaces</h4>
|
||
|
||
<ul>
|
||
<li>AccessNode ➡️ <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ModifierOwner.html#"><code>ModifierOwner</code></a></li>
|
||
<li>ClassOrInterfaceType ➡️ ClassType (<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTClassType.html#"><code>ASTClassType</code></a>)</li>
|
||
<li>ClassOrInterfaceDeclaration ➡️ ClassDeclaration (<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.html#"><code>ASTClassDeclaration</code></a>)</li>
|
||
<li>AnyTypeDeclaration ➡️ TypeDeclaration (<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.html#"><code>ASTTypeDeclaration</code></a>)</li>
|
||
<li>MethodOrConstructorDeclaration ➡️ ExecutableDeclaration (<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTExecutableDeclaration.html#"><code>ASTExecutableDeclaration</code></a>)</li>
|
||
<li>VariableDeclaratorId ➡️ VariableId (<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTVariableId.html#"><code>ASTVariableId</code></a>)</li>
|
||
<li>ClassOrInterfaceBody ➡️ ClassBody (<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTClassBody.html#"><code>ASTClassBody</code></a>)</li>
|
||
</ul>
|
||
|
||
<h4 id="annotations">Annotations</h4>
|
||
|
||
<ul>
|
||
<li>What: Annotations are consolidated into a single node. <code class="language-plaintext highlighter-rouge">SingleMemberAnnotation</code>, <code class="language-plaintext highlighter-rouge">NormalAnnotation</code> and <code class="language-plaintext highlighter-rouge">MarkerAnnotation</code>
|
||
are removed in favour of <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTAnnotation.html#"><code>ASTAnnotation</code></a>. The Name node is removed, replaced by a
|
||
<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTClassType.html#"><code>ASTClassType</code></a>.</li>
|
||
<li>Why: Those different node types implement a syntax-only distinction, that only makes semantically equivalent annotations
|
||
have different possible representations. For example, <code class="language-plaintext highlighter-rouge">@A</code> and <code class="language-plaintext highlighter-rouge">@A()</code> are semantically equivalent, yet they were
|
||
parsed as MarkerAnnotation resp. NormalAnnotation. Similarly, <code class="language-plaintext highlighter-rouge">@A("")</code> and <code class="language-plaintext highlighter-rouge">@A(value="")</code> were parsed as
|
||
SingleMemberAnnotation resp. NormalAnnotation. This also makes parsing much simpler. The nested ClassOrInterface
|
||
type is used to share the disambiguation logic.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/2282">[java] Use single node for annotations (#2282)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Annotation AST Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@A</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@A</span><span class="o">()</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">NormalAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationMemberList</span></code></pre></figure>
|
||
|
||
</td>
|
||
</tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@A</span><span class="o">(</span><span class="n">value</span><span class="o">=</span><span class="s">"v"</span><span class="o">)</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">NormalAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">MemberValuePairs</span>
|
||
<span class="err">└─</span> <span class="nx">MemberValuePair</span> <span class="dl">"</span><span class="s2">value</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">MemberValue</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">'</span><span class="s1">"v"</span><span class="dl">'</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationMemberList</span>
|
||
<span class="err">└─</span> <span class="nx">MemberValuePair</span> <span class="dl">"</span><span class="s2">value</span><span class="dl">"</span> <span class="p">[</span> <span class="p">@</span><span class="nd">Shorthand</span> <span class="o">=</span> <span class="kc">false</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">StringLiteral</span> <span class="dl">'</span><span class="s1">"v"</span><span class="dl">'</span></code></pre></figure>
|
||
|
||
</td>
|
||
</tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@A</span><span class="o">(</span><span class="s">"v"</span><span class="o">)</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">SingleMemberAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">MemberValue</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">'</span><span class="s1">"v"</span><span class="dl">'</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationMemberList</span>
|
||
<span class="err">└─</span> <span class="nx">MemberValuePair</span> <span class="dl">"</span><span class="s2">value</span><span class="dl">"</span> <span class="p">[</span> <span class="p">@</span><span class="nd">Shorthand</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">StringLiteral</span> <span class="dl">'</span><span class="s1">"v"</span><span class="dl">'</span></code></pre></figure>
|
||
|
||
</td>
|
||
</tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@A</span><span class="o">(</span><span class="n">value</span><span class="o">=</span><span class="s">"v"</span><span class="o">,</span> <span class="n">on</span><span class="o">=</span><span class="kc">true</span><span class="o">)</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">NormalAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">MemberValuePairs</span>
|
||
<span class="err">├─</span> <span class="nx">MemberValuePair</span> <span class="dl">"</span><span class="s2">value</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MemberValue</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">'</span><span class="s1">"v"</span><span class="dl">'</span>
|
||
<span class="err">└─</span> <span class="nx">MemberValuePair</span> <span class="dl">"</span><span class="s2">on</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">MemberValue</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span>
|
||
<span class="err">└─</span> <span class="nx">BooleanLiteral</span> <span class="p">[</span> <span class="p">@</span><span class="nd">True</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationMemberList</span>
|
||
<span class="err">├─</span> <span class="nx">MemberValuePair</span> <span class="dl">"</span><span class="s2">value</span><span class="dl">"</span> <span class="p">[</span> <span class="p">@</span><span class="nd">Shorthand</span> <span class="o">=</span> <span class="kc">false</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">StringLiteral</span> <span class="dl">'</span><span class="s1">"v"</span><span class="dl">'</span>
|
||
<span class="err">└─</span> <span class="nx">MemberValuePair</span> <span class="dl">"</span><span class="s2">on</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">BooleanLiteral</span> <span class="p">[</span> <span class="p">@</span><span class="nd">True</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span></code></pre></figure>
|
||
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="annotation-nesting">Annotation nesting</h5>
|
||
|
||
<ul>
|
||
<li>What: <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTAnnotation.html#"><code>ASTAnnotation</code></a>s are now nested within the node, to which they are applied to.
|
||
E.g. if a method is annotated, the Annotation node is now a child of a <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTModifierList.html#"><code>ASTModifierList</code></a>,
|
||
inside the <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.html#"><code>ASTMethodDeclaration</code></a>.</li>
|
||
<li>Why: Fixes a lot of inconsistencies, where sometimes the annotations were inside the node, and sometimes just
|
||
somewhere in the parent, with no real structure.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/1875">[java] Move annotations inside the node they apply to (#1875)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Annotation nesting Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
Method
|
||
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@A</span>
|
||
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">set</span><span class="o">(</span><span class="kt">int</span> <span class="n">x</span><span class="o">)</span> <span class="o">{</span> <span class="o">}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassOrInterfaceBodyDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">MethodDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">ResultType</span><span class="p">[</span> <span class="p">@</span><span class="nd">Void</span> <span class="o">=</span> <span class="kc">true</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="p">...</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">MethodDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">VoidType</span>
|
||
<span class="err">├─</span> <span class="p">...</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
Top-level type declaration
|
||
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@A</span> <span class="kd">class</span> <span class="nc">C</span> <span class="o">{}</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">TypeDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceDeclaration</span> <span class="dl">"</span><span class="s2">C</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceBody</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassBody</span></code></pre></figure>
|
||
|
||
</td>
|
||
</tr>
|
||
|
||
<tr><td>
|
||
Cast expression
|
||
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kt">var</span> <span class="n">x</span> <span class="o">=</span> <span class="o">(</span><span class="nd">@A</span> <span class="no">T</span><span class="o">.</span><span class="nd">@B</span> <span class="no">S</span><span class="o">)</span> <span class="n">expr</span><span class="o">;</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">CastExpression</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">T.S</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">expr</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">CastExpression</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">S</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">T</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">expr</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
Cast expression with intersection
|
||
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kt">var</span> <span class="n">x</span> <span class="o">=</span> <span class="o">(</span><span class="nd">@A</span> <span class="no">T</span> <span class="o">&</span> <span class="no">S</span><span class="o">)</span> <span class="n">expr</span><span class="o">;</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">CastExpression</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">T</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">S</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">expr</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">CastExpression</span>
|
||
<span class="err">├─</span> <span class="nx">IntersectionType</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">T</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">S</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">expr</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
|
||
Notice <code>@A</code> binds to <code>T</code>, not <code>T & S</code>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
Constructor call
|
||
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="k">new</span> <span class="nd">@A</span> <span class="no">T</span><span class="o">()</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">AllocationExpression</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">T</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Arguments</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ConstructorCall</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">T</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArgumentList</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
Array allocation
|
||
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="k">new</span> <span class="nd">@A</span> <span class="kt">int</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">AllocationExpression</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimsAndInits</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">0</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ArrayAllocation</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayType</span>
|
||
<span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimensions</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimExpr</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">0</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
Array type
|
||
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@A</span> <span class="kt">int</span> <span class="nd">@B</span><span class="o">[]</span> <span class="n">x</span><span class="o">;</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">LocalVariableDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">Type</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayType</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclarator</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">x</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">LocalVariableDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ArrayType</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArrayDimensions</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArrayTypeDim</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclarator</span>
|
||
<span class="err">└─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">x</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
Type parameters
|
||
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="o"><</span><span class="nd">@A</span> <span class="no">T</span><span class="o">,</span> <span class="nd">@B</span> <span class="no">S</span> <span class="kd">extends</span> <span class="nd">@C</span> <span class="nc">Object</span><span class="o">></span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">TypeParameters</span>
|
||
<span class="err">├─</span> <span class="nx">TypeParameter</span> <span class="dl">"</span><span class="s2">T</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeParameter</span> <span class="dl">"</span><span class="s2">S</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeBound</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">C</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">C</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">C</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">Object</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">TypeParameters</span>
|
||
<span class="err">├─</span> <span class="nx">TypeParameter</span> <span class="dl">"</span><span class="s2">T</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeParameter</span> <span class="dl">"</span><span class="s2">S</span><span class="dl">"</span> <span class="p">[</span> <span class="p">@</span><span class="nd">TypeBound</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Object</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">C</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">C</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
|
||
<ul>
|
||
<li>TypeParameter<em>s</em> now only can have TypeParameter as a child</li>
|
||
<li>Annotations that apply to the param are <em>in</em> the param</li>
|
||
<li>Annotations that apply to the bound are <em>in</em> the type</li>
|
||
<li>This removes the need for TypeBound, because annotations are cleanly placed.</li>
|
||
</ul>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
Enum constants
|
||
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">enum</span> <span class="no">E</span> <span class="o">{</span>
|
||
<span class="nd">@A</span> <span class="no">E1</span><span class="o">,</span> <span class="nd">@B</span> <span class="no">E2</span><span class="o">;</span>
|
||
<span class="o">}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">EnumBody</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">EnumConstant</span> <span class="dl">"</span><span class="s2">E1</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">EnumConstant</span> <span class="dl">"</span><span class="s2">E2</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">EnumBody</span>
|
||
<span class="err">├─</span> <span class="nx">EnumConstant</span> <span class="dl">"</span><span class="s2">E1</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">E1</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">EnumConstant</span> <span class="dl">"</span><span class="s2">E2</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">B</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">E2</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
|
||
<ul>
|
||
<li>Annotations are not just randomly in the enum body anymore</li>
|
||
</ul>
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h4 id="types">Types</h4>
|
||
|
||
<h5 id="type-and-referencetype">Type and ReferenceType</h5>
|
||
|
||
<ul>
|
||
<li>What:
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTType.html#"><code>ASTType</code></a> and <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTReferenceType.html#"><code>ASTReferenceType</code></a> have been turned into
|
||
interfaces, implemented by <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTPrimitiveType.html#"><code>ASTPrimitiveType</code></a>, <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTClassType.html#"><code>ASTClassType</code></a>,
|
||
and the new node <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTArrayType.html#"><code>ASTArrayType</code></a>. This reduces the depth of the relevant
|
||
subtrees, and allows to explore them more easily and consistently.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Why:
|
||
<ul>
|
||
<li>some syntactic contexts only allow reference types, other allow any kind of type. If you want to match all types
|
||
of a program, then matching Type would be the intuitive solution. But in 6.0.x, it wouldn’t have sufficed,
|
||
since in some contexts, no Type node was pushed, only a ReferenceType</li>
|
||
<li>Regardless of the original syntactic context, any reference type <em>is</em> a type, and searching for ASTType should
|
||
yield all the types in the tree.</li>
|
||
<li>Using interfaces allows to abstract behaviour and make a nicer and safer API.</li>
|
||
</ul>
|
||
</li>
|
||
<li><strong>Migrating</strong>
|
||
<ul>
|
||
<li>There is currently no way to match abstract types (or interfaces) with XPath, so <code class="language-plaintext highlighter-rouge">Type</code>
|
||
and <code class="language-plaintext highlighter-rouge">ReferenceType</code> name tests won’t match anything anymore.</li>
|
||
<li><code class="language-plaintext highlighter-rouge">Type/ReferenceType/ClassOrInterfaceType</code> ➡️ <code class="language-plaintext highlighter-rouge">ClassType</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">Type/PrimitiveType</code> ➡️ <code class="language-plaintext highlighter-rouge">PrimitiveType</code>.</li>
|
||
<li><code class="language-plaintext highlighter-rouge">Type/ReferenceType[@ArrayDepth > 1]/ClassOrInterfaceType</code> ➡️ <code class="language-plaintext highlighter-rouge">ArrayType/ClassType</code>.</li>
|
||
<li><code class="language-plaintext highlighter-rouge">Type/ReferenceType/PrimitiveType</code> ➡️ <code class="language-plaintext highlighter-rouge">ArrayType/PrimitiveType</code>.</li>
|
||
<li>Note that in most cases you should check the type of a variable with e.g.
|
||
<code class="language-plaintext highlighter-rouge">VariableId[pmd-java:typeIs("java.lang.String[]")]</code> because it
|
||
considers the additional dimensions on declarations like <code class="language-plaintext highlighter-rouge">String foo[];</code>.
|
||
The Java equivalent is <code class="language-plaintext highlighter-rouge">TypeHelper.isA(id, String[].class);</code></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Type and ReferenceType Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="c1">// in the context of a variable declaration</span>
|
||
<span class="nc">List</span><span class="o"><</span><span class="nc">String</span><span class="o">></span> <span class="n">strs</span><span class="o">;</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Type</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">List</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArguments</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArgument</span>
|
||
<span class="err">└─</span> <span class="nx">ReferenceType</span> <span class="p">(</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">String</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
|
||
<ol>
|
||
<li>Notice that there is a Type node here, since a local var can have a primitive type.</li>
|
||
<li>In contrast, notice that there is no Type here, since only reference types are allowed as type arguments.</li>
|
||
</ol>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">List</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArguments</span>
|
||
<span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">String</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
|
||
<ul>
|
||
<li>ClassType implements ASTReferenceType, which implements ASTType.</li>
|
||
</ul>
|
||
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="array-changes">Array changes</h5>
|
||
|
||
<ul>
|
||
<li>What: Additional nodes <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTArrayType.html#"><code>ASTArrayType</code></a>, <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTArrayTypeDim.html#"><code>ASTArrayTypeDim</code></a>,
|
||
<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTArrayDimensions.html#"><code>ASTArrayDimensions</code></a>, <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTArrayAllocation.html#"><code>ASTArrayAllocation</code></a>.</li>
|
||
<li>Why: Support annotated array types (<a href="https://github.com/pmd/pmd/issues/997">[java] Java8 parsing corner case with annotated array types (#997)</a>)</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/1981">[java] Simplify array allocation expressions (#1981)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Array Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">String</span><span class="o">[][]</span> <span class="n">myArray</span><span class="o">;</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Type</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayType</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span><span class="p">[</span> <span class="p">@</span><span class="nd">Array</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">][</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">String</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ArrayType</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">String</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimensions</span><span class="p">[</span> <span class="p">@</span><span class="nd">Size</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ArrayTypeDim</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayTypeDim</span></code></pre></figure>
|
||
|
||
</td>
|
||
</tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">String</span> <span class="nd">@Annotation1</span><span class="o">[]</span> <span class="nd">@Annotation2</span><span class="o">[]</span> <span class="n">myArray</span><span class="o">;</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Type</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayType</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">├─</span> <span class="nx">ClassOrInterfaceType</span><span class="p">[</span> <span class="p">@</span><span class="nd">Array</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">][</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">String</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">Annotation1</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">Annotation1</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">Annotation1</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">Annotation2</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">Annotation2</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">Annotation2</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ArrayType</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">String</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimensions</span><span class="p">[</span> <span class="p">@</span><span class="nd">Size</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ArrayTypeDim</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">Annotation1</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Annotation1</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayTypeDim</span>
|
||
<span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">Annotation2</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Annotation2</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="k">new</span> <span class="kt">int</span><span class="o">[</span><span class="mi">2</span><span class="o">][];</span>
|
||
<span class="k">new</span> <span class="nd">@Bar</span> <span class="kt">int</span><span class="o">[</span><span class="mi">3</span><span class="o">][</span><span class="mi">2</span><span class="o">];</span>
|
||
<span class="k">new</span> <span class="nc">Foo</span><span class="o">[]</span> <span class="o">{</span> <span class="n">f</span><span class="o">,</span> <span class="n">g</span> <span class="o">};</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">AllocationExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimsAndInits</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">2</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">AllocationExpression</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">Bar</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">Bar</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">Bar</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimsAndInits</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">Expression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">3</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">2</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">AllocationExpression</span>
|
||
<span class="err">├─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimsAndInits</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">1</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayInitializer</span>
|
||
<span class="err">├─</span> <span class="nx">VariableInitializer</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">f</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableInitializer</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">g</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ArrayAllocation</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayType</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimensions</span><span class="p">[</span> <span class="p">@</span><span class="nd">Size</span> <span class="o">=</span> <span class="mi">2</span><span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ArrayDimExpr</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">2</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayTypeDim</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ArrayAllocation</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayType</span><span class="p">[</span> <span class="p">@</span><span class="nd">Array</span> <span class="nx">Depth</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">Bar</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Bar</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimensions</span><span class="p">[</span> <span class="p">@</span><span class="nd">Size</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ArrayDimExpr</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">3</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimExpr</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">2</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ArrayAllocation</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">1</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayType</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">1</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArrayDimensions</span><span class="p">[</span> <span class="p">@</span><span class="nd">Size</span> <span class="o">=</span> <span class="mi">1</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArrayTypeDim</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayInitializer</span><span class="p">[</span> <span class="p">@</span><span class="nd">Length</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">f</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">g</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="classtype-nesting">ClassType nesting</h5>
|
||
|
||
<ul>
|
||
<li>What: <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTClassType.html#"><code>ASTClassType</code></a> (formerly ASTClassOrInterfaceType) appears to be left recursive now,
|
||
and encloses its qualifying type.</li>
|
||
<li>Why: To preserve the position of annotations and type arguments</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/issues/1150">[java] ClassOrInterfaceType AST improvements (#1150)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>ClassType Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">Map</span><span class="o">.</span><span class="na">Entry</span><span class="o"><</span><span class="no">K</span><span class="o">,</span><span class="no">V</span><span class="o">></span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">Map.Entry</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArguments</span>
|
||
<span class="err">├─</span> <span class="nx">TypeArgument</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">K</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArgument</span>
|
||
<span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">V</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Entry</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Map</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArguments</span><span class="p">[</span> <span class="p">@</span><span class="nd">Size</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">K</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">V</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
</tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">First</span><span class="o"><</span><span class="no">K</span><span class="o">>.</span><span class="na">Second</span><span class="o">.</span><span class="na">Third</span><span class="o"><</span><span class="no">V</span><span class="o">></span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">First.Second.Third</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">TypeArguments</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">TypeArgument</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">K</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArguments</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArgument</span>
|
||
<span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">V</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Third</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Second</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">First</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">TypeArguments</span><span class="p">[</span> <span class="p">@</span><span class="nd">Size</span> <span class="o">=</span> <span class="mi">1</span><span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">K</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArguments</span><span class="p">[</span> <span class="p">@</span><span class="nd">Size</span> <span class="o">=</span> <span class="mi">1</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">V</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="typeargument-and-wildcardtype">TypeArgument and WildcardType</h5>
|
||
|
||
<ul>
|
||
<li>What:
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.2.0/net/sourceforge/pmd/lang/java/ast/ASTTypeArgument.html#"><code>ASTTypeArgument</code></a> is removed. Instead, the <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTTypeArguments.html#"><code>ASTTypeArguments</code></a> node contains directly
|
||
a sequence of <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTType.html#"><code>ASTType</code></a> nodes. To support this, the new node type <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTWildcardType.html#"><code>ASTWildcardType</code></a>
|
||
captures the syntax previously parsed as a TypeArgument.</li>
|
||
<li>The <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.2.0/net/sourceforge/pmd/lang/java/ast/ASTWildcardBounds.html#"><code>ASTWildcardBounds</code></a> node is removed. Instead, the bound is a direct child of the WildcardType.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Why: Because wildcard types are types in their own right, and having a node to represent them skims several levels
|
||
of nesting off.</li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>TypeArgument and WildcardType Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">Entry</span><span class="o"><</span><span class="nc">String</span><span class="o">,</span> <span class="o">?</span> <span class="kd">extends</span> <span class="nc">Node</span><span class="o">></span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">Entry</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArguments</span>
|
||
<span class="err">├─</span> <span class="nx">TypeArgument</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">String</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArgument</span><span class="p">[</span> <span class="p">@</span><span class="nd">Wildcard</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">WildcardBounds</span><span class="p">[</span> <span class="p">@</span><span class="nd">UpperBound</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">Node</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Entry</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArguments</span><span class="p">[</span> <span class="p">@</span><span class="nd">Size</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">String</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">WildcardType</span><span class="p">[</span> <span class="p">@</span><span class="nd">UpperBound</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Node</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
</tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">List</span><span class="o"><?></span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">List</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArguments</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArgument</span><span class="p">[</span> <span class="p">@</span><span class="nd">Wildcard</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">List</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeArguments</span><span class="p">[</span> <span class="p">@</span><span class="nd">Size</span> <span class="o">=</span> <span class="mi">1</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">WildcardType</span><span class="p">[</span> <span class="p">@</span><span class="nd">UpperBound</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span></code></pre></figure>
|
||
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h4 id="declarations">Declarations</h4>
|
||
|
||
<h5 id="import-and-package-declarations">Import and Package declarations</h5>
|
||
|
||
<ul>
|
||
<li>What: Remove the Name node in imports and package declaration nodes.</li>
|
||
<li>Why: Name is a TypeNode, but it’s equivalent to <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTAmbiguousName.html#"><code>ASTAmbiguousName</code></a> in that it describes nothing
|
||
about what it represents. The name in an import may represent a method name, a type name, a field name…
|
||
It’s too ambiguous to treat in the parser and could just be the image of the import, or package, or module.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/1888">[java] Remove Name nodes in Import- and PackageDeclaration (#1888)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Import and Package declarations Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">import</span> <span class="nn">java.util.ArrayList</span><span class="o">;</span>
|
||
<span class="kn">import</span> <span class="nn">static</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">Comparator</span><span class="o">.</span><span class="na">reverseOrder</span><span class="o">;</span>
|
||
<span class="kn">import</span> <span class="nn">java.util.*</span><span class="o">;</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">├─</span> <span class="nx">ImportDeclaration</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">java.util.ArrayList</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ImportDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">Static</span><span class="o">=</span><span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">java.util.Comparator.reverseOrder</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ImportDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">ImportOnDemand</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">java.util</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">├─</span> <span class="nx">ImportDeclaration</span> <span class="dl">"</span><span class="s2">java.util.ArrayList</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ImportDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">Static</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">java.util.Comparator.reverseOrder</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ImportDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">ImportOnDemand</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">java.util</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">com.example.tool</span><span class="o">;</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">PackageDeclaration</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">com.example.tool</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">PackageDeclaration</span> <span class="dl">"</span><span class="s2">com.example.tool</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ModifierList</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="modifier-lists">Modifier lists</h5>
|
||
|
||
<ul>
|
||
<li>What: <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ModifierOwner.html#"><code>ModifierOwner</code></a> (formerly AccessNode) is now based on a node: <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTModifierList.html#"><code>ASTModifierList</code></a>.
|
||
That node represents
|
||
modifiers occurring before a declaration. It provides a flexible API to query modifiers, both explicit and
|
||
implicit. All declaration nodes now have such a modifier list, even if it’s implicit (no explicit modifiers).</li>
|
||
<li>Why: ModifierOwner (formerly AccessNode) gave a lot of irrelevant methods to its subtypes.
|
||
E.g. <code class="language-plaintext highlighter-rouge">ASTFieldDeclaration::isSynchronized</code>
|
||
makes no sense. Now, these irrelevant methods don’t clutter the API. The API of ModifierList is both more
|
||
general and flexible.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/2259">[java] Rework AccessNode (#2259)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Modifier lists Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
Method
|
||
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@A</span>
|
||
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">set</span><span class="o">(</span><span class="kd">final</span> <span class="kt">int</span> <span class="n">x</span><span class="o">,</span> <span class="kt">int</span> <span class="n">y</span><span class="o">)</span> <span class="o">{</span> <span class="o">}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassOrInterfaceBodyDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">MethodDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">Public</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">set</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ResultType</span><span class="p">[</span> <span class="p">@</span><span class="nd">Void</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">MethodDeclarator</span>
|
||
<span class="err">└─</span> <span class="nx">FormalParameters</span><span class="p">[</span> <span class="p">@</span><span class="nd">Size</span> <span class="o">=</span> <span class="mi">2</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">FormalParameter</span><span class="p">[</span> <span class="p">@</span><span class="nd">Final</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">x</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">FormalParameter</span><span class="p">[</span> <span class="p">@</span><span class="nd">Final</span> <span class="o">=</span> <span class="kc">false</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">y</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">MethodDeclaration</span><span class="p">[</span> <span class="nx">pmd</span><span class="o">-</span><span class="nx">java</span><span class="p">:</span><span class="nx">modifiers</span><span class="p">()</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">public</span><span class="dl">'</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">set</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">VoidType</span>
|
||
<span class="err">└─</span> <span class="nx">FormalParameters</span>
|
||
<span class="err">├─</span> <span class="nx">FormalParameter</span><span class="p">[</span> <span class="nx">pmd</span><span class="o">-</span><span class="nx">java</span><span class="p">:</span><span class="nx">modifiers</span><span class="p">()</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">final</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">x</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">FormalParameter</span><span class="p">[</span> <span class="nx">pmd</span><span class="o">-</span><span class="nx">java</span><span class="p">:</span><span class="nx">modifiers</span><span class="p">()</span> <span class="o">=</span> <span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">└─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">y</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
Top-level type declaration
|
||
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="nd">@A</span> <span class="kd">class</span> <span class="nc">C</span> <span class="o">{}</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">TypeDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">Public</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">C</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceBody</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassDeclaration</span><span class="p">[</span> <span class="nx">pmd</span><span class="o">-</span><span class="nx">java</span><span class="p">:</span><span class="nx">modifiers</span><span class="p">()</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">public</span><span class="dl">'</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">C</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassBody</span></code></pre></figure>
|
||
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="flattened-body-declarations">Flattened body declarations</h5>
|
||
|
||
<ul>
|
||
<li>What: Removes <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.2.0/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceBodyDeclaration.html#"><code>ASTClassOrInterfaceBodyDeclaration</code></a>, <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.2.0/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.html#"><code>ASTTypeDeclaration</code></a>,
|
||
and <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.2.0/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTypeMemberDeclaration.html#"><code>ASTAnnotationTypeMemberDeclaration</code></a>.
|
||
These were unnecessary since annotations are nested (see above <a href="#annotation-nesting">Annotation nesting</a>).</li>
|
||
<li>Why: This flattens the tree, makes it less verbose and simpler.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/2300">[java] Flatten body declarations (#2300)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Flattened body declarations Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Flat</span> <span class="o">{</span>
|
||
<span class="kd">private</span> <span class="kt">int</span> <span class="n">f</span><span class="o">;</span>
|
||
<span class="o">}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">CompilationUnit</span>
|
||
<span class="err">└─</span> <span class="nx">TypeDeclaration</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceDeclaration</span> <span class="dl">"</span><span class="s2">Flat</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceBody</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceBodyDeclaration</span>
|
||
<span class="err">└─</span> <span class="nx">FieldDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclarator</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">f</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">CompilationUnit</span>
|
||
<span class="err">└─</span> <span class="nx">ClassDeclaration</span> <span class="dl">"</span><span class="s2">Flat</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">└─</span> <span class="nx">ClassBody</span>
|
||
<span class="err">└─</span> <span class="nx">FieldDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclarator</span>
|
||
<span class="err">└─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">f</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="nd">@interface</span> <span class="nc">FlatAnnotation</span> <span class="o">{</span>
|
||
<span class="nc">String</span> <span class="nf">value</span><span class="o">()</span> <span class="k">default</span> <span class="s">""</span><span class="o">;</span>
|
||
<span class="o">}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">CompilationUnit</span>
|
||
<span class="err">└─</span> <span class="nx">TypeDeclaration</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationTypeDeclaration</span> <span class="dl">"</span><span class="s2">FlatAnnotation</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationTypeBody</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationTypeMemberDeclaration</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationMethodDeclaration</span> <span class="dl">"</span><span class="s2">value</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">String</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">DefaultValue</span>
|
||
<span class="err">└─</span> <span class="nx">MemberValue</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="se">\"\"</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">CompilationUnit</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationTypeDeclaration</span> <span class="dl">"</span><span class="s2">FlatAnnotation</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationTypeBody</span>
|
||
<span class="err">└─</span> <span class="nx">MethodDeclaration</span> <span class="dl">"</span><span class="s2">value</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">String</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">FormalParameters</span>
|
||
<span class="err">└─</span> <span class="nx">DefaultValue</span>
|
||
<span class="err">└─</span> <span class="nx">StringLiteral</span> <span class="dl">"</span><span class="se">\"\"</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="module-declarations">Module declarations</h5>
|
||
|
||
<ul>
|
||
<li>What: Removes the generic Name node and uses instead <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTClassType.html#"><code>ASTClassType</code></a> where appropriate. Also
|
||
uses specific node types for different directives (requires, exports, uses, provides).</li>
|
||
<li>Why: Simplify queries, support type resolution</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/3890">[java] Improve module grammar (#3890)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Module declarations Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="n">open</span> <span class="n">module</span> <span class="n">com</span><span class="o">.</span><span class="na">example</span><span class="o">.</span><span class="na">foo</span> <span class="o">{</span>
|
||
<span class="n">requires</span> <span class="n">com</span><span class="o">.</span><span class="na">example</span><span class="o">.</span><span class="na">foo</span><span class="o">.</span><span class="na">http</span><span class="o">;</span>
|
||
<span class="n">requires</span> <span class="n">java</span><span class="o">.</span><span class="na">logging</span><span class="o">;</span>
|
||
<span class="n">requires</span> <span class="n">transitive</span> <span class="n">com</span><span class="o">.</span><span class="na">example</span><span class="o">.</span><span class="na">foo</span><span class="o">.</span><span class="na">network</span><span class="o">;</span>
|
||
|
||
<span class="n">exports</span> <span class="n">com</span><span class="o">.</span><span class="na">example</span><span class="o">.</span><span class="na">foo</span><span class="o">.</span><span class="na">bar</span><span class="o">;</span>
|
||
<span class="n">exports</span> <span class="n">com</span><span class="o">.</span><span class="na">example</span><span class="o">.</span><span class="na">foo</span><span class="o">.</span><span class="na">internal</span> <span class="n">to</span> <span class="n">com</span><span class="o">.</span><span class="na">example</span><span class="o">.</span><span class="na">foo</span><span class="o">.</span><span class="na">probe</span><span class="o">;</span>
|
||
|
||
<span class="n">uses</span> <span class="n">com</span><span class="o">.</span><span class="na">example</span><span class="o">.</span><span class="na">foo</span><span class="o">.</span><span class="na">spi</span><span class="o">.</span><span class="na">Intf</span><span class="o">;</span>
|
||
|
||
<span class="n">provides</span> <span class="n">com</span><span class="o">.</span><span class="na">example</span><span class="o">.</span><span class="na">foo</span><span class="o">.</span><span class="na">spi</span><span class="o">.</span><span class="na">Intf</span> <span class="n">with</span> <span class="n">com</span><span class="o">.</span><span class="na">example</span><span class="o">.</span><span class="na">foo</span><span class="o">.</span><span class="na">Impl</span><span class="o">;</span>
|
||
<span class="o">}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">CompilationUnit</span>
|
||
<span class="err">└─</span> <span class="nx">ModuleDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo</span><span class="dl">'</span> <span class="p">][</span> <span class="p">@</span><span class="nd">Open</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModuleDirective</span><span class="p">[</span> <span class="p">@</span><span class="nd">Type</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">REQUIRES</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ModuleName</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo.http</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModuleDirective</span><span class="p">[</span> <span class="p">@</span><span class="nd">Type</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">REQUIRES</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ModuleName</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">java.logging</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModuleDirective</span><span class="p">[</span> <span class="p">@</span><span class="nd">Type</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">REQUIRES</span><span class="dl">'</span> <span class="p">][</span> <span class="p">@</span><span class="nd">RequiresModifier</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">TRANSITIVE</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ModuleName</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo.network</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModuleDirective</span><span class="p">[</span> <span class="p">@</span><span class="nd">Type</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">EXPORTS</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo.bar</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModuleDirective</span><span class="p">[</span> <span class="p">@</span><span class="nd">Type</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">EXPORTS</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Name</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo.internal</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ModuleName</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo.probe</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModuleDirective</span><span class="p">[</span> <span class="p">@</span><span class="nd">Type</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">USES</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo.spi.Intf</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ModuleDirective</span><span class="p">[</span> <span class="p">@</span><span class="nd">Type</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">PROVIDES</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">Name</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo.spi.Intf</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo.Impl</span><span class="dl">'</span> <span class="p">]</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">CompilationUnit</span>
|
||
<span class="err">└─</span> <span class="nx">ModuleDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo</span><span class="dl">'</span> <span class="p">][</span> <span class="p">@</span><span class="nd">Open</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModuleName</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModuleRequiresDirective</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ModuleName</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo.http</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModuleRequiresDirective</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ModuleName</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">java.logging</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModuleRequiresDirective</span><span class="p">[</span> <span class="p">@</span><span class="nd">Transitive</span> <span class="o">=</span> <span class="kc">true</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ModuleName</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo.network</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModuleExportsDirective</span><span class="p">[</span> <span class="p">@</span><span class="nd">PackageName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo.bar</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModuleExportsDirective</span><span class="p">[</span> <span class="p">@</span><span class="nd">PackageName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo.internal</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ModuleName</span> <span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">com.example.foo.probe</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModuleUsesDirective</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span><span class="p">[</span> <span class="nx">pmd</span><span class="o">-</span><span class="nx">java</span><span class="p">:</span><span class="nx">typeIs</span><span class="p">(</span><span class="dl">"</span><span class="s2">com.example.foo.spi.Intf</span><span class="dl">"</span><span class="p">)</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ModuleProvidesDirective</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span><span class="p">[</span> <span class="nx">pmd</span><span class="o">-</span><span class="nx">java</span><span class="p">:</span><span class="nx">typeIs</span><span class="p">(</span><span class="dl">"</span><span class="s2">com.example.foo.spi.Intf</span><span class="dl">"</span><span class="p">)</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ClassType</span><span class="p">[</span> <span class="nx">pmd</span><span class="o">-</span><span class="nx">java</span><span class="p">:</span><span class="nx">typeIs</span><span class="p">(</span><span class="dl">"</span><span class="s2">com.example.foo.Impl</span><span class="dl">"</span><span class="p">)</span> <span class="p">]</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="anonymous-class-declarations">Anonymous class declarations</h5>
|
||
|
||
<ul>
|
||
<li>What: A separate node type <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTAnonymousClassDeclaration.html#"><code>ASTAnonymousClassDeclaration</code></a> is introduced for anonymous classes.</li>
|
||
<li>Why: Unify the AST for type declarations including anonymous class declaration in constructor calls
|
||
and enums.</li>
|
||
<li>Related issues:
|
||
<ul>
|
||
<li><a href="https://github.com/pmd/pmd/issues/905">[java] Add new node for anonymous class declaration (#905)</a></li>
|
||
<li><a href="https://github.com/pmd/pmd/pull/1759">[java] New expression and type grammar (#1759)</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Anonymous class declarations Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">Object</span> <span class="n">anonymous</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Object</span><span class="o">()</span> <span class="o">{</span> <span class="o">};</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">LocalVariableDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Object</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclarator</span>
|
||
<span class="err">├─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">anonymous</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableInitializer</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">AllocationExpression</span>
|
||
<span class="err">├─</span> <span class="nx">ClassOrInterfaceType</span><span class="p">[</span> <span class="p">@</span><span class="nd">AnonymousClass</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">][</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Object</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">Arguments</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceBody</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">LocalVariableDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Object</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclarator</span>
|
||
<span class="err">├─</span> <span class="nx">VariableId</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">anonymous</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ConstructorCall</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Object</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ArgumentList</span>
|
||
<span class="err">└─</span> <span class="nx">AnonymousClassDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">└─</span> <span class="nx">ClassBody</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h4 id="method-and-constructor-declarations">Method and Constructor declarations</h4>
|
||
|
||
<h5 id="method-grammar-simplification">Method grammar simplification</h5>
|
||
|
||
<ul>
|
||
<li>What: Simplify and align the grammar used for method and constructor declarations. The methods in an annotation
|
||
type are now also method declarations.</li>
|
||
<li>Why: The method declaration had a nested node “MethodDeclarator”, which was not available for constructor
|
||
declarations. This made it difficult to write rules, that concern both methods and constructors without
|
||
explicitly differentiate between these two.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/2034">[java] Align method and constructor declaration grammar (#2034)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Method grammar Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Sample</span> <span class="o">{</span>
|
||
<span class="kd">public</span> <span class="nf">Sample</span><span class="o">(</span><span class="kt">int</span> <span class="n">arg</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
|
||
<span class="kd">super</span><span class="o">();</span>
|
||
<span class="n">greet</span><span class="o">(</span><span class="n">arg</span><span class="o">);</span>
|
||
<span class="o">}</span>
|
||
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">greet</span><span class="o">(</span><span class="kt">int</span> <span class="n">arg</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
|
||
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Hello"</span><span class="o">);</span>
|
||
<span class="o">}</span>
|
||
<span class="o">}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassOrInterfaceBody</span>
|
||
<span class="err">├─</span> <span class="nx">ClassOrInterfaceBodyDeclaration</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ConstructorDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Sample</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">FormalParameters</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">FormalParameter</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">├─</span> <span class="p">...</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">NameList</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Exception</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ExplicitConstructorInvocation</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Arguments</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="p">...</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceBodyDeclaration</span>
|
||
<span class="err">└─</span> <span class="nx">MethodDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">greet</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ResultType</span>
|
||
<span class="err">├─</span> <span class="nx">MethodDeclarator</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">greet</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">FormalParameters</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">FormalParameter</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="p">...</span>
|
||
<span class="err">├─</span> <span class="nx">NameList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Exception</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span>
|
||
<span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="p">...</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ClassBody</span>
|
||
<span class="err">├─</span> <span class="nx">ConstructorDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Sample</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">FormalParameters</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">FormalParameter</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">├─</span> <span class="p">...</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ThrowsList</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Exception</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Block</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ExplicitConstructorInvocation</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ArgumentList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="p">...</span>
|
||
<span class="err">└─</span> <span class="nx">MethodDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">greet</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">├─</span> <span class="nx">VoidType</span>
|
||
<span class="err">├─</span> <span class="nx">FormalParameters</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">FormalParameter</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="p">...</span>
|
||
<span class="err">├─</span> <span class="nx">ThrowsList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Exception</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span>
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="p">...</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="nd">@interface</span> <span class="nc">MyAnnotation</span> <span class="o">{</span>
|
||
<span class="kt">int</span> <span class="nf">value</span><span class="o">()</span> <span class="k">default</span> <span class="mi">1</span><span class="o">;</span>
|
||
<span class="o">}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">AnnotationTypeDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">MyAnnotation</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationTypeBody</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationTypeMemberDeclaration</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationMethodDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">value</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">Type</span> <span class="p">...</span>
|
||
<span class="err">└─</span> <span class="nx">DefaultValue</span> <span class="p">...</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">AnnotationTypeDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">MyAnnotation</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">└─</span> <span class="nx">AnnotationTypeBody</span>
|
||
<span class="err">└─</span> <span class="nx">MethodDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">value</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">├─</span> <span class="nx">PrimitiveType</span>
|
||
<span class="err">├─</span> <span class="nx">FormalParameters</span>
|
||
<span class="err">└─</span> <span class="nx">DefaultValue</span> <span class="p">...</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="formal-parameters">Formal parameters</h5>
|
||
|
||
<ul>
|
||
<li>What: Use <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTFormalParameter.html#"><code>ASTFormalParameter</code></a> only for method and constructor declaration. Lambdas use
|
||
<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTLambdaParameter.html#"><code>ASTLambdaParameter</code></a>, catch clauses use <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTCatchParameter.html#"><code>ASTCatchParameter</code></a>.</li>
|
||
<li>Why: FormalParameter’s API is different from the other ones.
|
||
<ul>
|
||
<li>FormalParameter must mention a type node.</li>
|
||
<li>LambdaParameter can be inferred</li>
|
||
<li>CatchParameter cannot be varargs</li>
|
||
<li>CatchParameter can have multiple exception types (a <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTUnionType.html#"><code>ASTUnionType</code></a> now)</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Formal parameters Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="k">try</span> <span class="o">{</span>
|
||
|
||
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nd">@A</span> <span class="nc">IOException</span> <span class="o">|</span> <span class="nc">IllegalArgumentException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
|
||
|
||
<span class="o">}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">TryStatement</span>
|
||
<span class="err">├─</span> <span class="nx">Block</span>
|
||
<span class="err">└─</span> <span class="nx">CatchStatement</span>
|
||
<span class="err">├─</span> <span class="nx">FormalParameter</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Annotation</span><span class="p">[</span> <span class="p">@</span><span class="nd">AnnotationName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span><span class="p">[</span> <span class="p">@</span><span class="nd">AnnotationName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">IOException</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">IllegalArgumentException</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableDeclaratorId</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">e</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">TryStatement</span>
|
||
<span class="err">├─</span> <span class="nx">Block</span>
|
||
<span class="err">└─</span> <span class="nx">CatchClause</span>
|
||
<span class="err">├─</span> <span class="nx">CatchParameter</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">UnionType</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">├─</span> <span class="nx">ClassType</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">IOException</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">IllegalArgumentException</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableId</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">e</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="o">(</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">)</span> <span class="o">-></span> <span class="o">{};</span>
|
||
<span class="n">c</span> <span class="o">-></span> <span class="o">{};</span>
|
||
<span class="o">(</span><span class="nd">@A</span> <span class="kt">var</span> <span class="n">d</span><span class="o">)</span> <span class="o">-></span> <span class="o">{};</span>
|
||
<span class="o">(</span><span class="nd">@A</span> <span class="kt">int</span> <span class="n">e</span><span class="o">)</span> <span class="o">-></span> <span class="o">{};</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">LambdaExpression</span>
|
||
<span class="err">├─</span> <span class="nx">VariableDeclaratorId</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">a</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">VariableDeclaratorId</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">b</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">LambdaExpression</span>
|
||
<span class="err">├─</span> <span class="nx">VariableDeclaratorId</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">c</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">LambdaExpression</span>
|
||
<span class="err">├─</span> <span class="nx">FormalParameters</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">FormalParameter</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Annotation</span><span class="p">[</span> <span class="p">@</span><span class="nd">AnnotationName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span><span class="p">[</span> <span class="p">@</span><span class="nd">AnnotationName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableDeclaratorId</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">d</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">LambdaExpression</span>
|
||
<span class="err">├─</span> <span class="nx">FormalParameters</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">FormalParameter</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Annotation</span><span class="p">[</span> <span class="p">@</span><span class="nd">AnnotationName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span><span class="p">[</span> <span class="p">@</span><span class="nd">AnnotationName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimitiveType</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">int</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableDeclaratorId</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">e</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">LambdaExpression</span>
|
||
<span class="err">├─</span> <span class="nx">LambdaParameterList</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">LambdaParameter</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableId</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">a</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">LambdaParameter</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableId</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">b</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">LambdaExpression</span>
|
||
<span class="err">├─</span> <span class="nx">LambdaParameterList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">LambdaParameter</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableId</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">c</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">LambdaExpression</span>
|
||
<span class="err">├─</span> <span class="nx">LambdaParameterList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">LambdaParameter</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableId</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">d</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">LambdaExpression</span>
|
||
<span class="err">├─</span> <span class="nx">LambdaParameterList</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">LambdaParameter</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span><span class="p">[</span> <span class="p">@</span><span class="nd">SimpleName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">A</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">PrimitiveType</span><span class="p">[</span> <span class="p">@</span><span class="nd">Kind</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">int</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableId</span><span class="p">[</span> <span class="p">@</span><span class="nd">Name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">e</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="new-node-for-explicit-receiver-parameter">New node for explicit receiver parameter</h5>
|
||
|
||
<ul>
|
||
<li>What: A separate node type <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTReceiverParameter.html#"><code>ASTReceiverParameter</code></a> is introduced to differentiate it from formal parameters.</li>
|
||
<li>Why: A receiver parameter is not a formal parameter, even though it looks like one: it doesn’t declare a variable,
|
||
and doesn’t affect the arity of the method or constructor. It’s so rarely used that giving it its own node avoids
|
||
matching it by mistake and simplifies the API and grammar of the ubiquitous <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTFormalParameter.html#"><code>ASTFormalParameter</code></a>
|
||
and <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTVariableId.html#"><code>ASTVariableId</code></a>.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/1980">[java] Separate receiver parameter from formal parameter (#1980)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>explicit receiver parameter Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kt">void</span> <span class="nf">myMethod</span><span class="o">(</span><span class="nd">@A</span> <span class="nc">Foo</span> <span class="k">this</span><span class="o">,</span> <span class="nc">Foo</span> <span class="n">other</span><span class="o">)</span> <span class="o">{}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">FormalParameters</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="err">├─</span> <span class="nx">FormalParameter</span><span class="p">[</span> <span class="p">@</span><span class="nd">ExplicitReceiverParameter</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableDeclaratorId</span><span class="p">[</span> <span class="p">@</span><span class="nd">ExplicitReceiverParameter</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">this</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">FormalParameter</span>
|
||
<span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">other</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">FormalParameters</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="err">├─</span> <span class="nx">ReceiverParameter</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">FormalParameter</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">other</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="varargs">Varargs</h5>
|
||
|
||
<ul>
|
||
<li>What: parse the varargs ellipsis as an <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTArrayType.html#"><code>ASTArrayType</code></a>.</li>
|
||
<li>Why: this improves regularity of the grammar, and allows type annotations to be added to the ellipsis</li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Varargs Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kt">void</span> <span class="nf">myMethod</span><span class="o">(</span><span class="kt">int</span><span class="o">...</span> <span class="n">is</span><span class="o">)</span> <span class="o">{}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">FormalParameter</span><span class="p">[</span> <span class="p">@</span><span class="nd">Varargs</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">is</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">FormalParameter</span><span class="p">[</span> <span class="p">@</span><span class="nd">Varargs</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">├─</span> <span class="nx">ArrayType</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArrayDimensions</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArrayTypeDim</span><span class="p">[</span> <span class="p">@</span><span class="nd">Varargs</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">is</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kt">void</span> <span class="nf">myMethod</span><span class="o">(</span><span class="kt">int</span> <span class="nd">@A</span> <span class="o">...</span> <span class="n">is</span><span class="o">)</span> <span class="o">{}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">FormalParameter</span><span class="p">[</span> <span class="p">@</span><span class="nd">Varargs</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">MarkerAnnotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">is</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">FormalParameter</span><span class="p">[</span> <span class="p">@</span><span class="nd">Varargs</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">├─</span> <span class="nx">ArrayType</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArrayDimensions</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArrayTypeDim</span><span class="p">[</span> <span class="p">@</span><span class="nd">Varargs</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Annotation</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">A</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">is</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kt">void</span> <span class="nf">myMethod</span><span class="o">(</span><span class="kt">int</span><span class="o">[]...</span> <span class="n">is</span><span class="o">)</span> <span class="o">{}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">FormalParameter</span><span class="p">[</span> <span class="p">@</span><span class="nd">Varargs</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">Type</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayType</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">is</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td>
|
||
<td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">FormalParameter</span><span class="p">[</span> <span class="p">@</span><span class="nd">Varargs</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">├─</span> <span class="nx">ArrayType</span> <span class="p">(</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArrayDimensions</span> <span class="p">(</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ArrayTypeDim</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArrayTypeDim</span><span class="p">[</span> <span class="p">@</span><span class="nd">Varargs</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">is</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="add-void-type-node-to-replace-resulttype">Add void type node to replace ResultType</h5>
|
||
|
||
<ul>
|
||
<li>What: Add a <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTVoidType.html#"><code>ASTVoidType</code></a> node to replace <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.2.0/net/sourceforge/pmd/lang/java/ast/ASTResultType.html#"><code>ASTResultType</code></a>.</li>
|
||
<li>Why: This means we don’t need the ResultType wrapper when the method is not void, and the result type node is never null.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/2715">[java] Add void type node to replace ResultType (#2715)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Void Type Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kt">void</span> <span class="nf">foo</span><span class="o">();</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">MethodDeclaration</span> <span class="dl">"</span><span class="s2">foo</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ResultType</span><span class="p">[</span> <span class="p">@</span><span class="nd">Void</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">MethodDeclarator</span>
|
||
<span class="err">└─</span> <span class="nx">FormalParameters</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">MethodDeclaration</span> <span class="dl">"</span><span class="s2">foo</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">├─</span> <span class="nx">VoidType</span>
|
||
<span class="err">└─</span> <span class="nx">FormalParameters</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kt">int</span> <span class="nf">foo</span><span class="o">();</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">MethodDeclaration</span> <span class="dl">"</span><span class="s2">foo</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ResultType</span><span class="p">[</span> <span class="p">@</span><span class="nd">Void</span> <span class="o">=</span> <span class="kc">false</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">MethodDeclarator</span>
|
||
<span class="err">└─</span> <span class="nx">FormalParameters</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">MethodDeclaration</span> <span class="dl">"</span><span class="s2">foo</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">FormalParameters</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h4 id="statements">Statements</h4>
|
||
|
||
<h5 id="statements-are-flattened">Statements are flattened</h5>
|
||
|
||
<ul>
|
||
<li>What: Statements are flattened. There are no superfluous BlockStatement and Statement nodes anymore.
|
||
All children of a <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTBlock.html#"><code>ASTBlock</code></a> are by definition
|
||
<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTStatement.html#"><code>ASTStatement</code></a>s, which is now an interface implemented by all statements.</li>
|
||
<li>Why: This simplifies the tree traversal. The removed nodes BlockStatement and Statement didn’t add any
|
||
additional information. We only need a Statement abstraction. BlockStatement was used to enforce, that no
|
||
variable or local class declaration is found alone as the child of e.g. an unbraced if, else, for, etc.
|
||
This is a parser-only distinction that’s not that useful for analysis later on.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/2164">[java] Improve statement grammar (#2164)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Statements Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kt">int</span> <span class="n">i</span><span class="o">;</span>
|
||
<span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Block</span>
|
||
<span class="err">├─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">LocalVariableDeclaration</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableDeclarator</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">i</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">i</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">AssignmentOperator</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Block</span>
|
||
<span class="err">├─</span> <span class="nx">LocalVariableDeclaration</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableDeclarator</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">i</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">AssignmentExpression</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">i</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="new-node-for-for-each-statements">New node for For-each statements</h5>
|
||
|
||
<ul>
|
||
<li>What: New node for For-each statements: <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTForeachStatement.html#"><code>ASTForeachStatement</code></a> instead of ForStatement.</li>
|
||
<li>Why: This makes it a lot easier to distinguish in the AST between For-loops and For-Each-loops. E.g. some
|
||
rules only apply to one or the other, and it was complicated to write a rule that works with both different
|
||
subtrees (for loops have additional children ForInit and ForUpdate)</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/2164">[java] Improve statement grammar (#2164)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>For-each statement Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="k">for</span> <span class="o">(</span><span class="nc">String</span> <span class="n">s</span> <span class="o">:</span> <span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"a"</span><span class="o">,</span> <span class="s">"b"</span><span class="o">))</span> <span class="o">{</span> <span class="o">}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">ForStatement</span><span class="p">[</span> <span class="p">@</span><span class="nd">Foreach</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">LocalVariableDeclaration</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">String</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableDeclarator</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">s</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">Expression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">List.of</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimarySuffix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Arguments</span> <span class="p">(</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArgumentList</span> <span class="p">(</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Expression</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Literal</span><span class="p">[</span> <span class="p">@</span><span class="nd">StringLiteral</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">][</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">"a"</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Literal</span><span class="p">[</span> <span class="p">@</span><span class="nd">StringLiteral</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">][</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">"b"</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Block</span>
|
||
<span class="err">└─</span> <span class="nx">ForeachStatement</span>
|
||
<span class="err">├─</span> <span class="nx">LocalVariableDeclaration</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">String</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableDeclarator</span> <span class="dl">"</span><span class="s2">s</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">s</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">MethodCall</span> <span class="dl">"</span><span class="s2">of</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">TypeExpression</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">List</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArgumentList</span> <span class="p">(</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">StringLiteral</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">"a"</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">StringLiteral</span><span class="p">[</span> <span class="p">@</span><span class="nd">Image</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">"b"</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="new-nodes-for-expressionstatement-localclassstatement">New nodes for ExpressionStatement, LocalClassStatement</h5>
|
||
|
||
<ul>
|
||
<li>What: Renamed StatementExpression to <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTExpressionStatement.html#"><code>ASTExpressionStatement</code></a>.
|
||
Added new node <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTLocalClassStatement.html#"><code>ASTLocalClassStatement</code></a>.</li>
|
||
<li>Why: ExpressionStatement is now a <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTStatement.html#"><code>ASTStatement</code></a>, that can be used as a child in a
|
||
block. It itself has only one child, which is some kind of <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTExpression.html#"><code>ASTExpression</code></a>,
|
||
which can be really any kind of expression (like assignment).
|
||
In order to allow local class declarations as part of a block, we introduced <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTLocalClassStatement.html#"><code>ASTLocalClassStatement</code></a>
|
||
which is a statement that carries a type declaration. Now blocks are just a list of statements.
|
||
This allows us to have two distinct hierarchies for expressions and statements.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/2164">[java] Improve statement grammar (#2164)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>ExpressionStatement, LocalClassStatement Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="n">i</span><span class="o">++;</span>
|
||
<span class="kd">class</span> <span class="nc">LocalClass</span> <span class="o">{}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Block</span>
|
||
<span class="err">├─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PostfixExpression</span> <span class="dl">"</span><span class="s2">++</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">i</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceDeclaration</span><span class="p">[</span> <span class="p">@</span><span class="nd">Local</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">LocalClass</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ClassOrInterfaceBody</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Block</span>
|
||
<span class="err">├─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">UnaryExpression</span> <span class="dl">"</span><span class="s2">++</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">i</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">LocalClassStatement</span>
|
||
<span class="err">└─</span> <span class="nx">ClassDeclaration</span> <span class="dl">"</span><span class="s2">LocalClass</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">└─</span> <span class="nx">ClassBody</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="improve-try-with-resources-grammar">Improve try-with-resources grammar</h5>
|
||
|
||
<ul>
|
||
<li>What: The AST representation of a try-with-resources statement has been simplified.
|
||
It uses now <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTLocalVariableDeclaration.html#"><code>ASTLocalVariableDeclaration</code></a> unless it is a concise try-with-resources.</li>
|
||
<li>Why: Simpler integration try-with-resources into symboltable and type resolution.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/1897">[java] Improve try-with-resources grammar (#1897)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Try-With-Resources Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="k">try</span> <span class="o">(</span><span class="nc">InputStream</span> <span class="n">in</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FileInputStream</span><span class="o">();</span> <span class="nc">OutputStream</span> <span class="n">out</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FileOutputStream</span><span class="o">();)</span> <span class="o">{</span> <span class="o">}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">TryStatement</span>
|
||
<span class="err">└─</span> <span class="nx">ResourceSpecification</span>
|
||
<span class="err">└─</span> <span class="nx">Resources</span>
|
||
<span class="err">├─</span> <span class="nx">Resource</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">InputStream</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">in</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="p">...</span>
|
||
<span class="err">└─</span> <span class="nx">Resource</span>
|
||
<span class="err">├─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">OutputStream</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">out</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="p">...</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">TryStatement</span>
|
||
<span class="err">└─</span> <span class="nx">ResourceList</span><span class="p">[</span> <span class="p">@</span><span class="nd">TrailingSemiColon</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="p">(</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="err">├─</span> <span class="nx">Resource</span><span class="p">[</span> <span class="p">@</span><span class="nd">ConciseResource</span> <span class="o">=</span> <span class="kc">false</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">in</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">LocalVariableDeclaration</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">InputStream</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">VariableDeclarator</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">in</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ConstructorCall</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">FileInputStream</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArgumentList</span> <span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
||
<span class="err">└─</span> <span class="nx">Resource</span><span class="p">[</span> <span class="p">@</span><span class="nd">ConciseResource</span> <span class="o">=</span> <span class="kc">false</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">out</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">LocalVariableDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">OutputStream</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclarator</span>
|
||
<span class="err">├─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">out</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ConstructorCall</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">FileOutputStream</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArgumentList</span> <span class="p">(</span><span class="mi">0</span><span class="p">)</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">InputStream</span> <span class="n">in</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FileInputStream</span><span class="o">();</span>
|
||
<span class="k">try</span> <span class="o">(</span><span class="n">in</span><span class="o">)</span> <span class="o">{}</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">TryStatement</span>
|
||
<span class="err">└─</span> <span class="nx">ResourceSpecification</span>
|
||
<span class="err">└─</span> <span class="nx">Resources</span>
|
||
<span class="err">└─</span> <span class="nx">Resource</span> <span class="dl">"</span><span class="s2">in</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">in</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">TryStatement</span>
|
||
<span class="err">└─</span> <span class="nx">ResourceList</span><span class="p">[</span> <span class="p">@</span><span class="nd">TrailingSemiColon</span> <span class="o">=</span> <span class="kc">false</span><span class="p">()</span> <span class="p">]</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="err">└─</span> <span class="nx">Resource</span><span class="p">[</span> <span class="p">@</span><span class="nd">ConciseResource</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">in</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">in</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h4 id="expressions">Expressions</h4>
|
||
|
||
<ul>
|
||
<li>
|
||
<p><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTExpression.html#"><code>ASTExpression</code></a> and <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTPrimaryExpression.html#"><code>ASTPrimaryExpression</code></a> have
|
||
been turned into interfaces. These added no information to the AST and increased
|
||
its depth unnecessarily. All expressions implement the first interface. Both of
|
||
those nodes can no more be found in ASTs.</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Migrating</strong>:</p>
|
||
<ul>
|
||
<li>Basically, <code class="language-plaintext highlighter-rouge">Expression/X</code> or <code class="language-plaintext highlighter-rouge">Expression/PrimaryExpression/X</code>, just becomes <code class="language-plaintext highlighter-rouge">X</code></li>
|
||
<li>There is currently no way to match abstract or interface types with XPath, so <code class="language-plaintext highlighter-rouge">Expression</code> or <code class="language-plaintext highlighter-rouge">PrimaryExpression</code>
|
||
name tests won’t match anything anymore. However, the axis step *[@Expression=true()] matches any expression.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h5 id="new-nodes-for-different-literals-types">New nodes for different literals types</h5>
|
||
|
||
<ul>
|
||
<li>What:
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTLiteral.html#"><code>ASTLiteral</code></a> has been turned into an interface.</li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTNumericLiteral.html#"><code>ASTNumericLiteral</code></a>, <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTCharLiteral.html#"><code>ASTCharLiteral</code></a>, <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTStringLiteral.html#"><code>ASTStringLiteral</code></a>,
|
||
and <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTClassLiteral.html#"><code>ASTClassLiteral</code></a> are new nodes that implement that interface.</li>
|
||
<li>ASTLiteral implements <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTPrimaryExpression.html#"><code>ASTPrimaryExpression</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li>Why: The fact that <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTNullLiteral.html#"><code>ASTNullLiteral</code></a>
|
||
and <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteral.html#"><code>ASTBooleanLiteral</code></a> were nested within it but other literals types were all directly represented
|
||
by it was inconsistent, and ultimately that level of nesting was unnecessary.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/1759">[java] New expression and type grammar (#1759)</a></li>
|
||
<li><strong>Migrating</strong>:
|
||
<ul>
|
||
<li>Remove all <code class="language-plaintext highlighter-rouge">/Literal/</code> segments from your XPath expressions</li>
|
||
<li>If you tested several types of literals, you can e.g. do it like <code class="language-plaintext highlighter-rouge">/*[self::StringLiteral or self::CharLiteral]/</code></li>
|
||
<li>As usual, use the designer to explore the new AST structure</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Literals Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kt">char</span> <span class="n">c</span> <span class="o">=</span> <span class="sc">'c'</span><span class="o">;</span>
|
||
<span class="kt">boolean</span> <span class="n">b</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span>
|
||
<span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
|
||
<span class="kt">double</span> <span class="n">d</span> <span class="o">=</span> <span class="mf">1.0</span><span class="o">;</span>
|
||
<span class="nc">String</span> <span class="n">s</span> <span class="o">=</span> <span class="s">"s"</span><span class="o">;</span>
|
||
<span class="nc">Object</span> <span class="n">n</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span></code></pre></figure>
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Literal</span><span class="p">[</span> <span class="p">@</span><span class="nd">CharLiteral</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">'c'</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span>
|
||
<span class="err">└─</span> <span class="nx">BooleanLiteral</span><span class="p">[</span> <span class="p">@</span><span class="nd">True</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span><span class="p">[</span> <span class="p">@</span><span class="nd">IntLiteral</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span><span class="p">[</span> <span class="p">@</span><span class="nd">DoubleLiteral</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">1.0</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span><span class="p">[</span> <span class="p">@</span><span class="nd">StringLiteral</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="se">\"</span><span class="s2">s</span><span class="se">\"</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span>
|
||
<span class="err">└─</span> <span class="nx">NullLiteral</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">CharLiteral</span> <span class="dl">"</span><span class="s2">'c'</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">BooleanLiteral</span><span class="p">[</span> <span class="p">@</span><span class="nd">True</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span><span class="p">[</span> <span class="p">@</span><span class="nd">IntLiteral</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span><span class="p">[</span> <span class="p">@</span><span class="nd">DoubleLiteral</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">1.0</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">StringLiteral</span> <span class="dl">"</span><span class="se">\"</span><span class="s2">s</span><span class="se">\"</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">NullLiteral</span></code></pre></figure>
|
||
|
||
</td></tr></table>
|
||
|
||
</details>
|
||
|
||
<h5 id="method-calls-constructor-calls-array-allocations">Method calls, constructor calls, array allocations</h5>
|
||
|
||
<ul>
|
||
<li>What: Extra nodes dedicated for method and constructor calls and array allocations
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTConstructorCall.html#"><code>ASTConstructorCall</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTMethodCall.html#"><code>ASTMethodCall</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTArrayAllocation.html#"><code>ASTArrayAllocation</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li>Why: It was extremely difficult to identify method calls in PMD 6 - these consisted of multiple nodes with
|
||
primary prefix, suffix and expressions. This was too low level to be easy to be used.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/1759">[java] New expression and type grammar (#1759)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Method calls, constructor calls, array allocations Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="n">o</span><span class="o">.</span><span class="na">myMethod</span><span class="o">(</span><span class="s">"a"</span><span class="o">);</span>
|
||
<span class="k">new</span> <span class="nf">Object</span><span class="o">(</span><span class="s">"b"</span><span class="o">);</span>
|
||
<span class="k">new</span> <span class="kt">int</span><span class="o">[</span><span class="mi">10</span><span class="o">];</span>
|
||
<span class="k">new</span> <span class="kt">int</span><span class="o">[]</span> <span class="o">{</span> <span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">,</span> <span class="mi">3</span> <span class="o">};</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">o.myMethod</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">PrimarySuffix</span>
|
||
<span class="err">└─</span> <span class="nx">Arguments</span>
|
||
<span class="err">└─</span> <span class="nx">ArgumentList</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="se">\"</span><span class="s2">a</span><span class="se">\"</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">AllocationExpression</span>
|
||
<span class="err">├─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">Object</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Arguments</span>
|
||
<span class="err">└─</span> <span class="nx">ArgumentList</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="se">\"</span><span class="s2">b</span><span class="se">\"</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">AllocationExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimsAndInits</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">10</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">AllocationExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimsAndInits</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayInitializer</span>
|
||
<span class="err">├─</span> <span class="nx">VariableInitializer</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">VariableInitializer</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">2</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableInitializer</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">3</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">MethodCall</span> <span class="dl">"</span><span class="s2">myMethod</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">o</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArgumentList</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="err">└─</span> <span class="nx">StringLiteral</span> <span class="dl">"</span><span class="se">\"</span><span class="s2">a</span><span class="se">\"</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ConstructorCall</span>
|
||
<span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Object</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArgumentList</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="err">└─</span> <span class="nx">StringLiteral</span> <span class="dl">"</span><span class="se">\"</span><span class="s2">b</span><span class="se">\"</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ArrayAllocation</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">1</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayType</span>
|
||
<span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimensions</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayDimExpr</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">10</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ArrayAllocation</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayDepth</span> <span class="o">=</span> <span class="mi">1</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">ArrayType</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">PrimitiveType</span> <span class="dl">"</span><span class="s2">int</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArrayDimensions</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArrayTypeDim</span>
|
||
<span class="err">└─</span> <span class="nx">ArrayInitializer</span><span class="p">[</span> <span class="p">@</span><span class="nd">Length</span> <span class="o">=</span> <span class="mi">3</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">2</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">3</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr></table>
|
||
|
||
</details>
|
||
|
||
<h5 id="method-call-chains-are-left-recursive">Method call chains are left-recursive</h5>
|
||
|
||
<ul>
|
||
<li>What: The nodes <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.2.0/net/sourceforge/pmd/lang/java/ast/ASTPrimaryPrefix.html#"><code>ASTPrimaryPrefix</code></a> and <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.2.0/net/sourceforge/pmd/lang/java/ast/ASTPrimarySuffix.html#"><code>ASTPrimarySuffix</code></a> are removed from the
|
||
grammar. Subtrees for primary expressions appear to be left-recursive now.</li>
|
||
<li>Why: Allows to reuse abstractions like method calls without introducing a new artificial node (like method chain).</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/1759">[java] New expression and type grammar (#1759)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Method call chain Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="k">new</span> <span class="nc">Foo</span><span class="o">().</span><span class="na">bar</span><span class="o">.</span><span class="na">foo</span><span class="o">(</span><span class="mi">1</span><span class="o">);</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">AllocationExpression</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Arguments</span> <span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
||
<span class="err">├─</span> <span class="nx">PrimarySuffix</span> <span class="dl">"</span><span class="s2">bar</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">PrimarySuffix</span> <span class="dl">"</span><span class="s2">foo</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">PrimarySuffix</span><span class="p">[</span> <span class="p">@</span><span class="nd">Arguments</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Arguments</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="err">└─</span> <span class="nx">ArgumentList</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">MethodCall</span> <span class="dl">"</span><span class="s2">foo</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">FieldAccess</span> <span class="dl">"</span><span class="s2">bar</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ConstructorCall</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ArgumentList</span> <span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
||
<span class="err">└─</span> <span class="nx">ArgumentList</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr></table>
|
||
|
||
</details>
|
||
|
||
<p>Instead of being flat, the subexpressions are now nested within one another.
|
||
The nesting follows the naturally recursive structure of expressions:</p>
|
||
|
||
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">new</span> <span class="nc">Foo</span><span class="o">().</span><span class="na">bar</span><span class="o">.</span><span class="na">foo</span><span class="o">(</span><span class="mi">1</span><span class="o">)</span>
|
||
<span class="err">└───────┘</span> <span class="err">│</span> <span class="err">│</span> <span class="nc">ConstructorCall</span>
|
||
<span class="err">└───────────┘</span> <span class="err">│</span> <span class="nc">FieldAccess</span>
|
||
<span class="err">└──────────────────┘</span> <span class="nc">MethodCall</span>
|
||
</code></pre></div></div>
|
||
|
||
<p>This makes the AST more regular and easier to navigate. Each node contains
|
||
the other nodes that are relevant to it (e.g. arguments) instead of them
|
||
being spread out over several siblings. The API of all nodes has been
|
||
enriched with high-level accessors to query the AST in a semantic way,
|
||
without bothering with the placement details.</p>
|
||
|
||
<p>The amount of changes in the grammar that this change entails is enormous,
|
||
but hopefully firing up the designer to inspect the new structure should
|
||
give you the information you need quickly.</p>
|
||
|
||
<p>Note: this also affect binary expressions like <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTInfixExpression.html#"><code>ASTInfixExpression</code></a>.
|
||
E.g. <code class="language-plaintext highlighter-rouge">a+b+c</code> is not parsed as</p>
|
||
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>AdditiveExpression
|
||
+ (a)
|
||
+ (b)
|
||
+ (c)
|
||
</code></pre></div></div>
|
||
|
||
<p>But it is now (note: AdditiveExpression is now InfixExpression)</p>
|
||
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>InfixExpression
|
||
+ InfixExpression
|
||
+ (a)
|
||
+ (b)
|
||
+ (c)
|
||
</code></pre></div></div>
|
||
|
||
<h5 id="field-access-array-access-variable-access">Field access, array access, variable access</h5>
|
||
|
||
<ul>
|
||
<li>What: New nodes dedicated to accessing field, variables and referencing arrays.
|
||
Also provide info about the access type, like whether a variable is read or written.
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTFieldAccess.html#"><code>ASTFieldAccess</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTVariableAccess.html#"><code>ASTVariableAccess</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTArrayAccess.html#"><code>ASTArrayAccess</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li>Why: Like MethodCalls, this was a missing abstraction in the AST that has been added now.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/1759">[java] New expression and type grammar (#1759)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Field access, array access, variable access Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="n">field</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
|
||
<span class="n">localVar</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
|
||
<span class="n">array</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
|
||
<span class="nc">Foo</span><span class="o">.</span><span class="na">staticField</span> <span class="o">=</span> <span class="n">localVar</span><span class="o">;</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">field</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">AssignmentOperator</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">localVar</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">AssignmentOperator</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">array</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimarySuffix</span><span class="p">[</span> <span class="p">@</span><span class="nd">ArrayDereference</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">0</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">AssignmentOperator</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">Foo.staticField</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">AssignmentOperator</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">localVar</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">AssignmentExpression</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">field</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">AssignmentExpression</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">localVar</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">AssignmentExpression</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ArrayAccess</span><span class="p">[</span> <span class="p">@</span><span class="nd">AccessType</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">WRITE</span><span class="dl">"</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">array</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">0</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">AssignmentExpression</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">FieldAccess</span><span class="p">[</span> <span class="p">@</span><span class="nd">AccessType</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">WRITE</span><span class="dl">"</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">staticField</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">TypeExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableAccess</span><span class="p">[</span> <span class="p">@</span><span class="nd">AccessType</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">READ</span><span class="dl">"</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">localVar</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
|
||
<ul>
|
||
<li>As seen above, an unqualified field access currently shows up as a VariableAccess. This may be fixed
|
||
future versions of PMD.</li>
|
||
</ul>
|
||
|
||
</td></tr></table>
|
||
|
||
</details>
|
||
|
||
<h5 id="explicit-nodes-for-thissuper-expressions">Explicit nodes for this/super expressions</h5>
|
||
|
||
<ul>
|
||
<li>What: <code class="language-plaintext highlighter-rouge">this</code> and <code class="language-plaintext highlighter-rouge">super</code> are now explicit nodes instead of PrimaryPrefix.
|
||
<ul>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTThisExpression.html#"><code>ASTThisExpression</code></a></li>
|
||
<li><a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTSuperExpression.html#"><code>ASTSuperExpression</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li>Why: That way these nodes can qualify other nodes like FieldAccess.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/1759">[java] New expression and type grammar (#1759)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>this/super expressions Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="k">this</span><span class="o">.</span><span class="na">field</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
|
||
<span class="kd">super</span><span class="o">.</span><span class="na">field</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
|
||
|
||
<span class="k">this</span><span class="o">.</span><span class="na">method</span><span class="o">();</span>
|
||
<span class="kd">super</span><span class="o">.</span><span class="na">method</span><span class="o">();</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">PrimaryPrefix</span><span class="p">[</span> <span class="p">@</span><span class="nd">ThisModifier</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimarySuffix</span> <span class="dl">"</span><span class="s2">field</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">AssignmentOperator</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">PrimaryPrefix</span><span class="p">[</span> <span class="p">@</span><span class="nd">SuperModifier</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimarySuffix</span> <span class="dl">"</span><span class="s2">field</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">AssignmentOperator</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryPrefix</span><span class="p">[</span> <span class="p">@</span><span class="nd">ThisModifier</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">PrimarySuffix</span> <span class="dl">"</span><span class="s2">method</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">PrimarySuffix</span><span class="p">[</span> <span class="p">@</span><span class="nd">Arguments</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Arguments</span> <span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryPrefix</span><span class="p">[</span> <span class="p">@</span><span class="nd">SuperModifier</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">PrimarySuffix</span> <span class="dl">"</span><span class="s2">method</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">PrimarySuffix</span><span class="p">[</span> <span class="p">@</span><span class="nd">Arguments</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Arguments</span> <span class="p">(</span><span class="mi">0</span><span class="p">)</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">AssignmentExpression</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">FieldAccess</span><span class="p">[</span> <span class="p">@</span><span class="nd">AccessType</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">WRITE</span><span class="dl">"</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">field</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ThisExpression</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">AssignmentExpression</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">FieldAccess</span><span class="p">[</span> <span class="p">@</span><span class="nd">AcessType</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">WRITE</span><span class="dl">"</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">field</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">SuperExpression</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">MethodCall</span> <span class="dl">"</span><span class="s2">method</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">ThisExpression</span>
|
||
<span class="err">└─</span> <span class="nx">ArgumentList</span> <span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">MethodCall</span> <span class="dl">"</span><span class="s2">method</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">SuperExpression</span>
|
||
<span class="err">└─</span> <span class="nx">ArgumentList</span> <span class="p">(</span><span class="mi">0</span><span class="p">)</span></code></pre></figure>
|
||
|
||
</td></tr></table>
|
||
|
||
</details>
|
||
|
||
<h5 id="type-expressions">Type expressions</h5>
|
||
|
||
<ul>
|
||
<li>What: The node <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTTypeExpression.html#"><code>ASTTypeExpression</code></a> wraps a <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTType.html#"><code>ASTType</code></a> node (such as
|
||
<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTClassType.html#"><code>ASTClassType</code></a>) and is used to qualify a method call or field access or method reference.</li>
|
||
<li>Why: Simplify the qualifier of method calls, treat instanceof as infix expression.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/2039">[java] Grammar type expr (#2039)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Type expressions Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">Foo</span><span class="o">.</span><span class="na">staticMethod</span><span class="o">();</span>
|
||
<span class="k">if</span> <span class="o">(</span><span class="n">x</span> <span class="k">instanceof</span> <span class="nc">Foo</span><span class="o">)</span> <span class="o">{}</span>
|
||
<span class="kt">var</span> <span class="n">x</span> <span class="o">=</span> <span class="nl">Foo:</span><span class="o">:</span><span class="n">method</span><span class="o">;</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">Foo.staticMethod</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">PrimarySuffix</span><span class="p">[</span> <span class="p">@</span><span class="nd">Arguments</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">Arguments</span> <span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">IfStatement</span>
|
||
<span class="err">├─</span> <span class="nx">Expression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">InstanceOfExpression</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">x</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Type</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ReferenceType</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassOrInterfaceType</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Statement</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">BlockStatement</span>
|
||
<span class="err">└─</span> <span class="nx">LocalVariableDeclaration</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclarator</span>
|
||
<span class="err">├─</span> <span class="nx">VariableDeclaratorId</span> <span class="dl">"</span><span class="s2">x</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableInitializer</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">PrimarySuffix</span>
|
||
<span class="err">└─</span> <span class="nx">MemberSelector</span>
|
||
<span class="err">└─</span> <span class="nx">MethodReference</span> <span class="dl">"</span><span class="s2">method</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">MethodCall</span> <span class="dl">"</span><span class="s2">staticMethod</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">TypeExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">ArgumentList</span> <span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">IfStatement</span>
|
||
<span class="err">├─</span> <span class="nx">InfixExpression</span> <span class="dl">"</span><span class="s2">instanceof</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">VariableAccess</span><span class="p">[</span> <span class="p">@</span><span class="nd">AccessType</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">READ</span><span class="dl">"</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">x</span><span class="dl">"</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">TypeExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Block</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">LocalVariableDeclaration</span>
|
||
<span class="err">├─</span> <span class="nx">ModifierList</span>
|
||
<span class="err">└─</span> <span class="nx">VariableDeclarator</span>
|
||
<span class="err">├─</span> <span class="nx">VariableId</span> <span class="dl">"</span><span class="s2">x</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">MethodReference</span> <span class="dl">"</span><span class="s2">method</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">TypeExpression</span>
|
||
<span class="err">└─</span> <span class="nx">ClassType</span> <span class="dl">"</span><span class="s2">Foo</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr></table>
|
||
|
||
</details>
|
||
|
||
<h5 id="merge-unary-expressions">Merge unary expressions</h5>
|
||
|
||
<ul>
|
||
<li>What: Merge AST nodes for postfix and prefix expressions into the single <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTUnaryExpression.html#"><code>ASTUnaryExpression</code></a> node.
|
||
The merged nodes are:
|
||
<ul>
|
||
<li>PreIncrementExpression</li>
|
||
<li>PreDecrementExpression</li>
|
||
<li>UnaryExpression</li>
|
||
<li>UnaryExpressionNotPlusMinus</li>
|
||
</ul>
|
||
</li>
|
||
<li>Why: Those nodes were asymmetric, and inconsistently nested within UnaryExpression. By definition, they’re all unary,
|
||
so that using a single node is appropriate.</li>
|
||
<li>Related issues:
|
||
<ul>
|
||
<li><a href="https://github.com/pmd/pmd/pull/1890">[java] Merge different increment/decrement expressions (#1890)</a></li>
|
||
<li><a href="https://github.com/pmd/pmd/pull/2155">[java] Merge prefix/postfix expressions into one node (#2155)</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Unary Expressions Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="o">++</span><span class="n">a</span><span class="o">;</span>
|
||
<span class="o">--</span><span class="n">b</span><span class="o">;</span>
|
||
<span class="n">c</span><span class="o">++;</span>
|
||
<span class="n">d</span><span class="o">--;</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PreIncrementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">a</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PreDecrementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">b</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PostfixExpression</span> <span class="dl">"</span><span class="s2">++</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">c</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PostfixExpression</span> <span class="dl">"</span><span class="s2">--</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">d</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">UnaryExpression</span><span class="p">[</span> <span class="p">@</span><span class="nd">Prefix</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">][</span> <span class="p">@</span><span class="nd">Operator</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">++</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">VariableAccess</span><span class="p">[</span> <span class="p">@</span><span class="nd">AccessType</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">WRITE</span><span class="dl">"</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">a</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">UnaryExpression</span><span class="p">[</span> <span class="p">@</span><span class="nd">Prefix</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">][</span> <span class="p">@</span><span class="nd">Operator</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">--</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">VariableAccess</span><span class="p">[</span> <span class="p">@</span><span class="nd">AccessType</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">WRITE</span><span class="dl">"</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">b</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">UnaryExpression</span><span class="p">[</span> <span class="p">@</span><span class="nd">Prefix</span> <span class="o">=</span> <span class="kc">false</span><span class="p">()</span> <span class="p">][</span> <span class="p">@</span><span class="nd">Operator</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">++</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">VariableAccess</span><span class="p">[</span> <span class="p">@</span><span class="nd">AccessType</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">WRITE</span><span class="dl">"</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">c</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">UnaryExpression</span><span class="p">[</span> <span class="p">@</span><span class="nd">Prefix</span> <span class="o">=</span> <span class="kc">false</span><span class="p">()</span> <span class="p">][</span> <span class="p">@</span><span class="nd">Operator</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">--</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">VariableAccess</span><span class="p">[</span> <span class="p">@</span><span class="nd">AccessType</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">WRITE</span><span class="dl">"</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">d</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="n">x</span> <span class="o">=</span> <span class="o">~</span><span class="n">a</span><span class="o">;</span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="o">+</span><span class="n">a</span><span class="o">;</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">UnaryExpressionNotPlusMinus</span> <span class="dl">"</span><span class="s2">~</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">a</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">UnaryExpression</span> <span class="dl">"</span><span class="s2">+</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">a</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">UnaryExpression</span><span class="p">[</span> <span class="p">@</span><span class="nd">Prefix</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">~</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">a</span><span class="dl">"</span>
|
||
|
||
<span class="err">└─</span> <span class="nx">UnaryExpression</span><span class="p">[</span> <span class="p">@</span><span class="nd">Prefix</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">+</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">a</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="binary-operators-are-left-recursive">Binary operators are left-recursive</h5>
|
||
|
||
<ul>
|
||
<li>What: For each operator, there were separate AST nodes (like AdditiveExpression, AndExpression, …).
|
||
These are now unified into a <code class="language-plaintext highlighter-rouge">InfixExpression</code>, which gives access to the operator via <code class="language-plaintext highlighter-rouge">getOperator()</code>
|
||
and to the operands (<code class="language-plaintext highlighter-rouge">getLhs()</code>, <code class="language-plaintext highlighter-rouge">getRhs()</code>). Additionally, the resulting AST is not flat anymore,
|
||
but a more structured tree.</li>
|
||
<li>Why: Having different AST node types doesn’t add information, that the operator doesn’t already provide.
|
||
The new structure as a result, that the expressions are now parsed left recursive, makes the AST more JLS-like.
|
||
This makes it easier for the type mapping algorithms. It also provides the information, which operands are
|
||
used with which operator. This information was lost if more than 2 operands where used and the tree was
|
||
flattened with PMD 6.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/1979">[java] Make binary operators left-recursive (#1979)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Binary operators Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">*</span> <span class="mi">3</span> <span class="o">%</span> <span class="mi">4</span><span class="o">;</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">MultiplicativeExpression</span> <span class="dl">"</span><span class="s2">%</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">2</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">3</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">4</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">InfixExpression</span><span class="p">[</span> <span class="p">@</span><span class="nd">Operator</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">%</span><span class="dl">'</span> <span class="p">]</span>
|
||
<span class="err">├─</span> <span class="nx">InfixExpression</span><span class="p">[@</span><span class="nd">Operator</span><span class="o">=</span><span class="dl">'</span><span class="s1">*</span><span class="dl">'</span><span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">├─</span> <span class="nx">InfixExpression</span><span class="p">[@</span><span class="nd">Operator</span><span class="o">=</span><span class="dl">'</span><span class="s1">*</span><span class="dl">'</span><span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">├─</span> <span class="nx">NumericLiteral</span><span class="p">[@</span><span class="nd">ValueAsInt</span><span class="o">=</span><span class="mi">1</span><span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">│</span> <span class="err">└─</span> <span class="nx">NumericLiteral</span><span class="p">[@</span><span class="nd">ValueAsInt</span><span class="o">=</span><span class="mi">2</span><span class="p">]</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">NumericLiteral</span><span class="p">[@</span><span class="nd">ValueAsInt</span><span class="o">=</span><span class="mi">3</span><span class="p">]</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span><span class="p">[@</span><span class="nd">ValueAsInt</span><span class="o">=</span><span class="mi">4</span><span class="p">]</span></code></pre></figure>
|
||
|
||
</td></tr>
|
||
</table>
|
||
|
||
</details>
|
||
|
||
<h5 id="parenthesized-expressions">Parenthesized expressions</h5>
|
||
|
||
<ul>
|
||
<li>What: Parentheses are not modelled in the AST anymore, but can be checked with the attributes <code class="language-plaintext highlighter-rouge">@Parenthesized</code>
|
||
and <code class="language-plaintext highlighter-rouge">@ParenthesisDepth</code></li>
|
||
<li>Why: This keeps the tree flat while still preserving the information. The tree is the same in case of unnecessary
|
||
parenthesis, which makes it harder to fool rules that look at the structure of the tree.</li>
|
||
<li>Related issue: <a href="https://github.com/pmd/pmd/pull/1872">[java] Remove ParenthesizedExpr (#1872)</a></li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Parenthesized expressions Examples</summary>
|
||
|
||
<table>
|
||
<tr><th>Code</th><th>Old AST (PMD 6)</th><th>New AST (PMD 7)</th></tr>
|
||
<tr><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="n">a</span> <span class="o">=</span> <span class="o">(((</span><span class="mi">1</span><span class="o">)));</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">StatementExpression</span>
|
||
<span class="err">├─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">│</span> <span class="err">└─</span> <span class="nx">Name</span> <span class="dl">"</span><span class="s2">a</span><span class="dl">"</span>
|
||
<span class="err">├─</span> <span class="nx">AssignmentOperator</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Expression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryExpression</span>
|
||
<span class="err">└─</span> <span class="nx">PrimaryPrefix</span>
|
||
<span class="err">└─</span> <span class="nx">Literal</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td><td>
|
||
|
||
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="err">└─</span> <span class="nx">ExpressionStatement</span>
|
||
<span class="err">└─</span> <span class="nx">AssignmentExpression</span>
|
||
<span class="err">├─</span> <span class="nx">VariableAccess</span> <span class="dl">"</span><span class="s2">a</span><span class="dl">"</span>
|
||
<span class="err">└─</span> <span class="nx">NumericLiteral</span><span class="p">[</span> <span class="p">@</span><span class="nd">Parenthesized</span> <span class="o">=</span> <span class="kc">true</span><span class="p">()</span> <span class="p">][</span> <span class="p">@</span><span class="nd">ParenthesisDepth</span> <span class="o">=</span> <span class="mi">3</span> <span class="p">]</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span></code></pre></figure>
|
||
|
||
</td></tr></table>
|
||
|
||
</details>
|
||
|
||
<h3 id="apex-ast">Apex AST</h3>
|
||
|
||
<p>PMD 7.0.0 switched the underlying parser for Apex code from Jorje to <a href="https://github.com/google/summit-ast">Summit AST</a>,
|
||
which is based on an open source grammar for Apex: <a href="https://github.com/nawforce/apex-parser">apex-parser</a>.</p>
|
||
|
||
<p>The produced AST is mostly compatible, there are some unavoidable changes however:</p>
|
||
|
||
<ul>
|
||
<li>Node <code class="language-plaintext highlighter-rouge">Method</code> (<a href="https://docs.pmd-code.org/apidocs/pmd-apex/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/apex/ast/ASTMethod.html#"><code>ASTMethod</code></a>)
|
||
<ul>
|
||
<li>No attribute <code class="language-plaintext highlighter-rouge">@Synthetic</code> anymore. Unlike Jorje, Summit AST doesn’t generate synthetic methods anymore, so
|
||
this attribute would have been always false and is of no use. Therefore it has been removed completely.</li>
|
||
<li>There will be no methods anymore with the name <code class="language-plaintext highlighter-rouge"><clinit></code>, <code class="language-plaintext highlighter-rouge"><init></code>.</li>
|
||
</ul>
|
||
</li>
|
||
<li>There is no node <code class="language-plaintext highlighter-rouge">BridgeMethodCreator</code> anymore. This was an artificially generated node by Jorje. Since the
|
||
new parser doesn’t generate synthetic methods anymore, this node is not needed anymore.</li>
|
||
<li>There is in general no attribute <code class="language-plaintext highlighter-rouge">@Namespace</code> anymore. The attribute has been removed, as it was never fully
|
||
implemented. It always returned an empty string.</li>
|
||
<li>Node <code class="language-plaintext highlighter-rouge">ReferenceExpression</code> (<a href="https://docs.pmd-code.org/apidocs/pmd-apex/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/apex/ast/ASTReferenceExpression.html#"><code>ASTReferenceExpression</code></a>)
|
||
<ul>
|
||
<li>No attribute <code class="language-plaintext highlighter-rouge">@Context</code> anymore. It was not used and always returned <code class="language-plaintext highlighter-rouge">null</code>.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 id="language-versions">Language versions</h3>
|
||
|
||
<ul>
|
||
<li>Since all languages now have defined language versions, you could now write rules that apply only for specific
|
||
versions (using <code class="language-plaintext highlighter-rouge">minimumLanguageVersion</code> and <code class="language-plaintext highlighter-rouge">maximumLanguageVersion</code>).</li>
|
||
<li>All languages have a default version. If no specific version on the CLI is given using <code class="language-plaintext highlighter-rouge">--use-version</code>, then
|
||
this default version will be used. Usually the latest version is the default version.</li>
|
||
<li>The available versions for each language can be seen in the help message of the CLI <code class="language-plaintext highlighter-rouge">pmd check --help</code>.</li>
|
||
<li>See also <a href="pmd_release_notes_pmd7.html#changed-language-versions">Changed: Language versions</a></li>
|
||
</ul>
|
||
|
||
<h3 id="migrating-custom-cpd-language-modules">Migrating custom CPD language modules</h3>
|
||
|
||
<p>This is only relevant, if you are maintaining a CPD language module for a custom language.</p>
|
||
|
||
<ul>
|
||
<li>Instead of <code class="language-plaintext highlighter-rouge">AbstractLanguage</code> extend now <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/impl/CpdOnlyLanguageModuleBase.html#"><code>CpdOnlyLanguageModuleBase</code></a>.</li>
|
||
<li>Instead of <code class="language-plaintext highlighter-rouge">AntlrTokenManager</code> use now <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/TokenManager.html#"><code>TokenManager</code></a></li>
|
||
<li>Instead of <code class="language-plaintext highlighter-rouge">AntlrTokenFilter</code> also use now <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/TokenManager.html#"><code>TokenManager</code></a></li>
|
||
<li>Instead of <code class="language-plaintext highlighter-rouge">AntlrTokenFilter</code> extend now <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/cpd/impl/BaseTokenFilter.html#"><code>BaseTokenFilter</code></a></li>
|
||
<li>CPD Module discovery change. The service loader won’t load anymore <code class="language-plaintext highlighter-rouge">src/main/resources/META-INF/services/net.sourceforge.pmd.cpd.Language</code>
|
||
but instead <code class="language-plaintext highlighter-rouge">src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language</code>. This is the unified
|
||
language interface for both PMD and CPD capable languages. See also the subinterfaces
|
||
<a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/cpd/CpdCapableLanguage.html#"><code>CpdCapableLanguage</code></a> and <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0-SNAPSHOT/net/sourceforge/pmd/lang/PmdCapableLanguage.html#"><code>PmdCapableLanguage</code></a>.</li>
|
||
<li>The documentation <a href="pmd_devdocs_major_adding_new_cpd_language.html">How to add a new CPD language</a> has been updated
|
||
to reflect these changes.</li>
|
||
</ul>
|
||
|
||
<h3 id="build-tools">Build Tools</h3>
|
||
|
||
<div class="alert alert-info" role="alert"><i class="fas fa-info-circle"></i> <b>Note:</b>
|
||
When you switch from PMD 6.x to PMD 7 in your build tools, you most likely need to review your
|
||
ruleset(s) as well and check for removed rules.
|
||
See the use case <a href="#im-using-only-built-in-rules">I’m using only built-in rules</a> above.
|
||
</div>
|
||
|
||
<h4 id="ant">Ant</h4>
|
||
|
||
<ul>
|
||
<li>The Ant tasks <a href="https://docs.pmd-code.org/apidocs/pmd-ant/7.3.0-SNAPSHOT/net/sourceforge/pmd/ant/PMDTask.html#"><code>PMDTask</code></a> and <a href="https://docs.pmd-code.org/apidocs/pmd-ant/7.3.0-SNAPSHOT/net/sourceforge/pmd/ant/CPDTask.html#"><code>CPDTask</code></a> have been moved from the module
|
||
<code class="language-plaintext highlighter-rouge">pmd-core</code> into the new module <code class="language-plaintext highlighter-rouge">pmd-ant</code>.</li>
|
||
<li>You need to add this dependency/jar file onto the class path (<code class="language-plaintext highlighter-rouge">net.sourceforge.pmd:pmd-ant</code>) in order to
|
||
import the tasks into your build file.</li>
|
||
<li>When using the guide <a href="pmd_userdocs_tools_ant.html">Ant Task Usage</a> then no change is needed, since
|
||
the pmd-ant jar file is included in the binary distribution of PMD. It is part of PMD’s lib folder.</li>
|
||
</ul>
|
||
|
||
<h4 id="maven">Maven</h4>
|
||
|
||
<ul>
|
||
<li>Since maven-pmd-plugin 3.22.0, PMD 7 is supported directly.</li>
|
||
<li>See <a href="https://issues.apache.org/jira/browse/MPMD-379">MPMD-379</a></li>
|
||
<li>See <a href="pmd_userdocs_tools_maven.html#using-pmd-7-with-maven-pmd-plugin">Using PMD 7 with maven-pmd-plugin</a></li>
|
||
</ul>
|
||
|
||
<h4 id="gradle">Gradle</h4>
|
||
|
||
<ul>
|
||
<li>Gradle uses internally PMD’s Ant task to execute PMD</li>
|
||
<li>Gradle 8.6 supports PMD 7 out of the box, but does not yet use PMD 7 by default.</li>
|
||
<li>You can set <code class="language-plaintext highlighter-rouge">toolVersion = "7.3.0-SNAPSHOT"</code>.</li>
|
||
<li>Only for older gradle versions you need to configure the dependencies manually for now, since
|
||
the ant task is in an own dependency with PMD 7:
|
||
<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">pmd</span> <span class="s1">'net.sourceforge.pmd:pmd-ant:7.3.0-SNAPSHOT'</span>
|
||
<span class="n">pmd</span> <span class="s1">'net.sourceforge.pmd:pmd-java:7.3.0-SNAPSHOT'</span>
|
||
</code></pre></div> </div>
|
||
</li>
|
||
<li>See <a href="https://github.com/gradle/gradle/issues/24502">Support for PMD 7.0</a></li>
|
||
</ul>
|
||
|
||
<h3 id="xml-report-format">XML Report Format</h3>
|
||
|
||
<p>The <a href="pmd_userdocs_report_formats.html#xml">XML Report format</a> supports rendering <a href="pmd_userdocs_suppressing_warnings.html">suppressed violations</a>.</p>
|
||
|
||
<p>The content of the attribute <code class="language-plaintext highlighter-rouge">suppressiontype</code> is changed in PMD 7.0.0:</p>
|
||
<ul>
|
||
<li><code class="language-plaintext highlighter-rouge">nopmd</code> ➡️ <code class="language-plaintext highlighter-rouge">//nopmd</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">annotation</code> ➡️ <code class="language-plaintext highlighter-rouge">@suppresswarnings</code></li>
|
||
<li><code class="language-plaintext highlighter-rouge">xpath</code> - new value. Suppressed via property “violationSuppressXPath”.</li>
|
||
<li><code class="language-plaintext highlighter-rouge">regex</code> - new value. Suppressed via property “violationSuppressRegex”.</li>
|
||
</ul>
|
||
|
||
|
||
<div class="tags">
|
||
|
||
<b>Tags: </b>
|
||
|
||
|
||
|
||
|
||
|
||
<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/master/docs/pages/pmd/userdocs/migrating_to_pmd7.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">
|
||
©2024 PMD Open Source Project. All rights
|
||
reserved. <br />
|
||
<span>Page last updated:</span>
|
||
June 2024 (7.3.0)<br /> Site last generated: Jun 28, 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>
|