net.jbock.context.StatefulParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jbock-compiler Show documentation
Show all versions of jbock-compiler Show documentation
jbock annotation processor
package net.jbock.context;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import net.jbock.annotated.AnnotatedOption;
import net.jbock.annotated.AnnotatedParameter;
import net.jbock.annotated.AnnotatedParameters;
import net.jbock.convert.Mapping;
import net.jbock.processor.SourceElement;
import javax.inject.Inject;
import java.util.List;
import static javax.lang.model.element.Modifier.PRIVATE;
import static javax.lang.model.element.Modifier.STATIC;
/**
* Defines the inner class StatefulParser
*/
@ContextScope
public class StatefulParser {
private final StatefulParseMethod statefulParseMethod;
private final GeneratedTypes generatedTypes;
private final SourceElement sourceElement;
private final List> namedOptions;
private final List> positionalParameters;
private final List> repeatablePositionalParameters;
private final CommonFields commonFields;
private final BuildMethod buildMethod;
private final TryParseOptionMethod tryParseOptionMethod;
private final ReadOptionNameMethod readOptionNameMethod;
@Inject
StatefulParser(
GeneratedTypes generatedTypes,
StatefulParseMethod statefulParseMethod,
SourceElement sourceElement,
List> namedOptions,
List> positionalParameters,
List> repeatablePositionalParameters,
CommonFields commonFields,
BuildMethod buildMethod,
TryParseOptionMethod tryParseOptionMethod,
ReadOptionNameMethod readOptionNameMethod) {
this.generatedTypes = generatedTypes;
this.statefulParseMethod = statefulParseMethod;
this.sourceElement = sourceElement;
this.namedOptions = namedOptions;
this.positionalParameters = positionalParameters;
this.repeatablePositionalParameters = repeatablePositionalParameters;
this.commonFields = commonFields;
this.buildMethod = buildMethod;
this.tryParseOptionMethod = tryParseOptionMethod;
this.readOptionNameMethod = readOptionNameMethod;
}
TypeSpec define() {
TypeSpec.Builder spec = TypeSpec.classBuilder(generatedTypes.statefulParserType())
.addModifiers(PRIVATE, STATIC)
.addMethod(statefulParseMethod.define());
spec.addField(commonFields.suspiciousPattern());
if (!namedOptions.isEmpty()) {
spec.addMethod(readOptionNameMethod.get());
spec.addMethod(tryParseOptionMethod.get());
spec.addMethod(privateConstructor());
spec.addField(commonFields.optionNames());
spec.addField(commonFields.optionParsers());
}
if (!positionalParameters.isEmpty()) {
spec.addField(commonFields.params());
}
if (!repeatablePositionalParameters.isEmpty() || sourceElement.isSuperCommand()) {
spec.addField(commonFields.rest());
}
spec.addMethod(buildMethod.get());
return spec.build();
}
private MethodSpec privateConstructor() {
CodeBlock.Builder code = CodeBlock.builder();
for (Mapping namedOption : namedOptions) {
String enumConstant = namedOption.enumName().enumConstant();
for (String dashedName : namedOption.sourceMethod().names()) {
code.addStatement("$N.put($S, $T.$L)",
commonFields.optionNames(), dashedName, sourceElement.optionEnumType(),
enumConstant);
}
code.addStatement("$N.put($T.$L, new $T())",
commonFields.optionParsers(), sourceElement.optionEnumType(),
enumConstant, optionParserType(namedOption));
}
return MethodSpec.constructorBuilder()
.addCode(code.build())
.build();
}
private ClassName optionParserType(Mapping param) {
if (param.isRepeatable()) {
return generatedTypes.repeatableOptionParserType();
}
if (param.modeFlag()) {
return generatedTypes.flagParserType();
}
return generatedTypes.regularOptionParserType();
}
}