Skip to content

Commit 5ed959e

Browse files
Mossakadicej
andauthored
fix: enriched the keyword set and fixed Cgen keyword resolution (#483)
* enriched the keyword set and fixed Cgen keyword resolution Signed-off-by: Jiaxiao Zhou <[email protected]> * added name resolution for java-bindgen Signed-off-by: Jiaxiao Zhou <[email protected]> * fix keywords.wit test for Java generator Signed-off-by: Joel Dice <[email protected]> * run cargo fmt Signed-off-by: Jiaxiao Zhou <[email protected]> --------- Signed-off-by: Jiaxiao Zhou <[email protected]> Signed-off-by: Joel Dice <[email protected]> Co-authored-by: Joel Dice <[email protected]>
1 parent cd32dd8 commit 5ed959e

File tree

3 files changed

+119
-20
lines changed

3 files changed

+119
-20
lines changed

crates/gen-guest-c/src/lib.rs

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
504504
for field in record.fields.iter() {
505505
self.print_ty(SourceType::HDefs, &field.ty);
506506
self.src.h_defs(" ");
507-
self.src.h_defs(&field.name.to_snake_case());
507+
self.src.h_defs(&to_c_ident(&field.name));
508508
self.src.h_defs(";\n");
509509
}
510510
self.src.h_defs("} ");
@@ -570,7 +570,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
570570
if let Some(ty) = self.get_nonempty_type(case.ty.as_ref()) {
571571
self.print_ty(SourceType::HDefs, ty);
572572
self.src.h_defs(" ");
573-
self.src.h_defs(&case.name.to_snake_case());
573+
self.src.h_defs(&to_c_ident(&case.name));
574574
self.src.h_defs(";\n");
575575
}
576576
}
@@ -998,17 +998,17 @@ impl InterfaceGenerator<'_> {
998998
None
999999
};
10001000
let (print_ty, print_name) = if let Some(option_ty) = optional_type {
1001-
(option_ty, format!("maybe_{}", name.to_snake_case()))
1001+
(option_ty, format!("maybe_{}", to_c_ident(name)))
10021002
} else {
1003-
(ty, name.to_snake_case())
1003+
(ty, to_c_ident(name))
10041004
};
10051005
self.print_ty(SourceType::HFns, print_ty);
10061006
self.src.h_fns(" ");
10071007
if pointer {
10081008
self.src.h_fns("*");
10091009
}
10101010
self.src.h_fns(&print_name);
1011-
params.push((optional_type.is_none() && pointer, name.to_snake_case()));
1011+
params.push((optional_type.is_none() && pointer, to_c_ident(name)));
10121012
}
10131013
let mut retptrs = Vec::new();
10141014
let single_ret = ret.retptrs.len() == 1;
@@ -1400,7 +1400,7 @@ impl InterfaceGenerator<'_> {
14001400
if !self.owns_anything(&field.ty) {
14011401
continue;
14021402
}
1403-
self.free(&field.ty, &format!("&ptr->{}", field.name.to_snake_case()));
1403+
self.free(&field.ty, &format!("&ptr->{}", to_c_ident(&field.name)));
14041404
}
14051405
}
14061406

@@ -1433,7 +1433,7 @@ impl InterfaceGenerator<'_> {
14331433
continue;
14341434
}
14351435
uwriteln!(self.src.c_helpers, "case {}: {{", i);
1436-
let expr = format!("&ptr->val.{}", case.name.to_snake_case());
1436+
let expr = format!("&ptr->val.{}", to_c_ident(&case.name));
14371437
if let Some(ty) = &case.ty {
14381438
self.free(ty, &expr);
14391439
}
@@ -1759,7 +1759,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
17591759
Instruction::RecordLower { record, .. } => {
17601760
let op = &operands[0];
17611761
for f in record.fields.iter() {
1762-
results.push(format!("({}).{}", op, f.name.to_snake_case()));
1762+
results.push(format!("({}).{}", op, to_c_ident(&f.name)));
17631763
}
17641764
}
17651765
Instruction::RecordLift { ty, .. } => {
@@ -1862,7 +1862,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
18621862
operands[0],
18631863
);
18641864
self.src.push_str(".");
1865-
self.src.push_str(&case.name.to_snake_case());
1865+
self.src.push_str(&to_c_ident(&case.name));
18661866
self.src.push_str(";\n");
18671867
}
18681868
self.src.push_str(&block);
@@ -1896,7 +1896,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
18961896
if let Some(_) = self.gen.get_nonempty_type(case.ty.as_ref()) {
18971897
let mut dst = format!("{}.val", result);
18981898
dst.push_str(".");
1899-
dst.push_str(&case.name.to_snake_case());
1899+
dst.push_str(&to_c_ident(&case.name));
19001900
self.store_op(&block_results[0], &dst);
19011901
}
19021902
self.src.push_str("break;\n}\n");
@@ -2617,3 +2617,44 @@ fn flags_repr(f: &Flags) -> Int {
26172617
repr => panic!("unimplemented flags {:?}", repr),
26182618
}
26192619
}
2620+
2621+
pub fn to_c_ident(name: &str) -> String {
2622+
match name {
2623+
// Escape C keywords.
2624+
// Source: https://en.cppreference.com/w/c/keyword
2625+
"auto" => "auto_".into(),
2626+
"else" => "else_".into(),
2627+
"long" => "long_".into(),
2628+
"switch" => "switch_".into(),
2629+
"break" => "break_".into(),
2630+
"enum" => "enum_".into(),
2631+
"register" => "register_".into(),
2632+
"typedef" => "typedef_".into(),
2633+
"case" => "case_".into(),
2634+
"extern" => "extern_".into(),
2635+
"return" => "return_".into(),
2636+
"union" => "union_".into(),
2637+
"char" => "char_".into(),
2638+
"float" => "float_".into(),
2639+
"short" => "short_".into(),
2640+
"unsigned" => "unsigned_".into(),
2641+
"const" => "const_".into(),
2642+
"for" => "for_".into(),
2643+
"signed" => "signed_".into(),
2644+
"void" => "void_".into(),
2645+
"continue" => "continue_".into(),
2646+
"goto" => "goto_".into(),
2647+
"sizeof" => "sizeof_".into(),
2648+
"volatile" => "volatile_".into(),
2649+
"default" => "default_".into(),
2650+
"if" => "if_".into(),
2651+
"static" => "static_".into(),
2652+
"while" => "while_".into(),
2653+
"do" => "do_".into(),
2654+
"int" => "int_".into(),
2655+
"struct" => "struct_".into(),
2656+
"_Packed" => "_Packed_".into(),
2657+
"double" => "double_".into(),
2658+
s => s.to_snake_case(),
2659+
}
2660+
}

crates/gen-guest-teavm-java/src/lib.rs

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ impl InterfaceGenerator<'_> {
447447
&func.name,
448448
func.params
449449
.iter()
450-
.map(|(name, _)| name.to_lower_camel_case())
450+
.map(|(name, _)| name.to_java_ident())
451451
.collect(),
452452
);
453453

@@ -742,7 +742,7 @@ impl InterfaceGenerator<'_> {
742742
}
743743

744744
fn sig_string(&mut self, func: &Function, qualifier: bool) -> String {
745-
let name = func.name.to_lower_camel_case();
745+
let name = func.name.to_java_ident();
746746

747747
let result_type = match func.results.len() {
748748
0 => "void".into(),
@@ -768,7 +768,7 @@ impl InterfaceGenerator<'_> {
768768
.iter()
769769
.map(|(name, ty)| {
770770
let ty = self.type_name_with_qualifier(ty, qualifier);
771-
let name = name.to_lower_camel_case();
771+
let name = name.to_java_ident();
772772
format!("{ty} {name}")
773773
})
774774
.collect::<Vec<_>>()
@@ -795,7 +795,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
795795
format!(
796796
"{} {}",
797797
self.type_name(&field.ty),
798-
field.name.to_lower_camel_case()
798+
field.name.to_java_ident()
799799
)
800800
})
801801
.collect::<Vec<_>>()
@@ -805,7 +805,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
805805
.fields
806806
.iter()
807807
.map(|field| {
808-
let name = field.name.to_lower_camel_case();
808+
let name = field.name.to_java_ident();
809809
format!("this.{name} = {name};")
810810
})
811811
.collect::<Vec<_>>()
@@ -821,7 +821,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
821821
format!(
822822
"public final {} {};",
823823
self.type_name(&field.ty),
824-
field.name.to_lower_camel_case()
824+
field.name.to_java_ident()
825825
)
826826
})
827827
.collect::<Vec<_>>()
@@ -903,7 +903,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
903903
.cases
904904
.iter()
905905
.map(|case| {
906-
let case_name = case.name.to_lower_camel_case();
906+
let case_name = case.name.to_java_ident();
907907
let tag = case.name.to_shouty_snake_case();
908908
let (parameter, argument) = if let Some(ty) = self.non_empty_type(case.ty.as_ref())
909909
{
@@ -1209,7 +1209,7 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
12091209
String::new()
12101210
};
12111211

1212-
let method = case_name.to_lower_camel_case();
1212+
let method = case_name.to_java_ident();
12131213

12141214
let call = if let Some(position) = generics_position {
12151215
let (ty, generics) = ty.split_at(position);
@@ -1350,7 +1350,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
13501350
Instruction::RecordLower { record, .. } => {
13511351
let op = &operands[0];
13521352
for field in record.fields.iter() {
1353-
results.push(format!("({op}).{}", field.name.to_lower_camel_case()));
1353+
results.push(format!("({op}).{}", field.name.to_java_ident()));
13541354
}
13551355
}
13561356
Instruction::RecordLift { ty, .. } | Instruction::TupleLift { ty, .. } => {
@@ -1822,7 +1822,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
18221822
};
18231823

18241824
let module = self.gen.name.to_upper_camel_case();
1825-
let name = func.name.to_lower_camel_case();
1825+
let name = func.name.to_java_ident();
18261826

18271827
let args = operands.join(", ");
18281828

@@ -2182,3 +2182,24 @@ fn is_primitive(ty: &Type) -> bool {
21822182
| Type::Float64
21832183
)
21842184
}
2185+
2186+
trait ToJavaIdent: ToOwned {
2187+
fn to_java_ident(&self) -> Self::Owned;
2188+
}
2189+
2190+
impl ToJavaIdent for str {
2191+
fn to_java_ident(&self) -> String {
2192+
// Escape Java keywords
2193+
// Source: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
2194+
match self {
2195+
"abstract" | "continue" | "for" | "new" | "switch" | "assert" | "default" | "goto"
2196+
| "package" | "synchronized" | "boolean" | "do" | "if" | "private" | "this"
2197+
| "break" | "double" | "implements" | "protected" | "throw" | "byte" | "else"
2198+
| "import" | "public" | "throws" | "case" | "enum" | "instanceof" | "return"
2199+
| "transient" | "catch" | "extends" | "int" | "short" | "try" | "char" | "final"
2200+
| "interface" | "static" | "void" | "class" | "finally" | "long" | "strictfp"
2201+
| "volatile" | "const" | "float" | "native" | "super" | "while" => format!("{self}_"),
2202+
_ => self.to_lower_camel_case(),
2203+
}
2204+
}
2205+
}

tests/codegen/keywords.wit

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,42 @@
11
interface keywords {
2+
record for {
3+
return: u32,
4+
}
25
%type: func(%type: u32) -> (%type: u32, %flags: s32)
6+
%variant: func(%enum: s32) -> ()
7+
%interface: func(%interface: s32) -> ()
8+
throw: func(throw: s32) -> ()
9+
new: func(new: s32) -> ()
10+
package: func(package: s32) -> ()
11+
final: func(final: s32) -> ()
12+
auto: func(auto: s32) -> ()
13+
else: func(for: s32) -> ()
14+
long: func(long: s32) -> ()
15+
switch: func(switch: s32) -> ()
16+
break: func(break: s32) -> ()
17+
register: func(register: s32) -> ()
18+
typedef: func(typedef: s32) -> ()
19+
case: func(case: s32) -> ()
20+
extern: func(extern: s32) -> ()
21+
%union: func(%union: s32) -> ()
22+
%char: func(%char: s32) -> ()
23+
float: func(float: s32) -> ()
24+
short: func(short: s32) -> ()
25+
unsigned: func(unsigned: s32) -> ()
26+
const: func(const: s32) -> ()
27+
signed: func(signed: s32) -> ()
28+
void: func(void: s32) -> ()
29+
continue: func(continue: s32) -> ()
30+
goto: func(goto: s32) -> ()
31+
sizeof: func(sizeof: s32) -> ()
32+
volatile: func(volatile: s32) -> ()
33+
%default: func(%default: s32) -> ()
34+
if: func(if: s32) -> ()
35+
%static: func(%static: s32) -> ()
36+
while: func(while: s32) -> ()
37+
do: func(do: s32) -> ()
38+
%int: func(%int: s32) -> ()
39+
%struct: func(%struct: s32) -> ()
340
}
441

542
default world the-world {

0 commit comments

Comments
 (0)