|
| 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" |
0 commit comments