Skip to content

Commit 9d06e99

Browse files
committed
WIP!
1 parent d276a08 commit 9d06e99

File tree

21 files changed

+192
-80
lines changed

21 files changed

+192
-80
lines changed

hll/dynamodb-mapper/dynamodb-mapper-codegen/src/main/kotlin/aws/sdk/kotlin/hll/dynamodbmapper/codegen/model/MapperTypes.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,22 @@ public object MapperTypes {
4141

4242
public object Items {
4343
public fun itemSchema(typeVar: String): TypeRef =
44-
TypeRef(MapperPkg.Hl.Items, "ItemSchema", genericArgs = listOf(TypeVar(typeVar)))
44+
TypeRef(MapperPkg.Hl.Items, "ItemSchema", genericArgs = setOf(TypeVar(typeVar)))
4545

4646
public fun itemSchemaPartitionKey(objectType: TypeRef, pkType: TypeRef): TypeRef =
47-
TypeRef(MapperPkg.Hl.Items, "ItemSchema.PartitionKey", genericArgs = listOf(objectType, pkType))
47+
TypeRef(MapperPkg.Hl.Items, "ItemSchema.PartitionKey", genericArgs = setOf(objectType, pkType))
4848

4949
public fun itemSchemaCompositeKey(objectType: TypeRef, pkType: TypeRef, skType: TypeRef): TypeRef =
50-
TypeRef(MapperPkg.Hl.Items, "ItemSchema.CompositeKey", genericArgs = listOf(objectType, pkType, skType))
50+
TypeRef(MapperPkg.Hl.Items, "ItemSchema.CompositeKey", genericArgs = setOf(objectType, pkType, skType))
5151

52-
public fun keySpec(keyType: TypeRef): TypeRef = TypeRef(MapperPkg.Hl.Items, "KeySpec", genericArgs = listOf(keyType))
52+
public fun keySpec(keyType: TypeRef): TypeRef = TypeRef(MapperPkg.Hl.Items, "KeySpec", genericArgs = setOf(keyType))
5353
public val KeySpecByteArray: TypeRef = TypeRef(MapperPkg.Hl.Items, "KeySpec.ByteArray")
5454
public val KeySpecNumber: TypeRef = TypeRef(MapperPkg.Hl.Items, "KeySpec.Number")
5555
public val KeySpecString: TypeRef = TypeRef(MapperPkg.Hl.Items, "KeySpec.String")
5656
public val AttributeDescriptor: TypeRef = TypeRef(MapperPkg.Hl.Items, "AttributeDescriptor")
5757

5858
public fun itemConverter(objectType: TypeRef): TypeRef =
59-
TypeRef(MapperPkg.Hl.Items, "ItemConverter", genericArgs = listOf(objectType))
59+
TypeRef(MapperPkg.Hl.Items, "ItemConverter", genericArgs = setOf(objectType))
6060

6161
public val SimpleItemConverter: TypeRef = TypeRef(MapperPkg.Hl.Items, "SimpleItemConverter")
6262
}
@@ -65,18 +65,18 @@ public object MapperTypes {
6565
public fun tablePartitionKey(objectType: TypeRef, pkType: TypeRef): TypeRef = TypeRef(
6666
MapperPkg.Hl.Model,
6767
"Table.PartitionKey",
68-
genericArgs = listOf(objectType, pkType),
68+
genericArgs = setOf(objectType, pkType),
6969
)
7070
public fun tableCompositeKey(objectType: TypeRef, pkType: TypeRef, skType: TypeRef): TypeRef = TypeRef(
7171
MapperPkg.Hl.Model,
7272
"Table.CompositeKey",
73-
genericArgs = listOf(objectType, pkType, skType),
73+
genericArgs = setOf(objectType, pkType, skType),
7474
)
7575
public val toItem: TypeRef = TypeRef(MapperPkg.Hl.Model, "toItem")
7676
}
7777

7878
public object Values {
79-
public fun valueConverter(value: Type): TypeRef = TypeRef(MapperPkg.Hl.Values, "ValueConverter", genericArgs = listOf(value))
79+
public fun valueConverter(value: Type): TypeRef = TypeRef(MapperPkg.Hl.Values, "ValueConverter", genericArgs = setOf(value))
8080
public val ItemToValueConverter: TypeRef = TypeRef(MapperPkg.Hl.Values, "ItemToValueConverter")
8181
public val NullableConverter: TypeRef = TypeRef(MapperPkg.Hl.Values, "NullableConverter")
8282

@@ -102,7 +102,7 @@ public object MapperTypes {
102102
}
103103

104104
public object Scalars {
105-
public fun enumConverter(enumType: Type): TypeRef = TypeRef(MapperPkg.Hl.ScalarValues, "EnumConverter", genericArgs = listOf(enumType))
105+
public fun enumConverter(enumType: Type): TypeRef = TypeRef(MapperPkg.Hl.ScalarValues, "EnumConverter", genericArgs = setOf(enumType))
106106

107107
public val BooleanConverter: TypeRef = TypeRef(MapperPkg.Hl.ScalarValues, "BooleanConverter")
108108
public val StringConverter: TypeRef = TypeRef(MapperPkg.Hl.ScalarValues, "StringConverter")

hll/dynamodb-mapper/dynamodb-mapper-ops-codegen/src/main/kotlin/aws/sdk/kotlin/hll/dynamodbmapper/codegen/operations/HighLevelOpsProcessor.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.rendering.HighLevelR
1414
import aws.sdk.kotlin.services.dynamodb.DynamoDbClient
1515
import com.google.devtools.ksp.getClassDeclarationByName
1616
import com.google.devtools.ksp.getDeclaredFunctions
17-
import com.google.devtools.ksp.processing.*
17+
import com.google.devtools.ksp.processing.Resolver
18+
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
1819
import com.google.devtools.ksp.symbol.KSAnnotated
1920
import com.google.devtools.ksp.symbol.KSFunctionDeclaration
2021

hll/dynamodb-mapper/dynamodb-mapper-ops-codegen/src/main/kotlin/aws/sdk/kotlin/hll/dynamodbmapper/codegen/operations/model/ItemSourceKind.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ internal enum class ItemSourceKind(
4343
* Get the [TypeRef] for the `*Spec` type for this item source kind
4444
* @param typeVar The type variable name to use for the generic type
4545
*/
46-
fun getSpecType(typeVar: String): TypeRef = TypeRef(MapperPkg.Hl.Model, "${name}Spec", listOf(TypeVar(typeVar)))
46+
fun getSpecType(typeVar: String): TypeRef = TypeRef(MapperPkg.Hl.Model, "${name}Spec", setOf(TypeVar(typeVar)))
4747
}
4848

4949
/**

hll/dynamodb-mapper/dynamodb-mapper-ops-codegen/src/main/kotlin/aws/sdk/kotlin/hll/dynamodbmapper/codegen/operations/model/MemberCodegenBehavior.kt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ package aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.model
77
import aws.sdk.kotlin.hll.codegen.model.*
88
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.model.MapperPkg
99
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.model.MapperTypes
10-
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.model.ExpressionArgumentsType.*
11-
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.model.ExpressionLiteralType.*
10+
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.model.ExpressionArgumentsType.AttributeNames
11+
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.model.ExpressionArgumentsType.AttributeValues
12+
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.model.ExpressionLiteralType.Filter
13+
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.model.ExpressionLiteralType.KeyCondition
1214
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.model.MemberCodegenBehavior.*
1315

1416
/**
@@ -33,7 +35,7 @@ internal sealed interface MemberCodegenBehavior {
3335
/**
3436
* Indicates that a member is an attribute map which contains _key_ attributes for a data type (as opposed to _all_
3537
* attributes) and should be replaced with a generic type (i.e., a `Map<String, AttributeValue>` member in a
36-
* low-level structure should be replaced with a generic `T` member in a high-level structure)
38+
* low-level structure should be replaced with a generic `K` member in a high-level structure)
3739
*/
3840
data object MapKeys : MemberCodegenBehavior
3941

@@ -107,6 +109,9 @@ private data class Rule(
107109
constructor(name: String, type: TypeRef, behavior: MemberCodegenBehavior) :
108110
this(name::equals, type::isEquivalentTo, behavior)
109111

112+
constructor(names: Collection<String>, type: TypeRef, behavior: MemberCodegenBehavior) :
113+
this(names::contains, type::isEquivalentTo, behavior)
114+
110115
constructor(name: Regex, type: TypeRef, behavior: MemberCodegenBehavior) :
111116
this(name::matches, type::isEquivalentTo, behavior)
112117

@@ -123,6 +128,8 @@ private fun Type.isEquivalentTo(other: Type): Boolean = when (this) {
123128
genericArgs.zip(other.genericArgs).all { (thisArg, otherArg) -> thisArg.isEquivalentTo(otherArg) }
124129
}
125130

131+
private val keyMembers = setOf("key", "exclusiveStartKey", "lastEvaluatedKey")
132+
126133
/**
127134
* Priority-ordered list of dispositions to apply to members found in structures. The first element from this list that
128135
* successfully matches with a member will be chosen.
@@ -156,6 +163,6 @@ private val rules = listOf(
156163

157164
// Mappable members
158165
Rule(".*".toRegex(), Types.Kotlin.list(MapperTypes.AttributeMap), ListMapAll),
159-
Rule("key", MapperTypes.AttributeMap, MapKeys),
166+
Rule(keyMembers, MapperTypes.AttributeMap, PassThrough), // FIXME need to codegen a dedicated key type
160167
Rule(".*".toRegex(), MapperTypes.AttributeMap, MapAll),
161168
)

hll/dynamodb-mapper/dynamodb-mapper-ops-codegen/src/main/kotlin/aws/sdk/kotlin/hll/dynamodbmapper/codegen/operations/model/Operation.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ package aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.model
66

77
import aws.sdk.kotlin.hll.codegen.model.ModelAttributes
88
import aws.sdk.kotlin.hll.codegen.model.Operation
9+
import aws.sdk.kotlin.hll.codegen.model.TypeVar
10+
import aws.sdk.kotlin.hll.codegen.model.genericVars
911
import aws.sdk.kotlin.hll.codegen.util.plus
1012

1113
/**
@@ -19,3 +21,8 @@ internal fun Operation.toHighLevel(pkg: String): Operation {
1921
val hlAttributes = llOperation.attributes + (ModelAttributes.LowLevelOperation to llOperation)
2022
return Operation(llOperation.methodName, hlRequest, hlResponse, hlAttributes)
2123
}
24+
25+
internal fun Operation.genericVars(): Set<TypeVar> = buildSet {
26+
addAll(request.genericVars())
27+
addAll(response.genericVars())
28+
}

hll/dynamodb-mapper/dynamodb-mapper-ops-codegen/src/main/kotlin/aws/sdk/kotlin/hll/dynamodbmapper/codegen/operations/model/Structure.kt

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ import aws.sdk.kotlin.hll.dynamodbmapper.codegen.model.MapperTypes
1515
internal fun Structure.toHighLevel(pkg: String): Structure {
1616
val llStructure = this@toHighLevel
1717

18-
val hlType = TypeRef(pkg, llStructure.type.shortName, listOf(TypeVar("T")))
19-
2018
val hlMembers = llStructure.members.mapNotNull { llMember ->
2119
val nullable = llMember.type.nullable
2220

@@ -28,7 +26,7 @@ internal fun Structure.toHighLevel(pkg: String): Structure {
2826

2927
MemberCodegenBehavior.ListMapAll -> {
3028
val llListType = llMember.type as? TypeRef ?: error("`ListMapAll` member is required to be a TypeRef")
31-
val hlListType = llListType.copy(genericArgs = listOf(TypeVar("T")))
29+
val hlListType = llListType.copy(genericArgs = setOf(TypeVar("T")))
3230
llMember.copy(type = hlListType)
3331
}
3432

@@ -68,6 +66,22 @@ internal fun Structure.toHighLevel(pkg: String): Structure {
6866
hlMember?.copy(attributes = hlMember.attributes + (ModelAttributes.LowLevelMember to llMember))
6967
}.toSet()
7068

69+
val hlTypeParams = hlMembers.flatMap { it.type.genericVars() }.toSet()
70+
require(
71+
llStructure.type.shortName != "QueryResponse" ||
72+
hlTypeParams.isNotEmpty()
73+
) {
74+
buildString {
75+
appendLine("Did not find expected type params for ${llStructure.type.shortName}:")
76+
appendLine("hlTypeParams: $hlTypeParams")
77+
appendLine("hlMembers:")
78+
hlMembers.forEach { member ->
79+
appendLine(" ${member.name}: ${member.type} -> ${member.type.genericVars()}")
80+
}
81+
}
82+
}
83+
val hlType = TypeRef(pkg, llStructure.type.shortName, hlTypeParams)
84+
7185
val hlAttributes = llStructure.attributes + (ModelAttributes.LowLevelStructure to llStructure)
7286

7387
return Structure(hlType, hlMembers, hlAttributes)

hll/dynamodb-mapper/dynamodb-mapper-ops-codegen/src/main/kotlin/aws/sdk/kotlin/hll/dynamodbmapper/codegen/operations/rendering/DataTypeGenerator.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ package aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.rendering
66

77
import aws.sdk.kotlin.hll.codegen.core.CodeGenerator
88
import aws.sdk.kotlin.hll.codegen.model.*
9-
import aws.sdk.kotlin.hll.codegen.rendering.*
9+
import aws.sdk.kotlin.hll.codegen.rendering.BuilderRenderer
10+
import aws.sdk.kotlin.hll.codegen.rendering.RenderContext
11+
import aws.sdk.kotlin.hll.codegen.rendering.RenderOptions
12+
import aws.sdk.kotlin.hll.codegen.rendering.Visibility
1013
import aws.sdk.kotlin.hll.codegen.util.plus
1114

1215
/**
@@ -61,15 +64,15 @@ internal class DataTypeGenerator(
6164
) : CodeGenerator by generator {
6265
fun generate() {
6366
write("@#T", Types.Smithy.ExperimentalApi)
64-
withBlock("public interface #T {", "}", structure.type) {
67+
withBlock("public interface #T {", "}", structure.type.forDeclaration()) {
6568
write("@#T", Types.Smithy.ExperimentalApi)
6669
write("public companion object { }") // leave room for future expansion
6770
blankLine()
6871
members { write("public val #L: #T", name, type) }
6972
}
7073
blankLine()
7174

72-
val genericParams = structure.genericVars().asParamsList()
75+
val genericParams = structure.genericVars().noNulls().asParamsList(" ")
7376
val genericParamsWithSpacer = if (genericParams.isEmpty()) "" else "$genericParams "
7477
val implName = "${structure.type.shortName}Impl"
7578
val implType = structure.type.copy(shortName = implName)

hll/dynamodb-mapper/dynamodb-mapper-ops-codegen/src/main/kotlin/aws/sdk/kotlin/hll/dynamodbmapper/codegen/operations/rendering/OperationsTypeRenderer.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import aws.sdk.kotlin.hll.codegen.rendering.RendererBase
1111
import aws.sdk.kotlin.hll.codegen.util.lowercaseFirstChar
1212
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.model.MapperTypes
1313
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.model.ItemSourceKind
14+
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.model.genericVars
1415
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.model.itemSourceKinds
1516
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.operations.model.paginationInfo
1617

@@ -33,7 +34,8 @@ internal class OperationsTypeRenderer(
3334
private val entityName = itemSourceKind.name.lowercaseFirstChar
3435
private val intfName = "${itemSourceKind.name}Operations"
3536

36-
val interfaceType = TypeRef(ctx.pkg, intfName, listOf(TypeVar("T")))
37+
val opsTypeArgs = operations.flatMap { it.genericVars() }.noNulls().toSet()
38+
val interfaceType = TypeRef(ctx.pkg, intfName, opsTypeArgs)
3739

3840
override fun generate() {
3941
renderInterface()
@@ -55,14 +57,12 @@ internal class OperationsTypeRenderer(
5557

5658
private fun renderDslOp(op: Operation) {
5759
val builderType = BuilderRenderer.builderType(op.request.type)
58-
val generics = op.request.genericVars().asParamsList(" ")
59-
6060
if (op.paginationInfo != null) renderManualPaginationAnnotation(op) else blankLine()
6161

6262
withBlock(
6363
"public suspend inline fun #L#T.#L(crossinline block: #T.() -> Unit): #T =",
6464
"",
65-
generics,
65+
opsTypeArgs.asParamsList(" "),
6666
interfaceType,
6767
op.methodName,
6868
builderType,

hll/dynamodb-mapper/dynamodb-mapper-schema-codegen/src/main/kotlin/aws/sdk/kotlin/hll/dynamodbmapper/codegen/annotations/rendering/SchemaRenderer.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
package aws.sdk.kotlin.hll.dynamodbmapper.codegen.annotations.rendering
66

77
import aws.sdk.kotlin.hll.codegen.model.*
8-
import aws.sdk.kotlin.hll.codegen.rendering.*
8+
import aws.sdk.kotlin.hll.codegen.rendering.BuilderRenderer
9+
import aws.sdk.kotlin.hll.codegen.rendering.RenderContext
10+
import aws.sdk.kotlin.hll.codegen.rendering.RendererBase
911
import aws.sdk.kotlin.hll.codegen.util.visibility
1012
import aws.sdk.kotlin.hll.dynamodbmapper.*
1113
import aws.sdk.kotlin.hll.dynamodbmapper.codegen.annotations.AnnotationsProcessorOptions
@@ -103,6 +105,8 @@ internal class SchemaRenderer(
103105
}
104106
}
105107

108+
private inline fun <reified T> Any.castOrNull(): T? = this as? T
109+
106110
private fun renderBuilder() {
107111
val members = properties.map(Member.Companion::from).toSet()
108112
BuilderRenderer(this, classType, classType, members, ctx).render()

0 commit comments

Comments
 (0)