Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e24e79b

Browse files
committedJul 14, 2024·
Add Maven plugin implementation Parameter queries
1 parent bcd11a2 commit e24e79b

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed
 
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Finds Maven plugin implementations where a parameter field has an explicit initial value which
3+
* differs from the default value set using `@Parameter#defaultValue`. The `defaultValue` overwrites
4+
* the initial field value when the plugin is used, so the explicit field value is redundant and
5+
* can cause confusion.
6+
*
7+
* For example:
8+
* ```java
9+
* @Parameter(defaultValue = "false")
10+
* public boolean useCustomFeature = true; // `= true` is redundant and misleading
11+
* ```
12+
*
13+
* @kind problem
14+
* @id TODO
15+
*/
16+
17+
import java
18+
19+
predicate equalsDefaultValue(Literal l, string defaultValue) {
20+
exists(string literalValue | literalValue = l.getValue() |
21+
literalValue = defaultValue
22+
or
23+
// Or floating point value matches when removing `.0` suffix
24+
l.getType() instanceof FloatingPointType and
25+
literalValue.matches("%.0") and
26+
literalValue.prefix(literalValue.length() - ".0".length()) = defaultValue
27+
)
28+
}
29+
30+
from
31+
Field f, CompileTimeConstantExpr initializedFieldValue, Annotation parameterAnnotation,
32+
Expr defaultValueExpr, string defaultValue
33+
where
34+
initializedFieldValue = f.getInitializer() and
35+
parameterAnnotation = f.getAnAnnotation() and
36+
parameterAnnotation
37+
.getType()
38+
.hasQualifiedName("org.apache.maven.plugins.annotations", "Parameter") and
39+
defaultValue = parameterAnnotation.getStringValue("defaultValue") and
40+
// Ignore not set default value
41+
defaultValue != "" and
42+
defaultValueExpr = parameterAnnotation.getValue("defaultValue") and
43+
(
44+
initializedFieldValue instanceof Literal and
45+
not equalsDefaultValue(initializedFieldValue, defaultValue)
46+
or
47+
exists(initializedFieldValue.getStringValue()) and
48+
defaultValue != initializedFieldValue.getStringValue()
49+
or
50+
exists(initializedFieldValue.getBooleanValue()) and
51+
defaultValue != initializedFieldValue.getBooleanValue().toString()
52+
or
53+
exists(initializedFieldValue.getIntValue()) and
54+
defaultValue != initializedFieldValue.getIntValue().toString()
55+
) and
56+
// Ignore if default value is `${...}` expression
57+
// TODO: Does this work as expected when property is undefined, i.e. is field default value used then?
58+
// Or is field default value always overwritten? (in that case using `${...}` expression should not be ignored here)
59+
not defaultValue.matches("${%}")
60+
select initializedFieldValue, "Does not match the $@ specified by @Parameter", defaultValueExpr,
61+
"defaultValue"
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* Finds Maven plugin implementations where the implicit or explicit initial field value is
3+
* not specified as `@Parameter#defaultValue`. If `defaultValue` is not specified the plugin
4+
* documentation won't mention the default value, which makes the default behavior of the
5+
* plugin unclear to the user.
6+
*
7+
* For example:
8+
* ```java
9+
* @Parameter
10+
* // Should specify the default using `@Parameter(defaultValue = "true")` instead
11+
* public boolean useCustomFeature = true;
12+
* ```
13+
*
14+
* @kind problem
15+
* @id TODO
16+
*/
17+
18+
// Related to https://github.com/apache/maven-shade-plugin/pull/219
19+
20+
import java
21+
22+
string getDefaultValue(PrimitiveType t) {
23+
t.hasName("boolean") and result = "false"
24+
or
25+
// TODO: Is `char` correct here or is its default value rather `\0`?
26+
t.hasName(["byte", "short", "char", "int", "long", "float", "double"]) and result = "0"
27+
}
28+
29+
from Field f, Annotation parameterAnnotation, string defaultValue
30+
where
31+
parameterAnnotation = f.getAnAnnotation() and
32+
parameterAnnotation
33+
.getType()
34+
.hasQualifiedName("org.apache.maven.plugins.annotations", "Parameter") and
35+
// Does not specify a default value
36+
parameterAnnotation.getStringValue("defaultValue") = "" and
37+
// Only consider @Parameter usage in Mojos
38+
f.getDeclaringType().getASourceSupertype+().hasQualifiedName("org.apache.maven.plugin", "Mojo") and
39+
(
40+
if exists(f.getInitializer())
41+
then
42+
// Only consider constant initial values, otherwise might not be possible to use @Parameter#defaultValue
43+
exists(CompileTimeConstantExpr initalizer | initalizer = f.getInitializer() |
44+
defaultValue = initalizer.(Literal).getValue() or
45+
defaultValue = initalizer.getStringValue() or
46+
defaultValue = initalizer.getIntValue().toString() or
47+
defaultValue = initalizer.getBooleanValue().toString()
48+
)
49+
else defaultValue = getDefaultValue(f.getType())
50+
) and
51+
// Ignore if a value is assigned outside the initializer
52+
not f.getAnAssignedValue() != f.getInitializer() and
53+
// Ignore if default value is empty string, because it cannot be represented with @Parameter#defaultValue (?)
54+
defaultValue != ""
55+
select parameterAnnotation, "Should specify defaultValue: " + defaultValue

0 commit comments

Comments
 (0)
Please sign in to comment.