From 10f675522c422e5572921499b090f6de1098e200 Mon Sep 17 00:00:00 2001 From: siddsriv Date: Tue, 26 Nov 2024 17:51:00 +0000 Subject: [PATCH 1/4] chore(codegen): resolve obj and array JS literals from JMESPath types --- .../codegen/TypeScriptJmesPathVisitor.java | 59 ++++++++++++++++++- 1 file changed, 56 insertions(+), 3 deletions(-) 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..e1ec40de03d 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 @@ -59,6 +59,54 @@ class TypeScriptJmesPathVisitor implements ExpressionVisitor { scopeCount = 0; } + private String serializeObject(Map obj) { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + boolean first = true; // first key-value pair + for (Map.Entry entry: obj.entrySet()) { + if (!first) { + builder.append(","); + } + builder.append("\"").append(entry.getKey()).append("\":"); + // recursively serialize value (could be primitive, obj, array) + builder.append(serializeValue(entry.getValue())); + first = false; + } + builder.append("}"); + return builder.toString(); + } + + private String serializeArray(ArrayList array) { + StringBuilder builder = new StringBuilder(); + builder.append("["); + boolean first = true; + for (Object value: array) { + if (!first) { + builder.append(","); + } + builder.append(serializeValue(value)); + first = false; + } + builder.append("]"); + return builder.toString(); + } + + @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((ArrayList) value); + } + throw new CodegenException("Unsupported literal type: " + value.getClass()); + } + public void run() { writer.openBlock("let returnComparator = () => {", "}", () -> { executionContext = accessor; @@ -196,10 +244,15 @@ public Void visitLiteral(LiteralExpression expression) { executionContext = "\"" + expression.getValue().toString() + "\""; break; case OBJECT: + @SuppressWarnings("unchecked") + Map objValue = (Map) expression.getValue(); + executionContext = serializeObject(objValue); + 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 "); + @SuppressWarnings("unchecked") + ArrayList arrayValue = (ArrayList) expression.getValue(); + executionContext = serializeArray(arrayValue); + break; default: // All other options are already valid js literials. // (BOOLEAN, ANY, NULL, NUMBER, EXPRESSION) From 607220d40e0acc666792ea25448813d487719931 Mon Sep 17 00:00:00 2001 From: siddsriv Date: Tue, 26 Nov 2024 17:57:32 +0000 Subject: [PATCH 2/4] chore(codegen): add missing import --- .../smithy/typescript/codegen/TypeScriptJmesPathVisitor.java | 1 + 1 file changed, 1 insertion(+) 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 e1ec40de03d..52a54c7099b 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,7 @@ package software.amazon.smithy.typescript.codegen; import java.util.ArrayList; +import java.util.Map; import software.amazon.smithy.codegen.core.CodegenException; import software.amazon.smithy.jmespath.ExpressionVisitor; import software.amazon.smithy.jmespath.JmespathExpression; From e583e9235449a8b13f589a0f84eac5aad1c43040 Mon Sep 17 00:00:00 2001 From: siddsriv Date: Tue, 26 Nov 2024 18:24:19 +0000 Subject: [PATCH 3/4] chore(codegen): use LiteralExpression methods and map, join for serializers --- .../codegen/TypeScriptJmesPathVisitor.java | 48 ++++++------------- 1 file changed, 14 insertions(+), 34 deletions(-) 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 52a54c7099b..224a2ddc610 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,7 +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; @@ -61,35 +63,17 @@ class TypeScriptJmesPathVisitor implements ExpressionVisitor { } private String serializeObject(Map obj) { - StringBuilder builder = new StringBuilder(); - builder.append("{"); - boolean first = true; // first key-value pair - for (Map.Entry entry: obj.entrySet()) { - if (!first) { - builder.append(","); - } - builder.append("\"").append(entry.getKey()).append("\":"); - // recursively serialize value (could be primitive, obj, array) - builder.append(serializeValue(entry.getValue())); - first = false; - } - builder.append("}"); - return builder.toString(); + return "{" + obj.entrySet().stream() + .map(entry -> "\"" + entry.getKey() + "\":" + serializeValue(entry.getValue())) + .collect(Collectors.joining(",")) + + "}"; } - private String serializeArray(ArrayList array) { - StringBuilder builder = new StringBuilder(); - builder.append("["); - boolean first = true; - for (Object value: array) { - if (!first) { - builder.append(","); - } - builder.append(serializeValue(value)); - first = false; - } - builder.append("]"); - return builder.toString(); + private String serializeArray(List array) { + return "[" + array.stream() + .map(this::serializeValue) + .collect(Collectors.joining(",")) + + "]"; } @SuppressWarnings("unchecked") @@ -103,7 +87,7 @@ private String serializeValue(Object value) { } else if (value instanceof Map) { return serializeObject((Map) value); } else if (value instanceof ArrayList) { - return serializeArray((ArrayList) value); + return serializeArray((List) value); } throw new CodegenException("Unsupported literal type: " + value.getClass()); } @@ -245,14 +229,10 @@ public Void visitLiteral(LiteralExpression expression) { executionContext = "\"" + expression.getValue().toString() + "\""; break; case OBJECT: - @SuppressWarnings("unchecked") - Map objValue = (Map) expression.getValue(); - executionContext = serializeObject(objValue); + executionContext = serializeObject(expression.expectObjectValue()); break; case ARRAY: - @SuppressWarnings("unchecked") - ArrayList arrayValue = (ArrayList) expression.getValue(); - executionContext = serializeArray(arrayValue); + executionContext = serializeArray(expression.expectArrayValue()); break; default: // All other options are already valid js literials. From 7dc05bd7f09f70c2b5ea8e7da56ac28c84142ce1 Mon Sep 17 00:00:00 2001 From: siddsriv Date: Mon, 9 Dec 2024 17:56:33 +0000 Subject: [PATCH 4/4] chore(codegen): reorder methods --- .../codegen/TypeScriptJmesPathVisitor.java | 136 +++++++++--------- 1 file changed, 68 insertions(+), 68 deletions(-) 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 224a2ddc610..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 @@ -62,36 +62,6 @@ class TypeScriptJmesPathVisitor implements ExpressionVisitor { scopeCount = 0; } - 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()); - } - public void run() { writer.openBlock("let returnComparator = () => {", "}", () -> { executionContext = accessor; @@ -101,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) { @@ -374,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()); + } }