diff --git a/.all-contributorsrc b/.all-contributorsrc index e6cdc3259b..af7ea40ffe 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7268,6 +7268,16 @@ "contributions": [ "bug" ] + }, + { + "login": "shai-bennathan", + "name": "Shai Bennathan", + "avatar_url": "https://avatars.githubusercontent.com/u/62336907?v=4", + "profile": "https://github.com/shai-bennathan", + "contributions": [ + "bug", + "code" + ] } ], "contributorsPerLine": 7, diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5567a67c77..5deaf0faa4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,7 @@ jobs: os: [ ubuntu-latest, windows-latest, macos-latest ] if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 2 - uses: actions/cache@v3 diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index 4b79a42d6b..cce1368735 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest continue-on-error: false steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 100 - name: Setup Environment diff --git a/.github/workflows/troubleshooting.yml b/.github/workflows/troubleshooting.yml index 3216333733..c39674aad2 100644 --- a/.github/workflows/troubleshooting.yml +++ b/.github/workflows/troubleshooting.yml @@ -15,7 +15,7 @@ jobs: os: [ ubuntu-latest ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/cache@v3 with: path: | diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 6f3a7abe63..eaccf838e4 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -124,6 +124,9 @@ entries: - title: PMD Java API output: web, pdf url: /pmd_userdocs_tools_java_api.html + - title: bld PMD Extension + output: web, pdf + url: /pmd_userdocs_tools_bld.html - title: CI integrations output: web, pdf url: /pmd_userdocs_tools_ci.html @@ -313,7 +316,7 @@ entries: - title: null output: web, pdf subfolders: - - title: Salesforce VisualForce Rules + - title: Salesforce Visualforce Rules output: web, pdf subfolderitems: - title: Index @@ -349,7 +352,7 @@ entries: - title: null output: web, pdf subfolders: - - title: VM Rules + - title: Velocity Template Language (VTL) Rules output: web, pdf subfolderitems: - title: Index @@ -382,6 +385,9 @@ entries: - title: Index output: web, pdf url: /pmd_rules_xml.html + - title: Best Practices + output: web, pdf + url: /pmd_rules_xml_bestpractices.html - title: Error Prone output: web, pdf url: /pmd_rules_xml_errorprone.html @@ -403,12 +409,41 @@ entries: - title: Language-Specific Documentation output: web, pdf folderitems: + - title: Overview + url: /pmd_languages_index.html + output: web, pdf - title: Language configuration url: /pmd_languages_configuration.html output: web, pdf - title: Apex url: /pmd_languages_apex.html output: web, pdf + - title: C/C++ + url: /pmd_languages_cpp.html + output: web, pdf + - title: C# + url: /pmd_languages_cs.html + output: web, pdf + - title: Coco + url: /pmd_languages_coco.html + output: web, pdf + - title: Dart + url: /pmd_languages_dart.html + output: web, pdf + - title: Fortran + url: /pmd_languages_fortran.html + output: web, pdf + - title: Gherkin + url: /pmd_languages_gherkin.html + output: web, pdf + - title: Go + url: /pmd_languages_go.html + output: web, pdf + - title: Groovy + url: /pmd_languages_groovy.html + - title: HTML + url: /pmd_languages_html.html + output: web, pdf - title: Java url: /pmd_languages_java.html output: web, pdf @@ -418,30 +453,57 @@ entries: - title: JSP url: /pmd_languages_jsp.html output: web, pdf + - title: Julia + url: /pmd_languages_julia.html + output: web, pdf - title: Kotlin url: /pmd_languages_kotlin.html output: web, pdf + - title: Lua + url: /pmd_languages_lua.html + output: web, pdf + - title: Matlab + url: /pmd_languages_matlab.html + output: web, pdf + - title: Modelica + url: /pmd_languages_modelica.html + output: web, pdf + - title: Objective-C + url: /pmd_languages_objectivec.html + output: web, pdf + - title: Perl + url: /pmd_languages_perl.html + output: web, pdf + - title: PHP + url: /pmd_languages_php.html + output: web, pdf - title: PLSQL url: /pmd_languages_plsql.html output: web, pdf + - title: Python + url: /pmd_languages_python.html + output: web, pdf + - title: Ruby + url: /pmd_languages_ruby.html + output: web, pdf + - title: Scala + url: /pmd_languages_scala.html + output: web, pdf + - title: Swift + url: /pmd_languages_swift.html + output: web, pdf + - title: T-SQL + url: /pmd_languages_tsql.html + output: web, pdf - title: Visualforce url: /pmd_languages_visualforce.html output: web, pdf + - title: Velocity Template Language (VTL) + url: /pmd_languages_vm.html + output: web, pdf - title: XML and XML dialects url: /pmd_languages_xml.html output: web, pdf - - title: HTML - url: /pmd_languages_html.html - output: web, pdf - - title: Gherkin - url: /pmd_languages_gherkin.html - output: web, pdf - - title: Julia - url: /pmd_languages_julia.html - output: web, pdf - - title: Coco - url: /pmd_languages_coco.html - output: web, pdf - title: Developer Documentation output: web, pdf folderitems: @@ -493,6 +555,9 @@ entries: - title: Creating (XML) dump of the AST url: /pmd_devdocs_experimental_ast_dump.html output: web, pdf + - title: List of experimental Features + url: /tag_experimental.html + output: web, pdf - title: Project documentation output: web, pdf folderitems: diff --git a/docs/_data/tags.yml b/docs/_data/tags.yml index 88d01cea93..473b3dbe7b 100644 --- a/docs/_data/tags.yml +++ b/docs/_data/tags.yml @@ -10,3 +10,6 @@ allowed-tags: - tools # About tools and integrations, Maven, gradle, etc. - devdocs # About PMD internals, contributing, building, projects - languages # Language-specific documentation pages + - PmdCapableLanguage + - CpdCapableLanguage + - experimental diff --git a/docs/_includes/language_info.html b/docs/_includes/language_info.html new file mode 100644 index 0000000000..3b47eba14c --- /dev/null +++ b/docs/_includes/language_info.html @@ -0,0 +1,12 @@ +
+ Language Info for {{include.name}} +
+ +
+
diff --git a/docs/_plugins/javadoc_tag.rb b/docs/_plugins/javadoc_tag.rb index b3e79329f9..c31b9a655f 100644 --- a/docs/_plugins/javadoc_tag.rb +++ b/docs/_plugins/javadoc_tag.rb @@ -106,16 +106,25 @@ class JavadocTag < Liquid::Tag def initialize(tag_name, doc_ref, tokens) super - # sanitize a little - doc_ref.delete! " \"'" + @doc_ref = doc_ref + end - arr = doc_ref.split("#") # split into fqcn + member suffix + def render(var_ctx) + # maybe the parameter is actually a variable - try to resolve it first + if var_ctx.key?(@doc_ref) + @doc_ref = var_ctx[@doc_ref] + end + + # sanitize a little + @doc_ref.delete! " \"'" + + arr = @doc_ref.split("#") # split into fqcn + member suffix @type_fqcn = arr[0] @member_suffix = arr[1] || "" # default to empty string unless Regexp.new('(!\w*!)?' + Regexp.union(JDocNamespaceDeclaration::NAMESPACED_FQCN_REGEX, JDocNamespaceDeclaration::SYM_REGEX).source ) =~ @type_fqcn - fail "Wrong syntax for type reference, expected eg nspace::a.b.C, !opts!nspace::a.b.C, or :nspace" + fail "Wrong syntax for type reference, expected eg nspace::a.b.C, !opts!nspace::a.b.C, or :nspace, but got \'" + @type_fqcn + "\'" end # If no options, then split produces [@type_fqcn] @@ -130,14 +139,11 @@ class JavadocTag < Liquid::Tag elsif tag_name == "jdoc_old" @use_previous_api_version = true end - end - - def render(var_ctx) artifact_name, @type_fqcn = JDocNamespaceDeclaration::parse_fqcn(@type_fqcn, var_ctx) resolved_type = JavadocTag::fqcn_type(artifact_name, @type_fqcn) - JavadocTag::diagnose(artifact_name, @type_fqcn, @is_package_ref, resolved_type) + diagnose(var_ctx, artifact_name, @type_fqcn, @is_package_ref, resolved_type) # Expand FQCN of arguments @member_suffix.gsub!(JDocNamespaceDeclaration::NAMESPACED_FQCN_REGEX) {|fqcn| JDocNamespaceDeclaration::parse_fqcn(fqcn, var_ctx)[1]} @@ -215,15 +221,18 @@ class JavadocTag < Liquid::Tag BASE_PMD_DIR = File.join(File.expand_path(File.dirname(__FILE__)), "..", "..") - def self.diagnose(artifact_id, fqcn, expect_package, resolved_type) + def diagnose(context, artifact_id, fqcn, expect_package, resolved_type) tag_name= expect_package ? "jdoc_package" : "jdoc" + # Note: the line numbers don't account for the frontmatter lines + # See https://github.com/jekyll/jekyll/issues/7192 and https://github.com/jekyll/jekyll/pull/9385 + location = "#{context['page']['path']}:#{@line_number}+?" if resolved_type == :package && !expect_package - warn "\e[33;1m#{tag_name} generated link to #{fqcn}, but it was found to be a package name. Did you mean to use jdoc_package instead of jdoc?\e[0m" + warn "\e[33;1m#{location}: #{tag_name} generated link to #{fqcn}, but it was found to be a package name. Did you mean to use jdoc_package instead of jdoc?\e[0m" elsif resolved_type == :file && expect_package - warn "\e[33;1m#{tag_name} generated link to #{fqcn}, but it was found to be a java file name. Did you mean to use jdoc instead of jdoc_package?\e[0m" + warn "\e[33;1m#{location}: #{tag_name} generated link to #{fqcn}, but it was found to be a java file name. Did you mean to use jdoc instead of jdoc_package?\e[0m" elsif !resolved_type - warn "\e[33;1m#{tag_name} generated link to #{fqcn}, but the #{expect_package ? "directory" : "source file"} couldn't be found in the source tree of #{artifact_id}\e[0m" + warn "\e[33;1m#{location}: #{tag_name} generated link to #{fqcn}, but the #{expect_package ? "directory" : "source file"} couldn't be found in the source tree of #{artifact_id}\e[0m" end end diff --git a/docs/_plugins/jdoc_namespace_tag.rb b/docs/_plugins/jdoc_namespace_tag.rb index 660de18783..88a85e7bbb 100644 --- a/docs/_plugins/jdoc_namespace_tag.rb +++ b/docs/_plugins/jdoc_namespace_tag.rb @@ -99,10 +99,11 @@ class JDocNamespaceDeclaration < Liquid::Tag private JDOC_NAMESPACE_MAP = "jdoc_nspaces" - RESERVED_NSPACES = ['ant', 'apex', 'cli', 'core', 'cpp', 'cs', 'dart', 'dist', 'doc', 'fortran', 'go', 'groovy', 'java', - 'javascript', 'jsp', + RESERVED_NSPACES = ['ant', 'apex', 'cli', 'coco', 'core', 'cpp', 'cs', 'dart', 'dist', 'doc', + 'fortran', 'gherkin', 'go', 'groovy', 'html', 'java', + 'javascript', 'jsp', 'julia', 'kotlin', 'lang-test', 'lua', 'matlab', 'objectivec', 'perl', 'php', 'plsql', 'python', 'ruby', 'scala', 'swift', - 'test', 'test-schema', 'ui', + 'test', 'test-schema', 'tsql', 'ui', 'modelica', 'visualforce', 'vm', 'xml'].flat_map {|m| [m, "pmd-" + m]} def self.make_base_namespaces diff --git a/docs/css/customstyles.css b/docs/css/customstyles.css index 3324e4720f..98b6bee046 100644 --- a/docs/css/customstyles.css +++ b/docs/css/customstyles.css @@ -1008,8 +1008,11 @@ span.soft { } @media (min-height: 600px) and (min-width: 990px) { + /* sticky sidebar for big screens */ #mysidebar { position: fixed !important; + overflow: scroll; + height: 80%; } } @@ -1268,3 +1271,7 @@ h4.panel-title { a.edit-header { font-size: 15px; } + +.language-info { + margin: 2em; +} diff --git a/docs/css/theme-green.css b/docs/css/theme-green.css index 8f47c071de..cb41d83a3f 100644 --- a/docs/css/theme-green.css +++ b/docs/css/theme-green.css @@ -87,3 +87,10 @@ li.sidebarTitle { margin-bottom:2.5px; margin-left:5px; } + +blockquote { + border-left: 5px solid #01c172; + padding: 10px 0 10px 1rem; + margin: 1rem 0; + font-style: italic; +} diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md index e5890d1078..c1b8d09d9e 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md @@ -142,7 +142,9 @@ definitely don't come for free. It is much effort and requires perseverance to i * For a minimal implementation, it just needs to return a parser *(see step #6)*. * It can be used to provide other features for your language like * violation suppression logic - * violation decorators, to add additional language specific information to the created violations + * {% jdoc core::reporting::ViolationDecorator %}s, to add additional language specific information to the + created violations. The [Java language module](pmd_languages_java.html#violation-decorators) uses this to + provide the method name or class name, where the violation occurred. * metrics * custom XPath functions @@ -228,3 +230,25 @@ definitely don't come for free. It is much effort and requires perseverance to i This will load all rulesets and verify, that all required attributes are provided. *Note:* You'll need to add your ruleset to `categories.properties`, so that it can be found. + +### 15. Create documentation page +Finishing up your new language module by adding a page in the documentation. Create a new markdown file +`.md` in `docs/pages/pmd/languages/`. This file should have the following frontmatter: + +``` +--- +title: +permalink: pmd_languages_.html +last_updated: () +tags: [languages, PmdCapableLanguage, CpdCapableLanguage] +--- +``` + +On this page, language specifics can be documented, e.g. when the language was first supported by PMD. +There is also the following Jekyll Include, that creates summary box for the language: + +``` +{% raw %} +{% include language_info.html name='' id='' implementation='::lang..LanguageModule' supports_cpd=true supports_pmd=true %} +{% endraw %} +``` diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md index 1f3ede48a4..fb2f7fa6a2 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md @@ -81,7 +81,9 @@ definitely don't come for free. It is much effort and requires perseverance to i * For a minimal implementation, it just needs to return a parser *(see step #5)*. * It can be used to provide other features for your language like * violation suppression logic - * violation decorators, to add additional language specific information to the created violations + * {% jdoc core::reporting::ViolationDecorator %}s, to add additional language specific information to the + created violations. The [Java language module](pmd_languages_java.html#violation-decorators) uses this to + provide the method name or class name, where the violation occurred. * metrics (see below "Optional features") * custom XPath functions * See `VmHandler` class as an example @@ -181,6 +183,29 @@ The Scala module also has a test, written in Kotlin instead of Java: *Note:* You'll need to add your category ruleset to `categories.properties`, so that it can be found. +### 13. Create documentation page +Finishing up your new language module by adding a page in the documentation. Create a new markdown file +`.md` in `docs/pages/pmd/languages/`. This file should have the following frontmatter: + +``` +--- +title: +permalink: pmd_languages_.html +last_updated: () +tags: [languages, PmdCapableLanguage, CpdCapableLanguage] +--- +``` + +On this page, language specifics can be documented, e.g. when the language was first supported by PMD. +There is also the following Jekyll Include, that creates summary box for the language: + +``` +{% raw %} +{% include language_info.html name='' id='' implementation='::lang..LanguageModule' supports_cpd=true supports_pmd=true %} +{% endraw %} +``` + + ## Debugging with Rule Designer When implementing your grammar it may be very useful to see how PMD parses your example files. diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md index bb3b232c46..665aa7ce18 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md @@ -79,6 +79,27 @@ If your language only supports CPD, then you can subclass {% jdoc core::lang.imp 5. Add some tests for your tokenizer by following the [section below](#testing-your-implementation). +6. Finishing up your new language module by adding a page in the documentation. Create a new markdown file + `.md` in `docs/pages/pmd/languages/`. This file should have the following frontmatter: + + ``` + --- + title: + permalink: pmd_languages_.html + last_updated: () + tags: [languages, CpdCapableLanguage] + --- + ``` + + On this page, language specifics can be documented, e.g. when the language was first supported by PMD. + There is also the following Jekyll Include, that creates summary box for the language: + + ``` + {% raw %} + {% include language_info.html name='' id='' implementation='::lang..LanguageModule' supports_cpd=true %} + {% endraw %} + ``` + ### Declaring tokenizer options To make the tokenizer configurable, first define some property descriptors using diff --git a/docs/pages/pmd/languages/apex.md b/docs/pages/pmd/languages/apex.md index 18d0d749cc..f6904aa7a8 100644 --- a/docs/pages/pmd/languages/apex.md +++ b/docs/pages/pmd/languages/apex.md @@ -1,15 +1,40 @@ --- title: Apex support permalink: pmd_languages_apex.html +last_updated: September 2023 (7.0.0) author: Clément Fournier -last_updated: March 2021 (7.0.0) -tags: [languages] +tags: [languages, PmdCapableLanguage, CpdCapableLanguage] summary: "Apex-specific features and guidance" --- -{% include warning.html content="Todo for pmd 7" %} +> [Apex](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dev_guide.htm) is a strongly +> typed, object-oriented programming language that allows developers to execute flow and +> transaction control statements on the Salesforce Platform server, in conjunction with calls to the API. -### Metrics framework +{% include language_info.html name='Apex' id='apex' implementation='apex::lang.apex.ApexLanguageModule' supports_pmd=true supports_cpd=true since='5.5.0' %} -In order to use code metrics in Java, use the metrics constants in {% jdoc apex::lang.apex.metrics.ApexMetrics %}, +## Metrics framework + +In order to use code metrics in Apex, use the metrics constants in {% jdoc apex::lang.apex.metrics.ApexMetrics %}, together with {% jdoc core::lang.metrics.MetricsUtil %}. + +## Multifile Analysis + +Integration happens in {% jdoc apex::lang.apex.multifile.ApexMultifileAnalysis %}. It uses +[ApexLink](https://github.com/nawforce/apex-link). For detailed information, see also [Apexlink POC #2830](https://github.com/pmd/pmd/pull/2830). + +{% include note.html content="ApexLink's new home: " %} + +Used for rule {% rule apex/design/UnusedMethod %} + +## Language Properties + +See [Apex language properties](pmd_languages_configuration.html#apex-language-properties) + +## Parser + +We use Jorje, the Apex parsers that is shipped within the Apex Language Server. This is part of +the [Salesforce Extensions for VS Code](https://github.com/forcedotcom/salesforcedx-vscode). + +We take the binary from +and provide it as a maven dependency (see [pmd-apex-jorje](https://github.com/pmd/pmd/tree/master/pmd-apex-jorje)). diff --git a/docs/pages/pmd/languages/coco.md b/docs/pages/pmd/languages/coco.md index 44a6b31939..9c94c0d985 100644 --- a/docs/pages/pmd/languages/coco.md +++ b/docs/pages/pmd/languages/coco.md @@ -1,10 +1,15 @@ --- -title: Coco +title: Coco support permalink: pmd_languages_coco.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "Coco features and guidance" --- -Coco is a modern programming language designed specifically for building event-driven software. -It is part of the Coco Platform from . +> Coco is a modern programming language designed specifically for building event-driven software. +> It is part of the Coco Platform from . + +{% include language_info.html name='Coco' id='coco' implementation='coco::lang.coco.CocoLanguageModule' supports_cpd=true since='7.0.0' %} ## Support in PMD Starting from version 7.0.0, Coco support was added to CPD. diff --git a/docs/pages/pmd/languages/cpp.md b/docs/pages/pmd/languages/cpp.md new file mode 100644 index 0000000000..cd80ff3cf6 --- /dev/null +++ b/docs/pages/pmd/languages/cpp.md @@ -0,0 +1,13 @@ +--- +title: C/C++ support +permalink: pmd_languages_cpp.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "C/C++ features and guidance" +--- + +{% include language_info.html name='C++' id='cpp' implementation='cpp::lang.cpp.CppLanguageModule' supports_cpd=true since='3.5' %} + +## Language Properties + +See [Cpp language properties](pmd_languages_configuration.html#cpp-language-properties) diff --git a/docs/pages/pmd/languages/cs.md b/docs/pages/pmd/languages/cs.md new file mode 100644 index 0000000000..bdb204e4a8 --- /dev/null +++ b/docs/pages/pmd/languages/cs.md @@ -0,0 +1,9 @@ +--- +title: C# support +permalink: pmd_languages_cs.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "C#-specific features and guidance" +--- + +{% include language_info.html name='C#' id='cs' implementation='cs::lang.cs.CsLanguageModule' supports_cpd=true since='4.3' %} diff --git a/docs/pages/pmd/languages/dart.md b/docs/pages/pmd/languages/dart.md new file mode 100644 index 0000000000..2817dd9122 --- /dev/null +++ b/docs/pages/pmd/languages/dart.md @@ -0,0 +1,11 @@ +--- +title: Dart support +permalink: pmd_languages_dart.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "Dart-specific features and guidance" +--- + +> [Dart](https://dart.dev/) is a client-optimized language for fast apps on any platform. + +{% include language_info.html name='Dart' id='dart' implementation='dart::lang.dart.DartLanguageModule' supports_cpd=true since='6.14.0' %} diff --git a/docs/pages/pmd/languages/fortran.md b/docs/pages/pmd/languages/fortran.md new file mode 100644 index 0000000000..49119ed390 --- /dev/null +++ b/docs/pages/pmd/languages/fortran.md @@ -0,0 +1,9 @@ +--- +title: Fortran support +permalink: pmd_languages_fortran.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "Fortran features and guidance" +--- + +{% include language_info.html name='Fortran' id='fortran' implementation='fortran::lang.fortran.FortranLanguageModule' supports_cpd=true %} diff --git a/docs/pages/pmd/languages/gherkin.md b/docs/pages/pmd/languages/gherkin.md index 123bae7d49..9ffb2565ab 100644 --- a/docs/pages/pmd/languages/gherkin.md +++ b/docs/pages/pmd/languages/gherkin.md @@ -1,12 +1,17 @@ --- -title: Gherkin +title: Gherkin support permalink: pmd_languages_gherkin.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "Gherkin features and guidance" --- The [Gherkin](https://cucumber.io/docs/gherkin/) language is used to define test cases for the [Cucumber](https://cucumber.io/) testing tool for behavior-driven development. The Gherkin syntax is designed to be non-technical, making it human-readable for a wide audience. +{% include language_info.html name='Gherkin' id='gherkin' implementation='gherkin::lang.gherkin.GherkinLanguageModule' supports_cpd=true since='6.48.0' %} + ## Support in PMD Starting from version 6.48.0, Gherkin support was added to CPD. diff --git a/docs/pages/pmd/languages/go.md b/docs/pages/pmd/languages/go.md new file mode 100644 index 0000000000..7eb461cf9f --- /dev/null +++ b/docs/pages/pmd/languages/go.md @@ -0,0 +1,11 @@ +--- +title: Go support +permalink: pmd_languages_go.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "Go features and guidance" +--- + +> [Go](https://golang.org/) is a statically typed, compiled high-level programming language. + +{% include language_info.html name='Go' id='go' implementation='go::lang.go.GoLanguageModule' supports_cpd=true since='5.2.0' %} diff --git a/docs/pages/pmd/languages/groovy.md b/docs/pages/pmd/languages/groovy.md new file mode 100644 index 0000000000..25ea52b751 --- /dev/null +++ b/docs/pages/pmd/languages/groovy.md @@ -0,0 +1,13 @@ +--- +title: Groovy support +permalink: pmd_languages_groovy.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "Groovy-specific features and guidance" +--- + +> [Apache Groovy](https://groovy-lang.org/) is a powerful, optionally typed and dynamic language, with static-typing and +> static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, +> familiar and easy to learn syntax. + +{% include language_info.html name='Groovy' id='groovy' implementation='groovy::lang.groovy.GroovyLanguageModule' supports_cpd=true since='5.5.2' %} diff --git a/docs/pages/pmd/languages/html.md b/docs/pages/pmd/languages/html.md index 9c905571e1..44442f4cd2 100644 --- a/docs/pages/pmd/languages/html.md +++ b/docs/pages/pmd/languages/html.md @@ -1,24 +1,20 @@ --- -title: Processing HTML files +title: HTML support permalink: pmd_languages_html.html -last_updated: April 2022 (6.45.0) +last_updated: September 2023 (7.0.0) +tags: [languages, PmdCapableLanguage, CpdCapableLanguage, experimental] +summary: "HTML-specific features and guidance" --- -## The HTML language module - -**Since:** 6.45.0 - -**Minimum Java Runtime:** Java 8 +{% include language_info.html name='HTML' id='html' implementation='html::lang.html.HtmlLanguageModule' supports_pmd=true supports_cpd=true since='6.45.0' %} {% include warning.html content="This language module is experimental and may change any time." %} The HTML language module uses [jsoup](https://jsoup.org/) for parsing. -XPath 2.0 rules are supported, but the DOM is not always a typical XML/XPath DOM. +XPath rules are supported, but the DOM is not always a typical XML/XPath DOM. In the Designer, text nodes appear as nodes with name "#text", but they can be selected as usual using `text()`. -XML Namespaces are not supported. The local name of attributes include the prefix, +XML Namespaces are not supported. The local name of attributes includes the prefix, so that you have to select attributes by e.g. `//*[@*[local-name() = 'if:true']]`. - -Only XPath 1.0 rules are not supported. diff --git a/docs/pages/pmd/languages/index.md b/docs/pages/pmd/languages/index.md new file mode 100644 index 0000000000..4e85b73429 --- /dev/null +++ b/docs/pages/pmd/languages/index.md @@ -0,0 +1,9 @@ +--- +title: Overview +permalink: pmd_languages_index.html +last_updated: September 2023 (7.0.0) +tags: [languages] +--- + +* [PmdCapableLanguages](tag_PmdCapableLanguage.html) +* [CpdCapableLanguages](tag_CpdCapableLanguage.html) diff --git a/docs/pages/pmd/languages/java.md b/docs/pages/pmd/languages/java.md index 5c6685c87b..2a55d9f747 100644 --- a/docs/pages/pmd/languages/java.md +++ b/docs/pages/pmd/languages/java.md @@ -2,11 +2,13 @@ title: Java support permalink: pmd_languages_java.html author: Clément Fournier -last_updated: August 2023 (7.0.0) -tags: [languages] +last_updated: September 2023 (7.0.0) +tags: [languages, PmdCapableLanguage, CpdCapableLanguage] summary: "Java-specific features and guidance" --- +{% include language_info.html name='Java' id='java' implementation='java::lang.java.JavaLanguageModule' supports_pmd=true supports_cpd=true since='1.0.0' %} + {% include warning.html content="WIP, todo for pmd 7" %} ## Overview of supported Java language versions @@ -47,6 +49,10 @@ it via the environment variable `PMD_JAVA_OPTS` and select the new language vers Note: we only support preview language features for the latest two java versions. +## Language Properties + +See [Java language properties](pmd_languages_configuration.html#java-language-properties) + ## Type and symbol resolution Java being a statically typed language, a Java program contains more information that just its syntax tree; for instance, every expression has a static type, and every method call is bound to a method overload statically (even if that overload is virtual). In PMD, much of this information is resolved from the AST by additional passes, which run after parsing, and before rules can inspect the tree. @@ -62,7 +68,7 @@ TODO describe ## Type and symbol APIs -TODO describe APIs +TODO describe APIs: see #4319 and #2689 ## Metrics framework @@ -83,3 +89,15 @@ public Object visit(ASTMethodDeclaration node, Object data) { ``` The Javadocs are the reference documentation. + +## Violation Decorators + +Violations reported are the same for all languages, but languages can opt in to provide more details. +Java does this by adding the following additional information for each reported violation: + +* {% jdoc core::RuleViolation#VARIABLE_NAME %} +* {% jdoc core::RuleViolation#METHOD_NAME %} +* {% jdoc core::RuleViolation#CLASS_NAME %} +* {% jdoc core::RuleViolation#PACKAGE_NAME %} + +You can access these via {% jdoc core::RuleViolation#getAdditionalInfo() %} diff --git a/docs/pages/pmd/languages/js_ts.md b/docs/pages/pmd/languages/js_ts.md index 7633105a2d..3f0bd4ac0e 100644 --- a/docs/pages/pmd/languages/js_ts.md +++ b/docs/pages/pmd/languages/js_ts.md @@ -1,15 +1,22 @@ --- -title: JavaScript and TypeScript +title: JavaScript and TypeScript support permalink: pmd_languages_js_ts.html -tags: [languages] -summary: "JavaScript and TypeScript infos" +last_updated: September 2023 (7.0.0) +tags: [languages, PmdCapableLanguage, CpdCapableLanguage] +summary: "JavaScript- and TypeScript-specific features and guidance" --- +{% include language_info.html name='JavaScript' id='ecmascript' implementation='javascript::lang.ecmascript.EcmascriptLanguageModule' supports_pmd=true supports_cpd=true %} +{% include language_info.html name='TypeScript' id='ts' implementation='javascript::lang.typescript.TsLanguageModule' supports_cpd=true since='7.0.0' %} + +## JavaScript + **JavaScript** support is using [Rhino](https://github.com/mozilla/rhino) for parsing and supports CPD as well as PMD with rules. See [Compatibility Table](https://mozilla.github.io/rhino/compat/engines.html) for supported language features. +## TypeScript **TypeScript** is supported for Copy-Paste-Detection only and uses the ANTLR grammar from [antlr/grammars-v4](https://github.com/antlr/grammars-v4/tree/master/javascript/typescript). diff --git a/docs/pages/pmd/languages/jsp.md b/docs/pages/pmd/languages/jsp.md index 31b4995e54..ea53015d0e 100644 --- a/docs/pages/pmd/languages/jsp.md +++ b/docs/pages/pmd/languages/jsp.md @@ -1,11 +1,14 @@ --- title: JSP Support permalink: pmd_languages_jsp.html +last_updated: September 2023 (7.0.0) +tags: [languages, PmdCapableLanguage, CpdCapableLanguage] author: Pieter Vanraemdonck -tags: [languages] summary: "JSP-specific features and guidance" --- +{% include language_info.html name='Java Server Pages' id='jsp' implementation='jsp::lang.jsp.JspLanguageModule' supports_pmd=true supports_cpd=true %} + ## What is currently supported and what is not In short, JSP files that are XHTML-compliant, are supported. @@ -38,16 +41,3 @@ The XHTML support means that: further broken down. If you want to create rules that check the code inside EL expressions or JSP scriptlets (a.o.), you currently would have to do "manual" string manipulation (e.g. using regular expressions). - -## How to use it - -Using the command-line interface, two new options can be used in the arguments string: - -* "-jsp" : this triggers checking JSP files (they are not checked by default) -* "-nojava" : this tells PMD not to check java source files (they are checked by default) - -Using the Ant task, you decide if PMD must check JSP files by choosing -what files are given to the PMD task. If you use a fileset that -contains only ".java" files, JSP files obviously will not be checked. - -If you want to call the PMD API for checking JSP files, you should investigate the javadoc of PMD. diff --git a/docs/pages/pmd/languages/julia.md b/docs/pages/pmd/languages/julia.md index de36f3e9ea..bba4ef70b5 100644 --- a/docs/pages/pmd/languages/julia.md +++ b/docs/pages/pmd/languages/julia.md @@ -1,15 +1,20 @@ --- -title: Julia +title: Julia support permalink: pmd_languages_julia.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: Julia-specific features and guidance --- -The [Julia](https://julialang.org/) is dynamically typed, like a scripting language, -and has good support for interactive use. -Julia was designed from the beginning for high performance. -Julia programs compile to efficient native code for multiple platforms via LLVM. +> The [Julia](https://julialang.org/) language is dynamically typed, like a scripting language, +> and has good support for interactive use. +> Julia was designed from the beginning for high performance. +> Julia programs compile to efficient native code for multiple platforms via LLVM. + +{% include language_info.html name='Julia' id='julia' implementation='julia::lang.julia.JuliaLanguageModule' supports_cpd=true since='7.0.0' %} ## Support in PMD Starting from version 7.0.0, Julia support was added to CPD. -### Limitations +## Limitations - Support for Julia only extends to CPD to detect code duplication in Julia source files. diff --git a/docs/pages/pmd/languages/kotlin.md b/docs/pages/pmd/languages/kotlin.md index ad9297a248..e6a5c77b1a 100644 --- a/docs/pages/pmd/languages/kotlin.md +++ b/docs/pages/pmd/languages/kotlin.md @@ -1,11 +1,14 @@ --- title: Kotlin Support permalink: pmd_languages_kotlin.html -tags: [languages] +last_updated: September 2023 (7.0.0) +tags: [languages, PmdCapableLanguage, CpdCapableLanguage, experimental] summary: "Kotlin-specific features and guidance" --- -Kotlin support in PMD is based on the official grammar from . +[Kotlin](https://kotlinlang.org/) support in PMD is based on the official grammar from . + +{% include language_info.html name='Kotlin' id='kotlin' implementation='kotlin::lang.kotlin.JspLanguageModule' supports_pmd=true supports_cpd=true %} Java-based rules and XPath-based rules are supported. diff --git a/docs/pages/pmd/languages/language_properties.md b/docs/pages/pmd/languages/language_properties.md index d8adf105a9..91f396489f 100644 --- a/docs/pages/pmd/languages/language_properties.md +++ b/docs/pages/pmd/languages/language_properties.md @@ -108,7 +108,7 @@ The Java language can be configured with the following properties: Environment variable: `PMD_APEX_ROOT_DIRECTORY` -## VisualForce language properties +## Visualforce language properties - `apexDirectories`: Comma separated list of directories for Apex classes. Absolute or relative to the Visualforce directory. Default is `../classes`. Specifying an diff --git a/docs/pages/pmd/languages/lua.md b/docs/pages/pmd/languages/lua.md new file mode 100644 index 0000000000..fbc95b6607 --- /dev/null +++ b/docs/pages/pmd/languages/lua.md @@ -0,0 +1,14 @@ +--- +title: Lua support +permalink: pmd_languages_lua.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "Lua-specifc features and guidance" +--- + +> [Lua](https://www.lua.org/) is a powerful, efficient, lightweight, embeddable scripting language. + +{% include language_info.html name='Lua' id='lua' implementation='lua::lang.lua.LuaLanguageModule' supports_cpd=true since='6.17.0' %} + +CPD support was added with PMD 6.17.0. Since PMD 6.50.0 support for [Luau](https://github.com/Roblox/luau), +a gradually typed language derived from Lua, was added. diff --git a/docs/pages/pmd/languages/matlab.md b/docs/pages/pmd/languages/matlab.md new file mode 100644 index 0000000000..1d5df24b7f --- /dev/null +++ b/docs/pages/pmd/languages/matlab.md @@ -0,0 +1,11 @@ +--- +title: Matlab support +permalink: pmd_languages_matlab.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "Matlab-specific features and guidance" +--- + +[Matlab](https://www.mathworks.com/) scripts are supported for Copy-Paste-Detection only. + +{% include language_info.html name='Matlab' id='matlab' implementation='matlab::lang.matlab.MatlabLanguageModule' supports_cpd=true since='5.3.0' %} diff --git a/docs/pages/pmd/languages/modelica.md b/docs/pages/pmd/languages/modelica.md new file mode 100644 index 0000000000..d1d188a61a --- /dev/null +++ b/docs/pages/pmd/languages/modelica.md @@ -0,0 +1,11 @@ +--- +title: Modelica support +permalink: pmd_languages_modelica.html +last_updated: September 2023 (7.0.0) +tags: [languages, PmdCapableLanguage, CpdCapableLanguage] +summary: "Modelica-specific features and guidance" +--- + +[Modelica](https://modelica.org/modelicalanguage) is a language to model complex physical systems. + +{% include language_info.html name='Modelica' id='modelica' implementation='modelica::lang.modelica.ModelicaLanguageModule' supports_pmd=true supports_cpd=true since='6.21.0' %} diff --git a/docs/pages/pmd/languages/objectivec.md b/docs/pages/pmd/languages/objectivec.md new file mode 100644 index 0000000000..a302774f8d --- /dev/null +++ b/docs/pages/pmd/languages/objectivec.md @@ -0,0 +1,12 @@ +--- +title: Objective-C support +permalink: pmd_languages_objectivec.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "Objective-C-specific features and guidance" +--- + +> [Objective-C](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html) is +> a superset of the C programming language and provides object-oriented capabilities and a dynamic runtime. + +{% include language_info.html name='objectivec' id='objectivec' implementation='objectivec::lang.objectivec.ObjectiveCLanguageModule' supports_cpd=true since='5.3.0' %} diff --git a/docs/pages/pmd/languages/perl.md b/docs/pages/pmd/languages/perl.md new file mode 100644 index 0000000000..56cbe3cd07 --- /dev/null +++ b/docs/pages/pmd/languages/perl.md @@ -0,0 +1,11 @@ +--- +title: Perl support +permalink: pmd_languages_perl.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "Perl-specific features and guidance" +--- + +> [Perl](https://www.perl.org/) is a highly capable, feature-rich programming language with over 30 years of development. + +{% include language_info.html name='Perl' id='perl' implementation='perl::lang.perl.PerlLanguageModule' supports_cpd=true since='5.5.0' %} diff --git a/docs/pages/pmd/languages/php.md b/docs/pages/pmd/languages/php.md new file mode 100644 index 0000000000..a2d200ee69 --- /dev/null +++ b/docs/pages/pmd/languages/php.md @@ -0,0 +1,11 @@ +--- +title: PHP support +permalink: pmd_languages_php.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "PHP-specific features and guidance" +--- + +> [PHP](https://www.php.net/) is a popular general-purpose scripting language that is especially suited to web development. + +{% include language_info.html name='PHP' id='php' implementation='php::lang.php.PhpLanguageModule' supports_cpd=true since='1.1' %} diff --git a/docs/pages/pmd/languages/plsql.md b/docs/pages/pmd/languages/plsql.md index 38f22bab03..d594652fa9 100644 --- a/docs/pages/pmd/languages/plsql.md +++ b/docs/pages/pmd/languages/plsql.md @@ -1,14 +1,24 @@ --- -title: PLSQL Support +title: PL/SQL Support permalink: pmd_languages_plsql.html -last_updated: March 2021 (6.33.0) -tags: [languages] -summary: "PLSQL-specific features and guidance" +last_updated: September 2023 (7.0.0) +tags: [languages, PmdCapableLanguage, CpdCapableLanguage] +summary: "PL/SQL-specific features and guidance" --- +> [Oracle Database PL/SQL Language Reference](https://docs.oracle.com/en/database/oracle/oracle-database/23/lnpls/index.html) +> describes and explains how to use PL/SQL, the Oracle procedural extension of SQL. + +{% include language_info.html name='PLSQL' id='plsql' implementation='plsql::lang.plsql.PLSQLLanguageModule' supports_pmd=true supports_cpd=true since='5.1.0' %} + +## Grammar + +PL/SQL support started out using the grammar from [PlDoc](https://pldoc.sourceforge.net/), an open-source utility for +generating HTML documentation of PL/SQL code. But the grammar has been changed significantly. + ## Parsing Exclusions -The grammar for PLSQL used in PMD has several bugs and might not parse all DDL scripts +The grammar for PL/SQL used in PMD has several bugs and might not parse all DDL scripts without errors. However, it should be best practice to call PMD for _every_ DDL script. Thus, we introduce the following workaround to cope with the situation. @@ -17,9 +27,9 @@ which cause PMD to treat the source in between these comments more or less like a multi-line comment, or in other words, just not try to parse them. It is good practice to include a reason for excluding inside the -`-- PMD-EXCUDE-BEGIN` comment separated by a colon. +`-- PMD-EXCLUDE-BEGIN` comment separated by a colon. -The `PMD-EXCLUDE-BEGIN` and `PMD-EXLUDE-END` comment lines must not contain +The `PMD-EXCLUDE-BEGIN` and `PMD-EXCLUDE-END` comment lines must not contain other statements, e.g. `do_xy(); -- PMD-EXCLUDE-BEGIN` is invalid. Example: diff --git a/docs/pages/pmd/languages/python.md b/docs/pages/pmd/languages/python.md new file mode 100644 index 0000000000..5f21999ce7 --- /dev/null +++ b/docs/pages/pmd/languages/python.md @@ -0,0 +1,11 @@ +--- +title: Python support +permalink: pmd_languages_python.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "Python-specific features and guidance" +--- + +> [Python](https://www.python.org/) is a high-level, general-purpose programming language. + +{% include language_info.html name='Python' id='python' implementation='python::lang.python.PythonLanguageModule' supports_cpd=true since='5.3.0' %} diff --git a/docs/pages/pmd/languages/ruby.md b/docs/pages/pmd/languages/ruby.md new file mode 100644 index 0000000000..a9169aa122 --- /dev/null +++ b/docs/pages/pmd/languages/ruby.md @@ -0,0 +1,12 @@ +--- +title: Ruby support +permalink: pmd_languages_ruby.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "Ruby-specific features and guidance" +--- + +> [Ruby](https://www.ruby-lang.org/en/) is a dynamic, open source programming language with a focus on simplicity and +> productivity. It has an elegant syntax that is natural to read and easy to write. + +{% include language_info.html name='Ruby' id='ruby' implementation='ruby::lang.ruby.RubyLanguageModule' supports_cpd=true since='3.0' %} diff --git a/docs/pages/pmd/languages/scala.md b/docs/pages/pmd/languages/scala.md new file mode 100644 index 0000000000..364e91cc7d --- /dev/null +++ b/docs/pages/pmd/languages/scala.md @@ -0,0 +1,13 @@ +--- +title: Scala support +permalink: pmd_languages_scala.html +last_updated: September 2023 (7.0.0) +tags: [languages, PmdCapableLanguage, CpdCapableLanguage] +summary: "Scala-specific features and guidance" +--- + +> [Scala](https://scala-lang.org/) is a modern multi-paradigm programming language designed to express common +> programming patterns in a concise, elegant, and type-safe way. It seamlessly integrates features of +> object-oriented and functional languages. + +{% include language_info.html name='Scala' id='scala' implementation='scala::lang.scala.ScalaLanguageModule' supports_pmd=true supports_cpd=true since='5.3.0' %} diff --git a/docs/pages/pmd/languages/swift.md b/docs/pages/pmd/languages/swift.md new file mode 100644 index 0000000000..c4d23bcf97 --- /dev/null +++ b/docs/pages/pmd/languages/swift.md @@ -0,0 +1,12 @@ +--- +title: Swift support +permalink: pmd_languages_swift.html +last_updated: September 2023 (7.0.0) +tags: [languages, PmdCapableLanguage, CpdCapableLanguage] +summary: "Swift-specific features and guidance" +--- + +> [Swift](https://www.swift.org/) is a general-purpose programming language that's approachable for newcomers and +> powerful for experts. It is fast, modern, safe, and a joy to write. + +{% include language_info.html name='Swift' id='swift' implementation='swift::lang.swift.SwiftLanguageModule' supports_pmd=true supports_cpd=true since='5.3.7' %} diff --git a/docs/pages/pmd/languages/tsql.md b/docs/pages/pmd/languages/tsql.md new file mode 100644 index 0000000000..51686018c5 --- /dev/null +++ b/docs/pages/pmd/languages/tsql.md @@ -0,0 +1,12 @@ +--- +title: T-SQL support +permalink: pmd_languages_tsql.html +last_updated: September 2023 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "T-SQL-specific features and guidance" +--- + +> [Transact-SQL](https://docs.microsoft.com/en-us/sql/t-sql/language-reference) (T-SQL) is Microsoft's and Sybase's +> proprietary extension to the SQL (Structured Query Language) used to interact with relational databases. + +{% include language_info.html name='T-SQL' id='tsql' implementation='tsql::lang.tsql.TSqlLanguageModule' supports_cpd=true since='6.55.0' %} diff --git a/docs/pages/pmd/languages/visualforce.md b/docs/pages/pmd/languages/visualforce.md index 8699883564..c1ca10e625 100644 --- a/docs/pages/pmd/languages/visualforce.md +++ b/docs/pages/pmd/languages/visualforce.md @@ -1,10 +1,21 @@ --- title: Visualforce Support permalink: pmd_languages_visualforce.html +last_updated: September 2023 +tags: [languages, PmdCapableLanguage, CpdCapableLanguage, experimental] author: Andreas Dangel -last_updated: October 2021 +summary: "Visualforce-specific features and guidance" --- +> [Visualforce](https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/) consists of a tag-based markup +> language that gives developers way to build applications and customize the Salesforce user interface. + +{% include language_info.html name='Salesforce Visualforce' id='vf' implementation='visualforce::lang.vf.VfLanguageModule' supports_pmd=true supports_cpd=true since='5.6.0' %} + +## Language Properties + +See [Visualforce language properties](pmd_languages_configuration.html#visualforce-language-properties) + ## Type resolution Since PMD 6.30.0 support for type resolution has been added. @@ -13,16 +24,22 @@ The Visualforce AST now can resolve the data type of Visualforce expressions tha Apex Controller properties and Custom Object fields. This feature improves the precision of existing rules, like {% rule vf/security/VfUnescapeEl %}. -This can be configured using two environment variables: +This can be configured using two language properties, which can be set as environment variables: -* `PMD_VF_APEXDIRECTORIES`: Comma separated list of directories for Apex classes. Absolute or relative +* `PMD_VF_APEX_DIRECTORIES`: Comma separated list of directories for Apex classes. Absolute or relative to the Visualforce directory. Default is `../classes`. Specifying an empty string will disable data type resolution for Apex Controller properties. -* `PMD_VF_OBJECTSDIRECTORIES`: Comma separated list of directories for Custom Objects. Absolute or relative +* `PMD_VF_OBJECTS_DIRECTORIES`: Comma separated list of directories for Custom Objects. Absolute or relative to the Visualforce directory. Default is `../objects`. Specifying an empty string will disable data type resolution for Custom Object fields. +{% include warning.html content=" +These env vars have changed from PMD 6 to PMD 7: +* `PMD_VF_APEXDIRECTORIES` ➡️ `PMD_VF_APEX_DIRECTORIES` +* `PMD_VF_OBJECTSDIRECTORIES` ➡️ `PMD_VF_OBJECTS_DIRECTORIES` +"%} + This feature is experimental, in particular, expect changes to the way the configuration is specified. We'll probably extend the CLI instead of relying on environment variables in a future version. diff --git a/docs/pages/pmd/languages/vm.md b/docs/pages/pmd/languages/vm.md new file mode 100644 index 0000000000..11f62468d1 --- /dev/null +++ b/docs/pages/pmd/languages/vm.md @@ -0,0 +1,12 @@ +--- +title: Velocity Template Language (VTL) support +permalink: pmd_languages_vm.html +last_updated: September 2023 (7.0.0) +tags: [languages, PmdCapableLanguage, CpdCapableLanguage] +summary: "VTL-specific features and guidance" +--- + +> [Velocity](https://velocity.apache.org/engine/devel/vtl-reference.html) is a Java-based template engine. +> It permits web page designers to reference methods defined in Java code. + +{% include language_info.html name='Velocity Template Language (VTL)' id='vm' implementation='vm::lang.vm.VmLanguageModule' supports_pmd=true supports_cpd=true since='5.1.0' %} diff --git a/docs/pages/pmd/languages/xml.md b/docs/pages/pmd/languages/xml.md index 409194aa63..227b3a6f0b 100644 --- a/docs/pages/pmd/languages/xml.md +++ b/docs/pages/pmd/languages/xml.md @@ -1,9 +1,16 @@ --- -title: Processing XML files +title: XML support permalink: pmd_languages_xml.html -last_updated: March 2022 (6.44.0) +last_updated: September 2023 (7.0.0) +tags: [languages, PmdCapableLanguage, CpdCapableLanguage] +summary: "XML-specific features and guidance" --- +{% include language_info.html name='Maven POM' id='pom' implementation='xml::lang.pom.PomLanguageModule' supports_pmd=true supports_cpd=true since='5.4.0' %} +{% include language_info.html name='WSDL' id='wsdl' implementation='xml::lang.wsdl.WsdlLanguageModule' supports_pmd=true supports_cpd=true since='5.4.0' %} +{% include language_info.html name='XML' id='xml' implementation='xml::lang.xml.XmlLanguageModule' supports_pmd=true supports_cpd=true since='5.0.0' %} +{% include language_info.html name='XSL' id='xsl' implementation='xml::lang.xsl.XslLanguageModule' supports_pmd=true supports_cpd=true since='5.0.0' %} + ## The XML language module PMD has an XML language module which exposes the [DOM](https://de.wikipedia.org/wiki/Document_Object_Model) diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 64be0f432d..d02ef3456a 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -13,1026 +13,1029 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

0xflotus

💻 🐛

1henni

🐛

ALiNew

🐛

ASBrouwers

💻

Abhijit Sarkar

🐛

Abhishek Kumar

🐛

Adam

🐛

Adam Carroll

🐛

Adam Obuchowicz

🐛

Adrian Price

🐛

Adrien Lecharpentier

🐛

Aidan Harding

🐛

Akshat Bahety

💻 🐛

Akshay Thapa

🐛

Alan Buttars

🐛

Alan Hohn

🐛

Alberto Fernández

💻 🐛

Alex

💻

Alex

🐛

Alex Rentz

🐛

Alex Saveau

🐛

Alex Shesterov

💻 🐛

Alexey Markevich

🐛

Alexey Naumov

🐛

Alexey Yudichev

🐛

Alix

🐛

Alix

🐛

Amish Shah

🐛

Amit Prasad

🐛

Amitosh Swain Mahapatra

🐛

Anand Subramanian

💻 🐛

Anastasiia Koba

💻

Anatoly Trosinenko

💻 🐛

Andi Pabst

💻 🐛

Andrea

🐛

Andrea Aime

🐛

Andreas Dangel

💻 📖 🐛 🚧

Andreas Deininger

📖

Andreas Markussen

🐛

Andreas Schmid

🐛

Andreas Turban

🐛

Andrei Paikin

🐛

Andrew

🐛

Andrew Green

🐛

Andrey Bozhko

📖

Andrey Fomin

🐛

Andrey Hitrin

🐛

Andrey Mochalov

💻 🐛

Andro72

🐛

Andrwyw

🐛

Andrés Catalán

🐛

Andy Pattenden

🐛

Andy Ray

🐛

Andy Robinson

🐛

Andy-2639

🐛

Ankush Somani

🐛

Anmol Kumar

🐛

Anthony Whitford

🐛

AnthonyKot

🐛

Aravind Hegde

🐛

Arda Aslan

🐛

Ari Fogel

🐛

Arnaud Jeansen

💻 🐛

Arpit Koolwal

🐛

Artem

💻 🐛

Artem

🐛

Artem Sheremet

🐛

Artur

🐛

Artur Bosch

🐛

Artur Dryomov

🐛

Artur Ossowski

🐛

AshTheMash

🐛

Ashish Rana

🐛

Atul Kaushal

🐛

August Boland

🐛

Aurel Hudec

🐛

Austin

🐛

Austin Shalit

🐛

Austin Tice

🐛

Ayoub Kaanich

🐛

BBG

💻 📖 🐛

Bailey Tjiong

💻

Barthélemy L.

🐛

Basavaraj K N

🐛

Basil Peace

🐛

Belle

🐛

Ben Lerner

🐛

Ben Manes

🐛

Ben McCann

🐛

Bendegúz Nagy

🐛

Bennet S Yee

🐛

Benoit Lacelle

🐛

Bernardo Macêdo

🐛

Bernd Farka

🐛

Betina Cynthia Mamani

🐛

Bhanu Prakash Pamidi

💻 🐛

Bhargav Thanki

🐛

Binu R J

🐛

Björn Kautler

💻 🐛

Blightbuster

🐛

Bo Zhang

🐛

Bob "Wombat" Hogg

🐛

Bobby Wertman

🐛

Bolarinwa Saheed Olayemi

💻 🐛

Boris Petrov

🐛

Brad Kent

🐛

Brandon Mikeska

🐛

Brian Batronis

🐛

Brian Johnson

🐛

Brice Dutheil

💻 🐛

Bruno Ferreira

🐛

Bruno Harbulot

🐛

Bruno Ritz

🐛

Cameron Donaldson

🐛

Carlos Macasaet

🐛

Carsten Otto

🐛

Charlie Housh

🐛

Charlie Jonas

🐛

Chas Honton

🐛

Chen Yang

🐛

Chotu

🐛

Chris Smith

🐛

Chris Toomey

🐛

Christian Hujer

🐛

Christian Pontesegger

🐛

ChristianWulf

🐛

Christofer Dutz

💻

Christoffer Anselm

🐛

Christophe Vidal

🐛

Christopher Dancy

🐛

Clemens Prill

🐛

Clint Chester

💻 🐛

Clément Fournier

💻 📖 🐛 🚧

Codacy Badger

🐛

Code-Nil

🐛

ColColonCleaner

🐛

Colin Ingarfield

🐛

Craig Andrews

🐛

Craig Muchinsky

🐛

Cyril

💻 🐛

Dale

💻

Damien Jiang

🐛

Dan Berindei

🐛

Dan Rollo

🐛

Dan Ziemba

🐛

Daniel Gredler

💻 🐛

Daniel Jipa

🐛

Daniel Paul Searles

💻

Daniel Reigada

🐛

Danilo Pianini

🐛

Darko

🐛

David

🐛

David Atkinson

🐛

David Burström

💻 🐛

David Goaté

🐛

David Golpira

🐛

David Kovařík

🐛

David M. Karr (fullname at gmail.com)

🐛

David Renz

💻 🐛

David Renz

🐛

Dawid Ciok

🐛 💻

Deleted user

🐛

Dell Green

🐛

Dem Pilafian

🐛

Den

🐛

Denis Borovikov

💻 🐛

Dennie Reniers

💻 🐛

Dennis Kieselhorst

🐛

Derek P. Moore

🐛

Dichotomia

🐛

Dionisio Cortés Fernández

💻 🐛

Dmitri Bourlatchkov

🐛

Dmitriy Kuzmin

🐛

Dmytro Dashenkov

🐛

Drew Hall

🐛

Dumitru Postoronca

🐛

Dylan Adams

🐛

Eden Hao

🐛

Edward Klimoshenko

🐛 💻

Egor Bredikhin

🐛

Elan P. Kugelmass

🐛

Elder S.

🐛

Eldrick Wega

📖

Emile

🐛

Eric

🐛

Eric Kintzer

🐛

Eric Perret

🐛

Eric Squires

🐛

Erich L Foster

🐛

Erik Bleske

🐛

Ernst Reissner

🐛

Ewan Tempero

🐛

F.W. Dekker

🐛

FSchliephacke

🐛

Facundo

🐛

Federico Giust

🐛

Fedor Sherstobitov

🐛

Felix Lampe

🐛

Filip Golonka

🐛

Filipe Esperandio

💻 🐛

Filippo Nova

🐛

Francesco la Torre

🐛

Francisco Duarte

🐛

Frieder Bluemle

🐛

Frits Jalvingh

💻 🐛

G. Bazior

🐛

Gabe Henkes

🐛

Gary Gregory

🐛

Genoud Magloire

🐛

Geoffrey555

🐛

Georg Romstorfer

🐛

Gio

🐛

Gol

🐛

Gonzalo Exequiel Ibars Ingman

💻 🐛

GooDer

🐛

Gregor Riegler

🐛

Grzegorz Olszewski

🐛

Gunther Schrijvers

💻 🐛

Gustavo Krieger

🐛

Guy Elsmore-Paddock

🐛

Görkem Mülayim

🐛

Hanzel Godinez

🐛

Haoliang Chen

🐛

Harsh Kukreja

🐛

Hassan ALAMI

🐛

Heber

🐛

Henning Schmiedehausen

💻 🐛

Henning von Bargen

💻

Hervé Boutemy

🐛

Himanshu Pandey

🐛

Hokwang Lee

🐛

Hooperbloob

💻

Hung PHAN

🐛

IDoCodingStuffs

💻 🐛

Iccen Gan

🐛

Ignacio Mariano Tirabasso

🐛

Igor Melnichenko

🐛

Igor Moreno

🐛

Intelesis-MS

🐛

Iroha_

🐛

Ishan Srivastava

🐛

Ivano Guerini

🐛

Ivar Andreas Bonsaksen

🐛

Ivo Šmíd

🐛

JJengility

🐛

Jake Hemmerle

🐛

James Harrison

🐛 💻

Jan

🐛

Jan Aertgeerts

💻 🐛

Jan Brümmer

🐛

Jan Tříska

🐛

Jan-Lukas Else

🐛

Jason Qiu

💻 📖

Jason Williams

🐛

Jean-Paul Mayer

🐛

Jean-Simon Larochelle

🐛

Jeff Bartolotta

💻 🐛

Jeff Hube

💻 🐛

Jeff Jensen

🐛

Jeff May

🐛

Jens Gerdes

🐛

Jeroen Borgers

🐛 💻 📢

Jeroen van Wilgenburg

📖

Jerome Russ

🐛

JerritEic

💻 📖 🐛

Jiri Pejchal

🐛

Jithin Sunny

🐛

Jiří Škorpil

🐛

Joao Machado

🐛

Jochen Krauss

🐛

Johan Hammar

🐛

John Karp

🐛

John Zhang

🐛

John-Teng

💻 🐛

Jon Moroney

💻 🐛

Jonas Geiregat

🐛

Jonathan Wiesel

💻 🐛

Jordan

🐛

Jordi Llach

🐛

Jorge Solórzano

🐛

JorneVL

🐛

Jose Palafox

🐛

Jose Stovall

🐛

Joseph

💻

Joseph Heenan

🐛

Josh Feingold

💻 🐛

Josh Holthaus

🐛

Joshua S Arquilevich

🐛

João Dinis Ferreira

📖

João Ferreira

💻 🐛

João Pedro Schmitt

🐛

Juan Martín Sotuyo Dodero

💻 📖 🐛 🚧

Juan Pablo Civile

🐛

Julian Voronetsky

🐛

Julien

🐛

Julius

🐛

JustPRV

🐛

Jörn Huxhorn

🐛

KThompso

🐛

Kai Amundsen

🐛

Karel Vervaeke

🐛

Karl-Andero Mere

🐛

Karl-Philipp Richter

🐛

Karsten Silz

🐛

Kazuma Watanabe

🐛

Kev

🐛

Keve Müller

🐛

Kevin Guerra

💻

Kevin Jones

🐛 💻

Kevin Wayne

🐛

Kieran Black

🐛

Kirill Zubov

🐛

Kirk Clemens

💻 🐛

Klaus Hartl

🐛

Koen Van Looveren

🐛

Kris Scheibe

💻 🐛

Krystian Dabrowski

🐛 💻

Kunal Thanki

🐛

LaLucid

💻

Larry Diamond

💻 🐛

Lars Knickrehm

🐛

Leo Gutierrez

🐛

LiGaOg

💻

Liam Sharp

🐛

Lintsi

🐛

Linus Fernandes

🐛

Lixon Lookose

🐛

Logesh

🐛

Lorenzo Gabriele

🐛

Loïc Ledoyen

🐛

Lucas Silva

🐛

Lucas Soncini

💻 🐛

Luis Alcantar

💻

Lukasz Slonina

🐛

Lukebray

🐛

Lynn

💻 🐛

Lyor Goldstein

🐛

MCMicS

🐛

Macarse

🐛

Machine account for PMD

💻

Maciek Siemczyk

🐛

Maikel Steneker

💻 🐛

Maksim Moiseikin

🐛

Manfred Koch

🐛

Manuel Moya Ferrer

💻 🐛

Manuel Ryan

🐛

Marat Vyshegorodtsev

🐛

Marcel Härle

🐛

Marcello Fialho

🐛

Marcin Rataj

🐛

Marcono1234

🐛

Mark Adamcin

🐛

Mark Hall

💻 🐛

Mark Kolich

🐛

Mark Pritchard

🐛

Markus Rathgeb

🐛

Marquis Wang

🐛

MartGit

🐛

Martin Feldsztejn

🐛

Martin Lehmann

🐛

Martin Spamer

🐛

Martin Tarjányi

🐛

MatFl

🐛

Mateusz Stefanski

🐛

Mathieu Gouin

🐛

MatiasComercio

💻 🐛

Matt Benson

🐛

Matt De Poorter

🐛

Matt Hargett

💻 💵

Matt Harrah

🐛

Matt Nelson

🐛

Matthew Amos

🐛

Matthew Duggan

🐛

Matthew Hall

🐛

Matías Fraga

💻 🐛

Maxime Robert

💻 🐛

MetaBF

🐛

Michael

🐛

Michael Bell

🐛

Michael Bernstein

🐛

Michael Clay

🐛

Michael Dombrowski

🐛

Michael Hausegger

🐛

Michael Hoefer

🐛

Michael Möbius

🐛

Michael N. Lipp

🐛

Michael Pellegrini

🐛

Michal Kordas

🐛

Michał Borek

🐛

Michał Kuliński

🐛

Miguel Núñez Díaz-Montes

🐛

Mihai Ionut

🐛

Mirek Hankus

🐛

Mladjan Gadzic

🐛

MrAngry52

🐛

Muminur Choudhury

🐛

Mykhailo Palahuta

💻 🐛

Nagendra Kumar Singh

🐛

Nahuel Barrios

🐛

Nathan Braun

🐛

Nathan Reynolds

🐛

Nathan Reynolds

🐛

Nathanaël

🐛

Naveen

💻

Nazdravi

🐛

Neha-Dhonde

🐛

Nicholas Doyle

🐛

Nick Butcher

🐛

Nico Gallinal

🐛

Nicola Dal Maso

🐛

Nicolas Filotto

💻

Nicolas Vervelle

🐛

Nicolas Vuillamy

📖

Nikita Chursin

🐛

Niklas Baudy

🐛

Nikolas Havrikov

🐛

Nilesh Virkar

🐛

Nimit Patel

🐛

Niranjan Harpale

🐛

Nirvik Patel

💻

Noah Sussman

🐛

Noah0120

🐛

Noam Tamim

🐛

Noel Grandin

🐛

Olaf Haalstra

🐛

Oleg Andreych

💻 🐛

Oleg Pavlenko

🐛

Oleksii Dykov

💻 🐛

Oliver Eikemeier

🐛

Oliver Siegmar

💵

Olivier Parent

💻 🐛

Ollie Abbey

💻 🐛

OverDrone

🐛

Ozan Gulle

💻 🐛

PUNEET JAIN

🐛

Parbati Bose

🐛

Paul Berg

🐛

Paul Guyot

💻

Pavel Bludov

🐛

Pavel Mička

🐛

Pedro Nuno Santos

🐛

Pedro Rijo

🐛

Pelisse Romain

💻 📖 🐛

Per Abich

💻

Pete Davids

🐛

Peter Bruin

🐛

Peter Chittum

💻 🐛

Peter Cudmore

🐛

Peter Kasson

🐛

Peter Kofler

🐛

Peter Paul Bakker

💻

Pham Hai Trung

🐛

Philip Graf

💻 🐛

Philip Hachey

🐛

Philippe Ozil

🐛

Phinehas Artemix

🐛

Phokham Nonava

🐛

Pim van der Loos

💻 ⚠️

Piotr Szymański

🐛

Piotrek Żygieło

💻 🐛 📖

Pranay Jaiswal

🐛

Prasad Kamath

🐛

Prasanna

🐛

Presh-AR

🐛

Puneet1726

🐛

Rafael Cortês

🐛

RaheemShaik999

🐛

RajeshR

💻 🐛

Ramachandra Mohan

🐛

Ramel0921

🐛

Raquel Pau

🐛

Ravikiran Janardhana

🐛

Reda Benhemmouche

🐛

Renato Oliveira

💻 🐛

Rich DiCroce

🐛

Richard Corfield

💻

Richard Corfield

🐛 💻

Riot R1cket

🐛

Rishabh Jain

🐛

RishabhDeep Singh

🐛

Robbie Martinus

💻 🐛

Robert Henry

🐛

Robert Mihaly

🐛

Robert Painsi

🐛

Robert Russell

🐛

Robert Sösemann

💻 📖 📢 🐛

Robert Whitebit

🐛

Robin Richtsfeld

🐛

Robin Stocker

💻 🐛

Robin Wils

🐛

RochusOest

🐛

Rodolfo Noviski

🐛

Rodrigo Casara

🐛

Rodrigo Fernandes

🐛

Roman Salvador

💻 🐛

Ronald Blaschke

🐛

Róbert Papp

🐛

Saikat Sengupta

🐛

Saksham Handu

🐛

Saladoc

🐛

Salesforce Bob Lightning

🐛

Sam Carlberg

🐛

Satoshi Kubo

🐛

Scott Kennedy

🐛

Scott Wells

🐛 💻

Scrsloota

💻

Sebastian Bögl

🐛

Sebastian Schuberth

🐛

Sebastian Schwarz

🐛

Seren

🐛 💻

Sergey Gorbaty

🐛

Sergey Kozlov

🐛

Sergey Yanzin

💻 🐛

Seth Wilcox

💻

Shubham

💻 🐛

Simon Abykov

💻 🐛

Simon Xiao

🐛

Srinivasan Venkatachalam

🐛

Stanislav Gromov

🐛

Stanislav Myachenkov

💻

Stefan Birkner

🐛

Stefan Bohn

🐛

Stefan Endrullis

🐛

Stefan Klöss-Schuster

🐛

Stefan Wolf

🐛

Stephan H. Wissel

🐛

Stephen

🐛

Stephen Friedrich

🐛

Steve Babula

💻

Steven Stearns

🐛 💻

Stexxe

🐛

Stian Lågstad

🐛

StuartClayton5

🐛

Supun Arunoda

🐛

Suren Abrahamyan

🐛

Suvashri

📖

SwatiBGupta1110

🐛

SyedThoufich

🐛

Szymon Sasin

🐛

T-chuangxin

🐛

TERAI Atsuhiro

🐛

TIOBE Software

💻 🐛

Tarush Singh

💻

Taylor Smock

🐛

Techeira Damián

💻 🐛

Ted Husted

🐛

TehBakker

🐛

The Gitter Badger

🐛

Theodoor

🐛

Thiago Henrique Hüpner

🐛

Thibault Meyer

🐛

Thomas Güttler

🐛

Thomas Jones-Low

🐛

Thomas Smith

💻 🐛

ThrawnCA

🐛

Thunderforge

💻 🐛

Tim van der Lippe

🐛

Tobias Weimer

💻 🐛

Tom Copeland

🐛 💻 📖

Tom Daly

🐛

Tomer Figenblat

🐛

Tomi De Lucca

💻 🐛

Torsten Kleiber

🐛

TrackerSB

🐛

Tyson Stewart

🐛

Ullrich Hafner

🐛

Utku Cuhadaroglu

💻 🐛

Valentin Brandl

🐛

Valeria

🐛

Valery Yatsynovich

📖

Vasily Anisimov

🐛

Vibhor Goyal

🐛

Vickenty Fesunov

🐛

Victor Noël

🐛

Vincent Galloy

💻

Vincent HUYNH

🐛

Vincent Maurin

🐛

Vincent Privat

🐛

Vishhwas

🐛

Vitaly

🐛

Vitaly Polonetsky

🐛

Vojtech Polivka

🐛

Vsevolod Zholobov

🐛

Vyom Yadav

💻

Wang Shidong

🐛

Waqas Ahmed

🐛

Wayne J. Earl

🐛

Wchenghui

🐛

Wener

💻

Will Winder

🐛

William Brockhus

💻 🐛

Wilson Kurniawan

🐛

Wim Deblauwe

🐛

Woongsik Choi

🐛

XenoAmess

💻 🐛

Yang

💻

YaroslavTER

🐛

Yasar Shaikh

💻

Young Chan

💻 🐛

YuJin Kim

🐛

Yuri Dolzhenko

🐛

Yurii Dubinka

🐛

Zoltan Farkas

🐛

Zustin

🐛

aaronhurst-google

🐛 💻

alexmodis

🐛

andreoss

🐛

andrey81inmd

💻 🐛

anicoara

🐛

arunprasathav

🐛

asiercamara

🐛

astillich-igniti

💻

avesolovksyy

🐛

avishvat

🐛

avivmu

🐛

axelbarfod1

🐛

b-3-n

🐛

balbhadra9

🐛

base23de

🐛

bergander

🐛

berkam

💻 🐛

breizh31

🐛

caesarkim

🐛

carolyujing

🐛

cbfiddle

🐛

cesares-basilico

🐛

chrite

🐛

cobratbq

🐛

coladict

🐛

cosmoJFH

🐛

cristalp

🐛

crunsk

🐛

cwholmes

🐛

cyberjj999

🐛

cyw3

🐛 📖

d1ss0nanz

🐛

dague1

📖

dalizi007

💻

danbrycefairsailcom

🐛

dariansanity

🐛

darrenmiliband

🐛

davidburstrom

🐛

dbirkman-paloalto

🐛

deepak-patra

🐛

dependabot[bot]

💻 🐛

dinesh150

🐛

diziaq

🐛

dreaminpast123

🐛

duanyanan

🐛

dutt-sanjay

🐛

dylanleung

🐛

dzeigler

🐛

eant60

🐛

ekkirala

🐛

emersonmoura

🐛

eugenepugach

🐛

fairy

🐛

filiprafalowicz

💻

foxmason

🐛

frankegabor

🐛

frankl

🐛

freafrea

🐛

fsapatin

🐛

gracia19

🐛

guo fei

🐛

gurmsc5

🐛

gwilymatgearset

💻 🐛

haigsn

🐛

hemanshu070

🐛

henrik242

🐛

hongpuwu

🐛

hvbtup

💻 🐛

igniti GmbH

🐛

ilovezfs

🐛

itaigilo

🐛

jakivey32

🐛

jbennett2091

🐛

jcamerin

🐛

jkeener1

🐛

jmetertea

🐛

johnra2

💻

josemanuelrolon

💻 🐛

kabroxiko

💻 🐛

karwer

🐛

kaulonline

🐛

kdaemonv

🐛

kdebski85

🐛 💻

kenji21

💻 🐛

kfranic

🐛

khalidkh

🐛

koalalam

🐛

krzyk

🐛

lasselindqvist

🐛

lgemeinhardt

🐛

lihuaib

🐛

lonelyma1021

🐛

lpeddy

🐛

lujiefsi

💻

lukelukes

💻

lyriccoder

🐛

marcelmore

🐛

matchbox

🐛

matthiaskraaz

🐛

meandonlyme

🐛

mikesive

🐛

milossesic

🐛

mluckam

💻

mohan-chinnappan-n

💻

mriddell95

🐛

mrlzh

🐛

msloan

🐛

mucharlaravalika

🐛

mvenneman

🐛

nareshl119

🐛

nicolas-harraudeau-sonarsource

🐛

noerremark

🐛

novsirion

🐛

nwcm

📖 🐛

oggboy

🐛

oinume

🐛

orimarko

💻 🐛

pacvz

💻

pallavi agarwal

🐛

parksungrin

🐛

patpatpat123

🐛

patriksevallius

🐛

pbrajesh1

🐛

phoenix384

🐛

piotrszymanski-sc

💻

plan3d

🐛

poojasix

🐛

prabhushrikant

🐛

pujitha8783

🐛

r-r-a-j

🐛

raghujayjunk

🐛

rajeshveera

🐛

rajeswarreddy88

🐛

recdevs

🐛

reudismam

💻 🐛

rijkt

🐛

rillig-tk

🐛

rmohan20

💻 🐛

rnveach

🐛

rxmicro

🐛

ryan-gustafson

💻 🐛

sabi0

🐛

scais

🐛

sebbASF

🐛

sergeygorbaty

💻

shilko2013

🐛

shiomiyan

📖

simeonKondr

🐛

snajberk

🐛

sniperrifle2004

🐛

snuyanzin

🐛 💻

sratz

🐛

stonio

🐛

sturton

💻 🐛

sudharmohan

🐛

suruchidawar

🐛

svenfinitiv

🐛

tashiscool

🐛

test-git-hook

🐛

testation21

💻 🐛

thanosa

🐛

tiandiyixian

🐛

tobwoerk

🐛

tprouvot

🐛 💻

trentchilders

🐛

triandicAnt

🐛

trishul14

🐛

tsui

🐛

winhkey

🐛

witherspore

🐛

wjljack

🐛

wuchiuwong

🐛

xingsong

🐛

xioayuge

🐛

xnYi9wRezm

💻 🐛

xuanuy

🐛

xyf0921

🐛

yalechen-cyw3

🐛

yasuharu-sato

🐛

zenglian

🐛

zgrzyt93

💻 🐛

zh3ng

🐛

zt_soft

🐛

ztt79

🐛

zzzzfeng

🐛

Árpád Magosányi

🐛

任贵杰

🐛

茅延安

💻
0xflotus
0xflotus

💻 🐛
1henni
1henni

🐛
ALiNew
ALiNew

🐛
ASBrouwers
ASBrouwers

💻
Abhijit Sarkar
Abhijit Sarkar

🐛
Abhishek Kumar
Abhishek Kumar

🐛
Adam
Adam

🐛
Adam Carroll
Adam Carroll

🐛
Adam Obuchowicz
Adam Obuchowicz

🐛
Adrian Price
Adrian Price

🐛
Adrien Lecharpentier
Adrien Lecharpentier

🐛
Aidan Harding
Aidan Harding

🐛
Akshat Bahety
Akshat Bahety

💻 🐛
Akshay Thapa
Akshay Thapa

🐛
Alan Buttars
Alan Buttars

🐛
Alan Hohn
Alan Hohn

🐛
Alberto Fernández
Alberto Fernández

💻 🐛
Alex
Alex

💻
Alex
Alex

🐛
Alex Rentz
Alex Rentz

🐛
Alex Saveau
Alex Saveau

🐛
Alex Shesterov
Alex Shesterov

💻 🐛
Alexey Markevich
Alexey Markevich

🐛
Alexey Naumov
Alexey Naumov

🐛
Alexey Yudichev
Alexey Yudichev

🐛
Alix
Alix

🐛
Alix
Alix

🐛
Amish Shah
Amish Shah

🐛
Amit Prasad
Amit Prasad

🐛
Amitosh Swain Mahapatra
Amitosh Swain Mahapatra

🐛
Anand Subramanian
Anand Subramanian

💻 🐛
Anastasiia Koba
Anastasiia Koba

💻
Anatoly Trosinenko
Anatoly Trosinenko

💻 🐛
Andi Pabst
Andi Pabst

💻 🐛
Andrea
Andrea

🐛
Andrea Aime
Andrea Aime

🐛
Andreas Dangel
Andreas Dangel

💻 📖 🐛 🚧
Andreas Deininger
Andreas Deininger

📖
Andreas Markussen
Andreas Markussen

🐛
Andreas Schmid
Andreas Schmid

🐛
Andreas Turban
Andreas Turban

🐛
Andrei Paikin
Andrei Paikin

🐛
Andrew
Andrew

🐛
Andrew Green
Andrew Green

🐛
Andrey Bozhko
Andrey Bozhko

📖
Andrey Fomin
Andrey Fomin

🐛
Andrey Hitrin
Andrey Hitrin

🐛
Andrey Mochalov
Andrey Mochalov

💻 🐛
Andro72
Andro72

🐛
Andrwyw
Andrwyw

🐛
Andrés Catalán
Andrés Catalán

🐛
Andy Pattenden
Andy Pattenden

🐛
Andy Ray
Andy Ray

🐛
Andy Robinson
Andy Robinson

🐛
Andy-2639
Andy-2639

🐛
Ankush Somani
Ankush Somani

🐛
Anmol Kumar
Anmol Kumar

🐛
Anthony Whitford
Anthony Whitford

🐛
AnthonyKot
AnthonyKot

🐛
Aravind Hegde
Aravind Hegde

🐛
Arda Aslan
Arda Aslan

🐛
Ari Fogel
Ari Fogel

🐛
Arnaud Jeansen
Arnaud Jeansen

💻 🐛
Arpit Koolwal
Arpit Koolwal

🐛
Artem
Artem

💻 🐛
Artem
Artem

🐛
Artem Sheremet
Artem Sheremet

🐛
Artur
Artur

🐛
Artur Bosch
Artur Bosch

🐛
Artur Dryomov
Artur Dryomov

🐛
Artur Ossowski
Artur Ossowski

🐛
AshTheMash
AshTheMash

🐛
Ashish Rana
Ashish Rana

🐛
Atul Kaushal
Atul Kaushal

🐛
August Boland
August Boland

🐛
Aurel Hudec
Aurel Hudec

🐛
Austin
Austin

🐛
Austin Shalit
Austin Shalit

🐛
Austin Tice
Austin Tice

🐛
Ayoub Kaanich
Ayoub Kaanich

🐛
BBG
BBG

💻 📖 🐛
Bailey Tjiong
Bailey Tjiong

💻
Barthélemy L.
Barthélemy L.

🐛
Basavaraj K N
Basavaraj K N

🐛
Basil Peace
Basil Peace

🐛
Belle
Belle

🐛
Ben Lerner
Ben Lerner

🐛
Ben Manes
Ben Manes

🐛
Ben McCann
Ben McCann

🐛
Bendegúz Nagy
Bendegúz Nagy

🐛
Bennet S Yee
Bennet S Yee

🐛
Benoit Lacelle
Benoit Lacelle

🐛
Bernardo Macêdo
Bernardo Macêdo

🐛
Bernd Farka
Bernd Farka

🐛
Betina Cynthia Mamani
Betina Cynthia Mamani

🐛
Bhanu Prakash Pamidi
Bhanu Prakash Pamidi

💻 🐛
Bhargav Thanki
Bhargav Thanki

🐛
Binu R J
Binu R J

🐛
Björn Kautler
Björn Kautler

💻 🐛
Blightbuster
Blightbuster

🐛
Bo Zhang
Bo Zhang

🐛
Bob "Wombat" Hogg
Bob "Wombat" Hogg

🐛
Bobby Wertman
Bobby Wertman

🐛
Bolarinwa Saheed Olayemi
Bolarinwa Saheed Olayemi

💻 🐛
Boris Petrov
Boris Petrov

🐛
Brad Kent
Brad Kent

🐛
Brandon Mikeska
Brandon Mikeska

🐛
Brian Batronis
Brian Batronis

🐛
Brian Johnson
Brian Johnson

🐛
Brice Dutheil
Brice Dutheil

💻 🐛
Bruno Ferreira
Bruno Ferreira

🐛
Bruno Harbulot
Bruno Harbulot

🐛
Bruno Ritz
Bruno Ritz

🐛
Cameron Donaldson
Cameron Donaldson

🐛
Carlos Macasaet
Carlos Macasaet

🐛
Carsten Otto
Carsten Otto

🐛
Charlie Housh
Charlie Housh

🐛
Charlie Jonas
Charlie Jonas

🐛
Chas Honton
Chas Honton

🐛
Chen Yang
Chen Yang

🐛
Chotu
Chotu

🐛
Chris Smith
Chris Smith

🐛
Chris Toomey
Chris Toomey

🐛
Christian Hujer
Christian Hujer

🐛
Christian Pontesegger
Christian Pontesegger

🐛
ChristianWulf
ChristianWulf

🐛
Christofer Dutz
Christofer Dutz

💻
Christoffer Anselm
Christoffer Anselm

🐛
Christophe Vidal
Christophe Vidal

🐛
Christopher Dancy
Christopher Dancy

🐛
Clemens Prill
Clemens Prill

🐛
Clint Chester
Clint Chester

💻 🐛
Clément Fournier
Clément Fournier

💻 📖 🐛 🚧
Codacy Badger
Codacy Badger

🐛
Code-Nil
Code-Nil

🐛
ColColonCleaner
ColColonCleaner

🐛
Colin Ingarfield
Colin Ingarfield

🐛
Craig Andrews
Craig Andrews

🐛
Craig Muchinsky
Craig Muchinsky

🐛
Cyril
Cyril

💻 🐛
Dale
Dale

💻
Damien Jiang
Damien Jiang

🐛
Dan Berindei
Dan Berindei

🐛
Dan Rollo
Dan Rollo

🐛
Dan Ziemba
Dan Ziemba

🐛
Daniel Gredler
Daniel Gredler

💻 🐛
Daniel Jipa
Daniel Jipa

🐛
Daniel Paul Searles
Daniel Paul Searles

💻
Daniel Reigada
Daniel Reigada

🐛
Danilo Pianini
Danilo Pianini

🐛
Darko
Darko

🐛
David
David

🐛
David Atkinson
David Atkinson

🐛
David Burström
David Burström

💻 🐛
David Goaté
David Goaté

🐛
David Golpira
David Golpira

🐛
David Kovařík
David Kovařík

🐛
David M. Karr (fullname at gmail.com)
David M. Karr (fullname at gmail.com)

🐛
David Renz
David Renz

💻 🐛
David Renz
David Renz

🐛
Dawid Ciok
Dawid Ciok

🐛 💻
Deleted user
Deleted user

🐛
Dell Green
Dell Green

🐛
Dem Pilafian
Dem Pilafian

🐛
Den
Den

🐛
Denis Borovikov
Denis Borovikov

💻 🐛
Dennie Reniers
Dennie Reniers

💻 🐛
Dennis Kieselhorst
Dennis Kieselhorst

🐛
Derek P. Moore
Derek P. Moore

🐛
Dichotomia
Dichotomia

🐛
Dionisio Cortés Fernández
Dionisio Cortés Fernández

💻 🐛
Dmitri Bourlatchkov
Dmitri Bourlatchkov

🐛
Dmitriy Kuzmin
Dmitriy Kuzmin

🐛
Dmytro Dashenkov
Dmytro Dashenkov

🐛
Drew Hall
Drew Hall

🐛
Dumitru Postoronca
Dumitru Postoronca

🐛
Dylan Adams
Dylan Adams

🐛
Eden Hao
Eden Hao

🐛
Edward Klimoshenko
Edward Klimoshenko

🐛 💻
Egor Bredikhin
Egor Bredikhin

🐛
Elan P. Kugelmass
Elan P. Kugelmass

🐛
Elder S.
Elder S.

🐛
Eldrick Wega
Eldrick Wega

📖
Emile
Emile

🐛
Eric
Eric

🐛
Eric Kintzer
Eric Kintzer

🐛
Eric Perret
Eric Perret

🐛
Eric Squires
Eric Squires

🐛
Erich L Foster
Erich L Foster

🐛
Erik Bleske
Erik Bleske

🐛
Ernst Reissner
Ernst Reissner

🐛
Ewan Tempero
Ewan Tempero

🐛
F.W. Dekker
F.W. Dekker

🐛
FSchliephacke
FSchliephacke

🐛
Facundo
Facundo

🐛
Federico Giust
Federico Giust

🐛
Fedor Sherstobitov
Fedor Sherstobitov

🐛
Felix Lampe
Felix Lampe

🐛
Filip Golonka
Filip Golonka

🐛
Filipe Esperandio
Filipe Esperandio

💻 🐛
Filippo Nova
Filippo Nova

🐛
Francesco la Torre
Francesco la Torre

🐛
Francisco Duarte
Francisco Duarte

🐛
Frieder Bluemle
Frieder Bluemle

🐛
Frits Jalvingh
Frits Jalvingh

💻 🐛
G. Bazior
G. Bazior

🐛
Gabe Henkes
Gabe Henkes

🐛
Gary Gregory
Gary Gregory

🐛
Genoud Magloire
Genoud Magloire

🐛
Geoffrey555
Geoffrey555

🐛
Georg Romstorfer
Georg Romstorfer

🐛
Gio
Gio

🐛
Gol
Gol

🐛
Gonzalo Exequiel Ibars Ingman
Gonzalo Exequiel Ibars Ingman

💻 🐛
GooDer
GooDer

🐛
Gregor Riegler
Gregor Riegler

🐛
Grzegorz Olszewski
Grzegorz Olszewski

🐛
Gunther Schrijvers
Gunther Schrijvers

💻 🐛
Gustavo Krieger
Gustavo Krieger

🐛
Guy Elsmore-Paddock
Guy Elsmore-Paddock

🐛
Görkem Mülayim
Görkem Mülayim

🐛
Hanzel Godinez
Hanzel Godinez

🐛
Haoliang Chen
Haoliang Chen

🐛
Harsh Kukreja
Harsh Kukreja

🐛
Hassan ALAMI
Hassan ALAMI

🐛
Heber
Heber

🐛
Henning Schmiedehausen
Henning Schmiedehausen

💻 🐛
Henning von Bargen
Henning von Bargen

💻
Hervé Boutemy
Hervé Boutemy

🐛
Himanshu Pandey
Himanshu Pandey

🐛
Hokwang Lee
Hokwang Lee

🐛
Hooperbloob
Hooperbloob

💻
Hung PHAN
Hung PHAN

🐛
IDoCodingStuffs
IDoCodingStuffs

💻 🐛
Iccen Gan
Iccen Gan

🐛
Ignacio Mariano Tirabasso
Ignacio Mariano Tirabasso

🐛
Igor Melnichenko
Igor Melnichenko

🐛
Igor Moreno
Igor Moreno

🐛
Intelesis-MS
Intelesis-MS

🐛
Iroha_
Iroha_

🐛
Ishan Srivastava
Ishan Srivastava

🐛
Ivano Guerini
Ivano Guerini

🐛
Ivar Andreas Bonsaksen
Ivar Andreas Bonsaksen

🐛
Ivo Šmíd
Ivo Šmíd

🐛
JJengility
JJengility

🐛
Jake Hemmerle
Jake Hemmerle

🐛
James Harrison
James Harrison

🐛 💻
Jan
Jan

🐛
Jan Aertgeerts
Jan Aertgeerts

💻 🐛
Jan Brümmer
Jan Brümmer

🐛
Jan Tříska
Jan Tříska

🐛
Jan-Lukas Else
Jan-Lukas Else

🐛
Jason Qiu
Jason Qiu

💻 📖
Jason Williams
Jason Williams

🐛
Jean-Paul Mayer
Jean-Paul Mayer

🐛
Jean-Simon Larochelle
Jean-Simon Larochelle

🐛
Jeff Bartolotta
Jeff Bartolotta

💻 🐛
Jeff Hube
Jeff Hube

💻 🐛
Jeff Jensen
Jeff Jensen

🐛
Jeff May
Jeff May

🐛
Jens Gerdes
Jens Gerdes

🐛
Jeroen Borgers
Jeroen Borgers

🐛 💻 📢
Jeroen van Wilgenburg
Jeroen van Wilgenburg

📖
Jerome Russ
Jerome Russ

🐛
JerritEic
JerritEic

💻 📖 🐛
Jiri Pejchal
Jiri Pejchal

🐛
Jithin Sunny
Jithin Sunny

🐛
Jiří Škorpil
Jiří Škorpil

🐛
Joao Machado
Joao Machado

🐛
Jochen Krauss
Jochen Krauss

🐛
Johan Hammar
Johan Hammar

🐛
John Karp
John Karp

🐛
John Zhang
John Zhang

🐛
John-Teng
John-Teng

💻 🐛
Jon Moroney
Jon Moroney

💻 🐛
Jonas Geiregat
Jonas Geiregat

🐛
Jonathan Wiesel
Jonathan Wiesel

💻 🐛
Jordan
Jordan

🐛
Jordi Llach
Jordi Llach

🐛
Jorge Solórzano
Jorge Solórzano

🐛
JorneVL
JorneVL

🐛
Jose Palafox
Jose Palafox

🐛
Jose Stovall
Jose Stovall

🐛
Joseph
Joseph

💻
Joseph Heenan
Joseph Heenan

🐛
Josh Feingold
Josh Feingold

💻 🐛
Josh Holthaus
Josh Holthaus

🐛
Joshua S Arquilevich
Joshua S Arquilevich

🐛
João Dinis Ferreira
João Dinis Ferreira

📖
João Ferreira
João Ferreira

💻 🐛
João Pedro Schmitt
João Pedro Schmitt

🐛
Juan Martín Sotuyo Dodero
Juan Martín Sotuyo Dodero

💻 📖 🐛 🚧
Juan Pablo Civile
Juan Pablo Civile

🐛
Julian Voronetsky
Julian Voronetsky

🐛
Julien
Julien

🐛
Julius
Julius

🐛
JustPRV
JustPRV

🐛
Jörn Huxhorn
Jörn Huxhorn

🐛
KThompso
KThompso

🐛
Kai Amundsen
Kai Amundsen

🐛
Karel Vervaeke
Karel Vervaeke

🐛
Karl-Andero Mere
Karl-Andero Mere

🐛
Karl-Philipp Richter
Karl-Philipp Richter

🐛
Karsten Silz
Karsten Silz

🐛
Kazuma Watanabe
Kazuma Watanabe

🐛
Kev
Kev

🐛
Keve Müller
Keve Müller

🐛
Kevin Guerra
Kevin Guerra

💻
Kevin Jones
Kevin Jones

🐛 💻
Kevin Wayne
Kevin Wayne

🐛
Kieran Black
Kieran Black

🐛
Kirill Zubov
Kirill Zubov

🐛
Kirk Clemens
Kirk Clemens

💻 🐛
Klaus Hartl
Klaus Hartl

🐛
Koen Van Looveren
Koen Van Looveren

🐛
Kris Scheibe
Kris Scheibe

💻 🐛
Krystian Dabrowski
Krystian Dabrowski

🐛 💻
Kunal Thanki
Kunal Thanki

🐛
LaLucid
LaLucid

💻
Larry Diamond
Larry Diamond

💻 🐛
Lars Knickrehm
Lars Knickrehm

🐛
Leo Gutierrez
Leo Gutierrez

🐛
LiGaOg
LiGaOg

💻
Liam Sharp
Liam Sharp

🐛
Lintsi
Lintsi

🐛
Linus Fernandes
Linus Fernandes

🐛
Lixon Lookose
Lixon Lookose

🐛
Logesh
Logesh

🐛
Lorenzo Gabriele
Lorenzo Gabriele

🐛
Loïc Ledoyen
Loïc Ledoyen

🐛
Lucas Silva
Lucas Silva

🐛
Lucas Soncini
Lucas Soncini

💻 🐛
Luis Alcantar
Luis Alcantar

💻
Lukasz Slonina
Lukasz Slonina

🐛
Lukebray
Lukebray

🐛
Lynn
Lynn

💻 🐛
Lyor Goldstein
Lyor Goldstein

🐛
MCMicS
MCMicS

🐛
Macarse
Macarse

🐛
Machine account for PMD
Machine account for PMD

💻
Maciek Siemczyk
Maciek Siemczyk

🐛
Maikel Steneker
Maikel Steneker

💻 🐛
Maksim Moiseikin
Maksim Moiseikin

🐛
Manfred Koch
Manfred Koch

🐛
Manuel Moya Ferrer
Manuel Moya Ferrer

💻 🐛
Manuel Ryan
Manuel Ryan

🐛
Marat Vyshegorodtsev
Marat Vyshegorodtsev

🐛
Marcel Härle
Marcel Härle

🐛
Marcello Fialho
Marcello Fialho

🐛
Marcin Rataj
Marcin Rataj

🐛
Marcono1234
Marcono1234

🐛
Mark Adamcin
Mark Adamcin

🐛
Mark Hall
Mark Hall

💻 🐛
Mark Kolich
Mark Kolich

🐛
Mark Pritchard
Mark Pritchard

🐛
Markus Rathgeb
Markus Rathgeb

🐛
Marquis Wang
Marquis Wang

🐛
MartGit
MartGit

🐛
Martin Feldsztejn
Martin Feldsztejn

🐛
Martin Lehmann
Martin Lehmann

🐛
Martin Spamer
Martin Spamer

🐛
Martin Tarjányi
Martin Tarjányi

🐛
MatFl
MatFl

🐛
Mateusz Stefanski
Mateusz Stefanski

🐛
Mathieu Gouin
Mathieu Gouin

🐛
MatiasComercio
MatiasComercio

💻 🐛
Matt Benson
Matt Benson

🐛
Matt De Poorter
Matt De Poorter

🐛
Matt Hargett
Matt Hargett

💻 💵
Matt Harrah
Matt Harrah

🐛
Matt Nelson
Matt Nelson

🐛
Matthew Amos
Matthew Amos

🐛
Matthew Duggan
Matthew Duggan

🐛
Matthew Hall
Matthew Hall

🐛
Matías Fraga
Matías Fraga

💻 🐛
Maxime Robert
Maxime Robert

💻 🐛
MetaBF
MetaBF

🐛
Michael
Michael

🐛
Michael Bell
Michael Bell

🐛
Michael Bernstein
Michael Bernstein

🐛
Michael Clay
Michael Clay

🐛
Michael Dombrowski
Michael Dombrowski

🐛
Michael Hausegger
Michael Hausegger

🐛
Michael Hoefer
Michael Hoefer

🐛
Michael Möbius
Michael Möbius

🐛
Michael N. Lipp
Michael N. Lipp

🐛
Michael Pellegrini
Michael Pellegrini

🐛
Michal Kordas
Michal Kordas

🐛
Michał Borek
Michał Borek

🐛
Michał Kuliński
Michał Kuliński

🐛
Miguel Núñez Díaz-Montes
Miguel Núñez Díaz-Montes

🐛
Mihai Ionut
Mihai Ionut

🐛
Mirek Hankus
Mirek Hankus

🐛
Mladjan Gadzic
Mladjan Gadzic

🐛
MrAngry52
MrAngry52

🐛
Muminur Choudhury
Muminur Choudhury

🐛
Mykhailo Palahuta
Mykhailo Palahuta

💻 🐛
Nagendra Kumar Singh
Nagendra Kumar Singh

🐛
Nahuel Barrios
Nahuel Barrios

🐛
Nathan Braun
Nathan Braun

🐛
Nathan Reynolds
Nathan Reynolds

🐛
Nathan Reynolds
Nathan Reynolds

🐛
Nathanaël
Nathanaël

🐛
Naveen
Naveen

💻
Nazdravi
Nazdravi

🐛
Neha-Dhonde
Neha-Dhonde

🐛
Nicholas Doyle
Nicholas Doyle

🐛
Nick Butcher
Nick Butcher

🐛
Nico Gallinal
Nico Gallinal

🐛
Nicola Dal Maso
Nicola Dal Maso

🐛
Nicolas Filotto
Nicolas Filotto

💻
Nicolas Vervelle
Nicolas Vervelle

🐛
Nicolas Vuillamy
Nicolas Vuillamy

📖
Nikita Chursin
Nikita Chursin

🐛
Niklas Baudy
Niklas Baudy

🐛
Nikolas Havrikov
Nikolas Havrikov

🐛
Nilesh Virkar
Nilesh Virkar

🐛
Nimit Patel
Nimit Patel

🐛
Niranjan Harpale
Niranjan Harpale

🐛
Nirvik Patel
Nirvik Patel

💻
Noah Sussman
Noah Sussman

🐛
Noah0120
Noah0120

🐛
Noam Tamim
Noam Tamim

🐛
Noel Grandin
Noel Grandin

🐛
Olaf Haalstra
Olaf Haalstra

🐛
Oleg Andreych
Oleg Andreych

💻 🐛
Oleg Pavlenko
Oleg Pavlenko

🐛
Oleksii Dykov
Oleksii Dykov

💻 🐛
Oliver Eikemeier
Oliver Eikemeier

🐛
Oliver Siegmar
Oliver Siegmar

💵
Olivier Parent
Olivier Parent

💻 🐛
Ollie Abbey
Ollie Abbey

💻 🐛
OverDrone
OverDrone

🐛
Ozan Gulle
Ozan Gulle

💻 🐛
PUNEET JAIN
PUNEET JAIN

🐛
Parbati Bose
Parbati Bose

🐛
Paul Berg
Paul Berg

🐛
Paul Guyot
Paul Guyot

💻
Pavel Bludov
Pavel Bludov

🐛
Pavel Mička
Pavel Mička

🐛
Pedro Nuno Santos
Pedro Nuno Santos

🐛
Pedro Rijo
Pedro Rijo

🐛
Pelisse Romain
Pelisse Romain

💻 📖 🐛
Per Abich
Per Abich

💻
Pete Davids
Pete Davids

🐛
Peter Bruin
Peter Bruin

🐛
Peter Chittum
Peter Chittum

💻 🐛
Peter Cudmore
Peter Cudmore

🐛
Peter Kasson
Peter Kasson

🐛
Peter Kofler
Peter Kofler

🐛
Peter Paul Bakker
Peter Paul Bakker

💻
Pham Hai Trung
Pham Hai Trung

🐛
Philip Graf
Philip Graf

💻 🐛
Philip Hachey
Philip Hachey

🐛
Philippe Ozil
Philippe Ozil

🐛
Phinehas Artemix
Phinehas Artemix

🐛
Phokham Nonava
Phokham Nonava

🐛
Pim van der Loos
Pim van der Loos

💻 ⚠️
Piotr Szymański
Piotr Szymański

🐛
Piotrek Żygieło
Piotrek Żygieło

💻 🐛 📖
Pranay Jaiswal
Pranay Jaiswal

🐛
Prasad Kamath
Prasad Kamath

🐛
Prasanna
Prasanna

🐛
Presh-AR
Presh-AR

🐛
Puneet1726
Puneet1726

🐛
Rafael Cortês
Rafael Cortês

🐛
RaheemShaik999
RaheemShaik999

🐛
RajeshR
RajeshR

💻 🐛
Ramachandra Mohan
Ramachandra Mohan

🐛
Ramel0921
Ramel0921

🐛
Raquel Pau
Raquel Pau

🐛
Ravikiran Janardhana
Ravikiran Janardhana

🐛
Reda Benhemmouche
Reda Benhemmouche

🐛
Renato Oliveira
Renato Oliveira

💻 🐛
Rich DiCroce
Rich DiCroce

🐛
Richard Corfield
Richard Corfield

💻
Richard Corfield
Richard Corfield

🐛 💻
Riot R1cket
Riot R1cket

🐛
Rishabh Jain
Rishabh Jain

🐛
RishabhDeep Singh
RishabhDeep Singh

🐛
Robbie Martinus
Robbie Martinus

💻 🐛
Robert Henry
Robert Henry

🐛
Robert Mihaly
Robert Mihaly

🐛
Robert Painsi
Robert Painsi

🐛
Robert Russell
Robert Russell

🐛
Robert Sösemann
Robert Sösemann

💻 📖 📢 🐛
Robert Whitebit
Robert Whitebit

🐛
Robin Richtsfeld
Robin Richtsfeld

🐛
Robin Stocker
Robin Stocker

💻 🐛
Robin Wils
Robin Wils

🐛
RochusOest
RochusOest

🐛
Rodolfo Noviski
Rodolfo Noviski

🐛
Rodrigo Casara
Rodrigo Casara

🐛
Rodrigo Fernandes
Rodrigo Fernandes

🐛
Roman Salvador
Roman Salvador

💻 🐛
Ronald Blaschke
Ronald Blaschke

🐛
Róbert Papp
Róbert Papp

🐛
Saikat Sengupta
Saikat Sengupta

🐛
Saksham Handu
Saksham Handu

🐛
Saladoc
Saladoc

🐛
Salesforce Bob Lightning
Salesforce Bob Lightning

🐛
Sam Carlberg
Sam Carlberg

🐛
Satoshi Kubo
Satoshi Kubo

🐛
Scott Kennedy
Scott Kennedy

🐛
Scott Wells
Scott Wells

🐛 💻
Scrsloota
Scrsloota

💻
Sebastian Bögl
Sebastian Bögl

🐛
Sebastian Schuberth
Sebastian Schuberth

🐛
Sebastian Schwarz
Sebastian Schwarz

🐛
Seren
Seren

🐛 💻
Sergey Gorbaty
Sergey Gorbaty

🐛
Sergey Kozlov
Sergey Kozlov

🐛
Sergey Yanzin
Sergey Yanzin

💻 🐛
Seth Wilcox
Seth Wilcox

💻
Shai Bennathan
Shai Bennathan

🐛 💻
Shubham
Shubham

💻 🐛
Simon Abykov
Simon Abykov

💻 🐛
Simon Xiao
Simon Xiao

🐛
Srinivasan Venkatachalam
Srinivasan Venkatachalam

🐛
Stanislav Gromov
Stanislav Gromov

🐛
Stanislav Myachenkov
Stanislav Myachenkov

💻
Stefan Birkner
Stefan Birkner

🐛
Stefan Bohn
Stefan Bohn

🐛
Stefan Endrullis
Stefan Endrullis

🐛
Stefan Klöss-Schuster
Stefan Klöss-Schuster

🐛
Stefan Wolf
Stefan Wolf

🐛
Stephan H. Wissel
Stephan H. Wissel

🐛
Stephen
Stephen

🐛
Stephen Friedrich
Stephen Friedrich

🐛
Steve Babula
Steve Babula

💻
Steven Stearns
Steven Stearns

🐛 💻
Stexxe
Stexxe

🐛
Stian Lågstad
Stian Lågstad

🐛
StuartClayton5
StuartClayton5

🐛
Supun Arunoda
Supun Arunoda

🐛
Suren Abrahamyan
Suren Abrahamyan

🐛
Suvashri
Suvashri

📖
SwatiBGupta1110
SwatiBGupta1110

🐛
SyedThoufich
SyedThoufich

🐛
Szymon Sasin
Szymon Sasin

🐛
T-chuangxin
T-chuangxin

🐛
TERAI Atsuhiro
TERAI Atsuhiro

🐛
TIOBE Software
TIOBE Software

💻 🐛
Tarush Singh
Tarush Singh

💻
Taylor Smock
Taylor Smock

🐛
Techeira Damián
Techeira Damián

💻 🐛
Ted Husted
Ted Husted

🐛
TehBakker
TehBakker

🐛
The Gitter Badger
The Gitter Badger

🐛
Theodoor
Theodoor

🐛
Thiago Henrique Hüpner
Thiago Henrique Hüpner

🐛
Thibault Meyer
Thibault Meyer

🐛
Thomas Güttler
Thomas Güttler

🐛
Thomas Jones-Low
Thomas Jones-Low

🐛
Thomas Smith
Thomas Smith

💻 🐛
ThrawnCA
ThrawnCA

🐛
Thunderforge
Thunderforge

💻 🐛
Tim van der Lippe
Tim van der Lippe

🐛
Tobias Weimer
Tobias Weimer

💻 🐛
Tom Copeland
Tom Copeland

🐛 💻 📖
Tom Daly
Tom Daly

🐛
Tomer Figenblat
Tomer Figenblat

🐛
Tomi De Lucca
Tomi De Lucca

💻 🐛
Torsten Kleiber
Torsten Kleiber

🐛
TrackerSB
TrackerSB

🐛
Tyson Stewart
Tyson Stewart

🐛
Ullrich Hafner
Ullrich Hafner

🐛
Utku Cuhadaroglu
Utku Cuhadaroglu

💻 🐛
Valentin Brandl
Valentin Brandl

🐛
Valeria
Valeria

🐛
Valery Yatsynovich
Valery Yatsynovich

📖
Vasily Anisimov
Vasily Anisimov

🐛
Vibhor Goyal
Vibhor Goyal

🐛
Vickenty Fesunov
Vickenty Fesunov

🐛
Victor Noël
Victor Noël

🐛
Vincent Galloy
Vincent Galloy

💻
Vincent HUYNH
Vincent HUYNH

🐛
Vincent Maurin
Vincent Maurin

🐛
Vincent Privat
Vincent Privat

🐛
Vishhwas
Vishhwas

🐛
Vitaly
Vitaly

🐛
Vitaly Polonetsky
Vitaly Polonetsky

🐛
Vojtech Polivka
Vojtech Polivka

🐛
Vsevolod Zholobov
Vsevolod Zholobov

🐛
Vyom Yadav
Vyom Yadav

💻
Wang Shidong
Wang Shidong

🐛
Waqas Ahmed
Waqas Ahmed

🐛
Wayne J. Earl
Wayne J. Earl

🐛
Wchenghui
Wchenghui

🐛
Wener
Wener

💻
Will Winder
Will Winder

🐛
William Brockhus
William Brockhus

💻 🐛
Wilson Kurniawan
Wilson Kurniawan

🐛
Wim Deblauwe
Wim Deblauwe

🐛
Woongsik Choi
Woongsik Choi

🐛
XenoAmess
XenoAmess

💻 🐛
Yang
Yang

💻
YaroslavTER
YaroslavTER

🐛
Yasar Shaikh
Yasar Shaikh

💻
Young Chan
Young Chan

💻 🐛
YuJin Kim
YuJin Kim

🐛
Yuri Dolzhenko
Yuri Dolzhenko

🐛
Yurii Dubinka
Yurii Dubinka

🐛
Zoltan Farkas
Zoltan Farkas

🐛
Zustin
Zustin

🐛
aaronhurst-google
aaronhurst-google

🐛 💻
alexmodis
alexmodis

🐛
andreoss
andreoss

🐛
andrey81inmd
andrey81inmd

💻 🐛
anicoara
anicoara

🐛
arunprasathav
arunprasathav

🐛
asiercamara
asiercamara

🐛
astillich-igniti
astillich-igniti

💻
avesolovksyy
avesolovksyy

🐛
avishvat
avishvat

🐛
avivmu
avivmu

🐛
axelbarfod1
axelbarfod1

🐛
b-3-n
b-3-n

🐛
balbhadra9
balbhadra9

🐛
base23de
base23de

🐛
bergander
bergander

🐛
berkam
berkam

💻 🐛
breizh31
breizh31

🐛
caesarkim
caesarkim

🐛
carolyujing
carolyujing

🐛
cbfiddle
cbfiddle

🐛
cesares-basilico
cesares-basilico

🐛
chrite
chrite

🐛
cobratbq
cobratbq

🐛
coladict
coladict

🐛
cosmoJFH
cosmoJFH

🐛
cristalp
cristalp

🐛
crunsk
crunsk

🐛
cwholmes
cwholmes

🐛
cyberjj999
cyberjj999

🐛
cyw3
cyw3

🐛 📖
d1ss0nanz
d1ss0nanz

🐛
dague1
dague1

📖
dalizi007
dalizi007

💻
danbrycefairsailcom
danbrycefairsailcom

🐛
dariansanity
dariansanity

🐛
darrenmiliband
darrenmiliband

🐛
davidburstrom
davidburstrom

🐛
dbirkman-paloalto
dbirkman-paloalto

🐛
deepak-patra
deepak-patra

🐛
dependabot[bot]
dependabot[bot]

💻 🐛
dinesh150
dinesh150

🐛
diziaq
diziaq

🐛
dreaminpast123
dreaminpast123

🐛
duanyanan
duanyanan

🐛
dutt-sanjay
dutt-sanjay

🐛
dylanleung
dylanleung

🐛
dzeigler
dzeigler

🐛
eant60
eant60

🐛
ekkirala
ekkirala

🐛
emersonmoura
emersonmoura

🐛
eugenepugach
eugenepugach

🐛
fairy
fairy

🐛
filiprafalowicz
filiprafalowicz

💻
foxmason
foxmason

🐛
frankegabor
frankegabor

🐛
frankl
frankl

🐛
freafrea
freafrea

🐛
fsapatin
fsapatin

🐛
gracia19
gracia19

🐛
guo fei
guo fei

🐛
gurmsc5
gurmsc5

🐛
gwilymatgearset
gwilymatgearset

💻 🐛
haigsn
haigsn

🐛
hemanshu070
hemanshu070

🐛
henrik242
henrik242

🐛
hongpuwu
hongpuwu

🐛
hvbtup
hvbtup

💻 🐛
igniti GmbH
igniti GmbH

🐛
ilovezfs
ilovezfs

🐛
itaigilo
itaigilo

🐛
jakivey32
jakivey32

🐛
jbennett2091
jbennett2091

🐛
jcamerin
jcamerin

🐛
jkeener1
jkeener1

🐛
jmetertea
jmetertea

🐛
johnra2
johnra2

💻
josemanuelrolon
josemanuelrolon

💻 🐛
kabroxiko
kabroxiko

💻 🐛
karwer
karwer

🐛
kaulonline
kaulonline

🐛
kdaemonv
kdaemonv

🐛
kdebski85
kdebski85

🐛 💻
kenji21
kenji21

💻 🐛
kfranic
kfranic

🐛
khalidkh
khalidkh

🐛
koalalam
koalalam

🐛
krzyk
krzyk

🐛
lasselindqvist
lasselindqvist

🐛
lgemeinhardt
lgemeinhardt

🐛
lihuaib
lihuaib

🐛
lonelyma1021
lonelyma1021

🐛
lpeddy
lpeddy

🐛
lujiefsi
lujiefsi

💻
lukelukes
lukelukes

💻
lyriccoder
lyriccoder

🐛
marcelmore
marcelmore

🐛
matchbox
matchbox

🐛
matthiaskraaz
matthiaskraaz

🐛
meandonlyme
meandonlyme

🐛
mikesive
mikesive

🐛
milossesic
milossesic

🐛
mluckam
mluckam

💻
mohan-chinnappan-n
mohan-chinnappan-n

💻
mriddell95
mriddell95

🐛
mrlzh
mrlzh

🐛
msloan
msloan

🐛
mucharlaravalika
mucharlaravalika

🐛
mvenneman
mvenneman

🐛
nareshl119
nareshl119

🐛
nicolas-harraudeau-sonarsource
nicolas-harraudeau-sonarsource

🐛
noerremark
noerremark

🐛
novsirion
novsirion

🐛
nwcm
nwcm

📖 🐛
oggboy
oggboy

🐛
oinume
oinume

🐛
orimarko
orimarko

💻 🐛
pacvz
pacvz

💻
pallavi agarwal
pallavi agarwal

🐛
parksungrin
parksungrin

🐛
patpatpat123
patpatpat123

🐛
patriksevallius
patriksevallius

🐛
pbrajesh1
pbrajesh1

🐛
phoenix384
phoenix384

🐛
piotrszymanski-sc
piotrszymanski-sc

💻
plan3d
plan3d

🐛
poojasix
poojasix

🐛
prabhushrikant
prabhushrikant

🐛
pujitha8783
pujitha8783

🐛
r-r-a-j
r-r-a-j

🐛
raghujayjunk
raghujayjunk

🐛
rajeshveera
rajeshveera

🐛
rajeswarreddy88
rajeswarreddy88

🐛
recdevs
recdevs

🐛
reudismam
reudismam

💻 🐛
rijkt
rijkt

🐛
rillig-tk
rillig-tk

🐛
rmohan20
rmohan20

💻 🐛
rnveach
rnveach

🐛
rxmicro
rxmicro

🐛
ryan-gustafson
ryan-gustafson

💻 🐛
sabi0
sabi0

🐛
scais
scais

🐛
sebbASF
sebbASF

🐛
sergeygorbaty
sergeygorbaty

💻
shilko2013
shilko2013

🐛
shiomiyan
shiomiyan

📖
simeonKondr
simeonKondr

🐛
snajberk
snajberk

🐛
sniperrifle2004
sniperrifle2004

🐛
snuyanzin
snuyanzin

🐛 💻
sratz
sratz

🐛
stonio
stonio

🐛
sturton
sturton

💻 🐛
sudharmohan
sudharmohan

🐛
suruchidawar
suruchidawar

🐛
svenfinitiv
svenfinitiv

🐛
tashiscool
tashiscool

🐛
test-git-hook
test-git-hook

🐛
testation21
testation21

💻 🐛
thanosa
thanosa

🐛
tiandiyixian
tiandiyixian

🐛
tobwoerk
tobwoerk

🐛
tprouvot
tprouvot

🐛 💻
trentchilders
trentchilders

🐛
triandicAnt
triandicAnt

🐛
trishul14
trishul14

🐛
tsui
tsui

🐛
winhkey
winhkey

🐛
witherspore
witherspore

🐛
wjljack
wjljack

🐛
wuchiuwong
wuchiuwong

🐛
xingsong
xingsong

🐛
xioayuge
xioayuge

🐛
xnYi9wRezm
xnYi9wRezm

💻 🐛
xuanuy
xuanuy

🐛
xyf0921
xyf0921

🐛
yalechen-cyw3
yalechen-cyw3

🐛
yasuharu-sato
yasuharu-sato

🐛
zenglian
zenglian

🐛
zgrzyt93
zgrzyt93

💻 🐛
zh3ng
zh3ng

🐛
zt_soft
zt_soft

🐛
ztt79
ztt79

🐛
zzzzfeng
zzzzfeng

🐛
Árpád Magosányi
Árpád Magosányi

🐛
任贵杰
任贵杰

🐛
茅延安
茅延安

💻
diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md index 73b7368f1c..ab65964e5e 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd.md +++ b/docs/pages/pmd/userdocs/cpd/cpd.md @@ -333,8 +333,14 @@ For details, see [CPD Report Formats](pmd_userdocs_cpd_report_formats.html). Andy Glover wrote an Ant task for CPD; here's how to use it: ```xml + + + + + + + - diff --git a/docs/pages/pmd/userdocs/installation.md b/docs/pages/pmd/userdocs/installation.md index eaa4115bce..a4c475980c 100644 --- a/docs/pages/pmd/userdocs/installation.md +++ b/docs/pages/pmd/userdocs/installation.md @@ -47,7 +47,7 @@ On Windows this is achieved by: PMD ships with built-in completion support for Bash / Zsh. -To enable it, simply add `source *path_to_pmd*/shell/pmd-completion.sh` to your `~/.bashrc` / `~/.zshrc` file. +To enable it, simply add `source <(pmd generate-completion)` to your `~/.bashrc` / `~/.zshrc` file. ## Running PMD via command line diff --git a/docs/pages/pmd/userdocs/tools/ant.md b/docs/pages/pmd/userdocs/tools/ant.md index 02feb2cef1..f259bc7149 100644 --- a/docs/pages/pmd/userdocs/tools/ant.md +++ b/docs/pages/pmd/userdocs/tools/ant.md @@ -181,7 +181,6 @@ automatically and the latest language version is used. `ruleset` nested element - another way to specify rulesets. You can specify multiple elements. Here's an example: - rulesets/java/quickstart.xml config/my-ruleset.xml @@ -373,7 +372,6 @@ You can run pmd then with `ant pmd`. An HTML report with the "linkPrefix" and "linePrefix" properties: - diff --git a/docs/pages/pmd/userdocs/tools/bld.md b/docs/pages/pmd/userdocs/tools/bld.md new file mode 100644 index 0000000000..785184f20c --- /dev/null +++ b/docs/pages/pmd/userdocs/tools/bld.md @@ -0,0 +1,31 @@ +--- +title: bld PMD Extension +tags: [userdocs, tools] +permalink: pmd_userdocs_tools_bld.html +last_updated: September 2023 +--- + +> [bld](https://rife2.com/bld) is a new build system that allows you to write your build logic in pure Java. + +It has a [PMD Extension](https://github.com/rife2/bld-pmd) for it. + +To install, please refer to the [extensions documentation](https://github.com/rife2/bld/wiki/Extensions). + +To check all source code using the [java quickstart rule](pmd_rules_java.html), add the following to your build file + +```java +@BuildCommand +public void pmd() throws Exception { + new PmdOperation() + .fromProject(this) + .execute(); +} +``` + +```shell +./bld pmd test +``` + +* Homepage: +* Documentation: +* PMD Extension: diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index f30a145821..88fd9ff46c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -45,24 +45,56 @@ The remaining section describes the complete release notes for 7.0.0. **New Rules** +* {% rule apex/performance/OperationWithHighCostInLoop %} finds Schema class methods called in a loop, which is a + potential performance issue. * {% rule java/codestyle/UseExplicitTypes %} reports usages of `var` keyword, which was introduced with Java 10. * {% rule xml/bestpractices/MissingEncoding %} finds XML files without explicit encoding. #### Fixed issues +* cli + * [#4594](https://github.com/pmd/pmd/pull/4594): \[cli] Change completion generation to runtime + * [#4723](https://github.com/pmd/pmd/issues/4723): \[cli] Launch fails for "bash pmd" +* doc + * [#3175](https://github.com/pmd/pmd/issues/3175): \[doc] Document language module features + * [#4659](https://github.com/pmd/pmd/pull/4659): \[doc] Improve ant documentation + * [#4669](https://github.com/pmd/pmd/pull/4669): \[doc] Add bld PMD Extension to Tools / Integrations * miscellaneous * [#4699](https://github.com/pmd/pmd/pull/4699): Make PMD buildable with java 21 * [#4586](https://github.com/pmd/pmd/pull/4586): Use explicit encoding in ruleset xml files +* apex-performance + * [#4675](https://github.com/pmd/pmd/issues/4675): \[apex] New Rule: OperationWithHighCostInLoop * java-codestyle * [#2847](https://github.com/pmd/pmd/issues/2847): \[java] New Rule: Use Explicit Types * [#4578](https://github.com/pmd/pmd/issues/4578): \[java] CommentDefaultAccessModifier comment needs to be before annotation if present + * [#4645](https://github.com/pmd/pmd/issues/4645): \[java] CommentDefaultAccessModifier - False Positive with JUnit5's ParameterizedTest +* javascript + * [#4673](https://github.com/pmd/pmd/pull/4673): \[javascript] CPD: Added support for decorator notation * xml-bestpractices * [#4592](https://github.com/pmd/pmd/pull/4592): \[xml] Add MissingEncoding rule #### API Changes +**Removed classes and methods** + +The following previously deprecated classes have been removed: + +* pmd-apex + * {%jdoc apex::lang.apex.ast.ApexNode %} and {% jdoc apex::lang.apex.ast.ASTApexFile %} + * `#getApexVersion()`: In PMD 6, this method has been deprecated but was defined in the class `ApexRootNode`. + The version returned is always "Version.CURRENT", as the apex compiler integration + doesn't use additional information which Apex version actually is used. Therefore, this method can't be + used to determine the Apex version of the project that is being analyzed. + + If the current version is needed, then `Node.getTextDocument().getLanguageVersion()` can be used. This + is the version that has been selected via CLI `--use-version` parameter. + #### External Contributions +* [#4640](https://github.com/pmd/pmd/pull/4640): \[cli] Launch script fails if run via "bash pmd" - [Shai Bennathan](https://github.com/shai-bennathan) (@shai-bennathan) +* [#4673](https://github.com/pmd/pmd/pull/4673): \[javascript] CPD: Added support for decorator notation - [Wener](https://github.com/wener-tiobe) (@wener-tiobe) +* [#4677](https://github.com/pmd/pmd/pull/4677): \[apex] Add new rule: OperationWithHighCostInLoop - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) + ### 🚀 Major Features and Enhancements #### New official logo @@ -228,6 +260,8 @@ can be parsed now. PMD should now be able to parse Apex code up to version 59.0 **Apex** * {% rule apex/design/UnusedMethod %} finds unused methods in your code. +* {% rule apex/performance/OperationWithHighCostInLoop %} finds Schema class methods called in a loop, which is a + potential performance issue. **Java** * {% rule java/codestyle/UnnecessaryBoxing %} reports boxing and unboxing conversions that may be made implicit. @@ -457,12 +491,17 @@ See also [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7. * [#4423](https://github.com/pmd/pmd/pull/4423): \[cli] Fix NPE when only `--file-list` is specified * [#4482](https://github.com/pmd/pmd/issues/4482): \[cli] pmd.bat can only be executed once * [#4484](https://github.com/pmd/pmd/issues/4484): \[cli] ast-dump with no properties produce an NPE + * [#4594](https://github.com/pmd/pmd/pull/4594): \[cli] Change completion generation to runtime + * [#4723](https://github.com/pmd/pmd/issues/4723): \[cli] Launch fails for "bash pmd" * doc * [#2501](https://github.com/pmd/pmd/issues/2501): \[doc] Verify ANTLR Documentation + * [#3175](https://github.com/pmd/pmd/issues/3175): \[doc] Document language module features * [#4294](https://github.com/pmd/pmd/issues/4294): \[doc] Migration Guide for upgrading PMD 6 ➡️ 7 * [#4303](https://github.com/pmd/pmd/issues/4303): \[doc] Document new property framework * [#4438](https://github.com/pmd/pmd/issues/4438): \[doc] Documentation links in VS Code are outdated * [#4521](https://github.com/pmd/pmd/issues/4521): \[doc] Website is not mobile friendly + * [#4659](https://github.com/pmd/pmd/pull/4659): \[doc] Improve ant documentation + * [#4669](https://github.com/pmd/pmd/pull/4669): \[doc] Add bld PMD Extension to Tools / Integrations * testing * [#2435](https://github.com/pmd/pmd/issues/2435): \[test] Remove duplicated Dummy language module * [#4234](https://github.com/pmd/pmd/issues/4234): \[test] Tests that change the logging level do not work @@ -481,6 +520,8 @@ Language specific fixes: * [#2667](https://github.com/pmd/pmd/issues/2667): \[apex] Integrate nawforce/ApexLink to build robust Unused rule * [#4509](https://github.com/pmd/pmd/issues/4509): \[apex] ExcessivePublicCount doesn't consider inner classes correctly * [#4596](https://github.com/pmd/pmd/issues/4596): \[apex] ExcessivePublicCount ignores properties +* apex-performance + * [#4675](https://github.com/pmd/pmd/issues/4675): \[apex] New Rule: OperationWithHighCostInLoop * apex-security * [#4646](https://github.com/pmd/pmd/issues/4646): \[apex] ApexSOQLInjection does not recognise SObjectType or SObjectField as safe variable types * java @@ -582,6 +623,7 @@ Language specific fixes: * [#4512](https://github.com/pmd/pmd/issues/4512): \[java] MethodArgumentCouldBeFinal shouldn't report unused parameters * [#4557](https://github.com/pmd/pmd/issues/4557): \[java] UnnecessaryImport FP with static imports of overloaded methods * [#4578](https://github.com/pmd/pmd/issues/4578): \[java] CommentDefaultAccessModifier comment needs to be before annotation if present + * [#4645](https://github.com/pmd/pmd/issues/4645): \[java] CommentDefaultAccessModifier - False Positive with JUnit5's ParameterizedTest * java-design * [#1014](https://github.com/pmd/pmd/issues/1014): \[java] LawOfDemeter: False positive with lambda expression * [#1605](https://github.com/pmd/pmd/issues/1605): \[java] LawOfDemeter: False positive for standard UTF-8 charset name @@ -647,6 +689,8 @@ Language specific fixes: * [#3848](https://github.com/pmd/pmd/issues/3848): \[java] StringInstantiation: false negative when using method result * [#4070](https://github.com/pmd/pmd/issues/4070): \[java] A false positive about the rule RedundantFieldInitializer * [#4458](https://github.com/pmd/pmd/issues/4458): \[java] RedundantFieldInitializer: false positive with lombok's @Value +* javascript + * [#4673](https://github.com/pmd/pmd/pull/4673): \[javascript] CPD: Added support for decorator notation * kotlin * [#419](https://github.com/pmd/pmd/issues/419): \[kotlin] Add support for Kotlin * [#4389](https://github.com/pmd/pmd/pull/4389): \[kotlin] Update grammar to version 1.8 @@ -694,10 +738,13 @@ Language specific fixes: * [#4542](https://github.com/pmd/pmd/pull/4542): \[java] Fix #4510: A false positive about ConstructorCallsOverridableMethod and @Value - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) * [#4553](https://github.com/pmd/pmd/pull/4553): \[java] Fix #4492: GuardLogStatement gives false positive when argument is a Java method reference - [Anastasiia Koba](https://github.com/anastasiia-koba) (@anastasiia-koba) * [#4637](https://github.com/pmd/pmd/pull/4637): \[java] fix #4634 - JUnit4TestShouldUseTestAnnotation false positive with TestNG - [Krystian Dabrowski](https://github.com/krdabrowski) (@krdabrowski) +* [#4640](https://github.com/pmd/pmd/pull/4640): \[cli] Launch script fails if run via "bash pmd" - [Shai Bennathan](https://github.com/shai-bennathan) (@shai-bennathan) * [#4649](https://github.com/pmd/pmd/pull/4649): \[apex] Add SObjectType and SObjectField to list of injectable SOQL variable types - [Richard Corfield](https://github.com/rcorfieldffdc) (@rcorfieldffdc) * [#4651](https://github.com/pmd/pmd/pull/4651): \[doc] Add "Tencent Cloud Code Analysis" in Tools / Integrations - [yale](https://github.com/cyw3) (@cyw3) * [#4664](https://github.com/pmd/pmd/pull/4664): \[cli] CPD: Fix NPE when only `--file-list` is specified - [Wener](https://github.com/wener-tiobe) (@wener-tiobe) * [#4665](https://github.com/pmd/pmd/pull/4665): \[java] Doc: Fix references AutoClosable -> AutoCloseable - [Andrey Bozhko](https://github.com/AndreyBozhko) (@AndreyBozhko) +* [#4673](https://github.com/pmd/pmd/pull/4673): \[javascript] CPD: Added support for decorator notation - [Wener](https://github.com/wener-tiobe) (@wener-tiobe) +* [#4677](https://github.com/pmd/pmd/pull/4677): \[apex] Add new rule: OperationWithHighCostInLoop - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) ### 📈 Stats * 5007 commits diff --git a/docs/pages/release_notes_pmd7.md b/docs/pages/release_notes_pmd7.md index 2de83e1776..6ec4ba8b3f 100644 --- a/docs/pages/release_notes_pmd7.md +++ b/docs/pages/release_notes_pmd7.md @@ -114,11 +114,10 @@ current progress of the analysis. This can be disabled with the `--no-progress` flag. Finally, we now provide a completion script for Bash/Zsh to further help daily usage. -This script can be found under `shell/pmd-completion.sh` in the binary distribution. To use it, edit your `~/.bashrc` / `~/.zshrc` file and add the following line: ``` -source *path_to_pmd*/shell/pmd-completion.sh +source <(pmd generate-completion) ``` Contributors: [Juan Martín Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) @@ -282,6 +281,8 @@ can be parsed now. PMD should now be able to parse Apex code up to version 59.0 **Apex** * {% rule apex/design/UnusedMethod %} finds unused methods in your code. +* {% rule apex/performance/OperationWithHighCostInLoop %} finds Schema class methods called in a loop, which is a + potential performance issue. **Java** * {% rule java/codestyle/UnnecessaryBoxing %} reports boxing and unboxing conversions that may be made implicit. diff --git a/docs/pages/tags/tag_CpdCapableLanguage.md b/docs/pages/tags/tag_CpdCapableLanguage.md new file mode 100644 index 0000000000..e3af0232fc --- /dev/null +++ b/docs/pages/tags/tag_CpdCapableLanguage.md @@ -0,0 +1,11 @@ +--- +title: "CPD Capable Languages" +tagName: CpdCapableLanguage +search: exclude +permalink: tag_CpdCapableLanguage.html +sidebar: pmd_sidebar +folder: tags +--- +{% include taglogic.html %} + +{% include links.html %} diff --git a/docs/pages/tags/tag_PmdCapableLanguage.md b/docs/pages/tags/tag_PmdCapableLanguage.md new file mode 100644 index 0000000000..30d464c7b8 --- /dev/null +++ b/docs/pages/tags/tag_PmdCapableLanguage.md @@ -0,0 +1,11 @@ +--- +title: "PMD Capable Languages" +tagName: PmdCapableLanguage +search: exclude +permalink: tag_PmdCapableLanguage.html +sidebar: pmd_sidebar +folder: tags +--- +{% include taglogic.html %} + +{% include links.html %} diff --git a/docs/pages/tags/tag_experimental.md b/docs/pages/tags/tag_experimental.md new file mode 100644 index 0000000000..50b72cbe8a --- /dev/null +++ b/docs/pages/tags/tag_experimental.md @@ -0,0 +1,11 @@ +--- +title: "Experimental Features" +tagName: experimental +search: exclude +permalink: tag_experimental.html +sidebar: pmd_sidebar +folder: tags +--- +{% include taglogic.html %} + +{% include links.html %} diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/CPDTask.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/CPDTask.java index 177f1311de..85abfdc0ad 100644 --- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/CPDTask.java +++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/CPDTask.java @@ -40,20 +40,26 @@ import net.sourceforge.pmd.lang.LanguageRegistry; * *

Runs the CPD utility via ant. The ant task looks like this:

* - *
- * <project name="CPDProj" default="main" basedir=".">
- *   <taskdef name="cpd" classname="net.sourceforge.pmd.cpd.CPDTask" />
- *   <target name="main">
- *     <cpd encoding="UTF-16LE" language="java" ignoreIdentifiers="true"
- *          ignoreLiterals="true" ignoreAnnotations="true" minimumTokenCount="100"
- *          outputFile="c:\cpdrun.txt">
- *       <fileset dir="/path/to/my/src">
- *         <include name="*.java"/>
- *       </fileset>
- *     </cpd>
- *   </target>
- * </project>
- * 
+ *
{@code
+ *   
+ *     
+ *         
+ *             
+ *         
+ *     
+ *     
+ *
+ *     
+ *       
+ *         
+ *           
+ *         
+ *       
+ *     
+ *   
+ * }
* *

Required: minimumTokenCount, outputFile, and at least one file

*/ diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/PMDTask.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/PMDTask.java index 578db83ca5..db10833ff7 100644 --- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/PMDTask.java +++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/PMDTask.java @@ -24,6 +24,31 @@ import net.sourceforge.pmd.ant.internal.PMDTaskImpl; /** * PMD Ant task. Setters of this class are interpreted by Ant as properties * settable in the XML. This is therefore published API. + * + *

Runs PMD analysis via ant. The ant task looks like this:

+ * + *
{@code
+ *   
+ *     
+ *         
+ *             
+ *         
+ *     
+ *     
+ *
+ *     
+ *       
+ *         rulesets/java/quickstart.xml
+ *         config/my-ruleset.xml
+ *         
+ *             
+ *         
+ *       
+ *     
+ *   
+ * }
+ * + *

Required: rulesetfiles/ruleset, fileset

*/ public class PMDTask extends Task { diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTApexFile.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTApexFile.java index befd2d07ec..cfe2d097ff 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTApexFile.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTApexFile.java @@ -40,12 +40,6 @@ public final class ASTApexFile extends AbstractApexNode.Single return astInfo; } - @Override - public double getApexVersion() { - // TODO: remove this method? - return Double.parseDouble(astInfo.getTextDocument().getLanguageVersion().getVersion()); - } - public ASTUserClassOrInterface getMainNode() { return (ASTUserClassOrInterface) getChild(0); } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexNode.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexNode.java index c2cde5ea08..ed7b30715b 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexNode.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexNode.java @@ -41,15 +41,4 @@ public interface ApexNode extends GenericNode> { @Override @NonNull ASTApexFile getRoot(); - - /** - * Gets the apex version this class has been compiled with. - * Use {@link Version} to compare, e.g. - * {@code node.getApexVersion() >= Version.V176.getExternal()} - * - * @return the apex version - */ - default double getApexVersion() { - return getRoot().getApexVersion(); - } } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopRule.java new file mode 100644 index 0000000000..ee2a7ef06c --- /dev/null +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopRule.java @@ -0,0 +1,51 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.performance; + +import java.util.Locale; +import java.util.Set; +import java.util.stream.Collectors; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.apex.ast.ASTMethodCallExpression; +import net.sourceforge.pmd.lang.rule.RuleTargetSelector; +import net.sourceforge.pmd.util.CollectionUtil; + +/** + * Warn users when code that could impact performance is executing within a + * looping construct. + */ +public class OperationWithHighCostInLoopRule extends AbstractAvoidNodeInLoopsRule { + + private static final Set SCHEMA_PERFORMANCE_METHODS = CollectionUtil.setOf( + "System.Schema.getGlobalDescribe", + "Schema.getGlobalDescribe", + "System.Schema.describeSObjects", + "Schema.describeSObjects") + .stream().map(s -> s.toLowerCase(Locale.ROOT)).collect(Collectors.toSet()); + + @Override + protected @NonNull RuleTargetSelector buildTargetSelector() { + return RuleTargetSelector.forTypes( + // performance consuming methods + ASTMethodCallExpression.class); + } + + // Begin general method invocations + @Override + public Object visit(ASTMethodCallExpression node, Object data) { + if (checkHighCostClassMethods(node)) { + return checkForViolation(node, data); + } else { + return data; + } + } + + private boolean checkHighCostClassMethods(ASTMethodCallExpression node) { + return SCHEMA_PERFORMANCE_METHODS.contains(node.getFullMethodName().toLowerCase(Locale.ROOT)); + } + // End general method invocations +} diff --git a/pmd-apex/src/main/resources/category/apex/performance.xml b/pmd-apex/src/main/resources/category/apex/performance.xml index 2d067dc687..8f4e17523b 100644 --- a/pmd-apex/src/main/resources/category/apex/performance.xml +++ b/pmd-apex/src/main/resources/category/apex/performance.xml @@ -207,6 +207,74 @@ public class Foo { + + +This rule finds method calls inside loops that are known to be likely a performance issue. These methods should be +called only once before the loop. + +Schema class methods like [Schema.getGlobalDescribe()](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_schema.htm#apex_System_Schema_getGlobalDescribe) +and [Schema.describeSObjects()](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_schema.htm#apex_System_Schema_describeSObjects) +might be slow depending on the size of your organization. Calling these methods repeatedly inside a loop creates +a potential performance issue. + + 3 + fieldNameSet = new Set {'Id'}; + for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) { + // Schema.getGlobalDescribe() should be called only once before the for-loop + if (Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap().containsKey(fieldNameOrDefaultValue.trim())) { + fieldNameSet.add(fieldNameOrDefaultValue); + } + } + } + + // corrected example + public void getGlobalDescribeInLoopCorrected() { + Map fieldMap = Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap(); + Set fieldNameSet = new Set {'Id'}; + for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) { + if (fieldMap.containsKey(fieldNameOrDefaultValue.trim())) { + fieldNameSet.add(fieldNameOrDefaultValue); + } + } + } +} + ]]> + fieldNameSet = new Set {'Id'}; + for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) { + Schema.DescribeSObjectResult dsr = Account.sObjectType.getDescribe(); + if (Schema.describeSObjects(new List { sObjectType })[0].fields.getMap().containsKey(fieldNameOrDefaultValue.trim())) { + fieldNameSet.add(fieldNameOrDefaultValue); + } + } + } + + // corrected example + public void describeSObjectsInLoop() { + Map fieldMap = Schema.describeSObjects(new List { 'Account' })[0].fields.getMap(); + Set fieldNameSet = new Set {'Id'}; + for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) { + if (fieldMap.containsKey(fieldNameOrDefaultValue.trim())) { + fieldNameSet.add(fieldNameOrDefaultValue); + } + } + } +} + ]]> + + + diff --git a/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml b/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml index d6e3895450..5a0dfd0aef 100644 --- a/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml +++ b/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml @@ -69,6 +69,9 @@ 3 + + 3 + 3 diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopTest.java new file mode 100644 index 0000000000..6dc7ff3ba8 --- /dev/null +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopTest.java @@ -0,0 +1,11 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.performance; + +import net.sourceforge.pmd.testframework.PmdRuleTst; + +class OperationWithHighCostInLoopTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/SafeNavigationOperator.txt b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/SafeNavigationOperator.txt index 99ba0769d9..bba652c90b 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/SafeNavigationOperator.txt +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/SafeNavigationOperator.txt @@ -1,91 +1,91 @@ -+- ApexFile[@ApexVersion = 59.0, @DefiningType = null, @Namespace = null, @RealLoc = true] - +- UserClass[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "Foo", @Namespace = null, @RealLoc = true, @SimpleName = "Foo", @SuperClassName = ""] - +- ModifierNode[@Abstract = false, @ApexVersion = 59.0, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] - +- Field[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "x", @Name = "x", @Namespace = null, @RealLoc = false, @Type = "Integer", @Value = null] - | +- ModifierNode[@Abstract = false, @ApexVersion = 59.0, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] - +- Field[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "profileUrl", @Name = "profileUrl", @Namespace = null, @RealLoc = false, @Type = "String", @Value = null] - | +- ModifierNode[@Abstract = false, @ApexVersion = 59.0, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] - +- FieldDeclarationStatements[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true, @TypeName = "Integer"] - | +- ModifierNode[@Abstract = false, @ApexVersion = 59.0, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] - | +- FieldDeclaration[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "x", @Name = "x", @Namespace = null, @RealLoc = true] - | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "anIntegerField", @Namespace = null, @RealLoc = true] - | | +- ReferenceExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true] - | | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "anObject", @Namespace = null, @RealLoc = true] - | | +- EmptyReferenceExpression[@ApexVersion = 59.0, @DefiningType = null, @Namespace = null, @RealLoc = false] - | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "x", @Namespace = null, @RealLoc = true] - | +- EmptyReferenceExpression[@ApexVersion = 59.0, @DefiningType = null, @Namespace = null, @RealLoc = false] - +- FieldDeclarationStatements[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true, @TypeName = "String"] - | +- ModifierNode[@Abstract = false, @ApexVersion = 59.0, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] - | +- FieldDeclaration[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "profileUrl", @Name = "profileUrl", @Namespace = null, @RealLoc = true] - | +- MethodCallExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @FullMethodName = "toExternalForm", @InputParametersSize = 0, @MethodName = "toExternalForm", @Namespace = null, @RealLoc = true] - | | +- ReferenceExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false] - | | +- MethodCallExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @FullMethodName = "user.getProfileUrl", @InputParametersSize = 0, @MethodName = "getProfileUrl", @Namespace = null, @RealLoc = true] - | | +- ReferenceExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "user", @Namespace = null, @RealLoc = true, @SObjectType = false, @SafeNav = false] - | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "profileUrl", @Namespace = null, @RealLoc = true] - | +- EmptyReferenceExpression[@ApexVersion = 59.0, @DefiningType = null, @Namespace = null, @RealLoc = false] - +- Method[@ApexVersion = 59.0, @Arity = 1, @CanonicalName = "bar1", @Constructor = false, @DefiningType = "c__Foo", @Image = "bar1", @Namespace = null, @RealLoc = true, @ReturnType = "void", @StaticInitializer = false, @Synthetic = false] - | +- ModifierNode[@Abstract = false, @ApexVersion = 59.0, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] - | +- Parameter[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "a", @Namespace = null, @RealLoc = true, @Type = "Object"] - | | +- ModifierNode[@Abstract = false, @ApexVersion = 59.0, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] - | +- BlockStatement[@ApexVersion = 59.0, @CurlyBrace = true, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] - | +- ExpressionStatement[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] - | | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "b", @Namespace = null, @RealLoc = true] - | | +- ReferenceExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true] - | | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "a", @Namespace = null, @RealLoc = true] - | | +- EmptyReferenceExpression[@ApexVersion = 59.0, @DefiningType = null, @Namespace = null, @RealLoc = false] - | +- ExpressionStatement[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] - | +- MethodCallExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @FullMethodName = "c1", @InputParametersSize = 0, @MethodName = "c1", @Namespace = null, @RealLoc = true] - | +- ReferenceExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false] - | +- CastExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] - | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "b1", @Namespace = null, @RealLoc = true] - | +- ReferenceExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true] - | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "a1", @Namespace = null, @RealLoc = true] - | +- EmptyReferenceExpression[@ApexVersion = 59.0, @DefiningType = null, @Namespace = null, @RealLoc = false] - +- Method[@ApexVersion = 59.0, @Arity = 2, @CanonicalName = "bar2", @Constructor = false, @DefiningType = "c__Foo", @Image = "bar2", @Namespace = null, @RealLoc = true, @ReturnType = "void", @StaticInitializer = false, @Synthetic = false] - | +- ModifierNode[@Abstract = false, @ApexVersion = 59.0, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] - | +- Parameter[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "a", @Namespace = null, @RealLoc = true, @Type = "Object[]"] - | | +- ModifierNode[@Abstract = false, @ApexVersion = 59.0, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] - | +- Parameter[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "x", @Namespace = null, @RealLoc = true, @Type = "int"] - | | +- ModifierNode[@Abstract = false, @ApexVersion = 59.0, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] - | +- BlockStatement[@ApexVersion = 59.0, @CurlyBrace = true, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] - | +- ExpressionStatement[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] - | | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "aField", @Namespace = null, @RealLoc = true] - | | +- ReferenceExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false] - | | +- MethodCallExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @FullMethodName = "aMethod", @InputParametersSize = 0, @MethodName = "aMethod", @Namespace = null, @RealLoc = true] - | | +- ReferenceExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false] - | | +- ArrayLoadExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] - | | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "a", @Namespace = null, @RealLoc = true] - | | | +- EmptyReferenceExpression[@ApexVersion = 59.0, @DefiningType = null, @Namespace = null, @RealLoc = false] - | | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "x", @Namespace = null, @RealLoc = true] - | | +- EmptyReferenceExpression[@ApexVersion = 59.0, @DefiningType = null, @Namespace = null, @RealLoc = false] - | +- ExpressionStatement[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] - | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "aField", @Namespace = null, @RealLoc = true] - | +- ReferenceExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true] - | +- MethodCallExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @FullMethodName = "aMethod", @InputParametersSize = 0, @MethodName = "aMethod", @Namespace = null, @RealLoc = true] - | +- ReferenceExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false] - | +- ArrayLoadExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] - | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "a", @Namespace = null, @RealLoc = true] - | | +- EmptyReferenceExpression[@ApexVersion = 59.0, @DefiningType = null, @Namespace = null, @RealLoc = false] - | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "x", @Namespace = null, @RealLoc = true] - | +- EmptyReferenceExpression[@ApexVersion = 59.0, @DefiningType = null, @Namespace = null, @RealLoc = false] - +- Method[@ApexVersion = 59.0, @Arity = 1, @CanonicalName = "getName", @Constructor = false, @DefiningType = "c__Foo", @Image = "getName", @Namespace = null, @RealLoc = true, @ReturnType = "String", @StaticInitializer = false, @Synthetic = false] - +- ModifierNode[@Abstract = false, @ApexVersion = 59.0, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] - +- Parameter[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "accId", @Namespace = null, @RealLoc = true, @Type = "int"] - | +- ModifierNode[@Abstract = false, @ApexVersion = 59.0, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] - +- BlockStatement[@ApexVersion = 59.0, @CurlyBrace = true, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] - +- VariableDeclarationStatements[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] - | +- ModifierNode[@Abstract = false, @ApexVersion = 59.0, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] - | +- VariableDeclaration[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "s", @Namespace = null, @RealLoc = true, @Type = "String"] - | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "BillingCity", @Namespace = null, @RealLoc = true] - | | +- ReferenceExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true] - | | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "Account", @Namespace = null, @RealLoc = true] - | | +- ReferenceExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "contact", @Namespace = null, @RealLoc = true, @SObjectType = false, @SafeNav = false] - | +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "s", @Namespace = null, @RealLoc = true] - | +- EmptyReferenceExpression[@ApexVersion = 59.0, @DefiningType = null, @Namespace = null, @RealLoc = false] - +- ReturnStatement[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] - +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "Name", @Namespace = null, @RealLoc = true] - +- ReferenceExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true] - +- SoqlExpression[@ApexVersion = 59.0, @CanonicalQuery = "SELECT Name FROM Account WHERE Id = :accId", @DefiningType = "c__Foo", @Namespace = null, @Query = "SELECT Name FROM Account WHERE Id = :accId", @RealLoc = true] - +- BindExpressions[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] - +- VariableExpression[@ApexVersion = 59.0, @DefiningType = "c__Foo", @Image = "accId", @Namespace = null, @RealLoc = true] - +- EmptyReferenceExpression[@ApexVersion = 59.0, @DefiningType = null, @Namespace = null, @RealLoc = false] ++- ApexFile[@DefiningType = null, @Namespace = null, @RealLoc = true] + +- UserClass[@DefiningType = "c__Foo", @Image = "Foo", @Namespace = null, @RealLoc = true, @SimpleName = "Foo", @SuperClassName = ""] + +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + +- Field[@DefiningType = "c__Foo", @Image = "x", @Name = "x", @Namespace = null, @RealLoc = false, @Type = "Integer", @Value = null] + | +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + +- Field[@DefiningType = "c__Foo", @Image = "profileUrl", @Name = "profileUrl", @Namespace = null, @RealLoc = false, @Type = "String", @Value = null] + | +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + +- FieldDeclarationStatements[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true, @TypeName = "Integer"] + | +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + | +- FieldDeclaration[@DefiningType = "c__Foo", @Image = "x", @Name = "x", @Namespace = null, @RealLoc = true] + | +- VariableExpression[@DefiningType = "c__Foo", @Image = "anIntegerField", @Namespace = null, @RealLoc = true] + | | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true] + | | +- VariableExpression[@DefiningType = "c__Foo", @Image = "anObject", @Namespace = null, @RealLoc = true] + | | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false] + | +- VariableExpression[@DefiningType = "c__Foo", @Image = "x", @Namespace = null, @RealLoc = true] + | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false] + +- FieldDeclarationStatements[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true, @TypeName = "String"] + | +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + | +- FieldDeclaration[@DefiningType = "c__Foo", @Image = "profileUrl", @Name = "profileUrl", @Namespace = null, @RealLoc = true] + | +- MethodCallExpression[@DefiningType = "c__Foo", @FullMethodName = "toExternalForm", @InputParametersSize = 0, @MethodName = "toExternalForm", @Namespace = null, @RealLoc = true] + | | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false] + | | +- MethodCallExpression[@DefiningType = "c__Foo", @FullMethodName = "user.getProfileUrl", @InputParametersSize = 0, @MethodName = "getProfileUrl", @Namespace = null, @RealLoc = true] + | | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "user", @Namespace = null, @RealLoc = true, @SObjectType = false, @SafeNav = false] + | +- VariableExpression[@DefiningType = "c__Foo", @Image = "profileUrl", @Namespace = null, @RealLoc = true] + | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false] + +- Method[@Arity = 1, @CanonicalName = "bar1", @Constructor = false, @DefiningType = "c__Foo", @Image = "bar1", @Namespace = null, @RealLoc = true, @ReturnType = "void", @StaticInitializer = false, @Synthetic = false] + | +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + | +- Parameter[@DefiningType = "c__Foo", @Image = "a", @Namespace = null, @RealLoc = true, @Type = "Object"] + | | +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + | +- BlockStatement[@CurlyBrace = true, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] + | +- ExpressionStatement[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] + | | +- VariableExpression[@DefiningType = "c__Foo", @Image = "b", @Namespace = null, @RealLoc = true] + | | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true] + | | +- VariableExpression[@DefiningType = "c__Foo", @Image = "a", @Namespace = null, @RealLoc = true] + | | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false] + | +- ExpressionStatement[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] + | +- MethodCallExpression[@DefiningType = "c__Foo", @FullMethodName = "c1", @InputParametersSize = 0, @MethodName = "c1", @Namespace = null, @RealLoc = true] + | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false] + | +- CastExpression[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] + | +- VariableExpression[@DefiningType = "c__Foo", @Image = "b1", @Namespace = null, @RealLoc = true] + | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true] + | +- VariableExpression[@DefiningType = "c__Foo", @Image = "a1", @Namespace = null, @RealLoc = true] + | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false] + +- Method[@Arity = 2, @CanonicalName = "bar2", @Constructor = false, @DefiningType = "c__Foo", @Image = "bar2", @Namespace = null, @RealLoc = true, @ReturnType = "void", @StaticInitializer = false, @Synthetic = false] + | +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + | +- Parameter[@DefiningType = "c__Foo", @Image = "a", @Namespace = null, @RealLoc = true, @Type = "Object[]"] + | | +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + | +- Parameter[@DefiningType = "c__Foo", @Image = "x", @Namespace = null, @RealLoc = true, @Type = "int"] + | | +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + | +- BlockStatement[@CurlyBrace = true, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] + | +- ExpressionStatement[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] + | | +- VariableExpression[@DefiningType = "c__Foo", @Image = "aField", @Namespace = null, @RealLoc = true] + | | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false] + | | +- MethodCallExpression[@DefiningType = "c__Foo", @FullMethodName = "aMethod", @InputParametersSize = 0, @MethodName = "aMethod", @Namespace = null, @RealLoc = true] + | | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false] + | | +- ArrayLoadExpression[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] + | | +- VariableExpression[@DefiningType = "c__Foo", @Image = "a", @Namespace = null, @RealLoc = true] + | | | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false] + | | +- VariableExpression[@DefiningType = "c__Foo", @Image = "x", @Namespace = null, @RealLoc = true] + | | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false] + | +- ExpressionStatement[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] + | +- VariableExpression[@DefiningType = "c__Foo", @Image = "aField", @Namespace = null, @RealLoc = true] + | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true] + | +- MethodCallExpression[@DefiningType = "c__Foo", @FullMethodName = "aMethod", @InputParametersSize = 0, @MethodName = "aMethod", @Namespace = null, @RealLoc = true] + | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false] + | +- ArrayLoadExpression[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] + | +- VariableExpression[@DefiningType = "c__Foo", @Image = "a", @Namespace = null, @RealLoc = true] + | | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false] + | +- VariableExpression[@DefiningType = "c__Foo", @Image = "x", @Namespace = null, @RealLoc = true] + | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false] + +- Method[@Arity = 1, @CanonicalName = "getName", @Constructor = false, @DefiningType = "c__Foo", @Image = "getName", @Namespace = null, @RealLoc = true, @ReturnType = "String", @StaticInitializer = false, @Synthetic = false] + +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + +- Parameter[@DefiningType = "c__Foo", @Image = "accId", @Namespace = null, @RealLoc = true, @Type = "int"] + | +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + +- BlockStatement[@CurlyBrace = true, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] + +- VariableDeclarationStatements[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] + | +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + | +- VariableDeclaration[@DefiningType = "c__Foo", @Image = "s", @Namespace = null, @RealLoc = true, @Type = "String"] + | +- VariableExpression[@DefiningType = "c__Foo", @Image = "BillingCity", @Namespace = null, @RealLoc = true] + | | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true] + | | +- VariableExpression[@DefiningType = "c__Foo", @Image = "Account", @Namespace = null, @RealLoc = true] + | | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "contact", @Namespace = null, @RealLoc = true, @SObjectType = false, @SafeNav = false] + | +- VariableExpression[@DefiningType = "c__Foo", @Image = "s", @Namespace = null, @RealLoc = true] + | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false] + +- ReturnStatement[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] + +- VariableExpression[@DefiningType = "c__Foo", @Image = "Name", @Namespace = null, @RealLoc = true] + +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true] + +- SoqlExpression[@CanonicalQuery = "SELECT Name FROM Account WHERE Id = :accId", @DefiningType = "c__Foo", @Namespace = null, @Query = "SELECT Name FROM Account WHERE Id = :accId", @RealLoc = true] + +- BindExpressions[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true] + +- VariableExpression[@DefiningType = "c__Foo", @Image = "accId", @Namespace = null, @RealLoc = true] + +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false] diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/OperationWithHighCostInLoop.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/OperationWithHighCostInLoop.xml new file mode 100644 index 0000000000..15a05db1a0 --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/OperationWithHighCostInLoop.xml @@ -0,0 +1,138 @@ + + + + + + High cost performance getGlobalDescribe in loop (correct code) #4675 + 0 + fieldMap = Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap(); + Set fieldNameSet = new Set {'Id'}; + + for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) { + if (fieldMap.containsKey(fieldNameOrDefaultValue.trim())) { + fieldNameSet.add(fieldNameOrDefaultValue); + } + } + } +} + ]]> + + + + High cost performance getGlobalDescribe in loop #4675 + 1 + 5 + fieldNameSet = new Set {'Id'}; + for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) { + if (Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap().containsKey(fieldNameOrDefaultValue.trim() )) { + fieldNameSet.add(fieldNameOrDefaultValue); + } + } + } +} + ]]> + + + + High cost performance getGlobalDescribe in loop - fully qualified #4675 + 1 + 5 + fieldNameSet = new Set {'Id'}; + for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) { + if (System.Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap().containsKey(fieldNameOrDefaultValue.trim() )) { + fieldNameSet.add(fieldNameOrDefaultValue); + } + } + } +} + ]]> + + + + High cost performance describeSObjects in loop (correct code) #4675 + 0 + fieldMap = Schema.describeSObjects(new List { 'Account' })[0].fields.getMap(); + Set fieldNameSet = new Set {'Id'}; + for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) { + if (fieldMap.containsKey(fieldNameOrDefaultValue.trim())) { + fieldNameSet.add(fieldNameOrDefaultValue); + } + } + } +} + ]]> + + + + High cost performance describeSObjects in loop #4675 + 1 + 6 + fieldNameSet = new Set {'Id'}; + for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) { + if (Schema.describeSObjects(new List { sObjectType })[0].fields.getMap().containsKey(fieldNameOrDefaultValue.trim())) { + fieldNameSet.add(fieldNameOrDefaultValue); + } + } + } +} + ]]> + + + + High cost performance describeSObjects in loop with SObjectDescribeOptions #4675 + 1 + 6 + fieldNameSet = new Set {'Id'}; + for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) { + if (Schema.describeSObjects(new List { sObjectType }, SObjectDescribeOptions.FULL)[0].fields.getMap().containsKey(fieldNameOrDefaultValue.trim())) { + fieldNameSet.add(fieldNameOrDefaultValue); + } + } + } +} + ]]> + + + + High cost performance describeSObjects in loop - fully qualified #4675 + 1 + 6 + fieldNameSet = new Set {'Id'}; + for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) { + if (System.Schema.describeSObjects(new List { sObjectType })[0].fields.getMap().containsKey(fieldNameOrDefaultValue.trim())) { + fieldNameSet.add(fieldNameOrDefaultValue); + } + } + } +} + ]]> + + + diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 2df635e272..a217e76abd 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -20,55 +20,6 @@ pmd-cli-checkstyle-suppressions.xml - - - org.codehaus.mojo - exec-maven-plugin - - - generate-autocompletion-script - package - - exec - - - - - java - - -Dpicocli.autocomplete.systemExitOnError - -cp - - picocli.AutoComplete - --force - --completionScript - ${project.build.directory}/pmd_completion.sh - net.sourceforge.pmd.cli.commands.internal.PmdRootCommand - - - - - - org.codehaus.mojo - build-helper-maven-plugin - - - add-completion-artifact - - attach-artifact - - - - - ${project.build.directory}/pmd_completion.sh - sh - completion - - - - - - diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java index 1de2edc64a..4fb3877359 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java @@ -13,9 +13,9 @@ public final class PmdCli { private PmdCli() { } public static void main(String[] args) { - final int exitCode = new CommandLine(new PmdRootCommand()) - .setCaseInsensitiveEnumValuesAllowed(true) - .execute(args); - System.exit(exitCode); + final CommandLine cli = new CommandLine(new PmdRootCommand()) + .setCaseInsensitiveEnumValuesAllowed(true); + + System.exit(cli.execute(args)); } } diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdRootCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdRootCommand.java index ef15d504fd..169690f98a 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdRootCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdRootCommand.java @@ -6,6 +6,7 @@ package net.sourceforge.pmd.cli.commands.internal; import net.sourceforge.pmd.PMDVersion; +import picocli.AutoComplete.GenerateCompletion; import picocli.CommandLine.Command; import picocli.CommandLine.IVersionProvider; @@ -14,7 +15,8 @@ import picocli.CommandLine.IVersionProvider; exitCodeListHeading = "Exit Codes:%n", exitCodeList = { "0:Successful analysis, no violations found", "1:An unexpected error occurred during execution", "2:Usage error, please refer to the command help", "4:Successful analysis, at least 1 violation found" }, - subcommands = { PmdCommand.class, CpdCommand.class, DesignerCommand.class, CpdGuiCommand.class, TreeExportCommand.class }) + subcommands = { PmdCommand.class, CpdCommand.class, DesignerCommand.class, + CpdGuiCommand.class, TreeExportCommand.class, GenerateCompletion.class }) public class PmdRootCommand { } diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/CpdLanguageTypeSupport.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/CpdLanguageTypeSupport.java index 82b0125f52..74bdcd594d 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/CpdLanguageTypeSupport.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/CpdLanguageTypeSupport.java @@ -8,9 +8,6 @@ import net.sourceforge.pmd.lang.LanguageRegistry; /** * Provider of candidates / conversion support for supported CPD languages. - * - *

Beware, the help will report this on runtime, and be accurate to available - * modules in the classpath, but autocomplete will include all available at build time. */ public class CpdLanguageTypeSupport extends LanguageTypeSupport { diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/LanguageTypeSupport.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/LanguageTypeSupport.java index e1cf8978c3..0630b125f6 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/LanguageTypeSupport.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/LanguageTypeSupport.java @@ -14,9 +14,6 @@ import picocli.CommandLine.TypeConversionException; /** * Provider of candidates / conversion support for supported PMD/CPD languages. - * - *

Beware, the help will report this on runtime, and be accurate to available - * modules in the classpath, but autocomplete will include all available at build time. */ public class LanguageTypeSupport implements ITypeConverter, Iterable { diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageTypeSupport.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageTypeSupport.java index 6b6332b343..41023a59b0 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageTypeSupport.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageTypeSupport.java @@ -8,9 +8,6 @@ import net.sourceforge.pmd.lang.LanguageRegistry; /** * Provider of candidates / conversion support for supported PMD languages. - * - *

Beware, the help will report this on runtime, and be accurate to available - * modules in the classpath, but autocomplete will include all available at build time. */ public class PmdLanguageTypeSupport extends LanguageTypeSupport { diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageVersionTypeSupport.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageVersionTypeSupport.java index 114bcf64d0..fdc5f51efa 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageVersionTypeSupport.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageVersionTypeSupport.java @@ -17,9 +17,6 @@ import picocli.CommandLine.TypeConversionException; /** * Provider of candidates for valid language-version combinations. - * - * Beware, the help will report this on runtime, and be accurate to available - * modules in the classpath, but autocomplete will include all available at build time. */ public class PmdLanguageVersionTypeSupport implements ITypeConverter, Iterable { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessor.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessor.java index 035accf05f..cd0e26dc37 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessor.java @@ -4,8 +4,12 @@ package net.sourceforge.pmd.lang.impl; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import net.sourceforge.pmd.RuleSets; @@ -18,13 +22,15 @@ import net.sourceforge.pmd.util.log.MessageReporter; * @author Romain Pelisse <belaran@gmail.com> */ final class MultiThreadProcessor extends AbstractPMDProcessor { - private final ExecutorService executor; + private final List> futureList; + MultiThreadProcessor(final AnalysisTask task) { super(task); executor = Executors.newFixedThreadPool(task.getThreadCount(), new PmdThreadFactory()); + futureList = new LinkedList<>(); } @Override @@ -42,18 +48,30 @@ final class MultiThreadProcessor extends AbstractPMDProcessor { }); for (final TextFile textFile : task.getFiles()) { - executor.submit(new PmdRunnable(textFile, task) { + futureList.add(executor.submit(new PmdRunnable(textFile, task) { @Override protected RuleSets getRulesets() { return ruleSetCopy.get(); } - }); + })); } } @Override public void close() { try { + try { + for (Future task : futureList) { + task.get(); + } + } catch (ExecutionException e) { + task.getMessageReporter().error("Unknown error occurred while executing a PmdRunnable: {0}", + e.getCause().toString(), e.getCause()); + if (e.getCause() instanceof Error) { + throw (Error) e.getCause(); + } + } + executor.shutdown(); while (!executor.awaitTermination(10, TimeUnit.HOURS)) { // still waiting diff --git a/pmd-core/src/main/resources/rulesets/releases/700.xml b/pmd-core/src/main/resources/rulesets/releases/700.xml index 6b3eaf09c5..edd237b438 100644 --- a/pmd-core/src/main/resources/rulesets/releases/700.xml +++ b/pmd-core/src/main/resources/rulesets/releases/700.xml @@ -9,6 +9,7 @@ This ruleset contains links to rules that are new in PMD v7.0.0 + @@ -23,4 +24,3 @@ This ruleset contains links to rules that are new in PMD v7.0.0 - diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/AbstractPMDProcessorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/AbstractPMDProcessorTest.java index a95f36e3da..ca52a03e65 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/AbstractPMDProcessorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/AbstractPMDProcessorTest.java @@ -4,24 +4,136 @@ package net.sourceforge.pmd.lang.impl; +import static net.sourceforge.pmd.util.CollectionUtil.listOf; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; +import java.util.concurrent.atomic.AtomicInteger; + import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import net.sourceforge.pmd.PMDConfiguration; +import net.sourceforge.pmd.PmdAnalysis; +import net.sourceforge.pmd.Report; +import net.sourceforge.pmd.RuleContext; +import net.sourceforge.pmd.RuleSet; +import net.sourceforge.pmd.RuleViolation; +import net.sourceforge.pmd.lang.DummyLanguageModule; import net.sourceforge.pmd.lang.LanguageProcessor; +import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.document.FileId; +import net.sourceforge.pmd.lang.document.TextFile; +import net.sourceforge.pmd.lang.rule.AbstractRule; +import net.sourceforge.pmd.reporting.FileAnalysisListener; +import net.sourceforge.pmd.reporting.GlobalAnalysisListener; +import net.sourceforge.pmd.util.log.MessageReporter; + +abstract class AbstractPMDProcessorTest { + protected SimpleReportListener reportListener; + + protected MessageReporter reporter; + + protected abstract int getThreads(); + + protected abstract Class getExpectedImplementation(); -class AbstractPMDProcessorTest { @Test - void shouldUseMonoThreadProcessorForZeroOnly() { - AbstractPMDProcessor processor = AbstractPMDProcessor.newFileProcessor(createTask(0)); - assertSame(MonoThreadProcessor.class, processor.getClass()); - - processor = AbstractPMDProcessor.newFileProcessor(createTask(1)); - assertSame(MultiThreadProcessor.class, processor.getClass()); + void shouldUseCorrectProcessorImpl() { + try (AbstractPMDProcessor processor = AbstractPMDProcessor.newFileProcessor(createTask(getThreads()))) { + assertSame(getExpectedImplementation(), processor.getClass()); + } } private LanguageProcessor.AnalysisTask createTask(int threads) { - LanguageProcessor.AnalysisTask task = new LanguageProcessor.AnalysisTask(null, null, null, threads, null, null, null); - return task; + return new LanguageProcessor.AnalysisTask(null, null, null, threads, null, null, null); + } + + @Test + void exceptionsShouldBeLogged() { + try (PmdAnalysis pmd = createPmdAnalysis()) { + pmd.addRuleSet(RuleSet.forSingleRule(new RuleThatThrowsException())); + pmd.performAnalysis(); + } + + assertEquals(2, reportListener.files.get()); + assertEquals(2, reportListener.errors.get()); + // exceptions are reported as processing errors + Mockito.verifyNoInteractions(reporter); + } + + protected PmdAnalysis createPmdAnalysis() { + PMDConfiguration configuration = new PMDConfiguration(); + configuration.setThreads(getThreads()); + configuration.setIgnoreIncrementalAnalysis(true); + reporter = Mockito.spy(configuration.getReporter()); + configuration.setReporter(reporter); + + PmdAnalysis pmd = PmdAnalysis.create(configuration); + LanguageVersion lv = DummyLanguageModule.getInstance().getDefaultVersion(); + pmd.files().addFile(TextFile.forCharSeq("abc", FileId.fromPathLikeString("file1-violation.dummy"), lv)); + pmd.files().addFile(TextFile.forCharSeq("DEF", FileId.fromPathLikeString("file2-foo.dummy"), lv)); + + reportListener = new SimpleReportListener(); + GlobalAnalysisListener listener = GlobalAnalysisListener.tee(listOf( + new Report.GlobalReportBuilderListener(), + reportListener + )); + + + pmd.addListener(listener); + return pmd; + } + + protected static class RuleThatThrowsException extends AbstractRule { + RuleThatThrowsException() { + setLanguage(DummyLanguageModule.getInstance().getDefaultVersion().getLanguage()); + } + + @Override + public void apply(Node target, RuleContext ctx) { + throw new RuntimeException("test exception"); + } + } + + protected static class RuleThatThrowsError extends AbstractRule { + RuleThatThrowsError() { + setLanguage(DummyLanguageModule.getInstance().getDefaultVersion().getLanguage()); + } + + @Override + public void apply(Node target, RuleContext ctx) { + throw new Error("test error"); + } + } + + protected static class SimpleReportListener implements GlobalAnalysisListener { + + public AtomicInteger violations = new AtomicInteger(0); + public AtomicInteger files = new AtomicInteger(0); + public AtomicInteger errors = new AtomicInteger(0); + + @Override + public FileAnalysisListener startFileAnalysis(TextFile file) { + files.incrementAndGet(); + + return new FileAnalysisListener() { + @Override + public void onRuleViolation(RuleViolation violation) { + violations.incrementAndGet(); + } + + @Override + public void onError(Report.ProcessingError error) { + errors.incrementAndGet(); + } + }; + } + + @Override + public void close() throws Exception { + + } } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessorTest.java new file mode 100644 index 0000000000..755003142b --- /dev/null +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessorTest.java @@ -0,0 +1,43 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.impl; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import net.sourceforge.pmd.PmdAnalysis; +import net.sourceforge.pmd.RuleSet; + +class MonoThreadProcessorTest extends AbstractPMDProcessorTest { + + @Override + protected int getThreads() { + return 0; + } + + @Override + protected Class getExpectedImplementation() { + return MonoThreadProcessor.class; + } + + @Test + void errorsShouldBeThrown() { + try (PmdAnalysis pmd = createPmdAnalysis()) { + pmd.addRuleSet(RuleSet.forSingleRule(new RuleThatThrowsError())); + Error exception = assertThrows(Error.class, pmd::performAnalysis); + assertEquals("test error", exception.getMessage()); + } + + // in mono thread, files are processed one after another. + // in case of error, we abort at the first error, so in this test case + // we abort at the first file, so only 1 file is processed. + assertEquals(1, reportListener.files.get()); + // in mono thread, the error just falls through, we don't additionally catch and log it. + Mockito.verifyNoInteractions(reporter); + } +} diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessorTest.java index f32b330b0a..12e381fac1 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessorTest.java @@ -4,51 +4,61 @@ package net.sourceforge.pmd.lang.impl; -import static net.sourceforge.pmd.util.CollectionUtil.listOf; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.concurrent.atomic.AtomicInteger; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; -import net.sourceforge.pmd.PMDConfiguration; import net.sourceforge.pmd.PmdAnalysis; -import net.sourceforge.pmd.Report.GlobalReportBuilderListener; import net.sourceforge.pmd.RuleContext; -import net.sourceforge.pmd.RuleViolation; -import net.sourceforge.pmd.lang.DummyLanguageModule; -import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.RuleSet; import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.document.FileId; -import net.sourceforge.pmd.lang.document.TextFile; import net.sourceforge.pmd.lang.rule.AbstractRule; -import net.sourceforge.pmd.reporting.FileAnalysisListener; -import net.sourceforge.pmd.reporting.GlobalAnalysisListener; -class MultiThreadProcessorTest { +class MultiThreadProcessorTest extends AbstractPMDProcessorTest { - private SimpleReportListener reportListener; + @Override + protected int getThreads() { + return 2; + } - PmdAnalysis setupForTest(final String ruleset) { - PMDConfiguration configuration = new PMDConfiguration(); - configuration.setThreads(2); - configuration.setIgnoreIncrementalAnalysis(true); - PmdAnalysis pmd = PmdAnalysis.create(configuration); - LanguageVersion lv = DummyLanguageModule.getInstance().getDefaultVersion(); - pmd.files().addFile(TextFile.forCharSeq("abc", FileId.fromPathLikeString("file1-violation.dummy"), lv)); - pmd.files().addFile(TextFile.forCharSeq("DEF", FileId.fromPathLikeString("file2-foo.dummy"), lv)); + @Override + protected Class getExpectedImplementation() { + return MultiThreadProcessor.class; + } - reportListener = new SimpleReportListener(); - GlobalAnalysisListener listener = GlobalAnalysisListener.tee(listOf( - new GlobalReportBuilderListener(), - reportListener - )); - - pmd.addListener(listener); + private PmdAnalysis createPmdAnalysis(final String ruleset) { + PmdAnalysis pmd = createPmdAnalysis(); pmd.addRuleSet(pmd.newRuleSetLoader().loadFromResource(ruleset)); return pmd; } + @Test + void errorsShouldBeThrown() { + // in multithreading mode, the errors are detected when closing PmdAnalysis + Error error = assertThrows(Error.class, () -> { + try (PmdAnalysis pmd = createPmdAnalysis()) { + pmd.addRuleSet(RuleSet.forSingleRule(new RuleThatThrowsError())); + pmd.performAnalysis(); + } + }); + assertEquals("test error", error.getMessage()); + + // in multithreading mode, all files are started but eventually fail + // depending on how many tasks have been started before getting the first results + // we might have started only one file analysis or more. But we rethrow + // the error on the first. + assertTrue(reportListener.files.get() >= 1); + // we report the first error + Mockito.verify(reporter).error(Mockito.eq("Unknown error occurred while executing a PmdRunnable: {0}"), + Mockito.eq("java.lang.Error: test error"), + Mockito.any(Error.class)); + } + // TODO: Dysfunctional rules are pruned upstream of the processor. // // @Test @@ -71,7 +81,7 @@ class MultiThreadProcessorTest { @Test void testRulesThreadSafety() throws Exception { - try (PmdAnalysis pmd = setupForTest("rulesets/MultiThreadProcessorTest/basic.xml")) { + try (PmdAnalysis pmd = createPmdAnalysis("rulesets/MultiThreadProcessorTest/basic.xml")) { pmd.performAnalysis(); } @@ -130,23 +140,4 @@ class MultiThreadProcessorTest { } } - private static class SimpleReportListener implements GlobalAnalysisListener { - - public AtomicInteger violations = new AtomicInteger(0); - - @Override - public FileAnalysisListener startFileAnalysis(TextFile file) { - return new FileAnalysisListener() { - @Override - public void onRuleViolation(RuleViolation violation) { - violations.incrementAndGet(); - } - }; - } - - @Override - public void close() throws Exception { - - } - } } diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 4a657699bf..facb2c6dc0 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -132,14 +132,6 @@ pmd-cli ${project.version} - - - net.sourceforge.pmd - pmd-cli - ${project.version} - sh - completion - net.sourceforge.pmd pmd-ant diff --git a/pmd-dist/src/main/resources/assemblies/pmd-bin.xml b/pmd-dist/src/main/resources/assemblies/pmd-bin.xml index a69cde3c66..f33bf93348 100644 --- a/pmd-dist/src/main/resources/assemblies/pmd-bin.xml +++ b/pmd-dist/src/main/resources/assemblies/pmd-bin.xml @@ -67,19 +67,6 @@ - - - runtime - - net.sourceforge.pmd:pmd-cli:sh:completion:* - - pmd-completion.sh - shell - 0755 - 0644 - false - - runtime diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 926238f9da..73476fdab9 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -52,7 +52,7 @@ set_lib_dir() { if [ -L "$0" ]; then local script_real_loc=$(readlink "$0") else - local script_real_loc=$0 + local script_real_loc=${BASH_SOURCE[0]:-${(%):-%x}} fi local script_dir=$(dirname "${script_real_loc}") @@ -74,7 +74,7 @@ set_conf_dir() { if [ -L $0 ]; then local script_real_loc=$(readlink "$0") else - local script_real_loc=$0 + local script_real_loc=${BASH_SOURCE[0]:-${(%):-%x}} fi local script_dir=$(dirname "${script_real_loc}") diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java index 86aec7be9b..86bb126f76 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java @@ -88,7 +88,6 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest { result.add(basedir + "bin/pmd"); result.add(basedir + "bin/pmd.bat"); result.add(basedir + "conf/simplelogger.properties"); - result.add(basedir + "shell/pmd-completion.sh"); result.add(basedir + "lib/pmd-core-" + PMDVersion.VERSION + ".jar"); result.add(basedir + "lib/pmd-java-" + PMDVersion.VERSION + ".jar"); result.add(basedir + "sbom/pmd-" + PMDVersion.VERSION + "-cyclonedx.xml"); diff --git a/pmd-doc/src/test/resources/expected/pmd_sidebar.yml b/pmd-doc/src/test/resources/expected/pmd_sidebar.yml index 685cfc5851..756c9ece74 100644 --- a/pmd-doc/src/test/resources/expected/pmd_sidebar.yml +++ b/pmd-doc/src/test/resources/expected/pmd_sidebar.yml @@ -93,7 +93,7 @@ entries: - title: null output: web, pdf subfolders: - - title: Salesforce VisualForce Rules + - title: Salesforce Visualforce Rules output: web, pdf subfolderitems: - title: Index @@ -120,7 +120,7 @@ entries: - title: null output: web, pdf subfolders: - - title: VM Rules + - title: Velocity Template Language (VTL) Rules output: web, pdf subfolderitems: - title: Index diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierRule.java index 5d5892bc43..23506062fe 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierRule.java @@ -52,16 +52,16 @@ public class CommentDefaultAccessModifierRule extends AbstractJavaRulechainRule "com.google.common.annotations.VisibleForTesting", "android.support.annotation.VisibleForTesting", "co.elastic.clients.util.VisibleForTesting", - "org.junit.jupiter.api.Test", - "org.junit.jupiter.api.extension.RegisterExtension", - "org.junit.jupiter.api.ParameterizedTest", + "org.junit.jupiter.api.AfterAll", + "org.junit.jupiter.api.AfterEach", + "org.junit.jupiter.api.BeforeAll", + "org.junit.jupiter.api.BeforeEach", "org.junit.jupiter.api.RepeatedTest", + "org.junit.jupiter.api.Test", "org.junit.jupiter.api.TestFactory", "org.junit.jupiter.api.TestTemplate", - "org.junit.jupiter.api.BeforeEach", - "org.junit.jupiter.api.BeforeAll", - "org.junit.jupiter.api.AfterEach", - "org.junit.jupiter.api.AfterAll", + "org.junit.jupiter.api.extension.RegisterExtension", + "org.junit.jupiter.params.ParameterizedTest", "org.testng.annotations.Test", "org.testng.annotations.AfterClass", "org.testng.annotations.AfterGroups", diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml index 8ce22f0ebe..6375c33a89 100755 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml @@ -454,16 +454,16 @@ public enum MyEnum { - #3859 #4273 [java] CommentDefaultAccessModifier is triggered in JUnit5 method and it was conflicting with rule JUnit5TestShouldBePackagePrivate + #3859 #4273 #4645 [java] CommentDefaultAccessModifier is triggered in JUnit5 method and it was conflicting with rule JUnit5TestShouldBePackagePrivate 0 >=" > : DEFAULT | < RUNSIGNEDSHIFTASSIGN: ">>>=" > : DEFAULT } + +/* + * Decorators + * See https://github.com/tc39/proposal-decorators + */ + +TOKEN : +{ + < AT: "@" > : DEFAULT +} diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/cpd/EcmascriptTokenizerTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/cpd/EcmascriptTokenizerTest.java index 9e0163405d..32c5c769c0 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/cpd/EcmascriptTokenizerTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/cpd/EcmascriptTokenizerTest.java @@ -9,6 +9,8 @@ import org.junit.jupiter.api.Test; import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; import net.sourceforge.pmd.lang.ecmascript.EcmascriptLanguageModule; + + class EcmascriptTokenizerTest extends CpdTextComparisonTest { EcmascriptTokenizerTest() { @@ -57,4 +59,9 @@ class EcmascriptTokenizerTest extends CpdTextComparisonTest { void testTabWidth() { doTest("tabWidth"); } + + @Test + void testDecorators() { + doTest("decorator"); + } } diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/decorator.js b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/decorator.js new file mode 100644 index 0000000000..53de860398 --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/decorator.js @@ -0,0 +1,8 @@ +// A simple decorator\n" +@annotation +class MyClass { } + +function annotation(target) { + // Add a property on target + target.annotated = true; +} \ No newline at end of file diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/decorator.txt b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/decorator.txt new file mode 100644 index 0000000000..0469118758 --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/decorator.txt @@ -0,0 +1,26 @@ + [Image] or [Truncated image[ Bcol Ecol +L2 + [@] 1 2 + [annotation] 2 12 +L3 + [class] 1 6 + [MyClass] 7 14 + [{] 15 16 + [}] 17 18 +L5 + [function] 1 9 + [annotation] 10 20 + [(] 20 21 + [target] 21 27 + [)] 27 28 + [{] 29 30 +L7 + [target] 4 10 + [.] 10 11 + [annotated] 11 20 + [=] 21 22 + [true] 23 27 + [;] 27 28 +L8 + [}] 1 2 +EOF diff --git a/pmd-tsql/src/main/java/net/sourceforge/pmd/lang/tsql/TSqlLanguageModule.java b/pmd-tsql/src/main/java/net/sourceforge/pmd/lang/tsql/TSqlLanguageModule.java index 293421b00e..5dbd3e88ef 100644 --- a/pmd-tsql/src/main/java/net/sourceforge/pmd/lang/tsql/TSqlLanguageModule.java +++ b/pmd-tsql/src/main/java/net/sourceforge/pmd/lang/tsql/TSqlLanguageModule.java @@ -17,7 +17,7 @@ public class TSqlLanguageModule extends CpdOnlyLanguageModuleBase { private static final String ID = "tsql"; public TSqlLanguageModule() { - super(LanguageMetadata.withId(ID).name("TSql").extensions("sql")); + super(LanguageMetadata.withId(ID).name("T-SQL").extensions("sql")); } public static TSqlLanguageModule getInstance() { diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfLanguageModule.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfLanguageModule.java index b6d6bd25d6..f596902c2b 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfLanguageModule.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfLanguageModule.java @@ -17,7 +17,7 @@ import net.sourceforge.pmd.lang.vf.cpd.VfTokenizer; */ public class VfLanguageModule extends SimpleLanguageModuleBase implements CpdCapableLanguage { static final String ID = "vf"; - static final String NAME = "Salesforce VisualForce"; + static final String NAME = "Salesforce Visualforce"; public VfLanguageModule() { super(LanguageMetadata.withId(ID).name(NAME) diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfLanguageProperties.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfLanguageProperties.java index 3ec4d2d21b..445e6d3f1f 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfLanguageProperties.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/VfLanguageProperties.java @@ -19,7 +19,7 @@ public class VfLanguageProperties extends LanguagePropertyBundle { /** * Directory that contains Apex classes that may be referenced from a Visualforce page. * - *

Env variable is {@code PMD_VF_APEXDIRECTORIES}. + *

Env variable is {@code PMD_VF_APEX_DIRECTORIES}. */ public static final PropertyDescriptor> APEX_DIRECTORIES_DESCRIPTOR = PropertyFactory.stringListProperty("apexDirectories") @@ -30,7 +30,7 @@ public class VfLanguageProperties extends LanguagePropertyBundle { /** * Directory that contains Object definitions that may be referenced from a Visualforce page. * - *

Env variable is {@code PMD_VF_OBJECTSDIRECTORIES}. + *

Env variable is {@code PMD_VF_OBJECTS_DIRECTORIES}. */ public static final PropertyDescriptor> OBJECTS_DIRECTORIES_DESCRIPTOR = PropertyFactory.stringListProperty("objectsDirectories") diff --git a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/VmLanguageModule.java b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/VmLanguageModule.java index ce35a109ec..b441d472ae 100644 --- a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/VmLanguageModule.java +++ b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/VmLanguageModule.java @@ -15,7 +15,7 @@ import net.sourceforge.pmd.lang.vm.cpd.VmTokenizer; */ public class VmLanguageModule extends SimpleLanguageModuleBase { static final String ID = "vm"; - static final String NAME = "VM"; + static final String NAME = "Velocity Template Language (VTL)"; public VmLanguageModule() { super(LanguageMetadata.withId(ID).name(NAME)