Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix capacity for option names, deprecate parser constructor #37

Merged
merged 1 commit into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package net.jbock.writing;

import io.jbock.javapoet.ClassName;
import io.jbock.javapoet.FieldSpec;
import net.jbock.annotated.Option;
import net.jbock.annotated.Parameter;
import net.jbock.annotated.VarargsParameter;
Expand All @@ -13,18 +12,10 @@
import java.util.Optional;
import java.util.function.Supplier;

import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PRIVATE;
import static net.jbock.common.Constants.STRING;
import static net.jbock.common.Constants.mapOf;
import static net.jbock.common.Suppliers.memoize;

public final class CommandRepresentation {

private final Supplier<FieldSpec> optionNames = memoize(() -> FieldSpec.builder(
mapOf(STRING, optType()), "optionNames")
.addModifiers(PRIVATE, FINAL).build());

private final Supplier<ClassName> optType = memoize(() -> namedOptions().isEmpty() ?
ClassName.get(Void.class) : // javapoet #739
sourceElement().optionEnumType());
Expand Down Expand Up @@ -70,10 +61,6 @@ List<Mapping<Option>> namedOptions() {
return namedOptions;
}

FieldSpec optionNames() {
return optionNames.get();
}

/** Returns the type of the option enum. */
ClassName optType() {
return optType.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import net.jbock.model.Multiplicity;
import net.jbock.model.Parameter;

import javax.lang.model.element.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
Expand Down Expand Up @@ -48,6 +49,7 @@ final class CreateModelMethod extends HasCommandRepresentation {
.addStatement(joinByNewline(code))
.returns(CommandModel.class)
.addModifiers(sourceElement().accessModifiers())
.addModifiers(Modifier.STATIC)
.build();
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package net.jbock.writing;

import io.jbock.javapoet.ClassName;
import io.jbock.javapoet.FieldSpec;
import net.jbock.annotated.Option;
import net.jbock.annotated.Parameter;
import net.jbock.annotated.VarargsParameter;
Expand Down Expand Up @@ -31,10 +30,6 @@ final ClassName optType() {
return commandRepresentation.optType();
}

final FieldSpec optionNames() {
return commandRepresentation.optionNames();
}

final List<Mapping<Parameter>> positionalParameters() {
return commandRepresentation.positionalParameters();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

import static javax.lang.model.element.Modifier.PRIVATE;
import static javax.lang.model.element.Modifier.STATIC;
import static net.jbock.common.Constants.STRING;
import static net.jbock.common.Constants.mapOf;
import static net.jbock.common.Suppliers.memoize;

final class OptionNamesMethod extends HasCommandRepresentation {
Expand All @@ -25,15 +27,16 @@ final class OptionNamesMethod extends HasCommandRepresentation {

private final Supplier<MethodSpec> define = memoize(() -> {
ParameterSpec result = ParameterSpec.builder(
optionNames().type, "result").build();
mapOf(STRING, optType()), "result").build();
long mapSize = namedOptions().stream()
.map(Mapping::item)
.map(Option::names)
.map(List::size)
.mapToLong(i -> i)
.sum();
CodeBlock.Builder code = CodeBlock.builder();
code.addStatement("$T $N = new $T<>($L)", result.type, result, HashMap.class, mapSize);
int capacity = (int) (1 + Math.max(mapSize * 1.35, 15));
code.addStatement("$T $N = new $T<>($L)", result.type, result, HashMap.class, capacity);
for (Mapping<Option> namedOption : namedOptions()) {
for (String dashedName : namedOption.item().names()) {
code.addStatement("$N.put($S, $T.$L)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.function.Supplier;

import static javax.lang.model.element.Modifier.PRIVATE;
import static javax.lang.model.element.Modifier.STATIC;
import static net.jbock.common.Constants.mapOf;
import static net.jbock.common.Suppliers.memoize;

Expand Down Expand Up @@ -45,7 +46,7 @@ result, sourceElement().optionEnumType(),
return MethodSpec.methodBuilder("optionStates")
.addCode(code.build())
.returns(result.type)
.addModifiers(PRIVATE)
.addModifiers(PRIVATE, STATIC)
.build();
});

Expand Down
2 changes: 2 additions & 0 deletions compiler/src/main/java/net/jbock/writing/ParseMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.jbock.simple.Inject;
import net.jbock.util.ExFailure;

import javax.lang.model.element.Modifier;
import java.util.function.Supplier;

import static io.jbock.javapoet.ParameterSpec.builder;
Expand Down Expand Up @@ -57,6 +58,7 @@ EITHER, e, createModelMethod().get())
.returns(generatedTypes().parseResultType())
.addCode(code.build())
.addModifiers(sourceElement().accessModifiers())
.addModifiers(Modifier.STATIC)
.build();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import net.jbock.util.AtFileError;
import net.jbock.util.ParseRequest;

import javax.lang.model.element.Modifier;
import java.util.List;

import static io.jbock.javapoet.MethodSpec.methodBuilder;
Expand Down Expand Up @@ -77,6 +78,7 @@ MethodSpec define() {
return methodBuilder("parseOrExit").addParameter(args)
.addModifiers(sourceElement().accessModifiers())
.returns(generatedTypes.sourceElement().typeName())
.addModifiers(Modifier.STATIC)
.addCode(code.build())
.build();
}
Expand Down
11 changes: 8 additions & 3 deletions compiler/src/main/java/net/jbock/writing/ParserClass.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package net.jbock.writing;

import io.jbock.javapoet.AnnotationSpec;
import io.jbock.javapoet.MethodSpec;
import io.jbock.javapoet.TypeSpec;
import io.jbock.simple.Inject;

Expand Down Expand Up @@ -53,17 +55,20 @@ TypeSpec define() {
spec.addMethod(parseOrExitMethod.define());
}
if (!namedOptions().isEmpty()) {
spec.addField(optionNames().toBuilder()
.initializer("$N()", optionNamesMethod.get()).build());
spec.addMethod(optionNamesMethod.get());
spec.addMethod(optionStatesMethod.get());
spec.addType(optionEnum.define());
}

spec.addMethod(createModelMethod.get());
Modifier[] modifiers = sourceElement().accessModifiers().toArray(new Modifier[0]);
spec.addMethod(MethodSpec.constructorBuilder().addModifiers(modifiers)
.addJavadoc("Constructor is deprecated, use the static methods instead.")
.addAnnotation(AnnotationSpec.builder(Deprecated.class).addMember("forRemoval", "true").build())
.build());

return spec.addOriginatingElement(sourceElement().element())
.addModifiers(sourceElement().accessModifiers().toArray(new Modifier[0]))
.addModifiers(modifiers)
.addModifiers(Modifier.FINAL)
.addType(implClass.define())
.addAnnotation(generatedAnnotation.define()).build();
Expand Down
11 changes: 9 additions & 2 deletions compiler/src/main/java/net/jbock/writing/ParserTypeFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,22 @@
final class ParserTypeFactory extends HasCommandRepresentation {

private final OptionStatesMethod optionStatesMethod;
private final OptionNamesMethod optionNamesMethod;

@Inject
ParserTypeFactory(
CommandRepresentation commandRepresentation,
OptionStatesMethod optionStatesMethod) {
OptionStatesMethod optionStatesMethod,
OptionNamesMethod optionNamesMethod) {
super(commandRepresentation);
this.optionStatesMethod = optionStatesMethod;
this.optionNamesMethod = optionNamesMethod;
}

private final Supplier<ParserType> parserType = memoize(() -> {
CodeBlock optionNames = namedOptions().isEmpty() ?
CodeBlock.of("$T.of()", Map.class) :
CodeBlock.of("$N", optionNames());
CodeBlock.of("$N()", optionNamesMethod().get());
CodeBlock optionStates = namedOptions().isEmpty() ?
CodeBlock.of("$T.of()", Map.class) :
CodeBlock.of("$N()", optionStatesMethod().get());
Expand Down Expand Up @@ -61,4 +64,8 @@ ParserType get() {
private OptionStatesMethod optionStatesMethod() {
return optionStatesMethod;
}

private OptionNamesMethod optionNamesMethod() {
return optionNamesMethod;
}
}
8 changes: 4 additions & 4 deletions compiler/src/test/java/net/jbock/processor/BasicFullTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void testBasicGenerated() {
" comments = \"https://github.com/jbock-java/jbock\"",
")",
"final class ArgumentsParser {",
" Either<ParsingFailed, Arguments> parse(List<String> tokens) {",
" static Either<ParsingFailed, Arguments> parse(List<String> tokens) {",
" VarargsParameterParser<Void> parser = VarargsParameterParser.create(Map.of(), Map.of(), 0);",
" try {",
" parser.parse(tokens);",
Expand All @@ -54,7 +54,7 @@ void testBasicGenerated() {
" }",
" }",
"",
" CommandModel createModel() {",
" static CommandModel createModel() {",
" return CommandModel.builder()",
" .withProgramName(\"arguments\")",
" .addParameter(Parameter.builder(Multiplicity.REPEATABLE)",
Expand Down Expand Up @@ -118,7 +118,7 @@ void testPublicParser() {
" comments = \"https://github.com/jbock-java/jbock\"",
")",
"public final class ArgumentsParser {",
" public Either<ParsingFailed, Arguments> parse(List<String> tokens) {",
" public static Either<ParsingFailed, Arguments> parse(List<String> tokens) {",
" VarargsParameterParser<Void> parser = VarargsParameterParser.create(Map.of(), Map.of(), 0);",
" try {",
" parser.parse(tokens);",
Expand All @@ -128,7 +128,7 @@ void testPublicParser() {
" }",
" }",
"",
" public CommandModel createModel() {",
" public static CommandModel createModel() {",
" return CommandModel.builder()",
" .withProgramName(\"arguments\")",
" .addParameter(Parameter.builder(Multiplicity.REPEATABLE)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ void testBasicGenerated() {
" comments = \"https://github.com/jbock-java/jbock\"",
")",
"final class ArgumentsParser {",
" Either<ParsingFailed, Arguments> parse(List<String> tokens) {",
" static Either<ParsingFailed, Arguments> parse(List<String> tokens) {",
" VarargsParameterParser<Void> parser = VarargsParameterParser.create(Map.of(), Map.of(), 0);",
" try {",
" parser.parse(tokens);",
Expand All @@ -55,7 +55,7 @@ void testBasicGenerated() {
" }",
" }",
"",
" Arguments parseOrExit(String[] args) {",
" static Arguments parseOrExit(String[] args) {",
" if (args.length > 0 && \"--help\".equals(args[0])) {",
" StandardErrorHandler.builder().build()",
" .printUsageDocumentation(createModel());",
Expand All @@ -68,7 +68,7 @@ void testBasicGenerated() {
" });",
" }",
"",
" CommandModel createModel() {",
" static CommandModel createModel() {",
" return CommandModel.builder()",
" .withProgramName(\"arguments\")",
" .addParameter(Parameter.builder(Multiplicity.REPEATABLE)",
Expand Down Expand Up @@ -133,7 +133,7 @@ void testPublicParser() {
" comments = \"https://github.com/jbock-java/jbock\"",
")",
"public final class ArgumentsParser {",
" public Either<ParsingFailed, Arguments> parse(List<String> tokens) {",
" public static Either<ParsingFailed, Arguments> parse(List<String> tokens) {",
" VarargsParameterParser<Void> parser = VarargsParameterParser.create(Map.of(), Map.of(), 0);",
" try {",
" parser.parse(tokens);",
Expand All @@ -143,7 +143,7 @@ void testPublicParser() {
" }",
" }",
"",
" public Arguments parseOrExit(String[] args) {",
" public static Arguments parseOrExit(String[] args) {",
" if (args.length > 0 && \"--help\".equals(args[0])) {",
" StandardErrorHandler.builder().build()",
" .printUsageDocumentation(createModel());",
Expand All @@ -156,7 +156,7 @@ void testPublicParser() {
" });",
" }",
"",
" public CommandModel createModel() {",
" public static CommandModel createModel() {",
" return CommandModel.builder()",
" .withProgramName(\"arguments\")",
" .addParameter(Parameter.builder(Multiplicity.REPEATABLE)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ abstract static class Arguments {
}

public static void main(String[] arguments) {
Arguments args = new Main_ArgumentsParser().parseOrExit(arguments);
Arguments args = Main_ArgumentsParser.parseOrExit(arguments);
System.out.println("The file '" + args.file() + "' was provided and verbosity is set to '" + args.verbose() + "'.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@

class MainTest {

private final Main_ArgumentsParser parser = new Main_ArgumentsParser();

private final ParserTestFixture<Main.Arguments> f =
ParserTestFixture.create(parser::parse);
ParserTestFixture.create(Main_ArgumentsParser::parse);

@Test
void testMain() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@

class AdditionArgumentsTest {

private final AdditionArgumentsParser parser = new AdditionArgumentsParser();

private final ParserTestFixture<AdditionArguments> f =
ParserTestFixture.create(parser::parse);
ParserTestFixture.create(AdditionArgumentsParser::parse);

@Test
void optionalAbsent() {
Expand Down Expand Up @@ -48,7 +46,7 @@ void dashesIgnored() {
@Test
void testPrint() {
f.assertPrintsHelp(
parser.createModel(),
AdditionArgumentsParser.createModel(),
"\u001B[1mUSAGE\u001B[m",
" addition-arguments A B [C]",
"",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@

class AllCharactersArgumentsTest {

private final AllCharactersArgumentsParser parser = new AllCharactersArgumentsParser();

private final ParserTestFixture<AllCharactersArguments> f =
ParserTestFixture.create(parser::parse);
ParserTestFixture.create(AllCharactersArgumentsParser::parse);

@Test
void tests() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@

class AllDoublesArgumentsTest {

private final AllDoublesArgumentsParser parser = new AllDoublesArgumentsParser();

private final ParserTestFixture<AllDoublesArguments> f =
ParserTestFixture.create(parser::parse);
ParserTestFixture.create(AllDoublesArgumentsParser::parse);

@Test
void listOfInteger() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@

class AllFlagsArgumentsTest {

private final AllFlagsArgumentsParser parser = new AllFlagsArgumentsParser();

private final ParserTestFixture<AllFlagsArguments> f =
ParserTestFixture.create(parser::parse);
ParserTestFixture.create(AllFlagsArgumentsParser::parse);

@Test
void tests() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@

class AllFloatsArgumentsTest {

private final AllFloatsArgumentsParser parser = new AllFloatsArgumentsParser();

private final ParserTestFixture<AllFloatsArguments> f =
ParserTestFixture.create(parser::parse);
ParserTestFixture.create(AllFloatsArgumentsParser::parse);

@Test
void listOfInteger() {
Expand Down
Loading
Loading