Unverified Commit 3308fef8 authored by Russell Cohen's avatar Russell Cohen Committed by GitHub
Browse files

Fully qualified model types (#244)

* Fully qualify types from models

For a long time, we've been fully qualifying depdency types but not model types. This produces code that's fine, but it's always been a confusing inconsistency and it posed problems trying to render Opaque types that specified namespaces (because the namespace was ignored).

This removes that inconsistency.

* A few more small refactorings

* Fix test failures

* CR feedback
parent 8b386a88
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ edition = "2018"

[features]
test-util = ["protocol-test-helpers"]
default = ["test-util"]

[dependencies]
hyper = { version = "0.14.2", features = ["client", "http1", "http2", "tcp", "runtime"] }
+17 −12
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ sealed class RustType {

    object String : RustType() {
        override val name: kotlin.String = "String"
        override val namespace = "::std::string"
        override val namespace = "std::string"
    }

    data class Float(val precision: Int) : RustType() {
@@ -54,13 +54,23 @@ sealed class RustType {
    data class HashMap(val key: RustType, override val member: RustType) : RustType(), Container {
        // TODO: assert that underneath, the member is a String
        override val name: kotlin.String = "HashMap"
        override val namespace = "::std::collections"
        override val namespace = "std::collections"

        companion object {
            val RuntimeType = RuntimeType("HashMap", dependency = null, namespace = "std::collections")
        }
    }

    data class HashSet(override val member: RustType) : RustType(), Container {
        // TODO: assert that underneath, the member is a String
        override val name: kotlin.String = SetType
        override val namespace = SetNamespace
        override val name: kotlin.String = Type
        override val namespace = Namespace

        companion object {
            const val Type = "BTreeSet"
            const val Namespace = "std::collections"
            val RuntimeType = RuntimeType(name = Type, namespace = Namespace, dependency = null)
        }
    }

    data class Reference(val lifetime: kotlin.String?, override val member: RustType) : RustType(), Container {
@@ -69,12 +79,12 @@ sealed class RustType {

    data class Option(override val member: RustType) : RustType(), Container {
        override val name: kotlin.String = "Option"
        override val namespace = "::std::option"
        override val namespace = "std::option"
    }

    data class Box(override val member: RustType) : RustType(), Container {
        override val name: kotlin.String = "Box"
        override val namespace = "::std::boxed"
        override val namespace = "std::boxed"
    }

    data class Dyn(override val member: RustType) : RustType(), Container {
@@ -84,15 +94,10 @@ sealed class RustType {

    data class Vec(override val member: RustType) : RustType(), Container {
        override val name: kotlin.String = "Vec"
        override val namespace = "::std::vec"
        override val namespace = "std::vec"
    }

    data class Opaque(override val name: kotlin.String, override val namespace: kotlin.String? = null) : RustType()

    companion object {
        const val SetType = "BTreeSet"
        const val SetNamespace = "::std::collections"
    }
}

fun RustType.render(fullyQualified: Boolean): String {
+6 −1
Original line number Diff line number Diff line
@@ -310,6 +310,11 @@ class RustWriter private constructor(
        }
    }

    fun addDepsRecursively(symbol: Symbol) {
        addDependency(symbol)
        symbol.references.forEach { addDepsRecursively(it.symbol) }
    }

    /**
     * Generate RustDoc links, eg. [`Abc`](crate::module::Abc)
     */
@@ -331,7 +336,7 @@ class RustWriter private constructor(
                    t.fullyQualifiedName()
                }
                is Symbol -> {
                    addImport(t, null)
                    addDepsRecursively(t)
                    t.rustType().render(fullyQualified = true)
                }
                else -> throw CodegenException("Invalid type provided to RustSymbolFormatter")
+43 −20
Original line number Diff line number Diff line
@@ -34,38 +34,45 @@ data class RuntimeConfig(val cratePrefix: String = "smithy", val relativePath: S
data class RuntimeType(val name: String?, val dependency: RustDependency?, val namespace: String) {
    fun toSymbol(): Symbol {
        val builder = Symbol.builder().name(name).namespace(namespace, "::")
            .rustType(RustType.Opaque(name ?: ""))
            .rustType(RustType.Opaque(name ?: "", namespace = namespace))

        dependency?.run { builder.addDependency(this) }
        return builder.build()
    }

    fun fullyQualifiedName(): String {
        val prefix = if (namespace.startsWith("crate")) {
            ""
        } else {
            "::"
    fun member(member: String): RuntimeType {
        val newName = name?.let { "$name::$member" } ?: member
        return copy(name = newName)
    }

    fun fullyQualifiedName(): String {
        val postFix = name?.let { "::$name" } ?: ""
        return "$prefix$namespace$postFix"
        return "$namespace$postFix"
    }

    // TODO: refactor to be RuntimeTypeProvider a la Symbol provider that packages the `RuntimeConfig` state.
    companion object {
        fun errorKind(runtimeConfig: RuntimeConfig) = RuntimeType("ErrorKind", dependency = CargoDependency.SmithyTypes(runtimeConfig), namespace = "${runtimeConfig.cratePrefix}_types::retry")
        fun provideErrorKind(runtimeConfig: RuntimeConfig) = RuntimeType("ProvideErrorKind", dependency = CargoDependency.SmithyTypes(runtimeConfig), namespace = "${runtimeConfig.cratePrefix}_types::retry")
        fun errorKind(runtimeConfig: RuntimeConfig) = RuntimeType(
            "ErrorKind",
            dependency = CargoDependency.SmithyTypes(runtimeConfig),
            namespace = "${runtimeConfig.cratePrefix}_types::retry"
        )

        fun provideErrorKind(runtimeConfig: RuntimeConfig) = RuntimeType(
            "ProvideErrorKind",
            dependency = CargoDependency.SmithyTypes(runtimeConfig),
            namespace = "${runtimeConfig.cratePrefix}_types::retry"
        )

        val From = RuntimeType("From", dependency = null, namespace = "std::convert")
        val AsRef = RuntimeType("AsRef", dependency = null, namespace = "std::convert")
        fun StdFmt(member: String?) = RuntimeType(member, dependency = null, namespace = "std::fmt")
        fun Std(member: String) = RuntimeType(member, dependency = null, namespace = "std")
        val std = RuntimeType(null, dependency = null, namespace = "std")
        val stdfmt = std.member("fmt")
        val StdError = RuntimeType("Error", dependency = null, namespace = "std::error")
        val HashSet = RuntimeType(RustType.SetType, dependency = null, namespace = "std::collections")
        val HashMap = RuntimeType("HashMap", dependency = null, namespace = "std::collections")
        val ByteSlab = RuntimeType("Vec<u8>", dependency = null, namespace = "std::vec")
        val Debug = StdFmt("Debug")
        val PartialEq = Std("cmp::PartialEq")
        val Clone = Std("clone::Clone")
        val Debug = stdfmt.member("Debug")
        val PartialEq = std.member("cmp::PartialEq")
        val Clone = std.member("clone::Clone")

        fun Instant(runtimeConfig: RuntimeConfig) =
            RuntimeType("Instant", CargoDependency.SmithyTypes(runtimeConfig), "${runtimeConfig.cratePrefix}_types")
@@ -149,10 +156,26 @@ data class RuntimeType(val name: String?, val dependency: RustDependency?, val n

        val Config = RuntimeType("config", null, "crate")

        fun operation(runtimeConfig: RuntimeConfig) = RuntimeType("Operation", dependency = CargoDependency.SmithyHttp(runtimeConfig), namespace = "smithy_http::operation")
        fun operationModule(runtimeConfig: RuntimeConfig) = RuntimeType(null, dependency = CargoDependency.SmithyHttp(runtimeConfig), namespace = "smithy_http::operation")
        fun sdkBody(runtimeConfig: RuntimeConfig): RuntimeType = RuntimeType("SdkBody", dependency = CargoDependency.SmithyHttp(runtimeConfig), "smithy_http::body")
        fun parseStrict(runtimeConfig: RuntimeConfig) = RuntimeType("ParseStrictResponse", dependency = CargoDependency.SmithyHttp(runtimeConfig), namespace = "smithy_http::response")
        fun operation(runtimeConfig: RuntimeConfig) = RuntimeType(
            "Operation",
            dependency = CargoDependency.SmithyHttp(runtimeConfig),
            namespace = "smithy_http::operation"
        )

        fun operationModule(runtimeConfig: RuntimeConfig) = RuntimeType(
            null,
            dependency = CargoDependency.SmithyHttp(runtimeConfig),
            namespace = "smithy_http::operation"
        )

        fun sdkBody(runtimeConfig: RuntimeConfig): RuntimeType =
            RuntimeType("SdkBody", dependency = CargoDependency.SmithyHttp(runtimeConfig), "smithy_http::body")

        fun parseStrict(runtimeConfig: RuntimeConfig) = RuntimeType(
            "ParseStrictResponse",
            dependency = CargoDependency.SmithyHttp(runtimeConfig),
            namespace = "smithy_http::response"
        )

        val Bytes = RuntimeType("Bytes", dependency = CargoDependency.Bytes, namespace = "bytes")
        fun BlobSerde(runtimeConfig: RuntimeConfig) = forInlineDependency(InlineDependency.blobSerde(runtimeConfig))
+4 −4
Original line number Diff line number Diff line
@@ -81,12 +81,12 @@ class BaseSymbolMetadataProvider(base: RustSymbolProvider) : SymbolMetadataProvi

    override fun enumMeta(stringShape: StringShape): RustMetadata {
        return containerDefault.withDerives(
            RuntimeType.Std("hash::Hash")
            RuntimeType.std.member("hash::Hash")
        ).withDerives( // enums can be eq because they can only contain strings
            RuntimeType.Std("cmp::Eq"),
            RuntimeType.std.member("cmp::Eq"),
            // enums can be Ord because they can only contain strings
            RuntimeType.Std("cmp::PartialOrd"),
            RuntimeType.Std("cmp::Ord")
            RuntimeType.std.member("cmp::PartialOrd"),
            RuntimeType.std.member("cmp::Ord")
        )
    }

Loading