Skip to content

Commit df2a027

Browse files
committed
Keyword escaping related fixes
1 parent 9e07f09 commit df2a027

File tree

1 file changed

+42
-10
lines changed

1 file changed

+42
-10
lines changed

src/lib.rs

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ impl MoonBitComponent {
179179
pub fn define_bindgen_packages(&mut self) -> anyhow::Result<()> {
180180
let moonbit_root_package = self.moonbit_root_package()?;
181181
let world_name = self.world_name()?;
182-
let world_snake = world_name.to_snake_case();
182+
let world_snake = to_moonbit_ident(&world_name);
183183

184184
let imported_interfaces = self.get_imported_interfaces()?;
185185
let exported_interfaces = self.get_exported_interfaces()?;
@@ -257,8 +257,8 @@ impl MoonBitComponent {
257257
gen_mbt_files.push(Utf8Path::new("gen").join(format!("world_{world_snake}_export.mbt")));
258258

259259
for (package_name, interface_name) in &imported_interfaces {
260-
let pkg_namespace = package_name.namespace.to_snake_case();
261-
let pkg_name = package_name.name.to_snake_case();
260+
let pkg_namespace = to_moonbit_ident(&package_name.namespace);
261+
let pkg_name = to_moonbit_ident(&package_name.name);
262262
let interface_name = interface_name.to_lower_camel_case();
263263

264264
let name = format!(
@@ -288,8 +288,10 @@ impl MoonBitComponent {
288288
}
289289

290290
for (package_name, interface_name) in &exported_interfaces {
291-
let pkg_namespace = package_name.namespace.to_snake_case();
292-
let pkg_name = package_name.name.to_snake_case();
291+
let pkg_namespace = to_moonbit_ident(&package_name.namespace);
292+
let unescaped_pkg_namespace = package_name.namespace.to_snake_case();
293+
let pkg_name = to_moonbit_ident(&package_name.name);
294+
let unescaped_pkg_name = package_name.name.to_snake_case();
293295
let interface_name = interface_name.to_lower_camel_case();
294296
let snake_interface_name = interface_name.to_snake_case();
295297

@@ -325,7 +327,7 @@ impl MoonBitComponent {
325327
interface_name.clone(),
326328
));
327329
gen_mbt_files.push(Utf8Path::new("gen").join(format!(
328-
"gen_interface_{pkg_namespace}_{pkg_name}_{snake_interface_name}_export.mbt"
330+
"gen_interface_{unescaped_pkg_namespace}_{unescaped_pkg_name}_{snake_interface_name}_export.mbt"
329331
)));
330332
}
331333

@@ -432,8 +434,13 @@ impl MoonBitComponent {
432434
interface_name: &str,
433435
moonbit_source: &str,
434436
) -> anyhow::Result<()> {
435-
let package_name_snake = package_name.name.to_snake_case();
436-
let package_namespace_snake = package_name.namespace.to_snake_case();
437+
let package_name_snake = to_moonbit_ident(&package_name.name);
438+
let package_namespace_snake = to_moonbit_ident(&package_name.namespace);
439+
440+
println!(
441+
"!!! writing interface stub for {package_name}/{interface_name} to {package_namespace_snake}/{package_name_snake}"
442+
);
443+
437444
let path = self
438445
.dir
439446
.join("gen")
@@ -456,8 +463,8 @@ impl MoonBitComponent {
456463
interface_name: &str,
457464
json: serde_json::Value,
458465
) -> anyhow::Result<()> {
459-
let package_name_snake = package_name.name.to_snake_case();
460-
let package_namespace_snake = package_name.namespace.to_snake_case();
466+
let package_name_snake = to_moonbit_ident(&package_name.name);
467+
let package_namespace_snake = to_moonbit_ident(&package_name.namespace);
461468
let path = self
462469
.dir
463470
.join("gen")
@@ -982,6 +989,31 @@ impl Display for WarningControl {
982989
}
983990
}
984991

992+
pub fn to_moonbit_ident(name: impl AsRef<str>) -> String {
993+
// Escape MoonBit keywords and reserved keywords
994+
let name = name.as_ref();
995+
match name {
996+
// Keywords
997+
"as" | "else" | "extern" | "fn" | "fnalias" | "if" | "let" | "const" | "match" | "using"
998+
| "mut" | "type" | "typealias" | "struct" | "enum" | "trait" | "traitalias" | "derive"
999+
| "while" | "break" | "continue" | "import" | "return" | "throw" | "raise" | "try" | "catch"
1000+
| "pub" | "priv" | "readonly" | "true" | "false" | "_" | "test" | "loop" | "for" | "in" | "impl"
1001+
| "with" | "guard" | "async" | "is" | "suberror" | "and" | "letrec" | "enumview" | "noraise"
1002+
| "defer" | "init" | "main"
1003+
// Reserved keywords
1004+
| "module" | "move" | "ref" | "static" | "super" | "unsafe" | "use" | "where" | "await"
1005+
| "dyn" | "abstract" | "do" | "final" | "macro" | "override" | "typeof" | "virtual" | "yield"
1006+
| "local" | "method" | "alias" | "assert" | "recur" | "isnot" | "define" | "downcast"
1007+
| "inherit" | "member" | "namespace" | "upcast" | "void" | "lazy" | "include" | "mixin"
1008+
| "protected" | "sealed" | "constructor" | "atomic" | "volatile" | "anyframe" | "anytype"
1009+
| "asm" | "comptime" | "errdefer" | "export" | "opaque" | "orelse" | "resume" | "threadlocal"
1010+
| "unreachable" | "dynclass" | "dynobj" | "dynrec" | "var" | "finally" | "noasync" => {
1011+
format ! ("{name}_")
1012+
}
1013+
_ => name.to_snake_case(),
1014+
}
1015+
}
1016+
9851017
#[cfg(test)]
9861018
test_r::enable!();
9871019

0 commit comments

Comments
 (0)