File tree Expand file tree Collapse file tree 5 files changed +49
-4
lines changed Expand file tree Collapse file tree 5 files changed +49
-4
lines changed Original file line number Diff line number Diff line change @@ -439,7 +439,9 @@ impl Code for Expression {
439439 ref right,
440440 ..
441441 } => {
442- if left. binding_power ( ) < self . binding_power ( ) {
442+ let bp = self . binding_power ( ) ;
443+
444+ if left. binding_power ( ) < bp {
443445 gen. write_byte ( b'(' ) ;
444446 gen. write ( left) ;
445447 gen. write_byte ( b')' ) ;
@@ -449,7 +451,14 @@ impl Code for Expression {
449451 gen. write_min ( b" " , b"" ) ;
450452 gen. write ( operator) ;
451453 gen. write_min ( b" " , b"" ) ;
452- gen. write ( right) ;
454+
455+ if right. needs_parens ( bp) {
456+ gen. write_byte ( b'(' ) ;
457+ gen. write ( right) ;
458+ gen. write_byte ( b')' ) ;
459+ } else {
460+ gen. write ( right) ;
461+ }
453462 } ,
454463
455464 Expression :: Prefix {
Original file line number Diff line number Diff line change @@ -343,6 +343,30 @@ impl Expression {
343343 arguments : arguments,
344344 }
345345 }
346+
347+ #[ inline]
348+ pub fn parenthesize ( mut self ) -> Expression {
349+ if let Expression :: Binary {
350+ ref mut parenthesized,
351+ ..
352+ } = self {
353+ * parenthesized = true ;
354+ }
355+
356+ self
357+ }
358+
359+ #[ inline]
360+ pub fn needs_parens ( & self , bp : u8 ) -> bool {
361+ match * self {
362+ Expression :: Binary {
363+ ref parenthesized,
364+ ref operator,
365+ ..
366+ } => * parenthesized && bp >= operator. binding_power ( ) ,
367+ _ => false
368+ }
369+ }
346370}
347371
348372impl From < & ' static str > for Expression {
Original file line number Diff line number Diff line change @@ -453,7 +453,7 @@ impl<'a> Parser<'a> {
453453
454454 expect ! ( self , ParenClose ) ;
455455
456- Ok ( expression)
456+ Ok ( expression. parenthesize ( ) )
457457 }
458458 }
459459 }
Original file line number Diff line number Diff line change @@ -344,7 +344,7 @@ impl Transformable for Expression {
344344 left = Expression :: binary (
345345 left,
346346 Addition ,
347- expression
347+ expression. parenthesize ( )
348348 ) ;
349349
350350 if quasi. len ( ) == 0 {
Original file line number Diff line number Diff line change @@ -39,10 +39,22 @@ fn template_strings_plain() {
3939 assert_compile ! ( "`foo\n bar`;" , "\" foo\\ nbar\" ;" ) ;
4040}
4141
42+ #[ test]
43+ fn operator_precedence_and_parens ( ) {
44+ // Preserve parens when necessary
45+ assert_compile ! ( "'foo'+(1+2);" , r#"'foo'+(1+2);"# ) ;
46+
47+ // Should strip parens when not necessary
48+ assert_compile ! ( "(1+2)+'foo';" , r#"1+2+'foo';"# ) ;
49+ assert_compile ! ( "'foo'+(1*2);" , r#"'foo'+1*2;"# ) ;
50+ assert_compile ! ( "(1*2)+'foo';" , r#"1*2+'foo';"# ) ;
51+ }
52+
4253#[ test]
4354fn template_strings_interpolation ( ) {
4455 assert_compile ! ( "`foo${1}bar`;" , r#""foo"+1+"bar";"# ) ;
4556 assert_compile ! ( "`foo${1+2}bar`;" , r#""foo"+(1+2)+"bar";"# ) ;
57+ assert_compile ! ( "`foo${1*2}bar`;" , r#""foo"+1*2+"bar";"# ) ;
4658 assert_compile ! ( "`foo${1}${2**2}bar`;" , r#""foo"+1+Math.pow(2,2)+"bar";"# ) ;
4759 assert_compile ! ( "`foo${1}bar${2**2}`;" , r#""foo"+1+"bar"+Math.pow(2,2);"# ) ;
4860}
You can’t perform that action at this time.
0 commit comments