forked from phoedos/pmd
Merge branch 'master' into junit-rule-pmd-test-runner
This commit is contained in:
@ -6,8 +6,8 @@ GEM
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.5.1)
|
||||
public_suffix (~> 2.0, >= 2.0.2)
|
||||
addressable (2.5.2)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
@ -16,21 +16,21 @@ GEM
|
||||
ethon (0.10.1)
|
||||
ffi (>= 1.3.0)
|
||||
execjs (2.7.0)
|
||||
faraday (0.13.0)
|
||||
faraday (0.13.1)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.9.18)
|
||||
forwardable-extended (2.6.0)
|
||||
gemoji (3.0.0)
|
||||
github-pages (151)
|
||||
github-pages (158)
|
||||
activesupport (= 4.2.8)
|
||||
github-pages-health-check (= 1.3.5)
|
||||
jekyll (= 3.5.1)
|
||||
jekyll (= 3.5.2)
|
||||
jekyll-avatar (= 0.4.2)
|
||||
jekyll-coffeescript (= 1.0.1)
|
||||
jekyll-default-layout (= 0.1.4)
|
||||
jekyll-feed (= 0.9.2)
|
||||
jekyll-gist (= 1.4.1)
|
||||
jekyll-github-metadata (= 2.6.0)
|
||||
jekyll-github-metadata (= 2.9.1)
|
||||
jekyll-mentions (= 1.2.0)
|
||||
jekyll-optional-front-matter (= 0.2.0)
|
||||
jekyll-paginate (= 1.1.0)
|
||||
@ -38,7 +38,7 @@ GEM
|
||||
jekyll-redirect-from (= 0.12.1)
|
||||
jekyll-relative-links (= 0.4.1)
|
||||
jekyll-sass-converter (= 1.5.0)
|
||||
jekyll-seo-tag (= 2.2.3)
|
||||
jekyll-seo-tag (= 2.3.0)
|
||||
jekyll-sitemap (= 1.0.0)
|
||||
jekyll-swiss (= 0.4.0)
|
||||
jekyll-theme-architect (= 0.1.0)
|
||||
@ -50,7 +50,7 @@ GEM
|
||||
jekyll-theme-midnight (= 0.1.0)
|
||||
jekyll-theme-minimal (= 0.1.0)
|
||||
jekyll-theme-modernist (= 0.1.0)
|
||||
jekyll-theme-primer (= 0.4.0)
|
||||
jekyll-theme-primer (= 0.5.2)
|
||||
jekyll-theme-slate (= 0.1.0)
|
||||
jekyll-theme-tactile (= 0.1.0)
|
||||
jekyll-theme-time-machine (= 0.1.0)
|
||||
@ -69,11 +69,11 @@ GEM
|
||||
octokit (~> 4.0)
|
||||
public_suffix (~> 2.0)
|
||||
typhoeus (~> 0.7)
|
||||
html-pipeline (2.6.0)
|
||||
html-pipeline (2.7.0)
|
||||
activesupport (>= 2)
|
||||
nokogiri (>= 1.4)
|
||||
i18n (0.8.6)
|
||||
jekyll (3.5.1)
|
||||
jekyll (3.5.2)
|
||||
addressable (~> 2.4)
|
||||
colorator (~> 1.0)
|
||||
jekyll-sass-converter (~> 1.0)
|
||||
@ -94,7 +94,7 @@ GEM
|
||||
jekyll (~> 3.3)
|
||||
jekyll-gist (1.4.1)
|
||||
octokit (~> 4.2)
|
||||
jekyll-github-metadata (2.6.0)
|
||||
jekyll-github-metadata (2.9.1)
|
||||
jekyll (~> 3.1)
|
||||
octokit (~> 4.0, != 4.4.0)
|
||||
jekyll-mentions (1.2.0)
|
||||
@ -112,7 +112,7 @@ GEM
|
||||
jekyll (~> 3.3)
|
||||
jekyll-sass-converter (1.5.0)
|
||||
sass (~> 3.4)
|
||||
jekyll-seo-tag (2.2.3)
|
||||
jekyll-seo-tag (2.3.0)
|
||||
jekyll (~> 3.3)
|
||||
jekyll-sitemap (1.0.0)
|
||||
jekyll (~> 3.3)
|
||||
@ -144,8 +144,9 @@ GEM
|
||||
jekyll-theme-modernist (0.1.0)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-primer (0.4.0)
|
||||
jekyll-theme-primer (0.5.2)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-github-metadata (~> 2.9)
|
||||
jekyll-seo-tag (~> 2.2)
|
||||
jekyll-theme-slate (0.1.0)
|
||||
jekyll (~> 3.5)
|
||||
@ -214,4 +215,4 @@ DEPENDENCIES
|
||||
jekyll
|
||||
|
||||
BUNDLED WITH
|
||||
1.13.6
|
||||
1.15.1
|
||||
|
@ -7,15 +7,16 @@ This site was built using the tomjohnson1492/documentation-theme-jekyll theme
|
||||
|
||||
A Jekyll-based theme designed for documentation and help systems. See the link for detailed instructions on setting up and configuring everything. http://idratherbewriting.com/documentation-theme-jekyll/
|
||||
|
||||
## Building using Bundler
|
||||
|
||||
Build the site to see the instructions for using it. Or just go here: [http://idratherbewriting.com/documentation-theme-jekyll/](http://idratherbewriting.com/documentation-theme-jekyll/)
|
||||
|
||||
Run `bundle exec jekyll serve --watch` to fire up Jekyll on local machine
|
||||
|
||||
## Using Docker
|
||||
|
||||
One time: `docker build --no-cache -t mydocs .`
|
||||
|
||||
Now run the site with `docker run --rm=true -v "$PWD:/src" -p 4005:4005 mydocs serve -H 0.0.0.0`
|
||||
bundle install # once
|
||||
bundle exec jekyll serve
|
||||
|
||||
Go to: http://localhost:4005/
|
||||
|
||||
## Building using Docker
|
||||
|
||||
docker build --no-cache -t pmd-doc . # once
|
||||
docker run --rm=true -v "$PWD:/src" -p 4005:4005 pmd-doc serve -H 0.0.0.0
|
||||
|
||||
Go to: http://localhost:4005/
|
||||
|
@ -2,6 +2,7 @@ repository: pmd/pmd
|
||||
|
||||
pmd:
|
||||
version: 6.0.0
|
||||
date: to-be-defined
|
||||
|
||||
output: web
|
||||
# this property is useful for conditional filtering of content that is separate from the PDF.
|
||||
|
@ -45,9 +45,20 @@ entries:
|
||||
- title: Suppressing
|
||||
url: /pmd_userdocs_suppressing.html
|
||||
output: web, pdf
|
||||
- title: Tools / Integrations
|
||||
url: /pmd_userdocs_tools.html
|
||||
output: web, pdf
|
||||
subfolders:
|
||||
- title: Tools / Integrations
|
||||
output: web, pdf
|
||||
subfolderitems:
|
||||
- title: Maven PMD Plugin
|
||||
output: web, pdf
|
||||
url: /pmd_userdocs_tools_maven.html
|
||||
- title: Ant
|
||||
output: web, pdf
|
||||
url: /pmd_userdocs_tools_ant.html
|
||||
- title: Other Tools / Integrations
|
||||
output: web, pdf
|
||||
url: /pmd_userdocs_tools.html
|
||||
|
||||
- title: FAQ
|
||||
url: /pmd_userdocs_faq.html
|
||||
output: web, pdf
|
||||
@ -123,6 +134,12 @@ entries:
|
||||
- title: Developer Documentation
|
||||
output: web, pdf
|
||||
folderitems:
|
||||
- title: Developer Resources
|
||||
url: /pmd_devdocs_development.html
|
||||
output: web, pdf
|
||||
- title: Writing Documentation
|
||||
url: /pmd_devdocs_writing_documentation.html
|
||||
output: web, pdf
|
||||
- title: Code Style
|
||||
url: /pmd_devdocs_codestyle.html
|
||||
output: web, pdf
|
||||
|
@ -6,7 +6,11 @@
|
||||
{% for folder in entry.folders %}
|
||||
{% if folder.output contains "web" %}
|
||||
<li>
|
||||
{% if folder.url %}
|
||||
<a href="{{ folder.url | remove: "/" }}">{{ folder.title }}</a>
|
||||
{% else %}
|
||||
<a href="#">{{ folder.title }}</a>
|
||||
{% endif %}
|
||||
<ul>
|
||||
{% for folderitem in folder.folderitems %}
|
||||
{% if folderitem.output contains "web" %}
|
||||
|
@ -2,38 +2,97 @@
|
||||
title: PMD Introduction
|
||||
keywords: java
|
||||
tags: [getting_started]
|
||||
sidebar: pmd_sidebar
|
||||
permalink: index.html
|
||||
summary: Welcome to PMD, an extensible cross-language static code analyzer.
|
||||
toc: false
|
||||
summary: >
|
||||
Welcome to PMD, an extensible cross-language static code analyzer.
|
||||
It finds common programming flaws like unused variables, empty catch blocks, unnecessary object creation,
|
||||
and so forth. Additionally it includes CPD, the copy-paste-detector. CPD finds duplicated code.
|
||||
last_updated: August 2017
|
||||
author: Jeff Jensen <jjensen@apache.org>, Andreas Dangel <andreas.dangel@adangel.org>
|
||||
---
|
||||
|
||||
{% include image.html file="pmd-logo-big.png" alt="PMD Logo" %}
|
||||
|
||||
# Welcome to PMD
|
||||
<br>
|
||||
|
||||
PMD scans source code in Java and other languages and looks for potential problems like:
|
||||
**PMD** scans source code in Java and other languages and looks for potential problems like:
|
||||
|
||||
* Possible bugs - empty try/catch/finally/switch statements
|
||||
* Dead code - unused local variables, parameters and private methods
|
||||
* Suboptimal code - wasteful String/StringBuffer usage
|
||||
* Overcomplicated expressions - unnecessary if statements, for loops that could be while loops
|
||||
* Duplicate code - copied/pasted code means copied/pasted bugs
|
||||
|
||||
## Download
|
||||
**CPD**, the copy-paste-detector, finds duplicated code in many languages:
|
||||
|
||||
You can [download everything from here](https://github.com/pmd/pmd/releases).
|
||||
* Duplicate code is often just copied and pasted. This means, the bugs are also copied and pasted. Fixing
|
||||
them means, fix all duplicated code locations.
|
||||
|
||||
You can get an overview of all the rules for e.g. Java at the [rulesets index](pmd_rules_java.html) page.
|
||||
## Features
|
||||
|
||||
PMD is [integrated](pmd_userdocs_tools.html) with JDeveloper, Eclipse, JEdit, JBuilder, BlueJ, CodeGuide, NetBeans/Sun Java Studio Enterprise/Creator, IntelliJ IDEA, TextPad, Maven, Ant, Gel, JCreator, and Emacs.
|
||||
{::options parse_block_html="true" /}
|
||||
|
||||
<div class="row"><div class="col-lg-6">
|
||||
### PMD
|
||||
|
||||
Features:
|
||||
|
||||
* Supporting 8 languages
|
||||
* Many ready-to-use built-in rules.
|
||||
* Custom rules can be written in Java
|
||||
* Custom rules can be written using XPath expression that query the AST of the sources
|
||||
* Many output formats
|
||||
* Many integrations into IDEs, build tools
|
||||
|
||||
Supported Languages:
|
||||
|
||||
* [Java](pmd_rules_java.html)
|
||||
* [JavaScript](pmd_rules_ecmascript.html)
|
||||
* [Salesforce.com Apex](pmd_rules_apex.html) and [Visualforce](pmd_rules_vf.html)
|
||||
* [PLSQL](pmd_rules_plsql.html)
|
||||
* [Apache Velocity](pmd_rules_vm.html)
|
||||
* [XML](pmd_rules_xml.html) and [Maven POM](pmd_rules_pom.html)
|
||||
* [XSL](pmd_rules_xsl.html)
|
||||
|
||||
</div><div class="col-lg-6">
|
||||
### CPD
|
||||
|
||||
Features:
|
||||
|
||||
* Supporting 19 languages
|
||||
* Simple GUI
|
||||
* Fast
|
||||
* Many integrations
|
||||
|
||||
Supported Languages:
|
||||
|
||||
* Java
|
||||
* C, C++
|
||||
* C#
|
||||
* Groovy
|
||||
* PHP
|
||||
* Ruby
|
||||
* Fortran
|
||||
* JavaScript
|
||||
* PLSQL
|
||||
* Apache Velocity
|
||||
* Scala
|
||||
* Objective C
|
||||
* Matlab
|
||||
* Python
|
||||
* Go
|
||||
* Swift
|
||||
* Salesforce.com Apex and Visualforce
|
||||
|
||||
</div></div>
|
||||
|
||||
## Download PMD {{ site.pmd.version }}
|
||||
|
||||
Latest Version: {{ site.pmd.version }} ({{ site.pmd.date }})
|
||||
|
||||
* [Release Notes](pmd_release_notes.html)
|
||||
* [Download](https://github.com/pmd/pmd/releases)
|
||||
|
||||
|
||||
## Future Releases
|
||||
|
||||
The next version of PMD will be developed in parallel with this release. We will release additional bugfix versions as needed.
|
||||
|
||||
A [snapshot](http://pmd.sourceforge.net/snapshot) of the web site for the new version is generated daily by our continuous integration server.
|
||||
|
||||
Maven packages are also generated regularly and uploaded to [Sonatypes OSS snapshot repository](https://oss.sonatype.org/content/repositories/snapshots/net/sourceforge/pmd/pmd/).
|
||||
|
||||
{% include links.html %}
|
||||
|
@ -2,13 +2,12 @@
|
||||
title: Adding support for metrics to a language
|
||||
short_title: Implement a metrics framework
|
||||
tags: [customizing]
|
||||
summary: "PMD's Java module has an extensive framework for the calculation of metrics, which allows rule developers
|
||||
to implement and use new code metrics very simply. Most of the functionality of this framework is abstracted in such
|
||||
summary: "PMD's Java module has an extensive framework for the calculation of metrics, which allows rule developers
|
||||
to implement and use new code metrics very simply. Most of the functionality of this framework is abstracted in such
|
||||
a way that any PMD supported language can implement such a framework without too much trouble. Here's how."
|
||||
last_updated: August 2017
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_devdocs_adding_metrics_support_to_language.html
|
||||
folder: pmd/devdocs
|
||||
author: Clément Fournier <clement.fournier76@gmail.com>
|
||||
---
|
||||
|
||||
{% include warning.html content="WIP, unstable API" %}
|
||||
@ -18,100 +17,100 @@ folder: pmd/devdocs
|
||||
### Overview of the Java framework
|
||||
|
||||
The framework has several subsystems, the two most easily identifiable being:
|
||||
* A **project memoizer** (`ProjectMemoizer`). When a metric is computed, it's stored back in this structure and can be
|
||||
reused later. This
|
||||
reduces the overhead on the calculation of e.g. aggregate results (`ResultOption` calculations). The contents of
|
||||
this data structure are indexed with fully qualified names (`JavaQualifiedName`), which must identify unambiguously
|
||||
* A **project memoizer** (`ProjectMemoizer`). When a metric is computed, it's stored back in this structure and can be
|
||||
reused later. This
|
||||
reduces the overhead on the calculation of e.g. aggregate results (`ResultOption` calculations). The contents of
|
||||
this data structure are indexed with fully qualified names (`JavaQualifiedName`), which must identify unambiguously
|
||||
classes and methods.
|
||||
|
||||
* The **façade**. The static end-user façade (`JavaMetrics`) is backed by an instance of a `JavaMetricsFaçade`. This
|
||||
allows us to abstract the functionality of the façade into `pmd-core` for other frameworks to use. The façade
|
||||
instance contains a project memoizer for the analysed project, and a metrics computer
|
||||
(`JavaMetricsComputer`). It's this last object which really computes the metric and stores back its result in the
|
||||
* The **façade**. The static end-user façade (`JavaMetrics`) is backed by an instance of a `JavaMetricsFaçade`. This
|
||||
allows us to abstract the functionality of the façade into `pmd-core` for other frameworks to use. The façade
|
||||
instance contains a project memoizer for the analysed project, and a metrics computer
|
||||
(`JavaMetricsComputer`). It's this last object which really computes the metric and stores back its result in the
|
||||
project mirror, while the façade only handles parameters.
|
||||
|
||||
Metrics (`Metric<N>`) plug in to this static system and only provide behaviour that's executed by the metrics computer.
|
||||
Internally, metric keys (`MetricKey<N>`) are parameterized with their version (`MetricVersion`) to index memoisation
|
||||
maps (see `ParameterizedMetricKey<N>`). This allows us to memoise several versions of the same metric without conflict.
|
||||
Metrics (`Metric<N>`) plug in to this static system and only provide behaviour that's executed by the metrics computer.
|
||||
Internally, metric keys (`MetricKey<N>`) are parameterized with their version (`MetricVersion`) to index memoisation
|
||||
maps (see `ParameterizedMetricKey<N>`). This allows us to memoise several versions of the same metric without conflict.
|
||||
|
||||
{% include important.html content="The following will be moved when multifile analysis and metrics are separated" %}
|
||||
<!-- We should probably create a dedicated page about the architecture of multifile analysis/ signature matching and how
|
||||
to implement that -->
|
||||
|
||||
At the very least, a metrics framework has those two components and is just a convenient way to compute and memoize
|
||||
metrics on a single file. Yet, one of the goals of the metrics framework is to allow for **multi-file analysis**, which
|
||||
make it possible, for instance, to compute the coupling between two classes. This feature uses two major
|
||||
At the very least, a metrics framework has those two components and is just a convenient way to compute and memoize
|
||||
metrics on a single file. Yet, one of the goals of the metrics framework is to allow for **multi-file analysis**, which
|
||||
make it possible, for instance, to compute the coupling between two classes. This feature uses two major
|
||||
components:
|
||||
* A **project mirror**. This data structure that stores info about all classes and operations (and other relevant
|
||||
* A **project mirror**. This data structure that stores info about all classes and operations (and other relevant
|
||||
entities, such as fields, packages, etc.) of the analysed project. This is implemented by `PackageStats` in the Java
|
||||
framework. The role of this structure is to make info about other files available to rules. It's filled by a visitor before rules apply.
|
||||
|
||||
The information stored in this data structure that's accessible to metrics is mainly comprised of method and field
|
||||
signatures (e.g. `JavaOperationSignature`), which describes concisely the characteristics of the method or field
|
||||
The information stored in this data structure that's accessible to metrics is mainly comprised of method and field
|
||||
signatures (e.g. `JavaOperationSignature`), which describes concisely the characteristics of the method or field
|
||||
(roughly, its modifiers).
|
||||
|
||||
* Some kind of method and field **usage resolution**, i.e. some way to find the fully qualified name of a method from a
|
||||
|
||||
* Some kind of method and field **usage resolution**, i.e. some way to find the fully qualified name of a method from a
|
||||
method call expression node. This is the trickiest part to implement. In Java it depends on type resolution.
|
||||
|
||||
### Abstraction layer
|
||||
|
||||
As you may have seen, most of the functionality of the first two components are abstracted into `pmd-core`. This
|
||||
allows us to implement new metrics frameworks quite quickly. These abstract components are parameterized by the
|
||||
node types of the class and operation AST nodes. Moreover, it makes the external behaviour of the framework is very
|
||||
As you may have seen, most of the functionality of the first two components are abstracted into `pmd-core`. This
|
||||
allows us to implement new metrics frameworks quite quickly. These abstract components are parameterized by the
|
||||
node types of the class and operation AST nodes. Moreover, it makes the external behaviour of the framework is very
|
||||
stable across languages, yet each component can easily be customized by adding methods or overriding existing ones.
|
||||
|
||||
The signature matching aspect is framed by generic interfaces, but it can't really be abstracted more
|
||||
The signature matching aspect is framed by generic interfaces, but it can't really be abstracted more
|
||||
than that. For instance, the project mirror is very language specific. Java's implementation uses the natural structure
|
||||
provided by the language's package system to structure the project's content. Apex, on the other, has no package
|
||||
system and thus can't use the same mechanism. That explains why the interfaces framing the project mirror are very
|
||||
provided by the language's package system to structure the project's content. Apex, on the other, has no package
|
||||
system and thus can't use the same mechanism. That explains why the interfaces framing the project mirror are very
|
||||
loose. Their main goal is to provide type safety through generics.
|
||||
|
||||
Moreover, usage resolution depends on the availability of type resolution for the given language, which is only implemented in
|
||||
Java. For these reasons, signature matching is considered an optional feature of the metrics framework. But despite
|
||||
this limitation, signature matching still provides a elegant way to find information about the class we're in. This
|
||||
feature requires no usage resolution and can be used to implement sophisticated metrics, that already give access to
|
||||
|
||||
Moreover, usage resolution depends on the availability of type resolution for the given language, which is only implemented in
|
||||
Java. For these reasons, signature matching is considered an optional feature of the metrics framework. But despite
|
||||
this limitation, signature matching still provides a elegant way to find information about the class we're in. This
|
||||
feature requires no usage resolution and can be used to implement sophisticated metrics, that already give access to
|
||||
detection strategies.
|
||||
|
||||
## Implementation of a new framework
|
||||
|
||||
### 1. Groundwork
|
||||
|
||||
* Create a class implementing `QualifiedName`. This implementation must be tailored to the target language so
|
||||
that it can indentify unambiguously any class and operation in the analysed project. You
|
||||
* Create a class implementing `QualifiedName`. This implementation must be tailored to the target language so
|
||||
that it can indentify unambiguously any class and operation in the analysed project. You
|
||||
must implement `equals`, `hashCode` and `toString`.
|
||||
[Example](https://github.com/pmd/pmd/blob/52d78d2fa97913cf73814d0307a1c1ae6125a437/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedName.java)
|
||||
* Determine the AST nodes that correspond to class and method declaration in your language. These types are
|
||||
referred hereafter as `T` and `O`, respectively. Both these types must implement the interface `QualifiableNode`,
|
||||
* Determine the AST nodes that correspond to class and method declaration in your language. These types are
|
||||
referred hereafter as `T` and `O`, respectively. Both these types must implement the interface `QualifiableNode`,
|
||||
which means they must expose a `getQualifiedName` method to give access to their qualified name.
|
||||
|
||||
### 2. Implement and wire the project memoizer
|
||||
* Create a class extending `BasicProjectMemoizer<T, O>`. There's no abstract functionality to implement.
|
||||
[Example](https://github.com/pmd/pmd/blob/52d78d2fa97913cf73814d0307a1c1ae6125a437/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaProjectMemoizer.java)
|
||||
* Create an AST visitor that fills the project memoizer with memoizers. For that, you use `BasicProjectMemoizer`'s
|
||||
`addClassMemoizer` and `addOperationMemoizer` methods with a qualified name.
|
||||
* Create an AST visitor that fills the project memoizer with memoizers. For that, you use `BasicProjectMemoizer`'s
|
||||
`addClassMemoizer` and `addOperationMemoizer` methods with a qualified name.
|
||||
[Example](https://github.com/pmd/pmd/blob/master/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitor.java)
|
||||
* Create a façade class for your visitor. This class extends a `*ParserVisitorAdapter` class and only overrides the
|
||||
`initializeWith(Node)` method. It's supposed to make your real visitor accept the node in parameter.
|
||||
* Create a façade class for your visitor. This class extends a `*ParserVisitorAdapter` class and only overrides the
|
||||
`initializeWith(Node)` method. It's supposed to make your real visitor accept the node in parameter.
|
||||
[Example](https://github.com/pmd/pmd/blob/52d78d2fa97913cf73814d0307a1c1ae6125a437/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitorFacade.java)
|
||||
* Override the `getMetricsVisitorFacade()` method in your language's handler (e.g. `ApexHandler`). This method gives
|
||||
back a `VisitorStarter` which initializes your façade with a `Node`.
|
||||
* Override the `getMetricsVisitorFacade()` method in your language's handler (e.g. `ApexHandler`). This method gives
|
||||
back a `VisitorStarter` which initializes your façade with a `Node`.
|
||||
[Example](https://github.com/pmd/pmd/blob/52d78d2fa97913cf73814d0307a1c1ae6125a437/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/AbstractJavaHandler.java#L100-L108)
|
||||
* Your project memoizer should now get filled when the `metrics` attribute is set to `true` in the rule XML.
|
||||
|
||||
### 3. Implement the façade
|
||||
* Create a class extending `AbstractMetricsComputer<T, O>`. This object will be responsible for calculating metrics
|
||||
given a memoizer, a node and info about the metric. Typically, this object is stateless so you might as well make it
|
||||
* Create a class extending `AbstractMetricsComputer<T, O>`. This object will be responsible for calculating metrics
|
||||
given a memoizer, a node and info about the metric. Typically, this object is stateless so you might as well make it
|
||||
a singleton.
|
||||
[Example](https://github.com/pmd/pmd/blob/52d78d2fa97913cf73814d0307a1c1ae6125a437/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsComputer.java)
|
||||
* Create a class extending `AbstractMetricsFacade<T, O>`. This class needs a reference to your `ProjectMemoizer` and
|
||||
your `MetricsComputer`. It backs the real end user façade, and handles user provided parameters before delegating to
|
||||
* Create a class extending `AbstractMetricsFacade<T, O>`. This class needs a reference to your `ProjectMemoizer` and
|
||||
your `MetricsComputer`. It backs the real end user façade, and handles user provided parameters before delegating to
|
||||
your `MetricsComputer`.
|
||||
[Example](https://github.com/pmd/pmd/blob/52d78d2fa97913cf73814d0307a1c1ae6125a437/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsFacade.java)
|
||||
* Create the static façade of your framework. This one has an instance of your `MetricsFaçade` object and delegates
|
||||
* Create the static façade of your framework. This one has an instance of your `MetricsFaçade` object and delegates
|
||||
static methods to that instance.
|
||||
[Example](https://github.com/pmd/pmd/blob/52d78d2fa97913cf73814d0307a1c1ae6125a437/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java)
|
||||
* Create classes `AbstractOperationMetric` and `AbstractClassMetric`. These must implement `Metric<T>` and
|
||||
`Metric<O>`, respectively. They typically provide defaults for the `supports` method of each metric.
|
||||
* Create classes `AbstractOperationMetric` and `AbstractClassMetric`. These must implement `Metric<T>` and
|
||||
`Metric<O>`, respectively. They typically provide defaults for the `supports` method of each metric.
|
||||
[Example](https://github.com/pmd/pmd/blob/52d78d2fa97913cf73814d0307a1c1ae6125a437/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/AbstractJavaOperationMetric.java)
|
||||
* Create enums `ClassMetricKey` and `OperationMetricKey`. These must implement `MetricKey<T>` and `MetricKey<O>`. The
|
||||
enums list all available metric keys for your language.
|
||||
@ -122,21 +121,20 @@ detection strategies.
|
||||
{% include important.html content="The following section will be moved when multifile analysis and metrics are separated" %}
|
||||
|
||||
### Optional: Signature matching
|
||||
|
||||
You can match the signature of anything: method, field, class, package... It depends on what's useful for you.
|
||||
Suppose you want to be able to match signatures for nodes of type `N`. What you have to do then is the following:
|
||||
|
||||
* Create a class implementing the interface `Signature<N>`. Signatures describe basic information about the node,
|
||||
which typically includes most of the modifiers they declare (eg visibility, abstract or virtual, etc.).
|
||||
|
||||
You can match the signature of anything: method, field, class, package... It depends on what's useful for you.
|
||||
Suppose you want to be able to match signatures for nodes of type `N`. What you have to do then is the following:
|
||||
|
||||
* Create a class implementing the interface `Signature<N>`. Signatures describe basic information about the node,
|
||||
which typically includes most of the modifiers they declare (eg visibility, abstract or virtual, etc.).
|
||||
It's up to you to define the right level of detail, depending on the accuracy of the pattern matching required.
|
||||
* Make type `N` implement `SignedNode<N>`. This makes the node capable of giving its signature. Factory methods to
|
||||
* Make type `N` implement `SignedNode<N>`. This makes the node capable of giving its signature. Factory methods to
|
||||
build a `Signature<N>` from a `N` are a good idea.
|
||||
* Create signature masks. A mask is an object that matches some signatures based on their features. For example, with
|
||||
the Java framework, you can build a `JavaOperationSigMask` that matches all method signatures with visibility
|
||||
the Java framework, you can build a `JavaOperationSigMask` that matches all method signatures with visibility
|
||||
`public`. A sigmask implements `SigMask<S>`, where `S` is the type of signature your mask handles.
|
||||
* Typically, the project mirror stores the signatures, so you have to implement it in a way that makes it possible to
|
||||
associate a signature with the qualified name of its node.
|
||||
* If you want to implement signature matching, create an `AbstractMetric` class, which gives access to a
|
||||
`SignatureMatcher` to your metrics. Typically, your implementation of `ProjectMirror` implements a
|
||||
associate a signature with the qualified name of its node.
|
||||
* If you want to implement signature matching, create an `AbstractMetric` class, which gives access to a
|
||||
`SignatureMatcher` to your metrics. Typically, your implementation of `ProjectMirror` implements a
|
||||
custom `SignatureMatcher` interface, and your façade can give back its instance of the project mirror.
|
||||
|
||||
|
@ -4,9 +4,8 @@ short_title: Add a New CPD Language
|
||||
tags: [customizing]
|
||||
summary: How to Add a New CPD Language
|
||||
last_updated: July 3, 2016
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_devdocs_adding_new_cpd_language.html
|
||||
folder: pmd/devdocs
|
||||
author: Romain PELISSE <belaran@gmail.com>
|
||||
---
|
||||
|
||||
# How to Add a New Language to CPD
|
||||
|
@ -1,8 +1,7 @@
|
||||
---
|
||||
title: Building PMD from source
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_devdocs_building.html
|
||||
folder: pmd/devdocs
|
||||
author: Tom Copeland, Xavier Le Vourch <xlv@users.sourceforge.net>
|
||||
---
|
||||
|
||||
# Compiling PMD
|
||||
|
36
docs/pages/pmd/devdocs/development.md
Normal file
36
docs/pages/pmd/devdocs/development.md
Normal file
@ -0,0 +1,36 @@
|
||||
---
|
||||
title: Developer Resources
|
||||
permalink: pmd_devdocs_development.html
|
||||
last_updated: August 2017
|
||||
---
|
||||
The next version of PMD will be developed in parallel with this release. We will release additional bugfix versions as needed.
|
||||
|
||||
## Source Code
|
||||
|
||||
The complete source code can be found on github:
|
||||
|
||||
* [github.com/pmd/pmd](https://github.com/pmd/pmd) - main PMD repository. Includes all the code to support all languages, including this documentation.
|
||||
* [github.com/pmd/pmd.github.io](https://github.com/pmd/pmd.github.io) - Contains the landing page [https://pmd.github.io](https://pmd.github.io)
|
||||
* [github.com/pmd/build-tools](https://github.com/pmd/build-tools) - Contains the checkstyle rules we use
|
||||
* [github.com/pmd/pmd-eclipse-plugin](https://github.com/pmd/pmd-eclipse-plugin) - The PMD eclipse plugin
|
||||
* [github.com/pmd](https://github.com/pmd) - PMD Organization at github. There are a couple of more repositories
|
||||
|
||||
## Continuous Integration
|
||||
|
||||
We use [Travis CI](https://travis-ci.org/pmd) as our ci service. The main repo and the eclipse plugin are built for
|
||||
every push. Each pull request is built as well.
|
||||
|
||||
The maven snapshot artifacts are deployed at [Sonatypes OSS snapshot repository](https://oss.sonatype.org/content/repositories/snapshots/net/sourceforge/pmd/pmd/).
|
||||
|
||||
Ready-to-use binary packages are uploaded to sourceforge at <https://sourceforge.net/projects/pmd/files/pmd/>.
|
||||
|
||||
## Documentation and Webpages
|
||||
|
||||
A [snapshot](http://pmd.sourceforge.net/snapshot) of the web site for the new version is generated travis-ci as well.
|
||||
|
||||
## Contributing
|
||||
|
||||
First off, thanks for taking the time to contribute!
|
||||
|
||||
Please have a look at [CONTRIBUTING.md](https://github.com/pmd/pmd/blob/master/CONTRIBUTING.md) and
|
||||
[BUILDING.md](https://github.com/pmd/pmd/blob/master/BUILDING.md).
|
@ -3,9 +3,8 @@ title: PMD How it Works
|
||||
tags: [customizing]
|
||||
summary: How PMD Works
|
||||
last_updated: July 3, 2016
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_devdocs_how_pmd_works.html
|
||||
folder: pmd/devdocs
|
||||
author: Tom Copeland
|
||||
---
|
||||
|
||||
# How it works
|
||||
|
@ -4,9 +4,8 @@ short_title: Info for Developers
|
||||
tags: [customizing]
|
||||
summary: Info for PMD Developers
|
||||
last_updated: July 3, 2016
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_devdocs_info_for_developers.html
|
||||
folder: pmd/devdocs
|
||||
author: Hooper Bloob <hooperbloob@users.sourceforge.net>, Romain Pelisse <rpelisse@users.sourceforge.net>
|
||||
---
|
||||
|
||||
# Information for PMD Developers
|
||||
|
@ -3,9 +3,8 @@ title: PMD Making Rulesets
|
||||
tags: [customizing]
|
||||
summary: Making Custom Rulesets for PMD
|
||||
last_updated: July 3, 2016
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_devdocs_making_rulesets.html
|
||||
folder: pmd/devdocs
|
||||
author: Tom Copeland <tomcopeland@users.sourceforge.net>
|
||||
---
|
||||
|
||||
# How to make a new rule set
|
||||
|
@ -1,22 +1,29 @@
|
||||
---
|
||||
title: Using code metrics in custom rules
|
||||
tags: [customizing]
|
||||
summary: "PMD was recently enhanced with the ability to compute code metrics on Java and Apex source (the so-called
|
||||
Metrics Framework). This framework provides developers with a straightforward interface to use code metrics in their
|
||||
summary: "PMD was recently enhanced with the ability to compute code metrics on Java and Apex source (the so-called
|
||||
Metrics Framework). This framework provides developers with a straightforward interface to use code metrics in their
|
||||
rules, and to extend the framework with their own custom metrics."
|
||||
last_updated: July 20, 2017
|
||||
permalink: pmd_devdocs_metrics_howto.html
|
||||
author: Clément Fournier <clement.fournier76@gmail.com>
|
||||
---
|
||||
# Using code metrics in custom rules
|
||||
|
||||
## Using the metrics framework
|
||||
|
||||
{%include note.html content="The following explains how to use the Java metrics framework. The Apex framework
|
||||
{%include note.html content="Using the metrics framework is for now restricted to Java rules (with plans to support
|
||||
XPath rules later)." %}
|
||||
|
||||
To use the metrics framework in a custom rule, the first thing to do would be to **enable metrics by adding the
|
||||
`metrics="true"` attribute** to your rule's XML element.
|
||||
|
||||
{%include note.html content="The following explains how to use the Java metrics framework. The Apex framework
|
||||
differs only by the name of its classes." %}
|
||||
|
||||
In PMD's Metrics framework, a metric is an operation that can be carried out on nodes of a certain type and produces
|
||||
a numeric result. In the Java framework, metrics can be computed on operation declaration nodes (constructor and
|
||||
method declaration), and type declaration nodes (class, interface, enum, and annotation declarations). A metric
|
||||
In PMD's Metrics framework, a metric is an operation that can be carried out on nodes of a certain type and produces
|
||||
a numeric result. In the Java framework, metrics can be computed on operation declaration nodes (constructor and
|
||||
method declaration), and type declaration nodes (class, interface, enum, and annotation declarations). A metric
|
||||
object in the framework can only handle either types or operations, but not both.
|
||||
|
||||
PMD ships with a library of already implemented metrics. These metrics are referenced by `MetricKey` objects,
|
||||
@ -27,9 +34,6 @@ each enum.
|
||||
|
||||
## For XPath rules
|
||||
|
||||
To use the metrics framework in a custom rule, the first thing to do would be to enable metrics by adding the
|
||||
`metrics="true"` attribute to your rule's XML element.
|
||||
|
||||
XPath rules can compute metrics using the `metric` function. This function takes a single **string argument**,
|
||||
which is the name of the metric key as defined in `JavaClassMetricKey` or `JavaOperationMetricKey`. The metric
|
||||
will be **computed on the context node**.
|
||||
@ -56,12 +60,13 @@ or `ConstructorDeclaration`.
|
||||
First, similarly to XPath rules, you should add the `metrics="true"` attribute to your rule's XML element.
|
||||
|
||||
The static façade class `JavaMetrics` is the single entry point to compute metrics in the Java framework.
|
||||
|
||||
This class provides the method `get` and its overloads. The following sections describes the interface of this class.
|
||||
|
||||
### Basic usage
|
||||
|
||||
The simplest overloads of `JavaMetrics.get` take two parameters: **a `MetricKey` and a node of the corresponding type.**
|
||||
Say you want to write a rule to report methods that have a high cyclomatic complexity. In your rule's visitor, you
|
||||
The simplest overloads of `JavaMetrics.get` take two parameters: **a `MetricKey` and a node of the corresponding type.**
|
||||
Say you want to write a rule to report methods that have a high cyclomatic complexity. In your rule's visitor, you
|
||||
can get the value of Cyclo for a method node like so:
|
||||
```java
|
||||
public Object visit(ASTMethodDeclaration method, Object data) {
|
||||
@ -74,18 +79,18 @@ public Object visit(ASTMethodDeclaration method, Object data) {
|
||||
```
|
||||
|
||||
The same goes for class metrics: you select one among `JavaClassMetricKey`'s constants and pass it along with the node
|
||||
to `JavaMetrics.get`.
|
||||
|
||||
{%include tip.html
|
||||
to `JavaMetrics.get`.
|
||||
|
||||
{%include tip.html
|
||||
content="A specific base rule class (`AbstractJavaMetricsRule`) exists
|
||||
to e.g. check constructors and method nodes completely alike. This comes
|
||||
in handy for metrics, as they usually don't make the distinction" %}
|
||||
|
||||
|
||||
### Capability checking
|
||||
|
||||
Metrics are not necessarily computable on any node of the type they handle. For example, Cyclo cannot be computed on
|
||||
Metrics are not necessarily computable on any node of the type they handle. For example, Cyclo cannot be computed on
|
||||
abstract methods. Metric keys provides a `supports(Node)` boolean method to find out if the metric can be computed on
|
||||
the specified node. **If the metric cannot be computed on the given node, `JavaMetrics.get` will return `Double.NaN` .**
|
||||
the specified node. **If the metric cannot be computed on the given node, `JavaMetrics.get` will return `Double.NaN` .**
|
||||
If you're concerned about that, you can condition your call on whether the node is supported or not:
|
||||
```java
|
||||
public Object visit(ASTMethodDeclaration method, Object data) {
|
||||
@ -101,16 +106,16 @@ public Object visit(ASTMethodDeclaration method, Object data) {
|
||||
|
||||
### Metric options
|
||||
|
||||
Some metrics define options that can be used to slightly modify the computation. You'll typically see these options
|
||||
gathered inside an enum in the implementation class of the metric, for example `CycloMetric.CycloOptions`. They're
|
||||
Some metrics define options that can be used to slightly modify the computation. You'll typically see these options
|
||||
gathered inside an enum in the implementation class of the metric, for example `CycloMetric.CycloOptions`. They're
|
||||
also documented on the [index of metrics](pmd_java_metrics_index.html).
|
||||
|
||||
To use options with a metric, you must first bundle them into a `MetricOptions` object. `MetricOptions` provides the
|
||||
utility method `ofOptions` to get a `MetricOptions` bundle from a collection or with varargs parameters. You can then
|
||||
To use options with a metric, you must first bundle them into a `MetricOptions` object. `MetricOptions` provides the
|
||||
utility method `ofOptions` to get a `MetricOptions` bundle from a collection or with varargs parameters. You can then
|
||||
pass this bundle as a parameter to `JavaMetrics.get`:
|
||||
```java
|
||||
public Object visit(ASTMethodDeclaration method, Object data) {
|
||||
int cyclo = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, method,
|
||||
int cyclo = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, method,
|
||||
MetricOptions.ofOptions(CycloOptions.IGNORE_BOOLEAN_PATHS));
|
||||
if (cyclo > 10) {
|
||||
// add violation
|
||||
@ -119,18 +124,18 @@ public Object visit(ASTMethodDeclaration method, Object data) {
|
||||
}
|
||||
```
|
||||
|
||||
The version of `MetricOptions.ofOptions` using a collection is useful when you're building a `MetricOptions` from eg
|
||||
the value of an `EnumeratedMultiProperty`, which gives users control of the options they use. See
|
||||
The version of `MetricOptions.ofOptions` using a collection is useful when you're building a `MetricOptions` from eg
|
||||
the value of an `EnumeratedMultiProperty`, which gives users control of the options they use. See
|
||||
[CyclomaticComplexityRule]( https://github.com/pmd/pmd/blob/master/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/rule/CyclomaticComplexityRule.java)
|
||||
for an example usage.
|
||||
|
||||
### Result options
|
||||
|
||||
The Metrics API also gives you the possibility to aggregate the result of an operation metric on all operations of a
|
||||
The Metrics API also gives you the possibility to aggregate the result of an operation metric on all operations of a
|
||||
class very simply. You can for example get the highest value of the metric over a class that way:
|
||||
```java
|
||||
public Object visit(ASTClassOrInterfaceDeclaration clazz, Object data) {
|
||||
int highest = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, clazz,
|
||||
int highest = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, clazz,
|
||||
ResultOption.HIGHEST);
|
||||
if (highest > 10) {
|
||||
// add violation
|
||||
@ -139,8 +144,8 @@ public Object visit(ASTClassOrInterfaceDeclaration clazz, Object data) {
|
||||
}
|
||||
```
|
||||
|
||||
Notice that **we use an operation metric and a class node**. The `ResultOption` parameter controls what result will be
|
||||
computed: you can choose among `HIGHEST`, `SUM` and `AVERAGE`. You can use metric options together with a result
|
||||
Notice that **we use an operation metric and a class node**. The `ResultOption` parameter controls what result will be
|
||||
computed: you can choose among `HIGHEST`, `SUM` and `AVERAGE`. You can use metric options together with a result
|
||||
option too.
|
||||
|
||||
### Complete use case
|
||||
@ -297,4 +302,3 @@ Language | Java | Apex |
|
||||
-----------|------|------|
|
||||
Operation metrics| supports constructors and non abstract methods| supports any non abstract method except `<init>`, `<clinit>`, and `clone`
|
||||
Type declaration|supports classes and enums|supports classes
|
||||
|
||||
|
@ -1,6 +1,173 @@
|
||||
---
|
||||
title: Pull Requests
|
||||
sidebar: pmd_sidebar
|
||||
title: Pull-Request Merge
|
||||
permalink: pmd_devdocs_pull_requests.html
|
||||
folder: pmd/devdocs
|
||||
last_updated: August 2017
|
||||
author: Andreas Dangel <andreas.dangel@adangel.org>
|
||||
---
|
||||
|
||||
## Contributing via pull requests
|
||||
|
||||
First off, thanks for taking the time to contribute!
|
||||
|
||||
* Please create your pull request against the `master` branch. We will rebase/merge it to the maintenance
|
||||
branches, if necessary. Just fork the [pmd repo](https://github.com/pmd/pmd/) and
|
||||
create a [pull request](https://github.com/pmd/pmd/pulls).
|
||||
|
||||
* We are using [checkstyle](http://checkstyle.sourceforge.net/) to enforce a common code style.
|
||||
The check is integrated into the default build - so, make sure, you can [build PMD](pmd_devdocs_building.html)
|
||||
without errors.
|
||||
|
||||
See [code style](pmd_devdocs_codestyle.html) for more info.
|
||||
|
||||
## Merging pull requests
|
||||
|
||||
### Example 1: Merging PR #123 into master
|
||||
|
||||
1. Review the pull request
|
||||
|
||||
* Compilation and checkstyle is verified already by travis build: PRs are automatically checked.
|
||||
* If it is a bug fix, a new unit test, that reproduces the bug, is mandatory. Without such a test, we might accidentally reintroduce the bug again.
|
||||
* Add the appropriate labels on the github issue: If the PR fixes a bug, the label "a:bug" should be used.
|
||||
* Make sure, the PR is added to the appropriate milestone. If the PR fixes a bug, make sure, that the bug issue is added to the same milestone.
|
||||
|
||||
2. The actual merge commands:
|
||||
|
||||
We assume, that the PR has been created from the master branch. If this is not the case,
|
||||
then we'll either need to rebase or ask for rebasing before merging.
|
||||
|
||||
```
|
||||
git checkout master && git pull origin master # make sure, you have the latest code
|
||||
git fetch origin pull/123/head:pr-123 && git checkout pr-123 # creates a new temporary branch
|
||||
```
|
||||
|
||||
3. Update the [release notes](https://github.com/pmd/pmd/blob/master/docs/pages/release_notes.md):
|
||||
|
||||
* Are there any API changes, that need to be documented? (Section "API Changes")
|
||||
* Are there any significant changes to existing rules, that should be mentioned?
|
||||
(Section "Modified Rules" / "New Rules" / "Removed Rules")
|
||||
* If the PR fixes a bug, make sure, it is listed under the section "Fixed Issues".
|
||||
* In any case, add the PR to the section "External Contributions"
|
||||
* Commit these changes with the message:
|
||||
|
||||
git add docs/pages/release_notes.md
|
||||
git commit -m "Update release notes, refs #123"
|
||||
|
||||
{% include note.html content="If the PR fixes a bug, verify, that we have a commit with the message
|
||||
\"Fixes #issue-number\". If this doesn't exist, you can add it to the commit message when
|
||||
updating the release notes: `Update release notes, refs #123, fixes #issue-number`.
|
||||
This will automatically close the github issue." %}
|
||||
|
||||
4. Now merge the pull request into the master branch:
|
||||
|
||||
```
|
||||
git checkout master
|
||||
git merge --no-ff pr-123
|
||||
```
|
||||
|
||||
{%include note.html content="If there are merge conflicts, you'll need to deal with them here." %}
|
||||
|
||||
5. Run the complete build: `./mvnw clean verify`
|
||||
|
||||
{% include note.html content="This will execute all the unit tests and the checkstyle tests. It ensures,
|
||||
that the complete project can be build and is functioning on top of the current master." %}
|
||||
|
||||
6. If the build was successful, you are ready to push:
|
||||
|
||||
```
|
||||
git push origin master
|
||||
```
|
||||
|
||||
Since the temporary branch is now not needed anymore, you can delete it:
|
||||
`git branch -d pr-123`.
|
||||
|
||||
|
||||
### Example 2: Merging PR #124 into a maintenance branch
|
||||
|
||||
We ask, to create every pull request against master, to make it easier to contribute.
|
||||
But if a pull request is intended to fix a bug in an older version of PMD, then we need to backport this pull request.
|
||||
|
||||
#### Creating a maintenance branch
|
||||
|
||||
For older versions, we use maintenance branches, like `pmd/5.8.x`. If there is no maintenance branch for
|
||||
the specific version, then we'll have to create it first. Let's say, we want a maintenance branch for
|
||||
PMD version 5.8.0, so that we can create a bugfix release 5.8.1.
|
||||
|
||||
1. We'll simply create a new branch off of the release tag:
|
||||
|
||||
```
|
||||
git branch pmd/5.8.x pmd_releases/5.8.0 && git checkout pmd/5.8.x
|
||||
```
|
||||
|
||||
2. Now we'll need to adjust the version, since it's currently the same as the release version.
|
||||
We'll change the version to the next patch version: "5.8.1-SNAPSHOT".
|
||||
|
||||
```
|
||||
./mvnw versions:set -DnewVersion=5.8.1-SNAPSHOT
|
||||
git add pom.xml \*/pom.xml
|
||||
git commit -m "prepare next version 5.8.1-SNAPSHOT"
|
||||
```
|
||||
|
||||
#### Merging the PR
|
||||
|
||||
1. As above: Review the PR
|
||||
|
||||
2. Fetch the PR and rebase it onto the maintenance branch:
|
||||
|
||||
```
|
||||
git fetch origin pull/124/head:pr-124 && git checkout pr-124 # creates a new temporary branch
|
||||
git rebase master --onto pmd/5.8.x
|
||||
./mvnw clean verify # make sure, everything works after the rebase
|
||||
```
|
||||
|
||||
{%include note.html content="You might need to fix conflicts / backport the commits for the older
|
||||
PMD version." %}
|
||||
|
||||
3. Update the release notes. See above for details.
|
||||
|
||||
4. Now merge the pull request into the maintenance branch:
|
||||
|
||||
```
|
||||
git checkout pmd/5.8.x
|
||||
git merge --no-ff pr-124
|
||||
```
|
||||
|
||||
5. Just to be sure, run the complete build again: `./mvnw clean verify`.
|
||||
|
||||
6. If the build was successful, you are ready to push:
|
||||
|
||||
```
|
||||
git push origin pmd/5.8.x
|
||||
```
|
||||
|
||||
7. Since we have rebased the pull request, it won't appear as merged on github.
|
||||
You need to manually close the pull request. Leave a comment, that it has been
|
||||
rebased onto the maintenance branch.
|
||||
|
||||
#### Merging into master
|
||||
|
||||
Now the PR has been merged into the maintenance branch, but it is missing in any later version of PMD.
|
||||
Therefore, we merge first into the next minor version maintenance branch (if existing):
|
||||
|
||||
git checkout pmd/5.9.x
|
||||
git merge pmd/5.8.x
|
||||
|
||||
After that, we merge the changes into the master branch:
|
||||
|
||||
git checkout master
|
||||
git merge pmd/5.9.x
|
||||
|
||||
{%include note.html content="This ensures, that every change on the maintenance branch eventually ends
|
||||
up in the master branch and therefore in any future version of PMD.<br>
|
||||
The downside is however, that there are inevitable merge conflicts for the maven `pom.xml` files, since
|
||||
every branch changed the version number differently.<br>
|
||||
We could avoid this by merging only the temporary branch \"pr-124\" into each maintenance branch and
|
||||
eventually into master, with the risk of missing single commits in a maintenance branch, that have been
|
||||
done outside the temporary branch." %}
|
||||
|
||||
#### Merging vs. Cherry-Picking
|
||||
|
||||
We are not using cherry-picking, so that each fix is represented by a single commit.
|
||||
Cherry-picking would duplicate the commit and you can't see in the log, on which branches the fix has been
|
||||
integrated (e.g. gitk and github show the branches, from which the specific commit is reachable).
|
||||
|
||||
The downside is a more complex history - the maintenance branches and master branch are "connected" and not separate.
|
||||
|
@ -1,8 +1,7 @@
|
||||
---
|
||||
title: Releasing
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_devdocs_releasing.html
|
||||
folder: pmd/devdocs
|
||||
author: Romain Pelisse <rpelisse@users.sourceforge.net>, Andreas Dangel <adangel@users.sourceforge.net>
|
||||
---
|
||||
|
||||
This page describes the current status of the release process.
|
||||
@ -172,7 +171,7 @@ Maybe there are some milestones on sourceforge, too: <https://sourceforge.net/p/
|
||||
### Merging
|
||||
|
||||
If the release was done on a maintenance branch, such as `pmd/5.4.x`, then this branch should be
|
||||
merge into the next "higher" branches, such as `pmd/5.5.x` and `master`.
|
||||
merged into the next "higher" branches, such as `pmd/5.5.x` and `master`.
|
||||
|
||||
This ensures, that all fixes done on the maintenance branch, finally end up in the other branches.
|
||||
In theory, the fixes should already be there, but you never now.
|
||||
@ -180,7 +179,7 @@ In theory, the fixes should already be there, but you never now.
|
||||
|
||||
### Multiple releases
|
||||
|
||||
If releases from multiple branches are being done, the order matters. You should start from the "oldes" branch,
|
||||
If releases from multiple branches are being done, the order matters. You should start from the "oldest" branch,
|
||||
e.g. `pmd/5.4.x`, release from there. Then merge (see above) into the next branch, e.g. `pmd/5.5.x` and release
|
||||
from there. Then merge into the `master` branch and release from there. This way, the last release done, becomes
|
||||
automatically the latest release on <https://pmd.github.io/latest/> and on sourceforge.
|
||||
|
@ -1,8 +1,9 @@
|
||||
---
|
||||
title: Roadmap
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_devdocs_roadmap.html
|
||||
folder: pmd/devdocs
|
||||
author: >
|
||||
Tom Copeland <tom@infoether.com>, Ryan Gustavson, Romain Pelisse <belaran@gmail.com>,
|
||||
Juan Martín Sotuyo Dodero <juansotuyo@gmail.com>, Andreas Dangel <adangel@users.sourceforge.net>
|
||||
---
|
||||
|
||||
|
||||
|
@ -3,9 +3,8 @@ title: PMD Rule Guidelines
|
||||
tags: [customizing]
|
||||
summary: Rule Guidelines
|
||||
last_updated: July 3, 2016
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_devdocs_rule_guidelines.html
|
||||
folder: pmd/devdocs
|
||||
author: Xavier Le Vourch, Ryan Gustafson, Romain Pelisse
|
||||
---
|
||||
|
||||
# Rule Guidelines
|
||||
|
143
docs/pages/pmd/devdocs/writing_documentation.md
Normal file
143
docs/pages/pmd/devdocs/writing_documentation.md
Normal file
@ -0,0 +1,143 @@
|
||||
---
|
||||
title: Writing Documentation
|
||||
last_update: August 2017
|
||||
permalink: pmd_devdocs_writing_documentation.html
|
||||
keywords: documentation, jekyll, markdown
|
||||
author: Andreas Dangel <andreas.dangel@adangel.org>
|
||||
---
|
||||
|
||||
PMD's documentation uses [Jekyll](https://jekyllrb.com/) with
|
||||
the [I'd rather be writing Jekyll Theme](http://idratherbewriting.com/documentation-theme-jekyll/index.html).
|
||||
|
||||
Here are some quick tips.
|
||||
|
||||
## Format
|
||||
|
||||
The pages are in general in [Github Flavored Markdown](https://kramdown.gettalong.org/parser/gfm.html).
|
||||
|
||||
## Structure
|
||||
|
||||
All documentation is stored in the folder `docs/`. This is the folder, that github and the travis-ci scripts
|
||||
use to render the site.
|
||||
|
||||
New pages are stored in the different subfolders under `pages`. The folder structure resembles the sidebar structure.
|
||||
Since all pages use a simple *permalink*, in the rendered html pages, all pages are flattened in one directory.
|
||||
This makes it easy to view the documentation also offline.
|
||||
|
||||
## Building
|
||||
|
||||
There are two ways, to execute jekyll:
|
||||
|
||||
1. Using [bundler](http://bundler.io/). This will install all the needed ruby packages locally and execute jekyll:
|
||||
|
||||
# this is required only once, to download and install the dependencies
|
||||
bundle install
|
||||
# this builds the documentation under _site
|
||||
bundle exec jekyll build
|
||||
# this runs a local webserver as http://localhost:4005
|
||||
bundle exec jekyll serve
|
||||
|
||||
2. Using [docker](https://www.docker.com/). This will create a local docker image, into which all needed ruby
|
||||
packages and jekyll is installed.
|
||||
|
||||
# this is required only once to create a local docker image named "pmd-doc"
|
||||
docker build --no-cache -t pmd-doc .
|
||||
# this builds the documentation under _site
|
||||
docker run --rm=true -v "$PWD:/src" pmd-doc build -H 0.0.0.0
|
||||
# this runs a local webserver as http://localhost:4005
|
||||
docker run --rm=true -v "$PWD:/src" -p 4005:4005 pmd-doc serve -H 0.0.0.0
|
||||
|
||||
The built site is stored locally in the (git ignored) directory `_site`. You can
|
||||
point your browser to `_site/index.html` to see the pmd documentation.
|
||||
|
||||
Alternatively, you can start the local webserver, that will serve the documentation.
|
||||
Just go to http://localhost:4005.
|
||||
If a page is modified, the documentation will automatically be rendered again and
|
||||
all you need to do, is refreshing the page in your browser.
|
||||
|
||||
See also the script [pmd-jekyll.sh](https://gist.github.com/oowekyala/ee6f8801138861072c59ce683bdf737b).
|
||||
It starts the jekyll server in the background and doesn't block the current shell.
|
||||
|
||||
## The sidebar
|
||||
|
||||
The sidebar is stored as a YAML document under `_data/sidebars/pmd_sidebar.yml`.
|
||||
|
||||
Make sure to add an entry there, whenever you create a new page.
|
||||
|
||||
|
||||
## The frontmatter
|
||||
|
||||
Each page in jekyll begins with a YAML section at the beginning. This section
|
||||
is separated by 3 dashes (`---`). Example:
|
||||
|
||||
---
|
||||
title: Writing Documentation
|
||||
last_update: August 2017
|
||||
permalink: pmd_devdocs_writing_documentation.html
|
||||
---
|
||||
|
||||
Some Text
|
||||
|
||||
# Some header
|
||||
|
||||
There are a couple of possible fields. Most important and always
|
||||
required are **title** and **permalink**.
|
||||
|
||||
By default, a page **toc** (table of contents) is automatically generated.
|
||||
You can prevent this with "toc: false".
|
||||
|
||||
You can add **keywords**, that will be used for the on-site search: "keywords: documentation, jekyll, markdown"
|
||||
|
||||
It's useful to maintain a **last_update** field. This will be added at the bottom of the
|
||||
page.
|
||||
|
||||
A **summary** can also be provided. It will be added in a box before the content.
|
||||
|
||||
For a more exhaustive list, see [Pages - Frontmatter](http://idratherbewriting.com/documentation-theme-jekyll/mydoc_pages.html#frontmatter).
|
||||
|
||||
|
||||
## Alerts and Callouts
|
||||
|
||||
See [Alerts](http://idratherbewriting.com/documentation-theme-jekyll/mydoc_alerts.html).
|
||||
|
||||
For example, a info-box can be created like this:
|
||||
|
||||
{%raw%}{% include note.html content="This is a note." %}{%endraw%}
|
||||
|
||||
It renders as:
|
||||
|
||||
{% include note.html content="This is a note." %}
|
||||
|
||||
Other available types are:
|
||||
|
||||
* note.html
|
||||
* tip.html
|
||||
* warning.html
|
||||
* important.html
|
||||
|
||||
|
||||
A callout is created like this:
|
||||
|
||||
{%raw%}{% include callout.html content="This is a callout of type default.<br/><br/>There are the following types available: danger, default, primary, success, info, and warning." type="default" %}{%endraw%}
|
||||
|
||||
It renders as:
|
||||
|
||||
{% include callout.html content="This is a callout of type default.<br/><br/>There are the following types available: danger, default, primary, success, info, and warning." type="default" %}
|
||||
|
||||
## Code samples with syntax highlighting
|
||||
|
||||
This is as easy as:
|
||||
|
||||
``` java
|
||||
public class Foo {
|
||||
public void bar() { System.out.println("x"); }
|
||||
}
|
||||
```
|
||||
|
||||
This looks as follows:
|
||||
|
||||
``` java
|
||||
public class Foo {
|
||||
public void bar() { System.out.println("x"); }
|
||||
}
|
||||
```
|
@ -3,9 +3,8 @@ title: PMD Writing a Custom Rule
|
||||
tags: [customizing]
|
||||
summary: Writing a Custom Rule for PMD
|
||||
last_updated: July 3, 2016
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_devdocs_writing_pmd_rules.html
|
||||
folder: pmd/devdocs
|
||||
author: Tom Copeland <tomcopeland@users.sourceforge.net>
|
||||
---
|
||||
|
||||
# How to write a PMD rule
|
||||
|
@ -1,11 +1,10 @@
|
||||
---
|
||||
title: PMD Writing XPath Rules
|
||||
title: Writing XPath Rules
|
||||
tags: [customizing]
|
||||
summary: "Writing XPath rules for PMD"
|
||||
last_updated: July 3, 2016
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_devdocs_writing_xpath_rules.html
|
||||
folder: pmd/devdocs
|
||||
author: Miguel Griffa <mikkey@users.sourceforge.net>
|
||||
---
|
||||
|
||||
# XPath Rule tutorial
|
||||
@ -151,4 +150,50 @@ The following expression does the magic we need:
|
||||
|
||||
We recommend at this point that you experiment with Designer putting the final modifier to the Factory and verifying that the results produced are those expected.
|
||||
|
||||
## Creating a new rule definition
|
||||
|
||||
To actually use your new XPath rule, it needs to be in a ruleset. You can create a new custom ruleset which just
|
||||
contains your new XPath rule. You can use the following template. Just make sure, to replace the `xpath` property,
|
||||
the example code and give your rule a useful name and message.
|
||||
|
||||
``` xml
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<ruleset name="Custom Rules"
|
||||
xmlns="http://pmd.sourceforge.net/ruleset/3.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/3.0.0 http://pmd.sourceforge.net/ruleset_3_0_0.xsd">
|
||||
<description>
|
||||
Custom rules
|
||||
</description>
|
||||
|
||||
<rule name="My Rule"
|
||||
language="java"
|
||||
message="violation message"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule">
|
||||
<description>
|
||||
Rule Description
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="xpath">
|
||||
<value><![CDATA[
|
||||
--- here comes your XPath expression
|
||||
]]></value>
|
||||
</property>
|
||||
</properties>
|
||||
<example>
|
||||
<![CDATA[
|
||||
public class ExampleCode {
|
||||
public void foo() {
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
</ruleset>
|
||||
```
|
||||
|
||||
|
||||
|
||||
Finally, for many more details on writing XPath rules, pick up [PMD Applied](http://pmdapplied.com/)!
|
||||
|
@ -1,8 +1,7 @@
|
||||
---
|
||||
title: JSP Support
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_languages_jsp.html
|
||||
folder: pmd/languages
|
||||
author: Pieter Vanraemdonck
|
||||
---
|
||||
|
||||
## What is currently supported and what is not
|
||||
|
@ -40,6 +40,11 @@ public class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/apexunit.xml/ApexUnitTestClassShouldHaveAsserts" />
|
||||
```
|
||||
|
||||
## ApexUnitTestShouldNotUseSeeAllDataTrue
|
||||
|
||||
**Since:** PMD 5.5.1
|
||||
@ -72,3 +77,8 @@ public class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/apexunit.xml/ApexUnitTestShouldNotUseSeeAllDataTrue" />
|
||||
```
|
||||
|
||||
|
@ -42,6 +42,11 @@ for (int i = 0; i < 42; i++) { // preferred approach
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/braces.xml/ForLoopsMustUseBraces" />
|
||||
```
|
||||
|
||||
## IfElseStmtsMustUseBraces
|
||||
|
||||
**Since:** PMD 5.6.0
|
||||
@ -79,6 +84,11 @@ else
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/braces.xml/IfElseStmtsMustUseBraces" />
|
||||
```
|
||||
|
||||
## IfStmtsMustUseBraces
|
||||
|
||||
**Since:** PMD 5.6.0
|
||||
@ -112,6 +122,11 @@ if (foo) { // preferred approach
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/braces.xml/IfStmtsMustUseBraces" />
|
||||
```
|
||||
|
||||
## WhileLoopsMustUseBraces
|
||||
|
||||
**Since:** PMD 5.6.0
|
||||
@ -145,3 +160,8 @@ while (true) { // preferred approach
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/braces.xml/WhileLoopsMustUseBraces" />
|
||||
```
|
||||
|
||||
|
@ -42,6 +42,11 @@ public class Foo {
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|problemDepth|3|The if statement depth reporting threshold|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/complexity.xml/AvoidDeeplyNestedIfStmts" />
|
||||
```
|
||||
|
||||
## ExcessiveClassLength
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -84,6 +89,11 @@ public class Foo {
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|sigma||Sigma value|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/complexity.xml/ExcessiveClassLength" />
|
||||
```
|
||||
|
||||
## ExcessiveParameterList
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -119,6 +129,11 @@ public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) {
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|sigma||Sigma value|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/complexity.xml/ExcessiveParameterList" />
|
||||
```
|
||||
|
||||
## ExcessivePublicCount
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -159,6 +174,11 @@ public class Foo {
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|sigma||Sigma value|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/complexity.xml/ExcessivePublicCount" />
|
||||
```
|
||||
|
||||
## NcssConstructorCount
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -198,6 +218,11 @@ public class Foo extends Bar {
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|sigma||Sigma value|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/complexity.xml/NcssConstructorCount" />
|
||||
```
|
||||
|
||||
## NcssMethodCount
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -236,6 +261,11 @@ public class Foo extends Bar {
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|sigma||Sigma value|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/complexity.xml/NcssMethodCount" />
|
||||
```
|
||||
|
||||
## NcssTypeCount
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -276,6 +306,11 @@ public class Foo extends Bar {
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|sigma||Sigma value|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/complexity.xml/NcssTypeCount" />
|
||||
```
|
||||
|
||||
## StdCyclomaticComplexity
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -341,6 +376,11 @@ public class Foo {
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|reportLevel|10|Cyclomatic Complexity reporting threshold|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/complexity.xml/StdCyclomaticComplexity" />
|
||||
```
|
||||
|
||||
## TooManyFields
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -381,3 +421,8 @@ public class Person {
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|maxfields|15|Max allowable fields|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/complexity.xml/TooManyFields" />
|
||||
```
|
||||
|
||||
|
@ -39,6 +39,11 @@ public class Something {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/performance.xml/AvoidDmlStatementsInLoops" />
|
||||
```
|
||||
|
||||
## AvoidSoqlInLoops
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -69,3 +74,8 @@ public class Something {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/performance.xml/AvoidSoqlInLoops" />
|
||||
```
|
||||
|
||||
|
@ -37,6 +37,11 @@ public without sharing class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/security.xml/ApexBadCrypto" />
|
||||
```
|
||||
|
||||
## ApexCRUDViolation
|
||||
|
||||
**Since:** PMD 5.5.3
|
||||
@ -76,6 +81,11 @@ public class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/security.xml/ApexCRUDViolation" />
|
||||
```
|
||||
|
||||
## ApexCSRF
|
||||
|
||||
**Since:** PMD 5.5.3
|
||||
@ -109,6 +119,11 @@ public class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/security.xml/ApexCSRF" />
|
||||
```
|
||||
|
||||
## ApexDangerousMethods
|
||||
|
||||
**Since:** PMD 5.5.3
|
||||
@ -144,6 +159,11 @@ public class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/security.xml/ApexDangerousMethods" />
|
||||
```
|
||||
|
||||
## ApexInsecureEndpoint
|
||||
|
||||
**Since:** PMD 5.5.3
|
||||
@ -174,6 +194,11 @@ public without sharing class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/security.xml/ApexInsecureEndpoint" />
|
||||
```
|
||||
|
||||
## ApexOpenRedirect
|
||||
|
||||
**Since:** PMD 5.5.3
|
||||
@ -204,6 +229,11 @@ public without sharing class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/security.xml/ApexOpenRedirect" />
|
||||
```
|
||||
|
||||
## ApexSharingViolations
|
||||
|
||||
**Since:** PMD 5.5.3
|
||||
@ -231,6 +261,11 @@ public without sharing class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/security.xml/ApexSharingViolations" />
|
||||
```
|
||||
|
||||
## ApexSOQLInjection
|
||||
|
||||
**Since:** PMD 5.5.3
|
||||
@ -259,6 +294,11 @@ public class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/security.xml/ApexSOQLInjection" />
|
||||
```
|
||||
|
||||
## ApexSuggestUsingNamedCred
|
||||
|
||||
**Since:** PMD 5.5.3
|
||||
@ -301,6 +341,11 @@ public class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/security.xml/ApexSuggestUsingNamedCred" />
|
||||
```
|
||||
|
||||
## ApexXSSFromEscapeFalse
|
||||
|
||||
**Since:** PMD 5.5.3
|
||||
@ -329,6 +374,11 @@ public without sharing class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/security.xml/ApexXSSFromEscapeFalse" />
|
||||
```
|
||||
|
||||
## ApexXSSFromURLParam
|
||||
|
||||
**Since:** PMD 5.5.3
|
||||
@ -357,3 +407,8 @@ public without sharing class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/security.xml/ApexXSSFromURLParam" />
|
||||
```
|
||||
|
||||
|
@ -36,6 +36,11 @@ global class Unchangeable {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/style.xml/AvoidGlobalModifier" />
|
||||
```
|
||||
|
||||
## AvoidLogicInTrigger
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -75,6 +80,11 @@ trigger Accounts on Account (before insert, before update, before delete, after
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/style.xml/AvoidLogicInTrigger" />
|
||||
```
|
||||
|
||||
## ClassNamingConventions
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -99,6 +109,11 @@ public class Foo {}
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/style.xml/ClassNamingConventions" />
|
||||
```
|
||||
|
||||
## MethodNamingConventions
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -126,6 +141,11 @@ public class Foo {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/style.xml/MethodNamingConventions" />
|
||||
```
|
||||
|
||||
## MethodWithSameNameAsEnclosingClass
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -155,6 +175,11 @@ public class MyClass {
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/style.xml/MethodWithSameNameAsEnclosingClass" />
|
||||
```
|
||||
|
||||
## VariableNamingConventions
|
||||
|
||||
**Since:** PMD 5.5.0
|
||||
@ -196,3 +221,8 @@ public class Foo {
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|checkMembers|true|Check member variables|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/style.xml/VariableNamingConventions" />
|
||||
```
|
||||
|
||||
|
@ -55,6 +55,11 @@ function getX() {
|
||||
|allowTernaryResults|false|Allow assignment within the result expressions of a ternary operator|
|
||||
|allowIncrementDecrement|false|Allow increment or decrement operators within the conditional expression of an if, for, or while statement|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/ecmascript/basic.xml/AssignmentInOperand" />
|
||||
```
|
||||
|
||||
## AvoidTrailingComma
|
||||
|
||||
**Since:** PMD 5.1
|
||||
@ -88,6 +93,11 @@ function(arg) {
|
||||
|allowObjectLiteral|false|Allow a trailing comma within an object literal|
|
||||
|allowArrayLiteral|false|Allow a trailing comma within an array literal|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/ecmascript/basic.xml/AvoidTrailingComma" />
|
||||
```
|
||||
|
||||
## ConsistentReturn
|
||||
|
||||
**Since:** PMD 5.0
|
||||
@ -128,6 +138,11 @@ function bar() {
|
||||
|recordingLocalJsDocComments|true|Specifies that JsDoc comments are produced in the AST.|
|
||||
|recordingComments|true|Specifies that comments are produced in the AST.|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/ecmascript/basic.xml/ConsistentReturn" />
|
||||
```
|
||||
|
||||
## EqualComparison
|
||||
|
||||
**Since:** PMD 5.0
|
||||
@ -167,6 +182,11 @@ if (someVar != 3) {
|
||||
}
|
||||
```
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/ecmascript/basic.xml/EqualComparison" />
|
||||
```
|
||||
|
||||
## GlobalVariable
|
||||
|
||||
**Since:** PMD 5.0
|
||||
@ -192,6 +212,11 @@ function(arg) {
|
||||
}
|
||||
```
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/ecmascript/basic.xml/GlobalVariable" />
|
||||
```
|
||||
|
||||
## InnaccurateNumericLiteral
|
||||
|
||||
**Since:** PMD 5.0
|
||||
@ -221,6 +246,11 @@ var y = 1.1234567890123; // Ok
|
||||
var z = 1.12345678901234567; // Not good
|
||||
```
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/ecmascript/basic.xml/InnaccurateNumericLiteral" />
|
||||
```
|
||||
|
||||
## ScopeForInVariable
|
||||
|
||||
**Since:** PMD 5.0
|
||||
@ -269,6 +299,11 @@ function bar() {
|
||||
}
|
||||
```
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/ecmascript/basic.xml/ScopeForInVariable" />
|
||||
```
|
||||
|
||||
## UnreachableCode
|
||||
|
||||
**Since:** PMD 5.0
|
||||
@ -303,6 +338,11 @@ function bar() {
|
||||
}
|
||||
```
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/ecmascript/basic.xml/UnreachableCode" />
|
||||
```
|
||||
|
||||
## UseBaseWithParseInt
|
||||
|
||||
**Since:** PMD 5.0.1
|
||||
@ -331,3 +371,8 @@ parseInt("010"); // unclear, could be interpreted as 10 or 7 (with a base of
|
||||
parseInt("10", 10); // good
|
||||
```
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/ecmascript/basic.xml/UseBaseWithParseInt" />
|
||||
```
|
||||
|
||||
|
@ -34,6 +34,11 @@ for (var i = 0; i < 42; i++)
|
||||
foo();
|
||||
```
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/ecmascript/braces.xml/ForLoopsMustUseBraces" />
|
||||
```
|
||||
|
||||
## IfElseStmtsMustUseBraces
|
||||
|
||||
**Since:** PMD 5.0
|
||||
@ -65,6 +70,11 @@ else
|
||||
y++;
|
||||
```
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/ecmascript/braces.xml/IfElseStmtsMustUseBraces" />
|
||||
```
|
||||
|
||||
## IfStmtsMustUseBraces
|
||||
|
||||
**Since:** PMD 5.0
|
||||
@ -90,6 +100,11 @@ if (foo)
|
||||
x++;
|
||||
```
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/ecmascript/braces.xml/IfStmtsMustUseBraces" />
|
||||
```
|
||||
|
||||
## WhileLoopsMustUseBraces
|
||||
|
||||
**Since:** PMD 5.0
|
||||
@ -115,3 +130,8 @@ while (true)
|
||||
x++;
|
||||
```
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/ecmascript/braces.xml/WhileLoopsMustUseBraces" />
|
||||
```
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user