Compare commits
5 Commits
b6c4cca2e7
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
85ca793893
|
|||
|
0ccffb0642
|
|||
|
1fe7ce65f6
|
|||
|
c5dcee554e
|
|||
|
91cf489630
|
@@ -4,12 +4,10 @@ on:
|
||||
branches: [ master ]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: hostinger
|
||||
runs-on: woryzen
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
- name: Execute Gradle build
|
||||
env:
|
||||
PUBLISHER_TOKEN: ${{ secrets.PUBLISHER_TOKEN }}
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ subprojects { subproject ->
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
languageVersion = JavaLanguageVersion.of(25)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ subprojects { subproject ->
|
||||
add("testImplementation", catalog.junit.jupiter.api)
|
||||
add("testImplementation", catalog.junit.jupiter.params)
|
||||
add("testRuntimeOnly", catalog.junit.jupiter.engine)
|
||||
// add("testRuntimeOnly", catalog.junit.platform.launcher)
|
||||
add("testRuntimeOnly", catalog.junit.platform.launcher)
|
||||
add("testImplementation", gradleTestKit())
|
||||
}
|
||||
|
||||
|
||||
+6
-7
@@ -20,8 +20,10 @@ import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.file.RegularFile;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.plugins.BasePluginExtension;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.plugins.JavaPluginConvention;
|
||||
import org.gradle.api.plugins.JavaPluginExtension;
|
||||
import org.gradle.api.plugins.ReportingBasePlugin;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Classpath;
|
||||
@@ -74,8 +76,6 @@ public class ExportDependencies extends DefaultTask {
|
||||
@Getter(onMethod_ = { @Input })
|
||||
private final Property<Boolean> showArtifacts;
|
||||
|
||||
private final JavaPluginConvention javaPluginConvention;
|
||||
|
||||
@InputFiles
|
||||
@Classpath
|
||||
public Provider<FileCollection> getConfigurationFiles() {
|
||||
@@ -101,11 +101,10 @@ public class ExportDependencies extends DefaultTask {
|
||||
@Inject
|
||||
public ExportDependencies(ObjectFactory objects) {
|
||||
setGroup(DEPENDENCY_EXPORT_GROUP);
|
||||
javaPluginConvention = getProject().getConvention().getPlugin(JavaPluginConvention.class);
|
||||
configurationName = objects.property(String.class).convention(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME);
|
||||
Provider<File> defaultOutputFileProvider =
|
||||
getProject().provider(() -> new File(javaPluginConvention.getDocsDir(), "dependencies.dot"));
|
||||
outputFile = objects.fileProperty().convention(getProject().getLayout().file(defaultOutputFileProvider));
|
||||
final JavaPluginExtension javaPluginExtension = getProject().getExtensions().findByType(JavaPluginExtension.class);
|
||||
final Provider<RegularFile> defaultOutputFileProvider = javaPluginExtension.getDocsDir().file("dependencies.dot");
|
||||
outputFile = objects.fileProperty().convention(defaultOutputFileProvider);
|
||||
showArtifacts = objects.property(Boolean.class).convention(false);
|
||||
}
|
||||
|
||||
|
||||
+4
-7
@@ -7,7 +7,7 @@ import org.gradle.api.GradleException;
|
||||
import org.gradle.api.file.RegularFile;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.plugins.JavaPluginConvention;
|
||||
import org.gradle.api.plugins.JavaPluginExtension;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.CacheableTask;
|
||||
@@ -59,8 +59,6 @@ public class RenderDependencies extends DefaultTask {
|
||||
return outputFile.map(RegularFile::getAsFile);
|
||||
}
|
||||
|
||||
private final JavaPluginConvention javaPluginConvention;
|
||||
|
||||
@Option(option = "output", description = "Set the output file name")
|
||||
public void setOutputCli(String outputFile) {
|
||||
Provider<File> fileProvider = getProject().provider(() -> new File(outputFile));
|
||||
@@ -81,12 +79,11 @@ public class RenderDependencies extends DefaultTask {
|
||||
public RenderDependencies(ObjectFactory objects) {
|
||||
setGroup(DEPENDENCY_EXPORT_GROUP);
|
||||
sourceFile = objects.property(File.class);
|
||||
javaPluginConvention = getProject().getConvention().getPlugin(JavaPluginConvention.class);
|
||||
format = objects.property(String.class).convention("xlib");
|
||||
graphvizExecutable = objects.property(String.class).convention("dot");
|
||||
Provider<File> defaultOutputFileProvider =
|
||||
getProject().provider(() -> new File(javaPluginConvention.getDocsDir(), "renderedDependencies"));
|
||||
outputFile = objects.fileProperty().convention(getProject().getLayout().file(defaultOutputFileProvider)
|
||||
final JavaPluginExtension javaPluginExtension = getProject().getExtensions().findByType(JavaPluginExtension.class);
|
||||
final Provider<RegularFile> defaultOutputFileProvider = javaPluginExtension.getDocsDir().file("renderedDependencies");
|
||||
outputFile = objects.fileProperty().convention(defaultOutputFileProvider
|
||||
.zip(format, (file, type) -> Objects.equals("xlib", type) ? null : file));
|
||||
getOutputs().upToDateWhen(t -> outputFile.isPresent());
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ plugins {
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ group = "net.woggioni.finalguard"
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
languageVersion = JavaLanguageVersion.of(25)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,19 @@ tasks.named(org.gradle.api.plugins.JavaPlugin.COMPILE_JAVA_TASK_NAME, JavaCompil
|
||||
options.compilerArgs << '-parameters'
|
||||
}
|
||||
|
||||
configurations {
|
||||
testCompileClasspath {
|
||||
attributes {
|
||||
attribute(org.gradle.api.attributes.java.TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 25)
|
||||
}
|
||||
}
|
||||
testRuntimeClasspath {
|
||||
attributes {
|
||||
attribute(org.gradle.api.attributes.java.TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 25)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
def testCompilationClassPath = sourceSets["main"].output.classesDirs.files +
|
||||
sourceSets["main"].runtimeClasspath.files +
|
||||
|
||||
+60
-23
@@ -21,14 +21,21 @@ import com.sun.source.util.TaskListener;
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.source.util.TreePathScanner;
|
||||
import com.sun.source.util.Trees;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.tools.Diagnostic;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
@@ -36,26 +43,26 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class FinalGuardPlugin implements Plugin {
|
||||
public static final String DIAGNOSTIC_LEVEL_KEY = "net.woggioni.finalguard.diagnostic.level";
|
||||
public static final String IGNORE_ABSTRACT_METHOD_PARAMS_KEY = "net.woggioni.finalguard.ignore.abstract.method.params";
|
||||
public static final String DEFAULT_LEVEL_KEY = "default.level";
|
||||
public static final String EXCLUDE_KEY = "exclude";
|
||||
|
||||
enum VariableType {
|
||||
LOCAL_VAR("net.woggioni.finalguard.diagnostic.local.variable.level"),
|
||||
METHOD_PARAM("net.woggioni.finalguard.diagnostic.method.param.level"),
|
||||
LOOP_PARAM("net.woggioni.finalguard.diagnostic.for.param.level"),
|
||||
TRY_WITH_PARAM("net.woggioni.finalguard.diagnostic.try.param.level"),
|
||||
CATCH_PARAM("net.woggioni.finalguard.diagnostic.catch.param.level"),
|
||||
LAMBDA_PARAM("net.woggioni.finalguard.diagnostic.lambda.param.level"),
|
||||
ABSTRACT_METHOD_PARAM("net.woggioni.finalguard.diagnostic.abstract.method.param.level");
|
||||
LOCAL_VAR("local.variable.level"),
|
||||
METHOD_PARAM("method.param.level"),
|
||||
LOOP_PARAM("for.param.level"),
|
||||
TRY_WITH_PARAM("try.param.level"),
|
||||
CATCH_PARAM("catch.param.level"),
|
||||
LAMBDA_PARAM("lambda.param.level"),
|
||||
ABSTRACT_METHOD_PARAM("abstract.method.param.level");
|
||||
|
||||
private final String propertyKey;
|
||||
private final String argKey;
|
||||
|
||||
VariableType(final String propertyKey) {
|
||||
this.propertyKey = propertyKey;
|
||||
VariableType(final String argKey) {
|
||||
this.argKey = argKey;
|
||||
}
|
||||
|
||||
public String getPropertyKey() {
|
||||
return propertyKey;
|
||||
public String getArgKey() {
|
||||
return argKey;
|
||||
}
|
||||
|
||||
public String getMessage(final String variableName) {
|
||||
@@ -91,12 +98,27 @@ public class FinalGuardPlugin implements Plugin {
|
||||
|
||||
private static final class Configuration {
|
||||
private final Map<VariableType, Diagnostic.Kind> levels;
|
||||
private final List<String> excludedPaths;
|
||||
|
||||
public Configuration() {
|
||||
public Configuration(final String... args) {
|
||||
final Map<String, String> props = new HashMap<>();
|
||||
final List<String> excluded = new ArrayList<>();
|
||||
for (final String arg : args) {
|
||||
final String[] parts = arg.split("=", 2);
|
||||
if (parts.length == 2) {
|
||||
if (EXCLUDE_KEY.equals(parts[0])) {
|
||||
final Path path = Paths.get(parts[1]);
|
||||
excluded.add(path.toAbsolutePath().toString());
|
||||
} else {
|
||||
props.put(parts[0], parts[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.excludedPaths = Collections.unmodifiableList(excluded);
|
||||
final Diagnostic.Kind defaultLevel =
|
||||
Optional.ofNullable(System.getProperty(DIAGNOSTIC_LEVEL_KEY)).map(Diagnostic.Kind::valueOf).orElse(null);
|
||||
Optional.ofNullable(props.get(DEFAULT_LEVEL_KEY)).map(Diagnostic.Kind::valueOf).orElse(null);
|
||||
this.levels = Arrays.stream(VariableType.values()).map(vt -> {
|
||||
final Diagnostic.Kind level = Optional.ofNullable(System.getProperty(vt.getPropertyKey())).map(Diagnostic.Kind::valueOf).orElse(defaultLevel);
|
||||
final Diagnostic.Kind level = Optional.ofNullable(props.get(vt.getArgKey())).map(Diagnostic.Kind::valueOf).orElse(defaultLevel);
|
||||
if (level != null) {
|
||||
return new AbstractMap.SimpleEntry<>(vt, level);
|
||||
} else {
|
||||
@@ -104,13 +126,21 @@ public class FinalGuardPlugin implements Plugin {
|
||||
}
|
||||
}).filter(Objects::nonNull).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
|
||||
public boolean isExcluded(final String sourcePath) {
|
||||
for (final String excludedPath : excludedPaths) {
|
||||
if (sourcePath.startsWith(excludedPath)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isJava17OrHigher() {
|
||||
return System.getProperty("java.version").compareTo("17") >= 0;
|
||||
}
|
||||
|
||||
private static final Configuration configuration = new Configuration();
|
||||
private static final boolean isJava17OrHigher = isJava17OrHigher();
|
||||
|
||||
@Override
|
||||
@@ -120,6 +150,7 @@ public class FinalGuardPlugin implements Plugin {
|
||||
|
||||
@Override
|
||||
public void init(JavacTask task, String... args) {
|
||||
final Configuration configuration = new Configuration(args);
|
||||
task.addTaskListener(new TaskListener() {
|
||||
@Override
|
||||
public void started(TaskEvent e) {
|
||||
@@ -128,14 +159,18 @@ public class FinalGuardPlugin implements Plugin {
|
||||
@Override
|
||||
public void finished(TaskEvent e) {
|
||||
if (e.getKind() == TaskEvent.Kind.ANALYZE) {
|
||||
analyzeFinalVariables(e.getCompilationUnit(), task, e.getTypeElement());
|
||||
analyzeFinalVariables(e.getCompilationUnit(), task, e.getTypeElement(), configuration);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void analyzeFinalVariables(CompilationUnitTree compilationUnit, JavacTask task, Element typeElement) {
|
||||
FinalVariableAnalyzer analyzer = new FinalVariableAnalyzer(compilationUnit, task);
|
||||
private void analyzeFinalVariables(CompilationUnitTree compilationUnit, JavacTask task, Element typeElement, Configuration configuration) {
|
||||
final String sourcePath = compilationUnit.getSourceFile().toUri().getPath();
|
||||
if (sourcePath != null && configuration.isExcluded(sourcePath)) {
|
||||
return;
|
||||
}
|
||||
FinalVariableAnalyzer analyzer = new FinalVariableAnalyzer(compilationUnit, task, configuration);
|
||||
TreePath path = Trees.instance(task).getPath(typeElement);
|
||||
if (path != null) {
|
||||
analyzer.scan(path, null);
|
||||
@@ -143,12 +178,14 @@ public class FinalGuardPlugin implements Plugin {
|
||||
}
|
||||
|
||||
private static class FinalVariableAnalyzer extends TreePathScanner<Void, Void> {
|
||||
private final Configuration configuration;
|
||||
private final CompilationUnitTree compilationUnit;
|
||||
private final Trees trees;
|
||||
private final Map<String, VariableInfo> variableInfoMap = new LinkedHashMap<>();
|
||||
private final Set<String> reassignedVariables = new HashSet<>();
|
||||
|
||||
public FinalVariableAnalyzer(CompilationUnitTree compilationUnit, JavacTask task) {
|
||||
public FinalVariableAnalyzer(CompilationUnitTree compilationUnit, JavacTask task, Configuration configuration) {
|
||||
this.configuration = configuration;
|
||||
this.compilationUnit = compilationUnit;
|
||||
this.trees = Trees.instance(task);
|
||||
}
|
||||
|
||||
+35
-29
@@ -1,45 +1,23 @@
|
||||
package net.woggioni.finalguard;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.ForwardingJavaFileManager;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.ToolProvider;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import javax.tools.*;
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static net.woggioni.finalguard.FinalGuardPlugin.VariableType.ABSTRACT_METHOD_PARAM;
|
||||
import static net.woggioni.finalguard.FinalGuardPlugin.VariableType.CATCH_PARAM;
|
||||
import static net.woggioni.finalguard.FinalGuardPlugin.VariableType.LAMBDA_PARAM;
|
||||
import static net.woggioni.finalguard.FinalGuardPlugin.VariableType.LOCAL_VAR;
|
||||
import static net.woggioni.finalguard.FinalGuardPlugin.VariableType.LOOP_PARAM;
|
||||
import static net.woggioni.finalguard.FinalGuardPlugin.VariableType.METHOD_PARAM;
|
||||
import static net.woggioni.finalguard.FinalGuardPlugin.VariableType.TRY_WITH_PARAM;
|
||||
import static net.woggioni.finalguard.FinalGuardPlugin.VariableType.*;
|
||||
|
||||
public class PluginTest {
|
||||
|
||||
@@ -104,18 +82,25 @@ public class PluginTest {
|
||||
}
|
||||
|
||||
private Optional<Iterable<Diagnostic<? extends JavaFileObject>>> compile(Iterable<URI> sources) {
|
||||
return compile(sources, "");
|
||||
}
|
||||
|
||||
private Optional<Iterable<Diagnostic<? extends JavaFileObject>>> compile(Iterable<URI> sources, String extraPluginArgs) {
|
||||
StringWriter output = new StringWriter();
|
||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||
FileManager fileManager =
|
||||
new FileManager(compiler.getStandardFileManager(null, null, null));
|
||||
List<JavaFileObject> compilationUnits = StreamSupport.stream(sources.spliterator(), false)
|
||||
.map(SourceFile::new).collect(Collectors.toList());
|
||||
String pluginArg = "-Xplugin:" + FinalGuardPlugin.class.getName() + " " + FinalGuardPlugin.DEFAULT_LEVEL_KEY + "=ERROR";
|
||||
if (!extraPluginArgs.isEmpty()) {
|
||||
pluginArg += " " + extraPluginArgs;
|
||||
}
|
||||
List<String> arguments = Arrays.asList(
|
||||
"-classpath", System.getProperty("test.compilation.classpath"),
|
||||
"-Xplugin:" + FinalGuardPlugin.class.getName()
|
||||
pluginArg
|
||||
);
|
||||
final ArrayList<Diagnostic<? extends JavaFileObject>> compilerMessages = new ArrayList<>();
|
||||
System.setProperty(FinalGuardPlugin.DIAGNOSTIC_LEVEL_KEY, "ERROR");
|
||||
JavaCompiler.CompilationTask task = compiler.getTask(
|
||||
output,
|
||||
fileManager,
|
||||
@@ -208,4 +193,25 @@ public class PluginTest {
|
||||
Assertions.assertTrue(compilationErrors.isEmpty(), "Unexpected compilation errors found in the output");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcludedSourceIsSkipped() throws Exception {
|
||||
// TestCase3 normally produces an error (local var 'n' not final).
|
||||
// When we exclude the directory containing TestCase3, it should compile without errors.
|
||||
ClassLoader cl = getClass().getClassLoader();
|
||||
URI sourceUri = cl.getResource("net/woggioni/finalguard/test/TestCase3.java").toURI();
|
||||
String sourcePath = new File(sourceUri).getParent();
|
||||
|
||||
// Compile WITH exclude — should succeed (no errors)
|
||||
Optional<Iterable<Diagnostic<? extends JavaFileObject>>> resultWithExclude =
|
||||
compile(Collections.singletonList(sourceUri), FinalGuardPlugin.EXCLUDE_KEY + "=" + sourcePath);
|
||||
Assertions.assertFalse(resultWithExclude.isPresent(),
|
||||
"Compilation should succeed when source directory is excluded");
|
||||
|
||||
// Compile WITHOUT exclude — should fail (TestCase3 has errors)
|
||||
Optional<Iterable<Diagnostic<? extends JavaFileObject>>> resultWithoutExclude =
|
||||
compile(Collections.singletonList(sourceUri));
|
||||
Assertions.assertTrue(resultWithoutExclude.isPresent(),
|
||||
"Compilation should fail when source directory is NOT excluded");
|
||||
}
|
||||
}
|
||||
|
||||
-2
@@ -1,4 +1,2 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
public record TestCase12<T, U>(double x, double y) {
|
||||
}
|
||||
-2
@@ -1,5 +1,3 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
public interface TestCase13 {
|
||||
void foo(double x, double y);
|
||||
}
|
||||
-2
@@ -1,5 +1,3 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
public abstract class TestCase14 {
|
||||
abstract public void foo(double x, double y);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.woggioni.gradle.finalguard;
|
||||
|
||||
import org.gradle.api.provider.ListProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
|
||||
import javax.tools.Diagnostic;
|
||||
@@ -21,4 +22,8 @@ public interface FinalGuardExtension {
|
||||
Property<Diagnostic.Kind> getAbstractMethodParameterLevel();
|
||||
|
||||
Property<Diagnostic.Kind> getCatchParameterLevel();
|
||||
|
||||
Property<Boolean> getSkipGeneratedSources();
|
||||
|
||||
ListProperty<String> getExcludedPrefixes();
|
||||
}
|
||||
|
||||
@@ -14,14 +14,15 @@ import org.gradle.api.tasks.compile.CompileOptions;
|
||||
import org.gradle.api.tasks.compile.JavaCompile;
|
||||
|
||||
import javax.tools.Diagnostic;
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
public class FinalGuardPlugin implements Plugin<Project> {
|
||||
private static final String FINALGUARD_PLUGIN_CONFIGURATION = "finalguard_plugin";
|
||||
private static final String PROPERTY_PREFIX = "net.woggioni.finalguard.diagnostic.";
|
||||
private static final String JAVAC_PLUGIN_NAME = "net.woggioni.finalguard.FinalGuardPlugin";
|
||||
private static final String EXCLUDE_KEY = "exclude";
|
||||
|
||||
@Override
|
||||
public void apply(final Project project) {
|
||||
@@ -50,74 +51,42 @@ public class FinalGuardPlugin implements Plugin<Project> {
|
||||
});
|
||||
|
||||
final FinalGuardExtension finalGuardExtension = objects.newInstance(FinalGuardExtension.class);
|
||||
extensionContainer.add("finalGuard", finalGuardExtension);
|
||||
finalGuardExtension.getSkipGeneratedSources().convention(true);
|
||||
extensionContainer.add("finalguard", finalGuardExtension);
|
||||
tasks.withType(JavaCompile.class, javaCompileTask -> {
|
||||
javaCompileTask.doFirst(t -> {
|
||||
final CompileOptions options = javaCompileTask.getOptions();
|
||||
final BiConsumer<String, Diagnostic.Kind> setProperty = (key, diagnosticKind) -> {
|
||||
final String propertyKey = PROPERTY_PREFIX + key;
|
||||
System.setProperty(propertyKey, diagnosticKind.toString());
|
||||
options.getForkOptions().getJvmArgs().add(String.format("-D%s=%s", propertyKey, diagnosticKind));
|
||||
};
|
||||
options.setAnnotationProcessorPath(options.getAnnotationProcessorPath().plus(javacPluginConfiguration));
|
||||
{
|
||||
final Property<Diagnostic.Kind> defaultLevel = finalGuardExtension.getDefaultLevel();
|
||||
if (defaultLevel.isPresent()) {
|
||||
final Diagnostic.Kind diagnosticKind = defaultLevel.get();
|
||||
setProperty.accept("level", diagnosticKind);
|
||||
final StringBuilder xpluginArg = new StringBuilder("-Xplugin:").append(JAVAC_PLUGIN_NAME);
|
||||
appendOption(xpluginArg, "default.level", finalGuardExtension.getDefaultLevel());
|
||||
appendOption(xpluginArg, "local.variable.level", finalGuardExtension.getLocalVariableLevel());
|
||||
appendOption(xpluginArg, "method.param.level", finalGuardExtension.getMethodParameterLevel());
|
||||
appendOption(xpluginArg, "abstract.method.param.level", finalGuardExtension.getAbstractMethodParameterLevel());
|
||||
appendOption(xpluginArg, "for.param.level", finalGuardExtension.getForLoopParameterLevel());
|
||||
appendOption(xpluginArg, "try.param.level", finalGuardExtension.getTryWithResourceLevel());
|
||||
appendOption(xpluginArg, "catch.param.level", finalGuardExtension.getCatchParameterLevel());
|
||||
appendOption(xpluginArg, "lambda.param.level", finalGuardExtension.getLambdaParameterLevel());
|
||||
if (finalGuardExtension.getSkipGeneratedSources().getOrElse(true)) {
|
||||
final File generatedSourceDir = project.getLayout().getBuildDirectory().getAsFile().get();
|
||||
if (generatedSourceDir != null) {
|
||||
appendOption(xpluginArg, EXCLUDE_KEY, generatedSourceDir.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
{
|
||||
final Property<Diagnostic.Kind> localVariableLevel = finalGuardExtension.getLocalVariableLevel();
|
||||
if (localVariableLevel.isPresent()) {
|
||||
final Diagnostic.Kind diagnosticKind = localVariableLevel.get();
|
||||
setProperty.accept("local.variable.level", diagnosticKind);
|
||||
}
|
||||
for(final String excludedPrefix : finalGuardExtension.getExcludedPrefixes().get()) {
|
||||
appendOption(xpluginArg, EXCLUDE_KEY, excludedPrefix);
|
||||
}
|
||||
{
|
||||
final Property<Diagnostic.Kind> methodParameterLevel = finalGuardExtension.getMethodParameterLevel();
|
||||
if (methodParameterLevel.isPresent()) {
|
||||
final Diagnostic.Kind diagnosticKind = methodParameterLevel.get();
|
||||
setProperty.accept("method.param.level", diagnosticKind);
|
||||
}
|
||||
}
|
||||
{
|
||||
final Property<Diagnostic.Kind> abstractMethodParameterLevel = finalGuardExtension.getAbstractMethodParameterLevel();
|
||||
if (abstractMethodParameterLevel.isPresent()) {
|
||||
final Diagnostic.Kind diagnosticKind = abstractMethodParameterLevel.get();
|
||||
setProperty.accept("abstract.method.param.level", diagnosticKind);
|
||||
}
|
||||
}
|
||||
{
|
||||
final Property<Diagnostic.Kind> forLoopParameterLevel = finalGuardExtension.getForLoopParameterLevel();
|
||||
if (forLoopParameterLevel.isPresent()) {
|
||||
final Diagnostic.Kind diagnosticKind = forLoopParameterLevel.get();
|
||||
setProperty.accept("for.param.level", diagnosticKind);
|
||||
}
|
||||
}
|
||||
{
|
||||
final Property<Diagnostic.Kind> tryParameterLevel = finalGuardExtension.getTryWithResourceLevel();
|
||||
if (tryParameterLevel.isPresent()) {
|
||||
final Diagnostic.Kind diagnosticKind = tryParameterLevel.get();
|
||||
setProperty.accept("try.param.level", diagnosticKind);
|
||||
}
|
||||
}
|
||||
{
|
||||
final Property<Diagnostic.Kind> catchParameterLevel = finalGuardExtension.getCatchParameterLevel();
|
||||
if (catchParameterLevel.isPresent()) {
|
||||
final Diagnostic.Kind diagnosticKind = catchParameterLevel.get();
|
||||
setProperty.accept("catch.param.level", diagnosticKind);
|
||||
}
|
||||
}
|
||||
{
|
||||
final Property<Diagnostic.Kind> lambdaParameterLevel = finalGuardExtension.getLambdaParameterLevel();
|
||||
if (lambdaParameterLevel.isPresent()) {
|
||||
final Diagnostic.Kind diagnosticKind = lambdaParameterLevel.get();
|
||||
setProperty.accept("lambda.param.level", diagnosticKind);
|
||||
}
|
||||
}
|
||||
options.getCompilerArgs().add("-Xplugin:net.woggioni.finalguard.FinalGuardPlugin");
|
||||
options.getCompilerArgs().add(xpluginArg.toString());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static void appendOption(StringBuilder sb, String key, String value) {
|
||||
sb.append(' ').append(key).append('=').append(value);
|
||||
}
|
||||
|
||||
private static void appendOption(StringBuilder sb, String key, Property<Diagnostic.Kind> property) {
|
||||
if (property.isPresent()) {
|
||||
appendOption(sb, key, property.get().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
lys.catalog.version=2025.11.18
|
||||
version.myGradlePlugins=2025.11.29
|
||||
version.gradle=8.12
|
||||
lys.catalog.version=2025.12.27
|
||||
version.myGradlePlugins=2026.02.23
|
||||
version.gradle=9.3.1
|
||||
|
||||
gitea.maven.url = https://gitea.woggioni.net/api/packages/woggioni/maven
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-all.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright © 2015 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -114,7 +114,6 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -172,7 +171,6 @@ fi
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
@@ -205,15 +203,14 @@ fi
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
|
||||
Vendored
+1
-2
@@ -70,11 +70,10 @@ goto fail
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
@@ -2,6 +2,12 @@ plugins {
|
||||
id 'groovy-gradle-plugin'
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility(JavaVersion.VERSION_1_8.toString())
|
||||
targetCompatibility(JavaVersion.VERSION_1_8.toString())
|
||||
modularity.inferModulePath = false
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
create("JPMSCheckPlugin") {
|
||||
|
||||
-2
@@ -10,7 +10,6 @@ import org.gradle.api.attributes.LibraryElements;
|
||||
import org.gradle.api.attributes.java.TargetJvmVersion;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.file.SourceDirectorySet;
|
||||
import org.gradle.api.internal.plugins.DslObject;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.plugins.JavaPluginExtension;
|
||||
import org.gradle.api.provider.MapProperty;
|
||||
@@ -167,7 +166,6 @@ public class MultiReleaseJarPlugin implements Plugin<Project> {
|
||||
"classes/" + mainSourceSet.getName() + "/" + sourceDirectorySet.getName())
|
||||
);
|
||||
sourcePaths.add(sourceDirectorySet.getSourceDirectories());
|
||||
new DslObject(mainSourceSet).getConvention().getPlugins().put(sourceDirectorySet.getName(), sourceDirectorySet);
|
||||
mainSourceSet.getExtensions().add(SourceDirectorySet.class, sourceDirectorySet.getName(), sourceDirectorySet);
|
||||
TaskProvider<JavaCompile> compileTask =
|
||||
project.getTasks().register(JavaPlugin.COMPILE_JAVA_TASK_NAME + javaVersion.getMajorVersion(), JavaCompile.class,
|
||||
|
||||
@@ -10,7 +10,6 @@ dependencyResolutionManagement {
|
||||
versionCatalogs {
|
||||
catalog {
|
||||
from group: 'com.lys', name: 'lys-catalog', version: getProperty('lys.catalog.version')
|
||||
version('junit.jupiter', '5.9.3')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user