@@ -15,6 +15,29 @@ use syn::spanned::Spanned;
15
15
16
16
thread_local ! ( static ATTRS : AttributeParseState = Default :: default ( ) ) ;
17
17
18
+ /// Javascript keywords which are not keywords in Rust.
19
+ const JS_KEYWORDS : [ & str ; 20 ] = [
20
+ "class" ,
21
+ "case" ,
22
+ "catch" ,
23
+ "debugger" ,
24
+ "default" ,
25
+ "delete" ,
26
+ "export" ,
27
+ "extends" ,
28
+ "finally" ,
29
+ "function" ,
30
+ "import" ,
31
+ "instanceof" ,
32
+ "new" ,
33
+ "null" ,
34
+ "switch" ,
35
+ "this" ,
36
+ "throw" ,
37
+ "var" ,
38
+ "void" ,
39
+ "with" ,
40
+ ] ;
18
41
#[ derive( Default ) ]
19
42
struct AttributeParseState {
20
43
parsed : Cell < usize > ,
@@ -462,6 +485,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a ast::ImportModule)> for syn::ForeignIte
462
485
self . vis . clone ( ) ,
463
486
false ,
464
487
None ,
488
+ false ,
465
489
) ?
466
490
. 0 ;
467
491
let catch = opts. catch ( ) . is_some ( ) ;
@@ -704,13 +728,19 @@ impl ConvertToAst<BindgenAttrs> for syn::ItemFn {
704
728
self . vis ,
705
729
false ,
706
730
None ,
731
+ false ,
707
732
) ?;
708
733
attrs. check_used ( ) ?;
709
734
Ok ( ret. 0 )
710
735
}
711
736
}
712
737
738
+ pub ( crate ) fn is_js_keyword ( keyword : & str ) -> bool {
739
+ JS_KEYWORDS . contains ( & keyword)
740
+ }
741
+
713
742
/// Construct a function (and gets the self type if appropriate) for our AST from a syn function.
743
+ #[ allow( clippy:: too_many_arguments) ]
714
744
fn function_from_decl (
715
745
decl_name : & syn:: Ident ,
716
746
opts : & BindgenAttrs ,
@@ -719,6 +749,7 @@ fn function_from_decl(
719
749
vis : syn:: Visibility ,
720
750
allow_self : bool ,
721
751
self_ty : Option < & Ident > ,
752
+ is_from_impl : bool ,
722
753
) -> Result < ( ast:: Function , Option < ast:: MethodSelf > ) , Diagnostic > {
723
754
if sig. variadic . is_some ( ) {
724
755
bail_span ! ( sig. variadic, "can't #[wasm_bindgen] variadic functions" ) ;
@@ -754,11 +785,21 @@ fn function_from_decl(
754
785
} )
755
786
} ;
756
787
788
+ let replace_colliding_arg = |i : & mut syn:: PatType | {
789
+ if let syn:: Pat :: Ident ( ref mut i) = * i. pat {
790
+ let ident = i. ident . to_string ( ) ;
791
+ if is_js_keyword ( ident. as_str ( ) ) {
792
+ i. ident = Ident :: new ( format ! ( "_{}" , ident) . as_str ( ) , i. ident . span ( ) ) ;
793
+ }
794
+ }
795
+ } ;
796
+
757
797
let mut method_self = None ;
758
798
let arguments = inputs
759
799
. into_iter ( )
760
800
. filter_map ( |arg| match arg {
761
801
syn:: FnArg :: Typed ( mut c) => {
802
+ replace_colliding_arg ( & mut c) ;
762
803
c. ty = Box :: new ( replace_self ( * c. ty ) ) ;
763
804
Some ( c)
764
805
}
@@ -784,21 +825,29 @@ fn function_from_decl(
784
825
syn:: ReturnType :: Type ( _, ty) => Some ( replace_self ( * ty) ) ,
785
826
} ;
786
827
787
- let ( name, name_span, renamed_via_js_name) =
788
- if let Some ( ( js_name, js_name_span) ) = opts. js_name ( ) {
789
- let kind = operation_kind ( & opts) ;
790
- let prefix = match kind {
791
- OperationKind :: Setter ( _) => "set_" ,
792
- _ => "" ,
793
- } ;
794
- (
795
- format ! ( "{}{}" , prefix, js_name. to_string( ) ) ,
796
- js_name_span,
797
- true ,
798
- )
828
+ let ( name, name_span, renamed_via_js_name) = if let Some ( ( js_name, js_name_span) ) =
829
+ opts. js_name ( )
830
+ {
831
+ let kind = operation_kind ( opts) ;
832
+ let prefix = match kind {
833
+ OperationKind :: Setter ( _) => "set_" ,
834
+ _ => "" ,
835
+ } ;
836
+ let name = if prefix. is_empty ( ) && opts. method ( ) . is_none ( ) && is_js_keyword ( js_name) {
837
+ format ! ( "_{}" , js_name)
799
838
} else {
800
- ( decl_name . to_string ( ) , decl_name . span ( ) , false )
839
+ format ! ( "{}{}" , prefix , js_name )
801
840
} ;
841
+ ( name, js_name_span, true )
842
+ } else {
843
+ let name =
844
+ if !is_from_impl && opts. method ( ) . is_none ( ) && is_js_keyword ( & decl_name. to_string ( ) ) {
845
+ format ! ( "_{}" , decl_name)
846
+ } else {
847
+ decl_name. to_string ( )
848
+ } ;
849
+ ( name, decl_name. span ( ) , false )
850
+ } ;
802
851
Ok ( (
803
852
ast:: Function {
804
853
arguments,
@@ -1054,6 +1103,7 @@ impl<'a, 'b> MacroParse<(&'a Ident, &'a str)> for &'b mut syn::ImplItemMethod {
1054
1103
self . vis . clone ( ) ,
1055
1104
true ,
1056
1105
Some ( class) ,
1106
+ true ,
1057
1107
) ?;
1058
1108
let method_kind = if opts. constructor ( ) . is_some ( ) {
1059
1109
ast:: MethodKind :: Constructor
0 commit comments