smaller methods
This commit is contained in:
parent
b383d83bf4
commit
8e50444ba6
|
@ -26,10 +26,9 @@ public class SampleJavacPlugin implements Plugin {
|
||||||
public static final String NAME = "MyPlugin";
|
public static final String NAME = "MyPlugin";
|
||||||
|
|
||||||
private static Set<String> TARGET_TYPES = new HashSet<>(Arrays.asList(
|
private static Set<String> TARGET_TYPES = new HashSet<>(Arrays.asList(
|
||||||
// Use only primitive types for simplicity
|
// Use only primitive types for simplicity
|
||||||
byte.class.getName(), short.class.getName(), char.class.getName(), int.class.getName(),
|
byte.class.getName(), short.class.getName(), char.class.getName(),
|
||||||
long.class.getName(), float.class.getName(), double.class.getName()
|
int.class.getName(), long.class.getName(), float.class.getName(), double.class.getName()));
|
||||||
));
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
@ -49,34 +48,35 @@ public class SampleJavacPlugin implements Plugin {
|
||||||
if (e.getKind() != TaskEvent.Kind.PARSE) {
|
if (e.getKind() != TaskEvent.Kind.PARSE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.getCompilationUnit().accept(new TreeScanner<Void, Void>() {
|
e.getCompilationUnit()
|
||||||
@Override
|
.accept(new TreeScanner<Void, Void>() {
|
||||||
public Void visitMethod(MethodTree method, Void v) {
|
@Override
|
||||||
List<VariableTree> parametersToInstrument = method.getParameters()
|
public Void visitMethod(MethodTree method, Void v) {
|
||||||
.stream()
|
List<VariableTree> parametersToInstrument = method.getParameters()
|
||||||
.filter(SampleJavacPlugin.this::shouldInstrument)
|
.stream()
|
||||||
.collect(Collectors.toList());
|
.filter(SampleJavacPlugin.this::shouldInstrument)
|
||||||
if (!parametersToInstrument.isEmpty()) {
|
.collect(Collectors.toList());
|
||||||
// There is a possible case that more than one argument is marked by @Positive,
|
if (!parametersToInstrument.isEmpty()) {
|
||||||
// as the checks are added to the method's body beginning, we process parameters RTL
|
// There is a possible case that more than one argument is marked by @Positive,
|
||||||
// to ensure correct order.
|
// as the checks are added to the method's body beginning, we process parameters RTL
|
||||||
Collections.reverse(parametersToInstrument);
|
// to ensure correct order.
|
||||||
parametersToInstrument.forEach(p -> addCheck(method, p, context));
|
Collections.reverse(parametersToInstrument);
|
||||||
|
parametersToInstrument.forEach(p -> addCheck(method, p, context));
|
||||||
|
}
|
||||||
|
// There is a possible case that there is a nested class declared in a method's body,
|
||||||
|
// hence, we want to proceed with method body AST as well.
|
||||||
|
return super.visitMethod(method, v);
|
||||||
}
|
}
|
||||||
// There is a possible case that there is a nested class declared in a method's body,
|
}, null);
|
||||||
// hence, we want to proceed with method body AST as well.
|
|
||||||
return super.visitMethod(method, v);
|
|
||||||
}
|
|
||||||
}, null);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldInstrument(VariableTree parameter) {
|
private boolean shouldInstrument(VariableTree parameter) {
|
||||||
return TARGET_TYPES.contains(parameter.getType().toString())
|
return TARGET_TYPES.contains(parameter.getType().toString())
|
||||||
&& parameter.getModifiers().getAnnotations()
|
&& parameter.getModifiers().getAnnotations()
|
||||||
.stream()
|
.stream()
|
||||||
.anyMatch(a -> Positive.class.getSimpleName().equals(a.getAnnotationType().toString()));
|
.anyMatch(a -> Positive.class.getSimpleName().equals(a.getAnnotationType().toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCheck(MethodTree method, VariableTree parameter, Context context) {
|
private void addCheck(MethodTree method, VariableTree parameter, Context context) {
|
||||||
|
@ -88,37 +88,36 @@ public class SampleJavacPlugin implements Plugin {
|
||||||
private static JCTree.JCIf createCheck(VariableTree parameter, Context context) {
|
private static JCTree.JCIf createCheck(VariableTree parameter, Context context) {
|
||||||
TreeMaker factory = TreeMaker.instance(context);
|
TreeMaker factory = TreeMaker.instance(context);
|
||||||
Names symbolsTable = Names.instance(context);
|
Names symbolsTable = Names.instance(context);
|
||||||
String parameterName = parameter.getName().toString();
|
|
||||||
String errorMessagePrefix = String.format("Argument '%s' of type %s is marked by @%s but got '",
|
return factory.at(((JCTree) parameter).pos)
|
||||||
parameterName, parameter.getType(), Positive.class.getSimpleName());
|
.If(factory.Parens(createIfCondition(factory, symbolsTable, parameter)),
|
||||||
String errorMessageSuffix = "' for it";
|
createIfBlock(factory, symbolsTable, parameter),
|
||||||
Name parameterId = symbolsTable.fromString(parameterName);
|
null);
|
||||||
return factory.at(((JCTree) parameter).pos).If(
|
|
||||||
factory.Parens(
|
|
||||||
factory.Binary(
|
|
||||||
JCTree.Tag.LE,
|
|
||||||
factory.Ident(parameterId),
|
|
||||||
factory.Literal(TypeTag.INT, 0))
|
|
||||||
),
|
|
||||||
factory.Block(0, com.sun.tools.javac.util.List.of(
|
|
||||||
factory.Throw(
|
|
||||||
factory.NewClass(
|
|
||||||
null,
|
|
||||||
nil(),
|
|
||||||
factory.Ident(
|
|
||||||
symbolsTable.fromString(IllegalArgumentException.class.getSimpleName())
|
|
||||||
),
|
|
||||||
com.sun.tools.javac.util.List.of(
|
|
||||||
factory.Binary(JCTree.Tag.PLUS,
|
|
||||||
factory.Binary(JCTree.Tag.PLUS,
|
|
||||||
factory.Literal(TypeTag.CLASS, errorMessagePrefix),
|
|
||||||
factory.Ident(parameterId)),
|
|
||||||
factory.Literal(TypeTag.CLASS, errorMessageSuffix))),
|
|
||||||
null
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)),
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static JCTree.JCBinary createIfCondition(TreeMaker factory, Names symbolsTable, VariableTree parameter) {
|
||||||
|
Name parameterId = symbolsTable.fromString(parameter.getName().toString());
|
||||||
|
return factory.Binary(JCTree.Tag.LE,
|
||||||
|
factory.Ident(parameterId),
|
||||||
|
factory.Literal(TypeTag.INT, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JCTree.JCBlock createIfBlock(TreeMaker factory, Names symbolsTable, VariableTree parameter) {
|
||||||
|
String parameterName = parameter.getName().toString();
|
||||||
|
Name parameterId = symbolsTable.fromString(parameterName);
|
||||||
|
|
||||||
|
String errorMessagePrefix = String.format("Argument '%s' of type %s is marked by @%s but got '",
|
||||||
|
parameterName, parameter.getType(), Positive.class.getSimpleName());
|
||||||
|
String errorMessageSuffix = "' for it";
|
||||||
|
|
||||||
|
return factory.Block(0, com.sun.tools.javac.util.List.of(
|
||||||
|
factory.Throw(
|
||||||
|
factory.NewClass(null, nil(),
|
||||||
|
factory.Ident(symbolsTable.fromString(IllegalArgumentException.class.getSimpleName())),
|
||||||
|
com.sun.tools.javac.util.List.of(factory.Binary(JCTree.Tag.PLUS,
|
||||||
|
factory.Binary(JCTree.Tag.PLUS, factory.Literal(TypeTag.CLASS, errorMessagePrefix),
|
||||||
|
factory.Ident(parameterId)),
|
||||||
|
factory.Literal(TypeTag.CLASS, errorMessageSuffix))), null))));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue