diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/TypeScriptJmesPathVisitor.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/TypeScriptJmesPathVisitor.java index 464eceb71b3..ad73bd1dd46 100644 --- a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/TypeScriptJmesPathVisitor.java +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/TypeScriptJmesPathVisitor.java @@ -16,6 +16,9 @@ package software.amazon.smithy.typescript.codegen; import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import software.amazon.smithy.codegen.core.CodegenException; import software.amazon.smithy.jmespath.ExpressionVisitor; import software.amazon.smithy.jmespath.JmespathExpression; @@ -68,44 +71,6 @@ public void run() { executionContext = "returnComparator()"; } - private String makeNewScope(String prefix) { - scopeCount += 1; - return prefix + scopeCount; - } - - void writeBooleanExpectation(String expectedValue, String returnValue) { - writer.openBlock("if ($L == $L) {", "}", executionContext, expectedValue, () -> { - writer.write("return $L;", returnValue); - }); - } - - void writeAnyStringEqualsExpectation(String expectedValue, String returnValue) { - String element = makeNewScope("anyStringEq_"); - writer.openBlock("for (let $L of $L) {", "}", element, executionContext, () -> { - writer.openBlock("if ($L == $S) {", "}", element, expectedValue, () -> { - writer.write("return $L;", returnValue); - }); - }); - } - - void writeAllStringEqualsExpectation(String expectedValue, String returnValue) { - String element = makeNewScope("element_"); - String result = makeNewScope("allStringEq_"); - writer.write("let $L = ($L.length > 0);", result, executionContext); - writer.openBlock("for (let $L of $L) {", "}", element, executionContext, () -> { - writer.write("$L = $L && ($L == $S)", result, result, element, expectedValue); - }); - writer.openBlock("if ($L) {", "}", result, () -> { - writer.write("return $L;", returnValue); - }); - } - - void writeStringExpectation(String expectedValue, String returnValue) { - writer.openBlock("if ($L === $S) {", "}", executionContext, expectedValue, () -> { - writer.write("return $L;", returnValue); - }); - } - @Override public Void visitComparator(ComparatorExpression expression) { @@ -196,10 +161,11 @@ public Void visitLiteral(LiteralExpression expression) { executionContext = "\"" + expression.getValue().toString() + "\""; break; case OBJECT: + executionContext = serializeObject(expression.expectObjectValue()); + break; case ARRAY: - // TODO: resolve JMESPATH OBJECTS and ARRAY types as literals - throw new CodegenException("TypeScriptJmesPath visitor has not implemented resolution of ARRAY and" - + " OBJECT literials "); + executionContext = serializeArray(expression.expectArrayValue()); + break; default: // All other options are already valid js literials. // (BOOLEAN, ANY, NULL, NUMBER, EXPRESSION) @@ -340,4 +306,72 @@ public Void visitSubexpression(Subexpression expression) { expression.getRight().accept(this); return null; } + + void writeBooleanExpectation(String expectedValue, String returnValue) { + writer.openBlock("if ($L == $L) {", "}", executionContext, expectedValue, () -> { + writer.write("return $L;", returnValue); + }); + } + + void writeAnyStringEqualsExpectation(String expectedValue, String returnValue) { + String element = makeNewScope("anyStringEq_"); + writer.openBlock("for (let $L of $L) {", "}", element, executionContext, () -> { + writer.openBlock("if ($L == $S) {", "}", element, expectedValue, () -> { + writer.write("return $L;", returnValue); + }); + }); + } + + void writeAllStringEqualsExpectation(String expectedValue, String returnValue) { + String element = makeNewScope("element_"); + String result = makeNewScope("allStringEq_"); + writer.write("let $L = ($L.length > 0);", result, executionContext); + writer.openBlock("for (let $L of $L) {", "}", element, executionContext, () -> { + writer.write("$L = $L && ($L == $S)", result, result, element, expectedValue); + }); + writer.openBlock("if ($L) {", "}", result, () -> { + writer.write("return $L;", returnValue); + }); + } + + void writeStringExpectation(String expectedValue, String returnValue) { + writer.openBlock("if ($L === $S) {", "}", executionContext, expectedValue, () -> { + writer.write("return $L;", returnValue); + }); + } + + private String makeNewScope(String prefix) { + scopeCount += 1; + return prefix + scopeCount; + } + + private String serializeObject(Map obj) { + return "{" + obj.entrySet().stream() + .map(entry -> "\"" + entry.getKey() + "\":" + serializeValue(entry.getValue())) + .collect(Collectors.joining(",")) + + "}"; + } + + private String serializeArray(List array) { + return "[" + array.stream() + .map(this::serializeValue) + .collect(Collectors.joining(",")) + + "]"; + } + + @SuppressWarnings("unchecked") + private String serializeValue(Object value) { + if (value == null) { + return "null"; + } else if (value instanceof String) { + return "\"" + value + "\""; + } else if (value instanceof Number || value instanceof Boolean) { + return value.toString(); + } else if (value instanceof Map) { + return serializeObject((Map) value); + } else if (value instanceof ArrayList) { + return serializeArray((List) value); + } + throw new CodegenException("Unsupported literal type: " + value.getClass()); + } }