updated finalguard to use plugin arguments instead of system properties
This commit is contained in:
@@ -25,37 +25,29 @@ import javax.lang.model.element.Element;
|
|||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import java.util.AbstractMap;
|
import java.util.*;
|
||||||
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.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class FinalGuardPlugin implements Plugin {
|
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";
|
public static final String IGNORE_ABSTRACT_METHOD_PARAMS_KEY = "net.woggioni.finalguard.ignore.abstract.method.params";
|
||||||
|
|
||||||
enum VariableType {
|
enum VariableType {
|
||||||
LOCAL_VAR("net.woggioni.finalguard.diagnostic.local.variable.level"),
|
LOCAL_VAR("local.variable.level"),
|
||||||
METHOD_PARAM("net.woggioni.finalguard.diagnostic.method.param.level"),
|
METHOD_PARAM("method.param.level"),
|
||||||
LOOP_PARAM("net.woggioni.finalguard.diagnostic.for.param.level"),
|
LOOP_PARAM("for.param.level"),
|
||||||
TRY_WITH_PARAM("net.woggioni.finalguard.diagnostic.try.param.level"),
|
TRY_WITH_PARAM("try.param.level"),
|
||||||
CATCH_PARAM("net.woggioni.finalguard.diagnostic.catch.param.level"),
|
CATCH_PARAM("catch.param.level"),
|
||||||
LAMBDA_PARAM("net.woggioni.finalguard.diagnostic.lambda.param.level"),
|
LAMBDA_PARAM("lambda.param.level"),
|
||||||
ABSTRACT_METHOD_PARAM("net.woggioni.finalguard.diagnostic.abstract.method.param.level");
|
ABSTRACT_METHOD_PARAM("abstract.method.param.level");
|
||||||
|
|
||||||
private final String propertyKey;
|
private final String argKey;
|
||||||
|
|
||||||
VariableType(final String propertyKey) {
|
VariableType(final String argKey) {
|
||||||
this.propertyKey = propertyKey;
|
this.argKey = argKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPropertyKey() {
|
public String getArgKey() {
|
||||||
return propertyKey;
|
return argKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMessage(final String variableName) {
|
public String getMessage(final String variableName) {
|
||||||
@@ -92,11 +84,18 @@ public class FinalGuardPlugin implements Plugin {
|
|||||||
private static final class Configuration {
|
private static final class Configuration {
|
||||||
private final Map<VariableType, Diagnostic.Kind> levels;
|
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 =
|
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 -> {
|
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) {
|
if (level != null) {
|
||||||
return new AbstractMap.SimpleEntry<>(vt, level);
|
return new AbstractMap.SimpleEntry<>(vt, level);
|
||||||
} else {
|
} else {
|
||||||
@@ -110,7 +109,6 @@ public class FinalGuardPlugin implements Plugin {
|
|||||||
return System.getProperty("java.version").compareTo("17") >= 0;
|
return System.getProperty("java.version").compareTo("17") >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Configuration configuration = new Configuration();
|
|
||||||
private static final boolean isJava17OrHigher = isJava17OrHigher();
|
private static final boolean isJava17OrHigher = isJava17OrHigher();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -120,6 +118,7 @@ public class FinalGuardPlugin implements Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(JavacTask task, String... args) {
|
public void init(JavacTask task, String... args) {
|
||||||
|
final Configuration configuration = new Configuration(args);
|
||||||
task.addTaskListener(new TaskListener() {
|
task.addTaskListener(new TaskListener() {
|
||||||
@Override
|
@Override
|
||||||
public void started(TaskEvent e) {
|
public void started(TaskEvent e) {
|
||||||
@@ -128,14 +127,14 @@ public class FinalGuardPlugin implements Plugin {
|
|||||||
@Override
|
@Override
|
||||||
public void finished(TaskEvent e) {
|
public void finished(TaskEvent e) {
|
||||||
if (e.getKind() == TaskEvent.Kind.ANALYZE) {
|
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) {
|
private void analyzeFinalVariables(CompilationUnitTree compilationUnit, JavacTask task, Element typeElement, Configuration configuration) {
|
||||||
FinalVariableAnalyzer analyzer = new FinalVariableAnalyzer(compilationUnit, task);
|
FinalVariableAnalyzer analyzer = new FinalVariableAnalyzer(compilationUnit, task, configuration);
|
||||||
TreePath path = Trees.instance(task).getPath(typeElement);
|
TreePath path = Trees.instance(task).getPath(typeElement);
|
||||||
if (path != null) {
|
if (path != null) {
|
||||||
analyzer.scan(path, null);
|
analyzer.scan(path, null);
|
||||||
@@ -143,12 +142,14 @@ public class FinalGuardPlugin implements Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class FinalVariableAnalyzer extends TreePathScanner<Void, Void> {
|
private static class FinalVariableAnalyzer extends TreePathScanner<Void, Void> {
|
||||||
|
private final Configuration configuration;
|
||||||
private final CompilationUnitTree compilationUnit;
|
private final CompilationUnitTree compilationUnit;
|
||||||
private final Trees trees;
|
private final Trees trees;
|
||||||
private final Map<String, VariableInfo> variableInfoMap = new LinkedHashMap<>();
|
private final Map<String, VariableInfo> variableInfoMap = new LinkedHashMap<>();
|
||||||
private final Set<String> reassignedVariables = new HashSet<>();
|
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.compilationUnit = compilationUnit;
|
||||||
this.trees = Trees.instance(task);
|
this.trees = Trees.instance(task);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,39 +7,16 @@ import org.junit.jupiter.params.provider.Arguments;
|
|||||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||||
|
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.*;
|
||||||
import javax.tools.FileObject;
|
import java.io.*;
|
||||||
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 java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
import static net.woggioni.finalguard.FinalGuardPlugin.VariableType.ABSTRACT_METHOD_PARAM;
|
import static net.woggioni.finalguard.FinalGuardPlugin.VariableType.*;
|
||||||
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;
|
|
||||||
|
|
||||||
public class PluginTest {
|
public class PluginTest {
|
||||||
|
|
||||||
@@ -112,10 +89,9 @@ public class PluginTest {
|
|||||||
.map(SourceFile::new).collect(Collectors.toList());
|
.map(SourceFile::new).collect(Collectors.toList());
|
||||||
List<String> arguments = Arrays.asList(
|
List<String> arguments = Arrays.asList(
|
||||||
"-classpath", System.getProperty("test.compilation.classpath"),
|
"-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<>();
|
final ArrayList<Diagnostic<? extends JavaFileObject>> compilerMessages = new ArrayList<>();
|
||||||
System.setProperty(FinalGuardPlugin.DIAGNOSTIC_LEVEL_KEY, "ERROR");
|
|
||||||
JavaCompiler.CompilationTask task = compiler.getTask(
|
JavaCompiler.CompilationTask task = compiler.getTask(
|
||||||
output,
|
output,
|
||||||
fileManager,
|
fileManager,
|
||||||
|
|||||||
@@ -15,13 +15,12 @@ import org.gradle.api.tasks.compile.JavaCompile;
|
|||||||
|
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.jar.Attributes;
|
import java.util.jar.Attributes;
|
||||||
import java.util.jar.Manifest;
|
import java.util.jar.Manifest;
|
||||||
|
|
||||||
public class FinalGuardPlugin implements Plugin<Project> {
|
public class FinalGuardPlugin implements Plugin<Project> {
|
||||||
private static final String FINALGUARD_PLUGIN_CONFIGURATION = "finalguard_plugin";
|
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
|
@Override
|
||||||
public void apply(final Project project) {
|
public void apply(final Project project) {
|
||||||
@@ -54,70 +53,23 @@ public class FinalGuardPlugin implements Plugin<Project> {
|
|||||||
tasks.withType(JavaCompile.class, javaCompileTask -> {
|
tasks.withType(JavaCompile.class, javaCompileTask -> {
|
||||||
javaCompileTask.doFirst(t -> {
|
javaCompileTask.doFirst(t -> {
|
||||||
final CompileOptions options = javaCompileTask.getOptions();
|
final CompileOptions options = javaCompileTask.getOptions();
|
||||||
final BiConsumer<String, Diagnostic.Kind> setProperty = (key, diagnosticKind) -> {
|
final StringBuilder xpluginArg = new StringBuilder("-Xplugin:").append(JAVAC_PLUGIN_NAME);
|
||||||
final String propertyKey = PROPERTY_PREFIX + key;
|
appendOption(xpluginArg, "default.level", finalGuardExtension.getDefaultLevel());
|
||||||
System.setProperty(propertyKey, diagnosticKind.toString());
|
appendOption(xpluginArg, "local.variable.level", finalGuardExtension.getLocalVariableLevel());
|
||||||
options.getForkOptions().getJvmArgs().add(String.format("-D%s=%s", propertyKey, diagnosticKind));
|
appendOption(xpluginArg, "method.param.level", finalGuardExtension.getMethodParameterLevel());
|
||||||
};
|
appendOption(xpluginArg, "abstract.method.param.level", finalGuardExtension.getAbstractMethodParameterLevel());
|
||||||
options.setAnnotationProcessorPath(options.getAnnotationProcessorPath().plus(javacPluginConfiguration));
|
appendOption(xpluginArg, "for.param.level", finalGuardExtension.getForLoopParameterLevel());
|
||||||
{
|
appendOption(xpluginArg, "try.param.level", finalGuardExtension.getTryWithResourceLevel());
|
||||||
final Property<Diagnostic.Kind> defaultLevel = finalGuardExtension.getDefaultLevel();
|
appendOption(xpluginArg, "catch.param.level", finalGuardExtension.getCatchParameterLevel());
|
||||||
if (defaultLevel.isPresent()) {
|
appendOption(xpluginArg, "lambda.param.level", finalGuardExtension.getLambdaParameterLevel());
|
||||||
final Diagnostic.Kind diagnosticKind = defaultLevel.get();
|
options.getCompilerArgs().add(xpluginArg.toString());
|
||||||
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");
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void appendOption(StringBuilder sb, String key, Property<Diagnostic.Kind> property) {
|
||||||
|
if (property.isPresent()) {
|
||||||
|
sb.append(' ').append(key).append('=').append(property.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user