Skip to content

Commit 0f10790

Browse files
authored
Fix trait codegen to support lists of enums (#2420)
Corrects 2 related bugs that were preventing enum list traits from being correctly generated: 1. Added `this` to a number of builder setter values to avoid clashes 2. Add missing `fromNode` method to nested enums so that can correctly be created by array node consumer.
1 parent 0291f02 commit 0f10790

File tree

8 files changed

+67
-4
lines changed

8 files changed

+67
-4
lines changed

smithy-trait-codegen/src/it/java/software/amazon/smithy/traitcodegen/test/CreatesTraitTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.example.traits.defaults.StructDefaultsTrait;
77
import com.example.traits.documents.DocumentTrait;
88
import com.example.traits.documents.StructWithNestedDocumentTrait;
9+
import com.example.traits.enums.EnumListMemberTrait;
910
import com.example.traits.enums.IntEnumTrait;
1011
import com.example.traits.enums.StringEnumTrait;
1112
import com.example.traits.enums.SuitTrait;
@@ -74,6 +75,9 @@ static Stream<Arguments> createTraitTests() {
7475
Arguments.of(StringEnumTrait.ID, Node.from("no")),
7576
Arguments.of(IntEnumTrait.ID, Node.from(2)),
7677
Arguments.of(SuitTrait.ID, Node.from("clubs")),
78+
Arguments.of(EnumListMemberTrait.ID, ObjectNode.objectNodeBuilder()
79+
.withMember("value", ArrayNode.fromStrings("some", "none", "some"))
80+
.build()),
7781
// Lists
7882
Arguments.of(NumberListTrait.ID, ArrayNode.fromNodes(
7983
Node.from(1), Node.from(2), Node.from(3))

smithy-trait-codegen/src/it/java/software/amazon/smithy/traitcodegen/test/LoadsFromModelTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
import com.example.traits.defaults.StructDefaultsTrait;
88
import com.example.traits.documents.DocumentTrait;
99
import com.example.traits.documents.StructWithNestedDocumentTrait;
10+
import com.example.traits.enums.EnumListMemberTrait;
1011
import com.example.traits.enums.IntEnumTrait;
12+
import com.example.traits.enums.SomeEnum;
1113
import com.example.traits.enums.StringEnumTrait;
1214
import com.example.traits.enums.SuitTrait;
1315
import com.example.traits.idref.IdRefListTrait;
@@ -95,6 +97,8 @@ static Stream<Arguments> loadsModelTests() {
9597
MapUtils.of("getValue", 1, "getEnumValue", IntEnumTrait.IntEnum.YES)),
9698
Arguments.of("enums/string-enum-compatibility.smithy", SuitTrait.class,
9799
MapUtils.of("getEnumValue", SuitTrait.Suit.CLUB, "getValue", "club")),
100+
Arguments.of("enums/enum-list-member-trait.smithy", EnumListMemberTrait.class,
101+
MapUtils.of("getValue", Optional.of(ListUtils.of(SomeEnum.SOME, SomeEnum.NONE, SomeEnum.SOME)))),
98102
// Id Refs
99103
Arguments.of("idref/idref-string.smithy", IdRefStringTrait.class,
100104
MapUtils.of("getValue", TARGET_ONE)),
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
$version: "2.0"
2+
3+
namespace test.smithy.traitcodegen
4+
5+
use test.smithy.traitcodegen.enums#EnumListMemberTrait
6+
7+
@EnumListMemberTrait(value: ["some", "none", "some"])
8+
structure myStruct {}

smithy-trait-codegen/src/main/java/software/amazon/smithy/traitcodegen/generators/BuilderGenerator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,22 +272,22 @@ public Void listShape(ListShape shape) {
272272

273273
// Clear all
274274
writer.openBlock("public Builder clear$U() {", "}", memberName, () -> {
275-
writer.write("$L.get().clear();", memberName);
275+
writer.write("this.$L.get().clear();", memberName);
276276
writer.writeWithNoFormatting("return this;");
277277
}).newLine();
278278

279279
// Set one
280280
writer.openBlock("public Builder add$U($T value) {", "}",
281281
memberName, symbolProvider.toSymbol(shape.getMember()), () -> {
282-
writer.write("$L.get().add(value);", memberName);
282+
writer.write("this.$L.get().add(value);", memberName);
283283
writer.write("return this;");
284284
}).newLine();
285285

286286
// Remove one
287287
writer.openBlock("public Builder remove$U($T value) {", "}",
288288
memberName, symbolProvider.toSymbol(shape.getMember()),
289289
() -> {
290-
writer.write("$L.get().remove(value);", memberName);
290+
writer.write("this.$L.get().remove(value);", memberName);
291291
writer.write("return this;");
292292
}).newLine();
293293
return null;

smithy-trait-codegen/src/main/java/software/amazon/smithy/traitcodegen/generators/FromNodeGenerator.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import software.amazon.smithy.model.shapes.TimestampShape;
3737
import software.amazon.smithy.model.shapes.UnionShape;
3838
import software.amazon.smithy.model.traits.TimestampFormatTrait;
39+
import software.amazon.smithy.traitcodegen.SymbolProperties;
3940
import software.amazon.smithy.traitcodegen.TraitCodegenUtils;
4041
import software.amazon.smithy.traitcodegen.writer.TraitCodegenWriter;
4142
import software.amazon.smithy.utils.StringUtils;
@@ -106,6 +107,34 @@ public Void stringShape(StringShape shape) {
106107
return null;
107108
}
108109

110+
@Override
111+
public Void enumShape(EnumShape shape) {
112+
// Enum traits do not need this method, only nested enums.
113+
if (symbol.getProperty(SymbolProperties.BASE_SYMBOL).isPresent()) {
114+
return null;
115+
}
116+
writeFromNodeJavaDoc();
117+
writer.openBlock("public static $T fromNode($T node) {", "}", symbol, Node.class, () -> {
118+
writer.write("return from(node.expectStringNode().getValue());");
119+
});
120+
writer.newLine();
121+
return null;
122+
}
123+
124+
@Override
125+
public Void intEnumShape(IntEnumShape shape) {
126+
// Enum traits do not need this method, only nested enums.
127+
if (symbol.getProperty(SymbolProperties.BASE_SYMBOL).isPresent()) {
128+
return null;
129+
}
130+
writeFromNodeJavaDoc();
131+
writer.openBlock("public static $T fromNode($T node) {", "}", symbol, Node.class, () -> {
132+
writer.writeWithNoFormatting("return from(node.expectNumberNode().getValue().intValue());");
133+
});
134+
writer.newLine();
135+
return null;
136+
}
137+
109138
@Override
110139
protected Void numberShape(NumberShape shape) {
111140
// Number shapes do not create a from node method

smithy-trait-codegen/src/test/java/software/amazon/smithy/traitcodegen/TraitCodegenPluginTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929

3030
public class TraitCodegenPluginTest {
31-
private static final int EXPECTED_NUMBER_OF_FILES = 58;
31+
private static final int EXPECTED_NUMBER_OF_FILES = 60;
3232

3333
private MockManifest manifest;
3434
private Model model;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
$version: "2.0"
2+
3+
namespace test.smithy.traitcodegen.enums
4+
5+
@trait(selector: "structure")
6+
structure EnumListMemberTrait {
7+
value: EnumList
8+
}
9+
10+
list EnumList {
11+
member: SomeEnum
12+
}
13+
14+
enum SomeEnum {
15+
SOME = "some"
16+
NONE = "none"
17+
}

smithy-trait-codegen/src/test/resources/META-INF/smithy/manifest

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ documents/struct-with-nested-document.smithy
44
enums/enum-trait.smithy
55
enums/int-enum-trait.smithy
66
enums/string-enum-compatibility.smithy
7+
enums/enum-list-member-trait.smithy
78
idref/idref-list.smithy
89
idref/idref-map.smithy
910
idref/idref-string.smithy

0 commit comments

Comments
 (0)