Skip to content

Commit

Permalink
Added type function to JMESPath visitor
Browse files Browse the repository at this point in the history
  • Loading branch information
0marperez committed Sep 29, 2023
1 parent a9aa47c commit d43d946
Show file tree
Hide file tree
Showing 8 changed files with 369 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ object RuntimeTypes {
val truthiness = symbol("truthiness")
val urlEncodeComponent = symbol("urlEncodeComponent", "text")
val toNumber = symbol("toNumber")
val type = symbol("type")
}

object Net : RuntimeTypePackage(KotlinDependency.CORE, "net") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,14 @@ class KotlinJmespathExpressionVisitor(
private fun FunctionExpression.args(): List<VisitedExpression> =
this.arguments.map { acceptSubexpression(it) }

private fun VisitedExpression.dotFunction(expression: FunctionExpression, expr: String, elvisExpr: String? = null, isObject: Boolean = false): VisitedExpression {
val dotFunctionExpr = ensureNullGuard(shape, expr, elvisExpr)
private fun VisitedExpression.dotFunction(
expression: FunctionExpression,
expr: String,
elvisExpr: String? = null,
isObject: Boolean = false,
enforceNullGuard: Boolean = true,
): VisitedExpression {
val dotFunctionExpr = if (enforceNullGuard) ensureNullGuard(shape, expr, elvisExpr) else ".$expr"
val ident = addTempVar(expression.name.toCamelCase(), "$identifier$dotFunctionExpr")

shape?.let { shapeCursor.addLast(shape) }
Expand Down Expand Up @@ -322,6 +328,12 @@ class KotlinJmespathExpressionVisitor(
arg.dotFunction(expression, "toNumber()")
}

"type" -> {
writer.addImport(RuntimeTypes.Core.Utils.type)
val arg = expression.singleArg()
arg.dotFunction(expression, "type()", enforceNullGuard = false)
}

else -> throw CodegenException("Unknown function type in $expression")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,19 @@ public inline fun <reified T> Collection<Collection<T>>.flattenIfPossible(): Col
@InternalApi
public val <T> Collection<T>.length: Int
get() = size

/**
* Returns a JS type as a string
*
* See: [JMESPath spec](https://jmespath.org/specification.html#type)
*/
@InternalApi
public fun Any?.type(): String = when (this) {
is String -> "string"
is Boolean -> "boolean"
is List<*>, is Array<*> -> "array"
is Short, is Int, is Long, is Float, is Double -> "number"
is HashMap<*, *>, is Any -> "object"
null -> "null"
else -> throw Exception("Undetected type for: $this")
}
169 changes: 169 additions & 0 deletions tests/codegen/waiter-tests/model/function-type.smithy
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
$version: "2"
namespace com.test

use smithy.waiters#waitable

@suppress(["WaitableTraitJmespathProblem"])
@waitable(
TypeFunctionStringEquals: {
acceptors: [
{
state: "success",
matcher: {
output: {
path: "type(primitives.string) == types.string",
expected: "true",
comparator: "booleanEquals"
}
}
}
]
},
TypeFunctionBooleanEquals: {
acceptors: [
{
state: "success",
matcher: {
output: {
path: "type(primitives.boolean) == types.boolean",
expected: "true",
comparator: "booleanEquals"
}
}
}
]
},
TypeFunctionArrayEquals: {
acceptors: [
{
state: "success",
matcher: {
output: {
path: "type(lists.booleans) == types.array",
expected: "true",
comparator: "booleanEquals"
}
}
}
]
},
TypeFunctionShortEquals: {
acceptors: [
{
state: "success",
matcher: {
output: {
path: "type(primitives.short) == types.number",
expected: "true",
comparator: "booleanEquals"
}
}
}
]
},
TypeFunctionIntegerEquals: {
acceptors: [
{
state: "success",
matcher: {
output: {
path: "type(primitives.integer) == types.number",
expected: "true",
comparator: "booleanEquals"
}
}
}
]
},
TypeFunctionLongEquals: {
acceptors: [
{
state: "success",
matcher: {
output: {
path: "type(primitives.long) == types.number",
expected: "true",
comparator: "booleanEquals"
}
}
}
]
},
TypeFunctionFloatEquals: {
acceptors: [
{
state: "success",
matcher: {
output: {
path: "type(primitives.float) == types.number",
expected: "true",
comparator: "booleanEquals"
}
}
}
]
},
TypeFunctionDoubleEquals: {
acceptors: [
{
state: "success",
matcher: {
output: {
path: "type(primitives.double) == types.number",
expected: "true",
comparator: "booleanEquals"
}
}
}
]
},
TypeFunctionObjectEquals: {
acceptors: [
{
state: "success",
matcher: {
output: {
path: "type(primitives) == types.objectType",
expected: "true",
comparator: "booleanEquals"
}
}
}
]
},
TypeFunctionMergedObjectEquals: {
acceptors: [
{
state: "success",
matcher: {
output: {
path: "type(merge(primitives, primitives)) == types.objectType",
expected: "true",
comparator: "booleanEquals"
}
}
}
]
},
TypeFunctionNullEquals: {
acceptors: [
{
state: "success",
matcher: {
output: {
path: "type(primitives.boolean) == types.nullType",
expected: "true",
comparator: "booleanEquals"
}
}
}
]
},
)
@readonly
@http(method: "GET", uri: "/type/{name}", code: 200)
operation GetFunctionTypeEquals {
input: GetEntityRequest,
output: GetEntityResponse,
errors: [NotFound],
}
10 changes: 10 additions & 0 deletions tests/codegen/waiter-tests/model/utils/structures.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ structure GetEntityResponse {
sampleValues: Values,
objectOne: Values,
objectTwo: Values,
types: Types,
}

structure EntityPrimitives {
Expand Down Expand Up @@ -172,3 +173,12 @@ structure Values {
valueTwo: String
valueThree: String
}

structure Types {
string: String
boolean: String
array: String
number: String
objectType: String
nullType: String
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ service WaitersTestService {
GetFunctionToArrayEquals,
GetFunctionToStringEquals,
GetFunctionToNumberEquals,
GetFunctionTypeEquals,
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ class DefaultWaitersTestClient<T>(resultList: List<Result<T>>) : WaitersTestClie

override suspend fun getFunctionToNumberEquals(input: GetFunctionToNumberEqualsRequest): GetFunctionToNumberEqualsResponse = findSuccess()

override suspend fun getFunctionTypeEquals(input: GetFunctionTypeEqualsRequest): GetFunctionTypeEqualsResponse = findSuccess()

private fun <Response> findSuccess(): Response {
val nextResult = results.next()
@Suppress("UNCHECKED_CAST")
Expand Down
Loading

0 comments on commit d43d946

Please sign in to comment.