Merge branch '7.0.x' into pmd7-merge-xml-rule

This commit is contained in:
Clément Fournier 2022-03-24 19:52:16 +01:00
commit b0ce80350f
No known key found for this signature in database
GPG Key ID: 4D8D42402E4F47E2
24 changed files with 680 additions and 413 deletions

View File

@ -6566,6 +6566,15 @@
"contributions": [
"bug"
]
},
{
"login": "btjiong",
"name": "Bailey Tjiong",
"avatar_url": "https://avatars.githubusercontent.com/u/15816011?v=4",
"profile": "https://github.com/btjiong",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,

View File

@ -40,10 +40,6 @@ mvn dependency:build-classpath -DincludeScope=test -Dmdep.outputFile=classpath.t
<exclude-pattern>.*/build/generated-sources/.*</exclude-pattern>
<build-command><![CDATA[#!/usr/bin/env bash
if test -e classpath.txt; then
exit
fi
set -e
# Make sure to use java11. This is already installed by build.sh
@ -133,6 +129,11 @@ index 6021fa574d..15d29ed699 100644
EOF
) | patch --strip=1
## Skip gradle execution
if test -e classpath.txt; then
exit
fi
./gradlew --console=plain --build-cache --no-daemon --max-workers=4 build testClasses -x test -x javadoc -x api -x asciidoctor -x asciidoctorPdf
./gradlew --console=plain --build-cache --no-daemon --max-workers=4 createSquishClasspath -q > classpath.txt
]]></build-command>

View File

@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar

View File

@ -1,12 +1,30 @@
<footer>
<div class="row">
<div class="col-lg-12 footer">
<p class="float-right"><img src="{{ "images/logo/pmd-logo-70px.png" }}" alt="PMD logo"/></p>
<p>
&copy;{{ site.time | date: "%Y" }} {{site.company_name}}. All rights reserved. <br />
{% if page.last_updated %}<span>Page last updated:</span> {{page.last_updated}}<br/>{% endif %}
Site last generated: {{ site.time | date: "%b %-d, %Y" }}
</p>
</div>
</div>
{% if site.github_editme_path and page.editmepath != false %}
<hr />
<div>
This documentation is written in markdown. <br />
If there is something missing or can be improved, edit this page on
github and create a PR:
<a
target="_blank"
href="https://github.com/{{site.github_editme_path}}{{editmepath}}"
role="button"
><i class="fa fa-github fa-lg"></i> Edit on GitHub</a
>
</div>
{% endif %}
<hr />
<div class="row">
<div class="col-lg-12 footer">
&copy;{{ site.time | date: "%Y" }} {{site.company_name}}. All rights
reserved. <br />
{% if page.last_updated %}<span>Page last updated:</span>
{{page.last_updated}}<br />{% endif %} Site last generated: {{
site.time | date: "%b %-d, %Y" }} <br />
<p>
<img src="{{ "images/logo/pmd-logo-70px.png" }}" alt="PMD
logo"/>
</p>
</div>
</div>
</footer>

View File

@ -0,0 +1,23 @@
<header>
<div class="row">
<div class="col-lg-12">
<a href="./" role="button"
><i class="fa fa-home fa-lg"></i
></a>
» {{page.title}} {% if site.github_editme_path %} {% assign
editmepath = page.path %} {% if page.editmepath %} {% assign
editmepath = page.editmepath %} {% endif %}{% unless page.editmepath
== false %}
<a
target="_blank"
href="https://github.com/{{site.github_editme_path}}{{editmepath}}"
class="float-right"
role="button"
><i class="fa fa-github fa-lg"></i> Edit on GitHub</a
>
{% endunless %} {% endif %}
</div>
</div>
<hr />
</header>

View File

@ -1,5 +0,0 @@
{% comment %}
Note: The content of the div-element is filled by javascript. See customscripts.js.
{% endcomment %}
<div id="toc"></div>

View File

@ -36,7 +36,7 @@
{% unless page.toc == false %}
<!-- Sticky TOC column -->
<div class="toc-col">
{% include toc.html %}
<div id="toc"></div>
</div>
{% endunless %}
<!-- /.toc-container-wrapper -->

View File

@ -2,31 +2,19 @@
layout: default
---
{% include header.html %}
<div class="post-header">
<h1 class="post-title-main">{{ page.title }}</h1>
</div>
<div class="post-content">
<div class="post-content" {% if site.github_editme_path and page.editmepath != false %}data-github-edit-url="https://github.com/{{site.github_editme_path}}{{editmepath}}"{% endif %}>
{% if page.summary %}
<div class="summary">{{page.summary}}</div>
{% endif %}
<div id="inline-toc"><!-- empty, move TOC here when screen size too small --></div>
{% if site.github_editme_path %}
{% assign editmepath = page.path %}
{% if page.editmepath %}
{% assign editmepath = page.editmepath %}
{% endif %}
{% unless page.editmepath == false %}
<a target="_blank" href="https://github.com/{{site.github_editme_path}}{{editmepath}}" class="btn btn-outline-secondary githubEditButton" role="button"><i class="fab fa-github fa-lg"></i> Edit me</a>
{% endunless %}
{% endif %}
{{content}}
<div class="tags">
@ -43,6 +31,5 @@ layout: default
</div>
{{site.data.alerts.hr_shaded}}
{% include footer.html %}

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,10 @@
width: 100%;
}
header {
margin-top: 40px;
}
details {
border-radius: 3px;
background: #EEE;

View File

@ -1,14 +1,21 @@
// Detect small devices and move the TOC in line
function moveToc(){
if(window.innerWidth < 1350){
$( "#toc" ).detach().appendTo("#inline-toc").removeClass("position-fixed");
$( '#toc' ).detach().appendTo('#inline-toc').removeClass('position-fixed');
} else {
$( "#toc" ).detach().appendTo(".toc-col").addClass("position-fixed");
$( '#toc' ).detach().appendTo('.toc-col').addClass('position-fixed');
}
}
$( document ).ready(function() {
$(document).ready(function () {
// This handles the automatic toc. Use ## for subheads to auto-generate the on-page minitoc.
// If you use html tags, you must supply an ID for the heading element in order for it to appear in the minitoc.
$('#toc').toc({
minimumHeaders: 0,
listType: 'ul',
showSpeed: 0,
headers: 'h2,h3,h4',
});
$('#mysidebar').height($(".nav").height());
@ -18,18 +25,31 @@ $( document ).ready(function() {
var h = $(window).height();
//console.log (h);
if (h > 600) {
$( "#mysidebar" ).attr("class", "nav position-fixed");
$( '#mysidebar' ).attr('class', 'nav position-fixed');
}
// activate tooltips. although this is a bootstrap js function, it must be activated this way in your theme.
$('[data-toggle="tooltip"]').tooltip({
placement : 'top'
placement: 'top',
});
/**
* AnchorJS
*/
anchors.add('h2,h3,h4,h5');
// Add an "Edit on GitHub" button to each header (except h1)
let url = $('div.post-content').data('githubEditUrl');
if ( url !== undefined ) {
$('div.post-content')
.find(':header:not(h1)')
.append(
' <a class="edit-header" target="_blank" href=' +
url +
' role="button">✏️️</a>'
);
}
// Check if TOC needs to be moved on page load
moveToc();
@ -37,10 +57,10 @@ $( document ).ready(function() {
// when you're viewing a page.
// Note: the class needs to be added before navgoco is initialized. Navgoco uses then this information
// to expand the menus.
$("li.active").parents('li').toggleClass("active");
$( 'li.active' ).parents('li').toggleClass('active');
// Initialize navgoco with default options
$("#mysidebar").navgoco({
$( '#mysidebar' ).navgoco({
caretHtml: '',
accordion: true,
openClass: 'active',
@ -51,10 +71,6 @@ $( document ).ready(function() {
}
});
// This handles the automatic toc. Use ## for subheads to auto-generate the on-page minitoc.
// If you use html tags, you must supply an ID for the heading element in order for it to appear in the minitoc.
$('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3,h4' });
// Initialize jekyll search in topnav.
SimpleJekyllSearch.init({
searchInput: document.getElementById('search-input'),
@ -85,4 +101,6 @@ $( document ).ready(function() {
});
// Check if TOC needs to be moved on window resizing
$(window).resize(function () {moveToc();});
$(window).resize(function () {
moveToc();
});

View File

@ -5,38 +5,38 @@
$('a[data-toggle="pill"], a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
var tabId, json, parentId, tabsState;
tabsState = localStorage.getItem("tabs-state");
tabsState = localStorage.getItem('tabs-state');
json = JSON.parse(tabsState || "{}");
parentId = $(e.target).parents("ul.nav.nav-pills, ul.nav.nav-tabs").attr("id");
parentId = $(e.target).parents('ul.nav.nav-pills, ul.nav.nav-tabs').attr('id');
tabId = $(e.target).attr('id');
json[parentId] = tabId;
return localStorage.setItem("tabs-state", JSON.stringify(json));
return localStorage.setItem('tabs-state', JSON.stringify(json));
});
};
document.addEventListener('DOMContentLoaded', function () {
var json, tabsState;
tabsState = localStorage.getItem("tabs-state");
json = JSON.parse(tabsState || "{}");
tabsState = localStorage.getItem('tabs-state');
json = JSON.parse(tabsState || '{}');
$.each(json, function(containerId, tabId) {
if (containerId && containerId !== "undefined" && tabId && tabId !== "undefined"
if (containerId && containerId !== 'undefined' && tabId && tabId !== 'undefined'
&& tabId.indexOf('#') !== 0) {
$("#" + tabId).tab('show');
$('#' + tabId).tab('show');
}
});
$("ul.nav.nav-pills, ul.nav.nav-tabs").each(function() {
$('ul.nav.nav-pills, ul.nav.nav-tabs').each(function() {
var $this = $(this);
if (!json[$this.attr("id")]) {
return $this.find("a[data-toggle=tab]:first, a[data-toggle=pill]:first").tab("show");
if (!json[$this.attr('id')]) {
return $this.find('a[data-toggle=tab]:first, a[data-toggle=pill]:first').tab('show');
}
});
// cleanup "undefined" entries
delete json['undefined'];
localStorage.setItem("tabs-state", JSON.stringify(json));
localStorage.setItem('tabs-state', JSON.stringify(json));
registerTabEvent();
});

View File

@ -84,9 +84,6 @@ Now the source and binary distribution zip files can be found in the folder `pmd
**Notes:**
* The rules that have already been written are specified in the `src/main/resources/rulesets/` directories of
the specific languages, e.g. `pmd-java/src/main/resources/rulesets`.
Theyre also in the jar file thats included with both the source and binary distributions.
A paucity of detail, Im sure youd agree. If you think this document can be improved,
please post [here](http://sourceforge.net/p/pmd/discussion/188192) and let me know how. Thanks!
- The rules that have already been written are specified in the `src/main/resources/category/` directories of
the specific languages, e.g. `pmd-java/src/main/resources/category`.
Theyre also in the jar file thats included with both the source and binary distributions.

File diff suppressed because it is too large Load Diff

View File

@ -56,11 +56,14 @@ The CLI itself remains compatible, if you run PMD via command-line, no action is
### Fixed Issues
* apex
* [#3817](https://github.com/pmd/pmd/pull/3817): \[apex] Add designer bindings to display main attributes
* apex-performance
* [#3773](https://github.com/pmd/pmd/pull/3773): \[apex] EagerlyLoadedDescribeSObjectResult false positives with SObjectField.getDescribe()
* core
* [#3299](https://github.com/pmd/pmd/issues/3299): \[core] Deprecate system properties of PMDCommandLineInterface
* doc
* [#2504](https://github.com/pmd/pmd/issues/2504): \[doc] Improve "Edit me on github" button
* [#3812](https://github.com/pmd/pmd/issues/3812): \[doc] Documentation website table of contents broken on pages with many subheadings
### API Changes
@ -84,6 +87,11 @@ The CLI itself remains compatible, if you run PMD via command-line, no action is
The whole class however was deprecated long ago already with 6.30.0. It is internal API and should
not be used.
* In modelica, the rule classes {% jdoc modelica::lang.modelica.rule.AmbiguousResolutionRule %}
and {% jdoc modelica::lang.modelica.rule.ConnectUsingNonConnector %} have been deprecated,
since they didn't comply to the usual rule class naming conventions yet.
The replacements are in the subpackage `bestpractices`.
#### Experimental APIs
* Together with the [new programmatic API](#new-programmatic-api) the interface
@ -98,6 +106,7 @@ The CLI itself remains compatible, if you run PMD via command-line, no action is
### External Contributions
* [#3773](https://github.com/pmd/pmd/pull/3773): \[apex] EagerlyLoadedDescribeSObjectResult false positives with SObjectField.getDescribe() - [@filiprafalowicz](https://github.com/filiprafalowicz)
* [#3811](https://github.com/pmd/pmd/pull/3811): \[doc] Improve "Edit me on github" button - [@btjiong](https://github.com/btjiong)
* [#3836](https://github.com/pmd/pmd/pull/3836): \[doc] Make TOC scrollable when too many subheadings - [@JerritEic](https://github.com/JerritEic)
{% endtocmaker %}

View File

@ -11,6 +11,7 @@ import java.util.Set;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.apex.ast.ApexParser;
import net.sourceforge.pmd.lang.apex.internal.ApexDesignerBindings;
import net.sourceforge.pmd.lang.apex.metrics.ApexMetrics;
import net.sourceforge.pmd.lang.apex.rule.internal.ApexRuleViolationFactory;
import net.sourceforge.pmd.lang.ast.Parser;
@ -18,6 +19,7 @@ import net.sourceforge.pmd.lang.metrics.LanguageMetricsProvider;
import net.sourceforge.pmd.lang.metrics.Metric;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
import net.sourceforge.pmd.properties.PropertySource;
import net.sourceforge.pmd.util.designerbindings.DesignerBindings;
@InternalApi
public class ApexHandler extends AbstractPmdLanguageVersionHandler {
@ -46,6 +48,11 @@ public class ApexHandler extends AbstractPmdLanguageVersionHandler {
return myMetricsProvider;
}
@Override
public DesignerBindings getDesignerBindings() {
return ApexDesignerBindings.INSTANCE;
}
private static final class ApexMetricsProvider implements LanguageMetricsProvider {
private final Set<Metric<?, ?>> metrics = setOf(

View File

@ -0,0 +1,64 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.internal;
import net.sourceforge.pmd.lang.apex.ast.ASTFieldDeclaration;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTMethodCallExpression;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
import net.sourceforge.pmd.lang.apex.ast.ASTVariableDeclaration;
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
import net.sourceforge.pmd.lang.apex.ast.ApexParserVisitorAdapter;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.xpath.Attribute;
import net.sourceforge.pmd.util.designerbindings.DesignerBindings.DefaultDesignerBindings;
public class ApexDesignerBindings extends DefaultDesignerBindings {
public static final ApexDesignerBindings INSTANCE = new ApexDesignerBindings();
@Override
public Attribute getMainAttribute(Node node) {
if (node instanceof ApexNode) {
Attribute attr = (Attribute) ((ApexNode<?>) node).jjtAccept(MainAttrVisitor.INSTANCE, null);
if (attr != null) {
return attr;
}
}
return super.getMainAttribute(node);
}
@Override
public TreeIconId getIcon(Node node) {
if (node instanceof ASTFieldDeclaration) {
return TreeIconId.FIELD;
} else if (node instanceof ASTUserClass) {
return TreeIconId.CLASS;
} else if (node instanceof ASTMethod) {
return TreeIconId.METHOD;
} else if (node instanceof ASTVariableDeclaration) {
return TreeIconId.VARIABLE;
}
return super.getIcon(node);
}
private static final class MainAttrVisitor extends ApexParserVisitorAdapter {
private static final MainAttrVisitor INSTANCE = new MainAttrVisitor();
@Override
public Object visit(ApexNode<?> node, Object data) {
return null; // don't recurse
}
@Override
public Object visit(ASTMethodCallExpression node, Object data) {
return new Attribute(node, "MethodName", node.getMethodName());
}
}
}

View File

@ -12,6 +12,12 @@
</parent>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>

View File

@ -1,26 +1,13 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.modelica.rule;
import net.sourceforge.pmd.lang.modelica.ast.ASTName;
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionResult;
import net.sourceforge.pmd.lang.modelica.resolver.ResolvableEntity;
/**
* @deprecated Use {@link net.sourceforge.pmd.lang.modelica.rule.bestpractices.AmbiguousResolutionRule}
*/
public class AmbiguousResolutionRule extends net.sourceforge.pmd.lang.modelica.rule.bestpractices.AmbiguousResolutionRule {
public class AmbiguousResolutionRule extends AbstractModelicaRule {
@Override
public Object visit(ASTName node, Object data) {
ResolutionResult<ResolvableEntity> candidates = node.getResolutionCandidates();
if (candidates.isClashed()) {
StringBuilder sb = new StringBuilder();
sb.append("Candidate resolutions: ");
for (ResolvableEntity candidate: candidates.getBestCandidates()) {
sb.append(candidate.getDescriptiveName());
sb.append(", ");
}
addViolation(data, node, sb.substring(0, sb.length() - 2));
}
return super.visit(node, data);
}
}

View File

@ -1,50 +1,16 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.modelica.rule;
import net.sourceforge.pmd.lang.modelica.ast.ASTComponentReference;
import net.sourceforge.pmd.lang.modelica.ast.ASTConnectClause;
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaClassSpecialization;
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaClassType;
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaComponentDeclaration;
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionResult;
import net.sourceforge.pmd.lang.modelica.resolver.ResolvableEntity;
import net.sourceforge.pmd.lang.modelica.rule.bestpractices.ConnectUsingNonConnectorRule;
public class ConnectUsingNonConnector extends AbstractModelicaRule {
private void reportIfViolated(ASTComponentReference ref, Object data) {
ResolutionResult<ResolvableEntity> resolution = ref.getResolutionCandidates();
if (!resolution.isUnresolved()) { // no false positive if not resolved at all
ResolvableEntity firstDecl = resolution.getBestCandidates().get(0);
if (firstDecl instanceof ModelicaComponentDeclaration) {
ModelicaComponentDeclaration componentDecl = (ModelicaComponentDeclaration) firstDecl;
ResolutionResult componentTypes = componentDecl.getTypeCandidates();
if (!componentTypes.isUnresolved()) {
if (componentTypes.getBestCandidates().get(0) instanceof ModelicaClassType) {
ModelicaClassType classDecl = (ModelicaClassType) componentTypes.getBestCandidates().get(0);
ModelicaClassSpecialization restriction = classDecl.getSpecialization();
if (!classDecl.isConnectorLike()) {
addViolation(data, ref, restriction.toString());
}
} else {
addViolation(data, ref, firstDecl.getDescriptiveName());
}
}
} else {
addViolation(data, ref, firstDecl.getDescriptiveName());
}
}
}
/**
* @deprecated Use {@link ConnectUsingNonConnectorRule}
*/
@Deprecated
public class ConnectUsingNonConnector extends ConnectUsingNonConnectorRule {
@Override
public Object visit(ASTConnectClause node, Object data) {
ASTComponentReference lhs = (ASTComponentReference) node.getChild(0);
ASTComponentReference rhs = (ASTComponentReference) node.getChild(1);
reportIfViolated(lhs, data);
reportIfViolated(rhs, data);
return super.visit(node, data);
}
}

View File

@ -0,0 +1,27 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.modelica.rule.bestpractices;
import net.sourceforge.pmd.lang.modelica.ast.ASTName;
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionResult;
import net.sourceforge.pmd.lang.modelica.resolver.ResolvableEntity;
import net.sourceforge.pmd.lang.modelica.rule.AbstractModelicaRule;
public class AmbiguousResolutionRule extends AbstractModelicaRule {
@Override
public Object visit(ASTName node, Object data) {
ResolutionResult<ResolvableEntity> candidates = node.getResolutionCandidates();
if (candidates.isClashed()) {
StringBuilder sb = new StringBuilder();
sb.append("Candidate resolutions: ");
for (ResolvableEntity candidate: candidates.getBestCandidates()) {
sb.append(candidate.getDescriptiveName());
sb.append(", ");
}
addViolation(data, node, sb.substring(0, sb.length() - 2));
}
return super.visit(node, data);
}
}

View File

@ -0,0 +1,51 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.modelica.rule.bestpractices;
import net.sourceforge.pmd.lang.modelica.ast.ASTComponentReference;
import net.sourceforge.pmd.lang.modelica.ast.ASTConnectClause;
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaClassSpecialization;
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaClassType;
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaComponentDeclaration;
import net.sourceforge.pmd.lang.modelica.resolver.ResolutionResult;
import net.sourceforge.pmd.lang.modelica.resolver.ResolvableEntity;
import net.sourceforge.pmd.lang.modelica.rule.AbstractModelicaRule;
public class ConnectUsingNonConnectorRule extends AbstractModelicaRule {
private void reportIfViolated(ASTComponentReference ref, Object data) {
ResolutionResult<ResolvableEntity> resolution = ref.getResolutionCandidates();
if (!resolution.isUnresolved()) { // no false positive if not resolved at all
ResolvableEntity firstDecl = resolution.getBestCandidates().get(0);
if (firstDecl instanceof ModelicaComponentDeclaration) {
ModelicaComponentDeclaration componentDecl = (ModelicaComponentDeclaration) firstDecl;
ResolutionResult componentTypes = componentDecl.getTypeCandidates();
if (!componentTypes.isUnresolved()) {
if (componentTypes.getBestCandidates().get(0) instanceof ModelicaClassType) {
ModelicaClassType classDecl = (ModelicaClassType) componentTypes.getBestCandidates().get(0);
ModelicaClassSpecialization restriction = classDecl.getSpecialization();
if (!classDecl.isConnectorLike()) {
addViolation(data, ref, restriction.toString());
}
} else {
addViolation(data, ref, firstDecl.getDescriptiveName());
}
}
} else {
addViolation(data, ref, firstDecl.getDescriptiveName());
}
}
}
@Override
public Object visit(ASTConnectClause node, Object data) {
ASTComponentReference lhs = (ASTComponentReference) node.getChild(0);
ASTComponentReference rhs = (ASTComponentReference) node.getChild(1);
reportIfViolated(lhs, data);
reportIfViolated(rhs, data);
return super.visit(node, data);
}
}

View File

@ -10,6 +10,7 @@ Rules which enforce generally accepted best practices.
<rule name="ClassStartNameEqualsEndName"
language="modelica"
since="6.21.0"
message="Class ends with an end clause with a different name"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_modelica_bestpractices.html#classstartnameequalsendname"
class="net.sourceforge.pmd.lang.rule.XPathRule">
@ -40,9 +41,10 @@ end SomeOtherName /* should be SomeName */;
<rule name="ConnectUsingNonConnector"
language="modelica"
since="6.21.0"
message="Arguments passed to `connect` should be connectors, not `{0}`"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_modelica_bestpractices.html#connectusingnonconnector"
class="net.sourceforge.pmd.lang.modelica.rule.ConnectUsingNonConnector">
class="net.sourceforge.pmd.lang.modelica.rule.bestpractices.ConnectUsingNonConnectorRule">
<description>
Modelica specification requires passing connectors to the `connect` clause,
while some implementations tolerate using it on plain variables, etc..
@ -74,8 +76,9 @@ end Example;
<rule name="AmbiguousResolution"
language="modelica"
message="Type resolution is ambiguous: {0}"
since="6.21.0"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_modelica_bestpractices.html#ambiguousresolution"
class="net.sourceforge.pmd.lang.modelica.rule.AmbiguousResolutionRule">
class="net.sourceforge.pmd.lang.modelica.rule.bestpractices.AmbiguousResolutionRule">
<description>
There is multiple candidates for this type resolution. While generally this is not an error,
this may indicate a bug.

View File

@ -284,10 +284,17 @@ public abstract class AbstractRuleSetFactoryTest {
}
private List<String> getRuleSetFileNames(String language) throws IOException {
List<String> ruleSetFileNames = new ArrayList<>();
ruleSetFileNames.addAll(getRuleSetFileNames(language, "rulesets/" + language + "/rulesets.properties"));
ruleSetFileNames.addAll(getRuleSetFileNames(language, "category/" + language + "/categories.properties"));
return ruleSetFileNames;
}
private List<String> getRuleSetFileNames(String language, String propertiesPath) throws IOException {
List<String> ruleSetFileNames = new ArrayList<>();
Properties properties = new Properties();
@SuppressWarnings("PMD.CloseResource")
InputStream input = getClass().getResourceAsStream("rulesets/" + language + "/rulesets.properties");
InputStream input = getClass().getResourceAsStream(propertiesPath);
if (input == null) {
// this might happen if a language is only support by CPD, but not
// by PMD
@ -302,7 +309,6 @@ public abstract class AbstractRuleSetFactoryTest {
while (st.hasMoreTokens()) {
ruleSetFileNames.add(st.nextToken());
}
return ruleSetFileNames;
}