From cdcab888eea7e8f5375bf4ebd7e26806033ca252 Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Mon, 17 Jan 2022 04:38:16 +0000 Subject: [PATCH] fix(napi-derive): correctly escape backslash in type definition doc comments (#1034) --- crates/backend/src/typegen.rs | 20 +++++++++++++++++++- examples/napi/__test__/typegen.spec.ts.md | 5 +++++ examples/napi/__test__/typegen.spec.ts.snap | Bin 2294 -> 2354 bytes examples/napi/index.d.ts | 5 +++++ examples/napi/src/class.rs | 3 +++ 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/crates/backend/src/typegen.rs b/crates/backend/src/typegen.rs index 123f6dc9..c8417a1a 100644 --- a/crates/backend/src/typegen.rs +++ b/crates/backend/src/typegen.rs @@ -51,7 +51,16 @@ fn escape_json(src: &str) -> String { use std::fmt::Write; let mut escaped = String::with_capacity(src.len()); let mut utf16_buf = [0u16; 2]; + let mut pending_backslash = false; for c in src.chars() { + if pending_backslash { + match c { + 'b' | 'f' | 'n' | 'r' | 't' | 'u' | '"' => escaped += "\\", + _ => escaped += "\\\\", + } + pending_backslash = false; + } + match c { '\x08' => escaped += "\\b", '\x0c' => escaped += "\\f", @@ -59,7 +68,10 @@ fn escape_json(src: &str) -> String { '\r' => escaped += "\\r", '\t' => escaped += "\\t", '"' => escaped += "\\\"", - '\\' => escaped += "\\", + '\\' => { + pending_backslash = true; + } + ' ' => escaped += " ", c if c.is_ascii_graphic() => escaped.push(c), c => { let encoded = c.encode_utf16(&mut utf16_buf); @@ -69,6 +81,12 @@ fn escape_json(src: &str) -> String { } } } + + // cater for trailing backslash + if pending_backslash { + escaped += "\\\\" + } + escaped } diff --git a/examples/napi/__test__/typegen.spec.ts.md b/examples/napi/__test__/typegen.spec.ts.md index d698d541..eb49d821 100644 --- a/examples/napi/__test__/typegen.spec.ts.md +++ b/examples/napi/__test__/typegen.spec.ts.md @@ -151,6 +151,11 @@ Generated by [AVA](https://avajs.dev). whoami(): string␊ /** This is static... */␊ static getDogKind(): Kind␊ + /**␊ + * Here are some characters and character sequences␊ + * that should be escaped correctly:␊ + * \\[]{}/\\:""␊ + */␊ returnOtherClass(): Dog␊ returnOtherClassWithCustomConstructor(): Bird␊ }␊ diff --git a/examples/napi/__test__/typegen.spec.ts.snap b/examples/napi/__test__/typegen.spec.ts.snap index 5fc4cad16f0549b5f9fd9ed7e3a70b8b8c125bc5..68d623b1b8ad6d4f91b34e697949b6f9afcc8f78 100644 GIT binary patch literal 2354 zcmV-23C;FFRzVP!>|JaQ+fPDX?h(;MaN7M~P z3&t8cJs*n*00000000B68QX5-xOLj1D3G_l?*ltUvGTylBY{j37HFcUF(V-xkO7YvSAxa>snt(EhauJU`>)P^_v{bP z@aH$bfA+`Uw!eD$f@l?Sp<5wW)Q=c>@p26|nb}--HgT7xTCV3jL*h?KuYGpBetuy9 z*nKP$O@fFjMUL(@O9YKh{Tq<$Rezs6tPzqh8cGpO$=6@E%*Mi2D){G=5jCCoGBU?k z?_1gOx<&f1^|S++DSsEuar)>815SuZ<$s^$qCEQmBYj((Mu-|1q-`h0#xb50K&Oi zfNj(Yh}P-CRkqbs1YS(_2+Uzb1e~)(PPk&P4${G(iX%m&lQh!2e6uIMxQJ8jP%SR6 z)>%M7ab!s4$OX;V2}b-JB@Fj>aM6`%0^hs%eZlYHa}Pg{_;7?;e1nS~H+24LkQoN` z)@GGo0o%Sj-r4q8YhIZ8JJ+K`-kGrW>H^dzth}muivOKC!L?BB>XPa_5gY9u+La0I zU9s}-6L4$yMVl{BYl?KOn&!)1$k1$5fvz@%>Cmi6->IHs)LG?fN0GhG z+}%y$LjPS>)d7SK*|OWO$WK{)DRD$I0;#ejl|JPv>LlOxhvW8zk-eQ4hXYKMGdWzH zA<9??St!l)1%ELF;Ir_T3JnJ0-0Bc!Bs}bAU209jGExho&bVXp3-p4qb6eM&%|-K+ zvuMpxT;d7<)`fDLk*EzHY@N@dRBdf;dU2^;u4tg=W)k6OiX}9L{t;Yd0~=1KY|enr zEWkTFFIgk2;82(Ih87|M%XCK8mi6q+!3tT-z;#5xnR-*oaa2tAtDQPzw})SZT6JwS zbaX>|JIkv3agKXfKjPVX4!5WxnZRGT-MCL#{$!)orUw6xIT&6L~Ak8>e)!W2zCdpt4wv< zhusd?Es;?K&2CNQST!^vwWpA362*t6$uQ6tX7L32IErE4NJB*jteb7S6WYec23#_j z6^tx2j=tPF>S0?wxB0>PzjtZT^ewCA7jKQCQ`RTxE z!fG(UsUiL7%bjgg{`21L5)xdtweopnzBlee*$*wP#vGlR{?&occy}X79p?Gtz#4f$ zKADP%g-Rx$h>UGjgEalg?tX%_^*QDERsfy_jS-7rs?w79kaAN$;z1M1NSylaz+WM; z3<;ma0E(4^IOGxT&sX>$;W@jF>os?HG7n~L!6!5-COtFuL7Jy_+hq9SscZ~~Edx^2 z23vTrC^&p9nzP}}Fq?BVrm;YX5-3Z6FeMWP86vclU|Q8YFky})9BO#IMpA$R7c;cI zhEt1FzFEN)ANm~Db~(X!tMv$nzCcbUFd^A}WR3-vP2>$H|NYOu|7rG7yt|R46F$e* z)yYZ^;WDQTNDHI1QK#YB)N=cl!OV_xyLko-Ml=Dl;7cG5$Hfw~`05y2o12ms&r7}5P5=LOxW!cmlvuP`54C_W~for9N05}s57L_~^ z=z%QQ4eKCG)JBpCo%*cDSoo&pylqvqU#?Lb^C}!d{`c@D-{~7N9>~Fjs^kBURVfA? z=g_`RIi6E>yEeSDyQ{zK<{V(jcY0jh(0-ceh}E^W9h3XX6kmY^f)j1v{{->7~uFfpN-}(`JHMjg)jZDiTzkGnmv4|xEP@9@zCjy zGEz%hW0z;nvVvnBL-UWFGpa{bVU;;uo*uec3a_xb<5Rs-R&JF@*aTh$sUf*83b6Px zTA@pUf#g(-BhdZ*XvaX#jkPdEzU`eH_4dX? zK+6ezL^-XZE)Bc$F;}8|c@{g3Lv(e6NwQUmpJ`U`Jmf=2eV!}AV~y>$UE8?|ZQ~fb Y;w`A!rXN>6#yzh64`%ROcAFdk0O*x{DgXcg literal 2294 zcmVDUyk-`Y(cZ!>Et{ESQ^s2g8WVDbS-(aM|t{1XwZN0me4O?zD zFpMl`hLUKF$jOjnTX75|e~{j1w zRzLs7G}jTk|En6wGz!U(36@aJNFbAh1)At-%t*)vWWXcFm7p;|YW4H4VMsOo_Ot)| z>Diy3;m;pFdG_fa|NYrl&xuwM7rGU4Mg548=U=VCCNrDs&L-~CRLk|8XGr`h>9x;} z*Uv8u0K1Q6qDc@@rO45}W{IHDsec1b5W6^}p+!Ui4c;q!XVd zIm93pf#y^M=?kS3E{6Mt#cQS&QF6jEbmcH{N%Yc*L&3uCmjG2d zF@SKc7GN8-0-|-gaFuN}6@eF1JpywW5dr5ckrS@ii-UA9sNzTw=_HLb@83y}Cc~VK zgIg!9&xhau?J)FcD_b;)pMN&;j}l%05^HwAhsQ#DPXjyN+g$<)_U+t-UO=PBr@^>I zP?62T3gqQJxs^Nw0{F+=8+bh@FUbSBg*!tUFUfY341i;rFa@itFBD5cwtl0e_~M#8 zR^4lE`7-CDB#{aE5u6nQjSChw2^?&_%4Kqo;9I0oR1$NM8{>M!k_&@>n)J-2cwEG( zcBmGYSL-aGpg1z5a^wPMfl7@8J2gztTiu8{hjMkBJWICdvyV76INc;JjH)tPH-($ySk)0PsB#M zhjwK`J9&M9T3(VWGGieR%RcHvsn>myYFDvUgqr9J|G@J?`AU0fbgu)QqUmao>&bWaizgA z-m; z+EHY$Gk15BxX^!>RdoQNL$>VpEAmrTUrHR&j6kX^Nu^J@iaN=+{qDGZVPtRT#o+)G zUzew^bT){l6$p2IDwNIAzqL8V+MPeE4^6lQD^=(T`>Q)sgmvx-7M z(NoZ~3+Q@w0DP$jTYFCje@CI0+IkAS0+%)O@3FwNX=mYlCazDSHqly4w0bsDFM{1c z>nc;-_F=aJc1vUwL9<&^IaUpgNbM=4nndxTX)+A-g;_j-K8|A8H_}ki0qbVl?u53n zu>qG1W(60$x;A4MeAPB7C0hMiCm8s@1HCTQG&+$X`<=;sw1^M@wxdF)uwUim7h~{e zV17Dqny?xSaB4_D`f_L6l>fYUyMzRnZLNGBneUDJQ1(Mht1(BXrhj$dGv3`uQipl| zIIu>ZlMkk1Vxf}B2O?uz)gVoOu)7~1ZGE3|d@BIYg2sqNFjZ+ud`P*eAMv1xWF$^~ zci^v(ScZg8VgSX;K^*c3_m?Ytkno({#`T&zJedcxw%`*Q6_cJB`ykCzyKORj@l-a3 z!)MlmGtfpFf#>6z^^% z>4eX*b#=1RL%7T-1Jc4MZPaNLHnm;$DPFJ{^6?0uDo(xuaqN`YamAlf^| znZ2UAyB9QXo&|iQ`Tr3xx6zTQeT-Xd>C9{KK}5%F+y6UNpc6EUc70&irmeY{$T4=n znn9n5abobYcVIr((PVPEB#gkW=dh_aX46*A7}kx}0@q3j0dOWBEGl^-&;wbp8gxnI`vtPvG7&Pd19*Qf?T6E=2bX^H0LS09>~E&jN^unRgsR4b7&ul9M7q` zT^nWD-PK=qa}KcNJ3TILXg^JK#OgZCj!D5}ijOe@!HG8TpF^1a^4nb02zGZ);}I(9 z5Vr1iLe;nhjE4 zR&cCiX#T%)M)jyFtTLy|(?d7Qq!m_oe5zMUj;#_2n@6i4HRQNO0Tv%9D|9I^kerHf z61l%0?HI_p=@N#y*S(XYUf*%Vinp7c@Ah`<9&W6U0npa=*E1yJR27r}XgQ(xD5q7_ zrD1p8=Sq|>&tj)>h^}rhNwzBSGd%;IhkOXB&vQk1tg+p;Ydcq=ZJZ`oJjqns^!>^= QvB$Ol0scH^#3CF300+5Hw*UYD diff --git a/examples/napi/index.d.ts b/examples/napi/index.d.ts index 09c4b881..4883f0e7 100644 --- a/examples/napi/index.d.ts +++ b/examples/napi/index.d.ts @@ -141,6 +141,11 @@ export class Animal { whoami(): string /** This is static... */ static getDogKind(): Kind + /** + * Here are some characters and character sequences + * that should be escaped correctly: + * \[]{}/\:"" + */ returnOtherClass(): Dog returnOtherClassWithCustomConstructor(): Bird } diff --git a/examples/napi/src/class.rs b/examples/napi/src/class.rs index 554d417d..53aa221c 100644 --- a/examples/napi/src/class.rs +++ b/examples/napi/src/class.rs @@ -62,6 +62,9 @@ impl Animal { } #[napi] + /// Here are some characters and character sequences + /// that should be escaped correctly: + /// \[]{}/\:"" pub fn return_other_class(&self) -> Dog { Dog { name: "Doge".to_owned(),