io.codemodder.ParameterModule Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of codemodder-base Show documentation
Show all versions of codemodder-base Show documentation
Base framework for writing codemods in Java
package io.codemodder;
import com.google.inject.AbstractModule;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Responsible for binding {@link Parameter}s to codemods. Also performs validation to ensure
* provided arguments are valid.
*/
final class ParameterModule extends AbstractModule {
private final List parameterArguments;
private final List injectableParameters;
ParameterModule(
final List codemodParameters,
final List injectableParameters) {
this.parameterArguments = Objects.requireNonNull(codemodParameters);
this.injectableParameters = Objects.requireNonNull(injectableParameters);
}
@Override
protected void configure() {
// this code is a little confusing to read because the collision between the
// java.lang.reflect.Parameter and io.codemodder.Parameter
List codemodParameters =
this.injectableParameters.stream()
.filter(param -> param.isAnnotationPresent(CodemodParameter.class))
.filter(param -> param.getType().equals(Parameter.class))
.toList();
for (java.lang.reflect.Parameter param : codemodParameters) {
CodemodParameter codemodParameter = param.getAnnotation(CodemodParameter.class);
Codemod codemod =
param.getDeclaringExecutable().getDeclaringClass().getAnnotation(Codemod.class);
ParameterArgument parameterArgument =
parameterArguments.stream()
.filter(p -> p.codemodId().equals(codemod.id()))
.findFirst()
.orElse(null);
Parameter parameter;
if (parameterArgument != null) {
parameter = new GivenParameter(codemodParameter, parameterArgument);
} else {
parameter = new NoValueProvidedParameter(codemodParameter);
}
String defaultValue = parameter.getDefaultValue();
Pattern p = Pattern.compile(codemodParameter.validationPattern());
Matcher matcher = p.matcher(defaultValue);
if (!matcher.matches()) {
throw new IllegalArgumentException(
"invalid parameter default value: "
+ defaultValue
+ " for parameter: "
+ codemodParameter.name()
+ " in codemod: "
+ codemod.id()
+ " with validation pattern: "
+ codemodParameter.validationPattern());
}
bind(Parameter.class).annotatedWith(codemodParameter).toInstance(parameter);
}
}
/**
* This is the {@link Parameter} implementation for when no value is provided for a given
* parameter.
*/
private record NoValueProvidedParameter(CodemodParameter declaration) implements Parameter {
private NoValueProvidedParameter {
Objects.requireNonNull(declaration);
}
@Override
public String getQuestion() {
return declaration.question();
}
@Override
public String getType() {
return declaration.type().name().toLowerCase();
}
@Override
public String getName() {
return declaration.name();
}
@Override
public String getValue(final Path path, final int currentLine) {
return declaration.defaultValue();
}
@Override
public String getLabel() {
return declaration.label();
}
@Override
public String getDefaultValue() {
return declaration.defaultValue();
}
}
/**
* This is the {@link Parameter} implementation for when a value is provided for a given
* parameter.
*/
private record GivenParameter(CodemodParameter declaration, ParameterArgument parameterArgument)
implements Parameter {
private GivenParameter {
Objects.requireNonNull(declaration);
Objects.requireNonNull(parameterArgument);
}
@Override
public String getQuestion() {
return declaration.question();
}
@Override
public String getType() {
return declaration.type().name().toLowerCase();
}
@Override
public String getName() {
return declaration.name();
}
@Override
public String getValue(final Path path, final int currentLine) {
String file = parameterArgument.file();
Integer line = parameterArgument.line();
if (file == null && line == null) {
// this is a default value for the whole run, so we return that
return parameterArgument.value();
}
if (file == null || !file.equals(path.toString())) {
// the parameter doesn't cover this file, so we return the default value
return declaration.defaultValue();
} else {
// only return the value if the line isn't specified by the arg or it matches
if (line == null || line == currentLine) {
return parameterArgument.value();
}
}
// if our parameter doesn't match, we return the default value
return declaration.defaultValue();
}
@Override
public String getLabel() {
return declaration.label();
}
@Override
public String getDefaultValue() {
if (parameterArgument.file() == null && parameterArgument.line() == null) {
return parameterArgument.value();
}
return declaration.defaultValue();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy