+ private DoubleQuoted createDoubleQuoted(final Token token) {
+ // Whitespace normalization happens irrespective of further handling and has no effect on the result
+ final String str = intern(trimWhitespace(token.getText(), token.getCharPositionInLine() - 1));
+
+ // TODO: turn this into a single-quoted literal if a backslash is not present. Doing so allows the
+ // argument to be treated as a literal. See IRArgument.Single#needUnescape() for more context.
+ // This may look unimportant, but there are scenarios where we process the same AST multiple times
+ // and remembering this detail saves a string scan.
+
+ return dquotArguments.computeIfAbsent(str, DoubleQuoted::new);
+ }
+
+ private SingleQuoted createSingleQuoted(final Token token) {
+ return squotArguments.computeIfAbsent(strOf(token), SingleQuoted::new);
+ }
+
+ private Single createUnquoted(final ArgumentContext argument) {
+ final ParseTree child = argument.getChild(0);
+ if (child instanceof TerminalNode) {
+ // This is as simple as it gets: we are dealing with an identifier here.
+ return idenArguments.computeIfAbsent(strOf(((TerminalNode) child).getSymbol()), Identifier::new);
+ }
+
+ verify(child instanceof UnquotedStringContext, "Unexpected shape of %s", argument);
+ // TODO: check non-presence of quotes and create a different subclass, so that ends up treated as if it
+ // was single-quoted, i.e. bypass the check implied by IRArgument.Single#needQuoteCheck().
+ return uquotArguments.computeIfAbsent(strOf(child), Unquoted::new);
+ }
+