Repository: smithy-lang/smithy
Pull request #2328 (2024-06-14 13:01:04)

Add useSymbolWriter function
This adds a method to the `WriterDelegator` to check out a writer from a symbol. This saves on a good amount of space when writing opening files to write, for example, private helper functions that are defined as symbols attached to shape symbols via properties.

---
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.



Patch:
diff --git a/smithy-codegen-core/src/main/java/software/amazon/smithy/codegen/core/WriterDelegator.java b/smithy-codegen-core/src/main/java/software/amazon/smithy/codegen/core/WriterDelegator.java
index 0156be49c..31492a473 100644
--- a/smithy-codegen-core/src/main/java/software/amazon/smithy/codegen/core/WriterDelegator.java
+++ b/smithy-codegen-core/src/main/java/software/amazon/smithy/codegen/core/WriterDelegator.java
@@ -176,8 +176,7 @@ public class WriterDelegator<W extends SymbolWriter<W, ? extends ImportContainer
     }
 
     /**
-     * Gets or creates a writer for a {@link Shape} by converting the {@link Shape}
-     * to a {@code Symbol}.
+     * Gets or creates a writer for a {@link Symbol}.
      *
      * <p>Any dependencies (i.e., {@link SymbolDependency}) required by the
      * {@code Symbol} are automatically registered with the writer.
@@ -190,14 +189,10 @@ public class WriterDelegator<W extends SymbolWriter<W, ? extends ImportContainer
      * the writer (either a newline or whatever value was set on
      * {@link #setAutomaticSeparator}).
      *
-     * <p>This method may be overridden as needed.
-     *
-     * @param shape Shape to create the writer for.
+     * @param symbol Symbol to create the writer for.
      * @param writerConsumer Consumer that is expected to write to the {@code SymbolWriter}.
      */
-    public void useShapeWriter(Shape shape, Consumer<W> writerConsumer) {
-        // Checkout/create the appropriate writer for the shape.
-        Symbol symbol = symbolProvider.toSymbol(shape);
+    public final void useSymbolWriter(Symbol symbol, Consumer<W> writerConsumer) {
         W writer = checkoutWriter(symbol.getDefinitionFile(), symbol.getNamespace());
 
         // Add any needed DECLARE symbols.
@@ -209,6 +204,31 @@ public class WriterDelegator<W extends SymbolWriter<W, ? extends ImportContainer
         writer.popState();
     }
 
+    /**
+     * Gets or creates a writer for a {@link Shape} by converting the {@link Shape}
+     * to a {@code Symbol}.
+     *
+     * <p>Any dependencies (i.e., {@link SymbolDependency}) required by the
+     * {@code Symbol} are automatically registered with the writer.
+     *
+     * <p>Any imports required to declare the {@code Symbol} in code (i.e.,
+     * {@link SymbolReference.ContextOption#DECLARE}) are automatically
+     * registered with the writer.
+     *
+     * <p>If a writer already exists, a newline is automatically appended to
+     * the writer (either a newline or whatever value was set on
+     * {@link #setAutomaticSeparator}).
+     *
+     * <p>This method may be overridden as needed.
+     *
+     * @param shape Shape to create the writer for.
+     * @param writerConsumer Consumer that is expected to write to the {@code SymbolWriter}.
+     */
+    public void useShapeWriter(Shape shape, Consumer<W> writerConsumer) {
+        // Checkout/create the appropriate writer for the shape.
+        useSymbolWriter(symbolProvider.toSymbol(shape), writerConsumer);
+    }
+
     /**
      * Sets the automatic separator that is written to a {@code SymbolWriter}
      * each time the writer is reused.


Test patch:
diff --git a/smithy-codegen-core/src/test/java/software/amazon/smithy/codegen/core/WriterDelegatorTest.java b/smithy-codegen-core/src/test/java/software/amazon/smithy/codegen/core/WriterDelegatorTest.java
index 4a5f48de0..b1ed5400a 100644
--- a/smithy-codegen-core/src/test/java/software/amazon/smithy/codegen/core/WriterDelegatorTest.java
+++ b/smithy-codegen-core/src/test/java/software/amazon/smithy/codegen/core/WriterDelegatorTest.java
@@ -47,6 +47,22 @@ public class WriterDelegatorTest {
         assertThat(delegator.getWriters(), hasKey(Paths.get("com/foo/Baz.bam").toString()));
     }
 
+    @Test
+    public void createsFilesForSymbolWriters() {
+        MockManifest mockManifest = new MockManifest();
+        SymbolProvider provider = (shape) -> null;
+        WriterDelegator<MySimpleWriter> delegator = new WriterDelegator<>(
+                mockManifest, provider, (f, n) -> new MySimpleWriter(n));
+        Symbol symbol =  Symbol.builder()
+                .namespace("com.foo", ".")
+                .name("Baz")
+                .definitionFile("com/foo/Baz.bam")
+                .build();
+        delegator.useSymbolWriter(symbol, writer -> { });
+
+        assertThat(delegator.getWriters(), hasKey(Paths.get("com/foo/Baz.bam").toString()));
+    }
+
     @Test
     public void aggregatesDependencies() {
         MockManifest mockManifest = new MockManifest();