|
| 1 | +/** |
| 2 | + * Finds configurations of the Maven Compiler Plugin which use `<source>` and `<target>` |
| 3 | + * instead of `<release>`. When building with JDK >= 9 (regardless of `<target>` version) |
| 4 | + * the `<release>` parameter should be preferred because it additionally ensures that |
| 5 | + * only API of that release is used, and not accidentally newer API when building with |
| 6 | + * a newer JDK (but targeting an older version). |
| 7 | + * |
| 8 | + * See also the [Maven Compiler Plugin documentation](https://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-release.html). |
| 9 | + * |
| 10 | + * @kind problem |
| 11 | + * @id TODO |
| 12 | + */ |
| 13 | + |
| 14 | +import java |
| 15 | +import lib.MavenLib |
| 16 | + |
| 17 | +class CompilerPluginElement extends PluginElement { |
| 18 | + CompilerPluginElement() { |
| 19 | + hasEffectiveCoordinates("org.apache.maven.plugins", "maven-compiler-plugin") |
| 20 | + } |
| 21 | +} |
| 22 | + |
| 23 | +from PomElement reportedElement, int targetVersion, string replacement |
| 24 | +where |
| 25 | + ( |
| 26 | + // Parameter in plugin configuration |
| 27 | + // TODO: Corrently does not work because this project here uses too old codeql Java library which contains |
| 28 | + // bug regarding `<target>` handling, see https://github.com/github/codeql/pull/15923/files#r2040662871 |
| 29 | + exists( |
| 30 | + CompilerPluginElement compilerPlugin, PomElement configElement, PomElement targetElement, |
| 31 | + string elementName, string replacementName |
| 32 | + | |
| 33 | + reportedElement = targetElement and |
| 34 | + ( |
| 35 | + elementName = "target" and replacementName = "release" |
| 36 | + or |
| 37 | + // Or `<testTarget>` for 'testCompile' goal |
| 38 | + elementName = "testTarget" and replacementName = "testRelease" |
| 39 | + ) |
| 40 | + | |
| 41 | + configElement = compilerPlugin.getAConfigElement() and |
| 42 | + targetElement = configElement.getAChild(elementName) and |
| 43 | + targetVersion = targetElement.getValue().toInt() and |
| 44 | + replacement = "`<" + replacementName + ">" + targetVersion + "</" + replacementName + ">`" and |
| 45 | + // And config does not additionally define 'release' parameter as well |
| 46 | + // (Note that in newer versions of the Maven Compiler Plugin, this will likely lead to a javac error, |
| 47 | + // see https://github.com/apache/maven-compiler-plugin/pull/271) |
| 48 | + not exists(configElement.getAChild(replacementName)) |
| 49 | + ) |
| 50 | + or |
| 51 | + // Or property setting plugin parameter value |
| 52 | + exists(Pom pom, PomProperty targetProperty, string propertyName, string replacementName | |
| 53 | + reportedElement = targetProperty and |
| 54 | + ( |
| 55 | + propertyName = "maven.compiler.target" and replacementName = "maven.compiler.release" |
| 56 | + or |
| 57 | + // Or `<maven.compiler.testTarget>` for 'testCompile' goal |
| 58 | + propertyName = "maven.compiler.testTarget" and |
| 59 | + replacementName = "maven.compiler.testRelease" |
| 60 | + ) |
| 61 | + | |
| 62 | + targetProperty = pom.getALocalProperty() and |
| 63 | + targetProperty.hasName(propertyName) and |
| 64 | + targetVersion = targetProperty.getValue().toInt() and |
| 65 | + replacement = "`<" + replacementName + ">" + targetVersion + "</" + replacementName + ">`" and |
| 66 | + // And properties do not additionally define 'release' property as well |
| 67 | + not pom.getALocalProperty().hasName(replacementName) |
| 68 | + ) |
| 69 | + ) and |
| 70 | + // If target is >= 9, then JDK must also be >= 9 and therefore supports `javac --release` |
| 71 | + targetVersion >= 9 |
| 72 | +select reportedElement, "Should instead use " + replacement |
0 commit comments