-
Notifications
You must be signed in to change notification settings - Fork 226
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
Add support for conditions and loops to AbstractCodeWriter #1144
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CodeWriter now supports Mustache-like behavior by allowing conditions and loops to be evaluated in templates. Note that this does disallow using '/', '?', '^', and '#' as formatters. Conditions are defined using `${?foo}` where "foo" is the writer named parameter to evaluate. `?` is used to check if a value is truthy. The following template with a "foo" value set to "Noid": ``` ${?foo} Hello, ${foo:L}! ${/foo} ``` Evaluates to: ``` Hello, Noid! ``` `^` can be used to check if a value is falsey. The following template with no set "baz" value: ``` ${baz} Yes baz ${/baz} ${^baz} No baz ${/baz} ``` Evaluates to: ``` No baz ``` A variable is falsey if it is Boolean false, an empty Iterable, an empty Optional, an empty Map, or an empty String. A variable is truthy if it is not falsey. If a conditional expression or loop expression is the non-whitespace text on a line and is immediately followed by a `\r` or `\n`, then the entire line is omitted from the output. Loops can be created using `${#foo}`. Each value contained in the referenced named parameter is sent through the contained templated one after the other. The following template with a "foo" value of ["a", "b"]: ``` ${#foo} - ${currentKey:L}: ${currentValue:L} ${/foo} ``` Evaluates to: ``` - 0: a - 1: b ``` Each iteration of the loop creates a new state in the writer that sets a named parameter named `currentKey` that contains the current index of the loop or the current key of a map entry; `currentValue` containing the current value of the iterable or current value of a map entry; `currentIsFirst` is set to true when the first value is being evaluated, and `currentIsLast` is set to true when the last value is being evaluated. ``` SimpleCodeWriter writer = new SimpleCodeWriter() .trimTrailingSpaces(false) .insertTrailingNewline(false); writer.putContext("foo", Arrays.asList("a", "b", "c")); writer.write(""" ${#foo} ${?currentIsFirst} [ ${/currentIsFirst} ${currentValue:L}${^currentIsLast},${/currentIsLast} ${?currentIsLast} ] ${/currentIsLast} ${/foo}"""); assertThat(writer.toString(), equalTo(""" [ a, b, c ] """); ```
I wonder if you could trim down some of the bloat from
|
?, #, /, and ^ are used for conditions and loops. Reserving ~ for potentially controlling whitespace in the future.
cff1e82
to
715b420
Compare
I pushed an update that allows loops to define a custom key and value variable name. It now defaults to |
adamthom-amzn
approved these changes
Mar 22, 2022
This commit adds documentation for templating controls and updates the existing documentation to no longer reference the deprecated CodeWriter.
JordonPhillips
previously requested changes
Mar 23, 2022
smithy-utils/src/main/java/software/amazon/smithy/utils/AbstractCodeWriter.java
Outdated
Show resolved
Hide resolved
smithy-utils/src/main/java/software/amazon/smithy/utils/AbstractCodeWriter.java
Outdated
Show resolved
Hide resolved
smithy-utils/src/main/java/software/amazon/smithy/utils/AbstractCodeWriter.java
Outdated
Show resolved
Hide resolved
6279b67
to
dc353b8
Compare
Feedback was addressed. The UI isn't showing any new requested changes.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
AbstractCodeWriter now supports Mustache-like behavior by allowing conditions and loops to be evaluated in templates. Note that this does disallow using '/', '?', '^', and '#' as formatters.
Conditions are defined using
${?foo}
where "foo" is the writer named parameter to evaluate.?
is used to check if a value is truthy.The following template with a "foo" value set to "Noid":
Evaluates to:
^
can be used to check if a value is falsey. The following template with no set "baz" value:Evaluates to:
A variable is falsey if it is Boolean false, an empty Iterable, an empty Optional, an empty Map, or an empty String. A variable is truthy if it is not falsey.
If a conditional expression or loop expression is the non-whitespace text on a line and is immediately followed by a
\r
or\n
, then the entire line is omitted from the output.Loops can be created using
${#foo}
. Each value contained in the referenced named parameter is sent through the contained template, one after the other.The following template with a "foo" value of ["a", "b"]:
Evaluates to:
Each iteration of the loop creates a new state in the writer that sets a named parameter named
key
that contains the current index of the loop or the current key of a map entry;value
containing the current value of the iterable or current value of a map entry;key.first
is set to true when the first value is being evaluated, andkey.last
is set to true when the last value is being evaluated.A custom variable name can be used in loops. For example:
Whitespace that comes before an expression removed by putting
~
at the beginning of an expression.Assuming that the first positional argument is "hi":
Expands to:
Whitespace that comes after an expression can be removed by adding
~
to the end of the expression:Expands to:
Leading whitespace cannot be removed when using inline block alignment ('|'). The following is invalid:
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.