|
17 | 17 |
|
18 | 18 | import java.util.ArrayList;
|
19 | 19 | import java.util.Collection;
|
| 20 | +import java.util.Collections; |
20 | 21 | import java.util.List;
|
21 | 22 | import java.util.Map;
|
22 | 23 | import java.util.Objects;
|
@@ -123,18 +124,20 @@ public ObjectNode serialize(Model model) {
|
123 | 124 | if (!shape.isMemberShape() && shapeFilter.test(shape)) {
|
124 | 125 | Node value = shape.accept(shapeSerializer);
|
125 | 126 | shapes.put(Node.from(shape.getId().toString()), value);
|
126 |
| - // Add any necessary apply statements to inherited mixin members that added traits. |
127 |
| - // Apply statements are used here instead of redefining members on structures because |
128 |
| - // apply statements are more resilient to change over time if the shapes targeted by |
| 127 | + // Add any necessary apply statements to inherited mixin members that added traits, but only if there |
| 128 | + // are actually traits to serialize. Apply statements are used here instead of redefining members on |
| 129 | + // structures because apply statements are more resilient to change over time if the shapes targeted by |
129 | 130 | // an inherited member changes.
|
130 | 131 | if (!shapeSerializer.mixinMemberTraits.isEmpty()) {
|
131 | 132 | for (MemberShape member : shapeSerializer.mixinMemberTraits) {
|
132 |
| - ObjectNode.Builder applyBuilder = Node.objectNodeBuilder(); |
133 |
| - applyBuilder.withMember("type", "apply"); |
134 |
| - shapes.put( |
135 |
| - Node.from(member.getId().toString()), |
136 |
| - serializeTraits(applyBuilder, member.getIntroducedTraits().values()).build() |
137 |
| - ); |
| 133 | + Map<StringNode, Node> introducedTraits = createIntroducedTraitsMap( |
| 134 | + member.getIntroducedTraits().values()); |
| 135 | + if (!introducedTraits.isEmpty()) { |
| 136 | + ObjectNode.Builder applyBuilder = Node.objectNodeBuilder(); |
| 137 | + applyBuilder.withMember("type", "apply"); |
| 138 | + ObjectNode traits = serializeTraits(applyBuilder, introducedTraits).build(); |
| 139 | + shapes.put(Node.from(member.getId().toString()), traits); |
| 140 | + } |
138 | 141 | }
|
139 | 142 | }
|
140 | 143 | }
|
@@ -258,20 +261,29 @@ public ModelSerializer build() {
|
258 | 261 | }
|
259 | 262 |
|
260 | 263 | private ObjectNode.Builder serializeTraits(ObjectNode.Builder builder, Collection<Trait> traits) {
|
| 264 | + return serializeTraits(builder, createIntroducedTraitsMap(traits)); |
| 265 | + } |
| 266 | + |
| 267 | + private ObjectNode.Builder serializeTraits(ObjectNode.Builder builder, Map<StringNode, Node> traits) { |
261 | 268 | if (!traits.isEmpty()) {
|
| 269 | + builder.withMember("traits", new ObjectNode(traits, SourceLocation.none())); |
| 270 | + } |
| 271 | + |
| 272 | + return builder; |
| 273 | + } |
| 274 | + |
| 275 | + private Map<StringNode, Node> createIntroducedTraitsMap(Collection<Trait> traits) { |
| 276 | + if (traits.isEmpty()) { |
| 277 | + return Collections.emptyMap(); |
| 278 | + } else { |
262 | 279 | Map<StringNode, Node> traitsToAdd = new TreeMap<>();
|
263 | 280 | for (Trait trait : traits) {
|
264 | 281 | if (traitFilter.test(trait)) {
|
265 | 282 | traitsToAdd.put(Node.from(trait.toShapeId().toString()), trait.toNode());
|
266 | 283 | }
|
267 | 284 | }
|
268 |
| - |
269 |
| - if (!traitsToAdd.isEmpty()) { |
270 |
| - builder.withMember("traits", new ObjectNode(traitsToAdd, SourceLocation.none())); |
271 |
| - } |
| 285 | + return traitsToAdd; |
272 | 286 | }
|
273 |
| - |
274 |
| - return builder; |
275 | 287 | }
|
276 | 288 |
|
277 | 289 | private final class ShapeSerializer extends ShapeVisitor.Default<Node> {
|
|
0 commit comments