Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prohibit access to static members via instance reference. #1191

Merged
merged 1 commit into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 20 additions & 1 deletion qulice-pmd/src/main/resources/com/qulice/pmd/ruleset.xml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ OF THE POSSIBILITY OF SUCH DAMAGE.
</property>
</properties>
</rule>
<rule name="StaticAccessToStaticFields" message="Static fields should be accessed in a static way [CLASS_NAME.FIELD_NAME]." language="java" class="net.sourceforge.pmd.lang.rule.XPathRule">
<rule name="AvoidDirectAccessToStaticFields" message="Static fields should be accessed in a static way [CLASS_NAME.FIELD_NAME]." language="java" class="net.sourceforge.pmd.lang.rule.XPathRule">
<description>
Avoid accessing static fields directly.
</description>
Expand All @@ -158,6 +158,25 @@ OF THE POSSIBILITY OF SUCH DAMAGE.
</property>
</properties>
</rule>
<rule name="AvoidAccessToStaticMembersViaThis" message="Static members should be accessed in a static way [CLASS_NAME.FIELD_NAME], not via instance reference." language="java" class="net.sourceforge.pmd.lang.rule.XPathRule">
<description>
Avoid accessing static fields or methods via instance with 'this' keyword.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value><![CDATA[
//PrimaryExpression[
(./PrimaryPrefix[@ThisModifier='true']) and
(./PrimarySuffix[
@Image=//FieldDeclaration[@Static='true']/@VariableName
or @Image=//MethodDeclaration[@Static='true']/@MethodName
])
]
]]></value>
</property>
</properties>
</rule>
<rule name="ProhibitPublicStaticMethods" message="Public static methods are prohibited." language="java" class="net.sourceforge.pmd.lang.rule.XPathRule">
<description>
Public static methods are prohibited.
Expand Down
60 changes: 54 additions & 6 deletions qulice-pmd/src/test/java/com/qulice/pmd/PmdValidatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ public final class PmdValidatorTest {
*/
private static final String STATIC_ACCESS = "%s\\[\\d+-\\d+\\]: Static fields should be accessed in a static way \\[CLASS_NAME.FIELD_NAME\\]\\.";

/**
* Error message for forbidding access to static members
* via instance reference using 'this' keyword.
* @checkstyle LineLength (2 lines)
*/
private static final String STATIC_VIA_THIS = "%s\\[\\d+-\\d+\\]: Static members should be accessed in a static way \\[CLASS_NAME.FIELD_NAME\\], not via instance reference.";

/**
* Error message for forbidding instructions inside a constructor
* other than field initialization or call to other constructors.
Expand Down Expand Up @@ -392,23 +399,30 @@ public void acceptsCallToStaticFieldsInStaticWay()
final String file = "StaticAccessToStaticFields.java";
new PmdAssert(
file, Matchers.is(true),
Matchers.not(
RegexMatchers.containsPattern(
String.format(PmdValidatorTest.STATIC_ACCESS, file)
Matchers.allOf(
Matchers.not(
RegexMatchers.containsPattern(
String.format(PmdValidatorTest.STATIC_ACCESS, file)
)
),
Matchers.not(
RegexMatchers.containsPattern(
String.format(PmdValidatorTest.STATIC_VIA_THIS, file)
)
)
)
).validate();
}

/**
* PmdValidator forbids calls to static fields
* PmdValidator forbids calls to static fields directly
* in a non static way.
* @throws Exception If something wrong happens inside.
*/
@Test
public void forbidsCallToStaticFieldsInNonStaticWay()
public void forbidsCallToStaticFieldsDirectly()
throws Exception {
final String file = "NonStaticAccessToStaticFields.java";
final String file = "DirectAccessToStaticFields.java";
new PmdAssert(
file, Matchers.is(false),
RegexMatchers.containsPattern(
Expand All @@ -417,6 +431,40 @@ public void forbidsCallToStaticFieldsInNonStaticWay()
).validate();
}

/**
* PmdValidator forbids calls to static fields
* in a non static way via instance reference.
* @throws Exception If something wrong happens inside.
*/
@Test
public void forbidsCallToStaticFieldsViaThis()
throws Exception {
final String file = "AccessToStaticFieldsViaThis.java";
new PmdAssert(
file, Matchers.is(false),
RegexMatchers.containsPattern(
String.format(PmdValidatorTest.STATIC_VIA_THIS, file)
)
).validate();
}

/**
* PmdValidator forbids calls to static methods
* in a non static way via instance reference.
* @throws Exception If something wrong happens inside.
*/
@Test
public void forbidsCallToStaticMethodsViaThis()
throws Exception {
final String file = "AccessToStaticMethodsViaThis.java";
new PmdAssert(
file, Matchers.is(false),
RegexMatchers.containsPattern(
String.format(PmdValidatorTest.STATIC_VIA_THIS, file)
)
).validate();
}

/**
* PmdValidator forbids non public clone methods (PMD rule
* rulesets/java/clone.xml/CloneMethodMustBePublic).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package foo;

public final class AccessToStaticFieldsViaThis {
private static final int num = 1;

public int number() {
return this.num;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package foo;

public final class AccessToStaticMethodsViaThis {
private static int number() {
return 1;
}

public int another() {
return 1 + this.number();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package foo;

public final class NonStaticAccessToStaticFields {
public final class DirectAccessToStaticFields {
private static int num = 1;

public static int number() {
Expand Down