Skip to content

Fix trait codegen for list with uniqueitems trait #2706

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
Expand Up @@ -25,10 +25,12 @@
import com.example.traits.lists.DocumentListTrait;
import com.example.traits.lists.ListMember;
import com.example.traits.lists.NestedListTrait;
import com.example.traits.lists.NestedUniqueItemsListTrait;
import com.example.traits.lists.NumberListTrait;
import com.example.traits.lists.StructureListTrait;
import com.example.traits.maps.MapValue;
import com.example.traits.maps.NestedMapTrait;
import com.example.traits.maps.NestedStringUniqueItemMapTrait;
import com.example.traits.maps.StringDocumentMapTrait;
import com.example.traits.maps.StringStringMapTrait;
import com.example.traits.maps.StringToStructMapTrait;
Expand All @@ -48,6 +50,7 @@
import com.example.traits.structures.NestedA;
import com.example.traits.structures.NestedB;
import com.example.traits.structures.StructWithListOfMapTrait;
import com.example.traits.structures.StructWithUniqueItemsListTrait;
import com.example.traits.structures.StructureTrait;
import com.example.traits.timestamps.DateTimeTimestampTrait;
import com.example.traits.timestamps.EpochSecondsTimestampTrait;
Expand Down Expand Up @@ -162,6 +165,10 @@ static Stream<Arguments> loadsModelTests() {
NestedListTrait.class,
MapUtils.of("getValues",
ListUtils.of(ListUtils.of(ListUtils.of("a"))))),
Arguments.of("lists/nested-uniqueitems-list-trait.smithy",
NestedUniqueItemsListTrait.class,
MapUtils.of("getValues",
ListUtils.of(ListUtils.of(ListUtils.of("a"), ListUtils.of("b"))))),
// Maps
Arguments.of("maps/string-string-map-trait.smithy",
StringStringMapTrait.class,
Expand Down Expand Up @@ -202,6 +209,15 @@ static Stream<Arguments> loadsModelTests() {
MapUtils.of(
"c",
"d"))))),
Arguments.of("maps/nested-string-uniqueitems-map-trait.smithy",
NestedStringUniqueItemMapTrait.class,
MapUtils.of("getValues",
MapUtils.of(
"a",
SetUtils.of(
MapUtils.of(
"b",
"c"))))),
// Mixins
Arguments.of("mixins/struct-with-mixin-member.smithy",
StructureListWithMixinMemberTrait.class,
Expand Down Expand Up @@ -310,6 +326,13 @@ static Stream<Arguments> loadsModelTests() {
Optional.of(
ListUtils.of(
MapUtils.of("b", "c"))))),
Arguments.of("structures/struct-with-uniqueitems-list-trait.smithy",
StructWithUniqueItemsListTrait.class,
MapUtils.of(
"getName",
Optional.of("a"),
"getItems",
Optional.of(SetUtils.of("b", "c")))),
// Timestamps
Arguments.of("timestamps/struct-with-nested-timestamps.smithy",
StructWithNestedTimestampsTrait.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
$version: "2.0"

namespace test.smithy.traitcodegen

use test.smithy.traitcodegen.lists#NestedUniqueItemsListTrait

@NestedUniqueItemsListTrait([[["a"],["b"]]])
structure myStruct {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
$version: "2.0"

namespace test.smithy.traitcodegen

use test.smithy.traitcodegen.maps#NestedStringUniqueItemMapTrait


@NestedStringUniqueItemMapTrait({a:[{b:"c"}]})
structure myStruct {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
$version: "2.0"

namespace test.smithy.traitcodegen
use test.smithy.traitcodegen.structures#StructWithUniqueItemsListTrait

@StructWithUniqueItemsListTrait(name:"a",items:["b","c"])
structure myStruct {
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package software.amazon.smithy.traitcodegen.generators;

import java.time.Instant;
import java.util.HashSet;
import java.util.Iterator;
import software.amazon.smithy.codegen.core.Symbol;
import software.amazon.smithy.codegen.core.SymbolProvider;
Expand Down Expand Up @@ -35,6 +36,7 @@
import software.amazon.smithy.model.shapes.TimestampShape;
import software.amazon.smithy.model.shapes.UnionShape;
import software.amazon.smithy.model.traits.TimestampFormatTrait;
import software.amazon.smithy.model.traits.UniqueItemsTrait;
import software.amazon.smithy.traitcodegen.SymbolProperties;
import software.amazon.smithy.traitcodegen.TraitCodegenUtils;
import software.amazon.smithy.traitcodegen.writer.TraitCodegenWriter;
Expand Down Expand Up @@ -251,10 +253,19 @@ public Void booleanShape(BooleanShape shape) {

@Override
public Void listShape(ListShape shape) {
writer.writeInline(memberPrefix + "ArrayMember($1S, n -> $3C, builder::$2L)",
fieldName,
memberName,
(Runnable) () -> shape.getMember().accept(new FromNodeMapperVisitor(writer, model, "n", 1)));
if (shape.hasTrait(UniqueItemsTrait.ID)) {
writer.writeInline(memberPrefix + "ArrayMember($1S, n -> $3C, l -> builder.$2L(new $4T<>(l)))",
fieldName,
memberName,
(Runnable) () -> shape.getMember().accept(new FromNodeMapperVisitor(writer, model, "n", 1)),
HashSet.class);
} else {
writer.writeInline(memberPrefix + "ArrayMember($1S, n -> $3C, builder::$2L)",
fieldName,
memberName,
(Runnable) () -> shape.getMember().accept(new FromNodeMapperVisitor(writer, model, "n", 1)));
}

return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import software.amazon.smithy.model.shapes.UnionShape;
import software.amazon.smithy.model.traits.IdRefTrait;
import software.amazon.smithy.model.traits.TimestampFormatTrait;
import software.amazon.smithy.model.traits.UniqueItemsTrait;
import software.amazon.smithy.traitcodegen.TraitCodegenUtils;
import software.amazon.smithy.traitcodegen.writer.TraitCodegenWriter;

Expand Down Expand Up @@ -78,7 +79,11 @@ public Void listShape(ListShape shape) {
if (nestedLevel == 0) { // Triggered when shape is a member.
writer.writeWithNoFormatting(".forEach(builder::addValues);");
} else { // Triggered when shape is nested.
writer.write(".collect($T.toList())", Collectors.class);
if (shape.hasTrait(UniqueItemsTrait.ID)) {
writer.write(".collect($T.toSet())", Collectors.class);
} else {
writer.write(".collect($T.toList())", Collectors.class);
}
}
writer.dedent();
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import software.amazon.smithy.model.shapes.StringShape;
import software.amazon.smithy.model.shapes.StructureShape;
import software.amazon.smithy.model.shapes.TimestampShape;
import software.amazon.smithy.model.traits.UniqueItemsTrait;
import software.amazon.smithy.traitcodegen.TraitCodegenUtils;
import software.amazon.smithy.traitcodegen.sections.GetterSection;
import software.amazon.smithy.traitcodegen.writer.TraitCodegenWriter;
Expand Down Expand Up @@ -139,14 +140,17 @@ public Void structureShape(StructureShape shape) {
Shape target = model.expectShape(member.getTarget());
boolean isListShape = target.isListShape();
if (isListShape || target.isMapShape()) {
// If the target list has @uniqueItems, we should create emptySet
String emptyListOrSet =
isListShape && target.hasTrait(UniqueItemsTrait.ID) ? "emptySet" : "emptyList";
writer.openBlock("public $T get$UOrEmpty() {",
"}",
symbolProvider.toSymbol(member),
symbolProvider.toMemberName(member),
() -> writer.write("return $1L == null ? $2T.$3L() : $1L;",
symbolProvider.toMemberName(member),
Collections.class,
isListShape ? "emptyList" : "emptyMap"));
isListShape ? emptyListOrSet : "emptyMap"));
}
} else {
writer.openBlock("public $T get$U() {",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import software.amazon.smithy.model.node.ObjectNode;

public class TraitCodegenPluginTest {
private static final int EXPECTED_NUMBER_OF_FILES = 64;
private static final int EXPECTED_NUMBER_OF_FILES = 67;

private MockManifest manifest;
private Model model;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
$version: "2.0"

namespace test.smithy.traitcodegen.lists


@trait
@uniqueItems
list NestedUniqueItemsListTrait {
member:UniqueItemsList
}

@uniqueItems
list UniqueItemsList {
member: UniqueItemsListEntry
}

@uniqueItems
list UniqueItemsListEntry {
member: String
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ lists/struct-list-trait.smithy
lists/document-list-trait.smithy
lists/nested-list-trait.smithy
lists/nested-boolean-list-trait.smithy
lists/nested-uniqueitems-list-trait.smithy
maps/string-string-map-trait.smithy
maps/string-to-struct-map-trait.smithy
maps/string-to-document-map-trait.smithy
maps/nested-map-trait.smithy
maps/nested-string-uniqueitems-map-trait.smithy
mixins/struct-with-mixin-member.smithy
mixins/struct-with-only-mixin-member.smithy
names/snake-case-structure.smithy
Expand All @@ -39,6 +41,7 @@ string-trait.smithy
structures/annotation-trait.smithy
structures/structure-trait.smithy
structures/struct-with-listofmap-trait.smithy
structures/struct-with-uniqueitems-list-trait.smithy
timestamps/date-time-format-timestamp-trait.smithy
timestamps/epoch-seconds-format-timestamp-trait.smithy
timestamps/http-date-format-timestamp-trait.smithy
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
$version: "2.0"

namespace test.smithy.traitcodegen.maps

@trait
map NestedStringUniqueItemMapTrait {
key: String
value: UniqueItemsList
}

@uniqueItems
list UniqueItemsList{
member: UniqueItemsMapEntry
}

map UniqueItemsMapEntry {
key: String
value: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
$version: "2.0"

namespace test.smithy.traitcodegen.structures

@trait
structure StructWithUniqueItemsListTrait {
name: String
items: UniqueItemsList
}

@uniqueItems
list UniqueItemsList {
member: String
}
Loading