updated finalguard to use plugin arguments instead of system properties

This commit is contained in:
2026-02-18 08:31:09 +08:00
parent 91cf489630
commit c5dcee554e
3 changed files with 53 additions and 124 deletions

View File

@@ -25,37 +25,29 @@ import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.ExecutableElement;
import javax.tools.Diagnostic;
import java.util.AbstractMap;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.*;
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 DEFAULT_LEVEL_KEY = "default.level";
public static final String IGNORE_ABSTRACT_METHOD_PARAMS_KEY = "net.woggioni.finalguard.ignore.abstract.method.params";
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) {
@@ -92,11 +84,18 @@ public class FinalGuardPlugin implements Plugin {
private static final class Configuration {
private final Map<VariableType, Diagnostic.Kind> levels;
public Configuration() {
public Configuration(final String... args) {
final Map<String, String> props = new HashMap<>();
for (final String arg : args) {
final String[] parts = arg.split("=", 2);
if (parts.length == 2) {
props.put(parts[0], parts[1]);
}
}
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 {
@@ -110,7 +109,6 @@ public class FinalGuardPlugin implements Plugin {
return System.getProperty("java.version").compareTo("17") >= 0;
}
private static final Configuration configuration = new Configuration();
private static final boolean isJava17OrHigher = isJava17OrHigher();
@Override
@@ -120,6 +118,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 +127,14 @@ 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) {
FinalVariableAnalyzer analyzer = new FinalVariableAnalyzer(compilationUnit, task, configuration);
TreePath path = Trees.instance(task).getPath(typeElement);
if (path != null) {
analyzer.scan(path, null);
@@ -143,12 +142,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);
}

View File

@@ -7,39 +7,16 @@ 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 {
@@ -112,10 +89,9 @@ public class PluginTest {
.map(SourceFile::new).collect(Collectors.toList());
List<String> arguments = Arrays.asList(
"-classpath", System.getProperty("test.compilation.classpath"),
"-Xplugin:" + FinalGuardPlugin.class.getName()
"-Xplugin:" + FinalGuardPlugin.class.getName() + " " + FinalGuardPlugin.DEFAULT_LEVEL_KEY + "=ERROR"
);
final ArrayList<Diagnostic<? extends JavaFileObject>> compilerMessages = new ArrayList<>();
System.setProperty(FinalGuardPlugin.DIAGNOSTIC_LEVEL_KEY, "ERROR");
JavaCompiler.CompilationTask task = compiler.getTask(
output,
fileManager,

View File

@@ -15,13 +15,12 @@ import org.gradle.api.tasks.compile.JavaCompile;
import javax.tools.Diagnostic;
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";
@Override
public void apply(final Project project) {
@@ -54,70 +53,23 @@ public class FinalGuardPlugin implements Plugin<Project> {
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 Property<Diagnostic.Kind> localVariableLevel = finalGuardExtension.getLocalVariableLevel();
if (localVariableLevel.isPresent()) {
final Diagnostic.Kind diagnosticKind = localVariableLevel.get();
setProperty.accept("local.variable.level", diagnosticKind);
}
}
{
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");
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());
options.getCompilerArgs().add(xpluginArg.toString());
});
});
}
private static void appendOption(StringBuilder sb, String key, Property<Diagnostic.Kind> property) {
if (property.isPresent()) {
sb.append(' ').append(key).append('=').append(property.get());
}
}
}