Skip to content
Snippets Groups Projects
Unverified Commit 08c16d31 authored by John DiSanti's avatar John DiSanti Committed by GitHub
Browse files

Fix escaping of `Self` in symbol providers (#2381)

* Fix escaping of `Self` in symbol providers

* Clean up an old hack
parent 6dd7bc76
Branches
Tags
No related merge requests found
...@@ -23,7 +23,10 @@ import software.amazon.smithy.rust.codegen.core.util.letIf ...@@ -23,7 +23,10 @@ import software.amazon.smithy.rust.codegen.core.util.letIf
class RustReservedWordSymbolProvider(private val base: RustSymbolProvider) : WrappingSymbolProvider(base) { class RustReservedWordSymbolProvider(private val base: RustSymbolProvider) : WrappingSymbolProvider(base) {
private val internal = private val internal =
ReservedWordSymbolProvider.builder().symbolProvider(base).memberReservedWords(RustReservedWords).build() ReservedWordSymbolProvider.builder().symbolProvider(base)
.nameReservedWords(RustReservedWords)
.memberReservedWords(RustReservedWords)
.build()
override fun toMemberName(shape: MemberShape): String { override fun toMemberName(shape: MemberShape): String {
val baseName = super.toMemberName(shape) val baseName = super.toMemberName(shape)
...@@ -49,20 +52,10 @@ class RustReservedWordSymbolProvider(private val base: RustSymbolProvider) : Wra ...@@ -49,20 +52,10 @@ class RustReservedWordSymbolProvider(private val base: RustSymbolProvider) : Wra
// that represent union variants that have been added since this SDK was generated. // that represent union variants that have been added since this SDK was generated.
UnionGenerator.UnknownVariantName -> "${UnionGenerator.UnknownVariantName}Value" UnionGenerator.UnknownVariantName -> "${UnionGenerator.UnknownVariantName}Value"
"${UnionGenerator.UnknownVariantName}Value" -> "${UnionGenerator.UnknownVariantName}Value_" "${UnionGenerator.UnknownVariantName}Value" -> "${UnionGenerator.UnknownVariantName}Value_"
// Self cannot be used as a raw identifier, so we can't use the normal escaping strategy
// https://internals.rust-lang.org/t/raw-identifiers-dont-work-for-all-identifiers/9094/4
"Self" -> "SelfValue"
// Real models won't end in `_` so it's safe to stop here
"SelfValue" -> "SelfValue_"
else -> reservedWordReplacedName else -> reservedWordReplacedName
} }
container is EnumShape || container.hasTrait<EnumTrait>() -> when (baseName) { container is EnumShape || container.hasTrait<EnumTrait>() -> when (baseName) {
// Self cannot be used as a raw identifier, so we can't use the normal escaping strategy
// https://internals.rust-lang.org/t/raw-identifiers-dont-work-for-all-identifiers/9094/4
"Self" -> "SelfValue"
// Real models won't end in `_` so it's safe to stop here
"SelfValue" -> "SelfValue_"
// Unknown is used as the name of the variant containing unexpected values // Unknown is used as the name of the variant containing unexpected values
"Unknown" -> "UnknownValue" "Unknown" -> "UnknownValue"
// Real models won't end in `_` so it's safe to stop here // Real models won't end in `_` so it's safe to stop here
...@@ -103,7 +96,7 @@ class RustReservedWordSymbolProvider(private val base: RustSymbolProvider) : Wra ...@@ -103,7 +96,7 @@ class RustReservedWordSymbolProvider(private val base: RustSymbolProvider) : Wra
}.build() }.build()
} }
else -> base.toSymbol(shape) else -> renamedSymbol
} }
} }
} }
...@@ -165,11 +158,20 @@ object RustReservedWords : ReservedWords { ...@@ -165,11 +158,20 @@ object RustReservedWords : ReservedWords {
"try", "try",
) )
private val cantBeRaw = setOf("self", "crate", "super") // Some things can't be used as a raw identifier, so we can't use the normal escaping strategy
// https://internals.rust-lang.org/t/raw-identifiers-dont-work-for-all-identifiers/9094/4
private val keywordEscapingMap = mapOf(
"crate" to "crate_",
"super" to "super_",
"self" to "self_",
"Self" to "SelfValue",
// Real models won't end in `_` so it's safe to stop here
"SelfValue" to "SelfValue_",
)
override fun escape(word: String): String = when { override fun escape(word: String): String = when (val mapped = keywordEscapingMap[word]) {
cantBeRaw.contains(word) -> "${word}_" null -> "r##$word"
else -> "r##$word" else -> mapped
} }
fun escapeIfNeeded(word: String): String = when (isReserved(word)) { fun escapeIfNeeded(word: String): String = when (isReserved(word)) {
...@@ -177,5 +179,5 @@ object RustReservedWords : ReservedWords { ...@@ -177,5 +179,5 @@ object RustReservedWords : ReservedWords {
else -> word else -> word
} }
override fun isReserved(word: String): Boolean = RustKeywords.contains(word) override fun isReserved(word: String): Boolean = RustKeywords.contains(word) || keywordEscapingMap.contains(word)
} }
...@@ -16,11 +16,23 @@ import software.amazon.smithy.rust.codegen.core.smithy.WrappingSymbolProvider ...@@ -16,11 +16,23 @@ import software.amazon.smithy.rust.codegen.core.smithy.WrappingSymbolProvider
import software.amazon.smithy.rust.codegen.core.smithy.renamedFrom import software.amazon.smithy.rust.codegen.core.smithy.renamedFrom
import software.amazon.smithy.rust.codegen.core.testutil.TestRustSymbolProviderConfig import software.amazon.smithy.rust.codegen.core.testutil.TestRustSymbolProviderConfig
import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel
import software.amazon.smithy.rust.codegen.core.util.lookup
internal class RustReservedWordSymbolProviderTest { internal class RustReservedWordSymbolProviderTest {
private class TestSymbolProvider(model: Model) : private class TestSymbolProvider(model: Model) :
WrappingSymbolProvider(SymbolVisitor(model, null, TestRustSymbolProviderConfig)) WrappingSymbolProvider(SymbolVisitor(model, null, TestRustSymbolProviderConfig))
@Test
fun `structs are escaped`() {
val model = """
namespace test
structure Self {}
""".asSmithyModel()
val provider = RustReservedWordSymbolProvider(TestSymbolProvider(model))
val symbol = provider.toSymbol(model.lookup("test#Self"))
symbol.name shouldBe "SelfValue"
}
@Test @Test
fun `member names are escaped`() { fun `member names are escaped`() {
val model = """ val model = """
...@@ -28,7 +40,7 @@ internal class RustReservedWordSymbolProviderTest { ...@@ -28,7 +40,7 @@ internal class RustReservedWordSymbolProviderTest {
structure container { structure container {
async: String async: String
} }
""".trimMargin().asSmithyModel() """.asSmithyModel()
val provider = RustReservedWordSymbolProvider(TestSymbolProvider(model)) val provider = RustReservedWordSymbolProvider(TestSymbolProvider(model))
provider.toMemberName( provider.toMemberName(
MemberShape.builder().id("namespace#container\$async").target("namespace#Integer").build(), MemberShape.builder().id("namespace#container\$async").target("namespace#Integer").build(),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment