99
1010import java .util .Locale ;
1111import java .util .Objects ;
12+ import java .util .Optional ;
1213import java .util .logging .Logger ;
1314import software .amazon .smithy .codegen .core .Symbol ;
1415import software .amazon .smithy .codegen .core .SymbolProvider ;
1718import software .amazon .smithy .model .shapes .ServiceShape ;
1819import software .amazon .smithy .model .shapes .Shape ;
1920import software .amazon .smithy .model .shapes .ShapeVisitor ;
21+ import software .amazon .smithy .model .shapes .StructureShape ;
2022import software .amazon .smithy .model .traits .StringTrait ;
2123import software .amazon .smithy .model .traits .TitleTrait ;
2224import software .amazon .smithy .utils .SmithyUnstableApi ;
25+ import software .amazon .smithy .utils .StringUtils ;
2326
2427/**
2528 * Creates documentation Symbols for each shape in the model.
3134 * <li>{@code name}: The name of the symbol will be used as the title for its
3235 * definition section. For services, this defaults to the value of the
3336 * {@code title} trait. For other shapes, it defaults to the shape name including
34- * any renames from the attached service. For members, the member name is appended
35- * to the parent with a separating {@code -}.
37+ * any renames from the attached service.
3638 * <li>{@code definitionFile}: The file in which the documentation for this shape
3739 * should be written. By default these are all written to a single flat directory.
38- * If this is empty, the shape does not have its own definition section.
40+ * If this is empty, the shape does not have its own definition section and cannot
41+ * be linked to.
3942 * <li>{@link #SHAPE_PROPERTY}: A named Shape property containing the shape that
4043 * the symbol represents. Decorators provided by
4144 * {@link DocIntegration#decorateSymbolProvider} MUST set or preserve this
@@ -128,23 +131,39 @@ public Symbol serviceShape(ServiceShape shape) {
128131 .build ();
129132 }
130133
134+ @ Override
135+ public Symbol structureShape (StructureShape shape ) {
136+ return getSymbolBuilder (shape )
137+ .definitionFile (getDefinitionFile (serviceShape , shape ))
138+ .build ();
139+ }
140+
141+ @ Override
142+ public Symbol memberShape (MemberShape shape ) {
143+ var builder = getSymbolBuilder (shape )
144+ .definitionFile (getDefinitionFile (serviceShape , model .expectShape (shape .getId ().withoutMember ())));
145+
146+ Optional <String > containerLinkId = model .expectShape (shape .getContainer ())
147+ .accept (this )
148+ .getProperty (LINK_ID_PROPERTY , String .class );
149+ if (containerLinkId .isPresent ()) {
150+ var linkId = containerLinkId .get () + "-" + getLinkId (getShapeName (serviceShape , shape ));
151+ builder .putProperty (LINK_ID_PROPERTY , linkId );
152+ }
153+ return builder .build ();
154+ }
155+
131156 private Symbol .Builder getSymbolBuilder (Shape shape ) {
132157 var name = getShapeName (serviceShape , shape );
133158 return Symbol .builder ()
134- .name (name )
135- .putProperty (SHAPE_PROPERTY , shape )
136- .definitionFile (getDefinitionFile (serviceShape , shape ))
137- .putProperty (LINK_ID_PROPERTY , getLinkId (name ))
138- .putProperty (ENABLE_DEFAULT_FILE_EXTENSION , true );
159+ .name (name )
160+ .putProperty (SHAPE_PROPERTY , shape )
161+ .putProperty (LINK_ID_PROPERTY , getLinkId (name ))
162+ .putProperty (ENABLE_DEFAULT_FILE_EXTENSION , true );
139163 }
140164
141165 private String getDefinitionFile (ServiceShape serviceShape , Shape shape ) {
142- if (shape .isMemberShape ()) {
143- return getDefinitionFile (serviceShape , model .expectShape (shape .getId ().withoutMember ()));
144- }
145- return getDefinitionFile (
146- getShapeName (serviceShape , shape ).replaceAll ("\\ s+" , "" )
147- );
166+ return getDefinitionFile (getShapeName (serviceShape , shape ).replaceAll ("\\ s+" , "" ));
148167 }
149168
150169 private String getDefinitionFile (String filename ) {
@@ -157,11 +176,11 @@ private String getShapeName(ServiceShape serviceShape, Shape shape) {
157176 .map (StringTrait ::getValue )
158177 .orElse (shape .getId ().getName ());
159178 }
160- var name = shape .getId ().getName (serviceShape );
161179 if (shape .isMemberShape ()) {
162- name += "-" + toMemberName (shape .asMemberShape ().get ());
180+ return toMemberName (shape .asMemberShape ().get ());
181+ } else {
182+ return shape .getId ().getName (serviceShape );
163183 }
164- return name ;
165184 }
166185
167186 private String getLinkId (String shapeName ) {
@@ -172,7 +191,7 @@ private String getLinkId(String shapeName) {
172191 // have impact.
173192 @ Override
174193 protected Symbol getDefault (Shape shape ) {
175- return null ;
194+ return getSymbolBuilder ( shape ). build () ;
176195 }
177196
178197 /**
@@ -209,7 +228,7 @@ public Symbol toSymbol(Shape shape) {
209228 }
210229
211230 private String addExtension (String path ) {
212- if (!path .endsWith (extension )) {
231+ if (!StringUtils . isBlank ( path ) && ! path .endsWith (extension )) {
213232 path += extension ;
214233 }
215234 return path ;
0 commit comments