Repository: rokucommunity/brighterscript
Pull request #1445 (2025-04-03 14:49:05)

More safely wrap expressions for template string transpile
Fixes a few bugs in the template string transpiling that wasn't safely wrapping items in parentheses.


Patch:
diff --git a/src/parser/Expression.ts b/src/parser/Expression.ts
index 0c1561de..a25acbc0 100644
--- a/src/parser/Expression.ts
+++ b/src/parser/Expression.ts
@@ -1423,7 +1423,8 @@ export class TemplateStringExpression extends Expression {
     public readonly range: Range | undefined;
 
     transpile(state: BrsTranspileState) {
-        if (this.quasis.length === 1 && this.expressions.length === 0) {
+        //if this is essentially just a normal brightscript string but with backticks, transpile it as a normal string without parens
+        if (this.expressions.length === 0 && this.quasis.length === 1 && this.quasis[0].expressions.length === 1) {
             return this.quasis[0].transpile(state);
         }
         let result = ['('];


Test patch:
diff --git a/src/parser/tests/expression/TemplateStringExpression.spec.ts b/src/parser/tests/expression/TemplateStringExpression.spec.ts
index b87408d5..72258dd4 100644
--- a/src/parser/tests/expression/TemplateStringExpression.spec.ts
+++ b/src/parser/tests/expression/TemplateStringExpression.spec.ts
@@ -167,7 +167,7 @@ describe('TemplateStringExpression', () => {
                 end sub
             `, `
                 sub main()
-                    a = chr(13) + chr(10) + chr(96) + chr(36)
+                    a = (chr(13) + chr(10) + chr(96) + chr(36))
                 end sub
             `);
         });
@@ -179,7 +179,7 @@ describe('TemplateStringExpression', () => {
                 end sub
             `, `
                 sub main()
-                    a = chr(2) + chr(987)
+                    a = (chr(2) + chr(987))
                 end sub
             `);
         });
@@ -191,7 +191,7 @@ describe('TemplateStringExpression', () => {
                 end sub
             `, `
                 sub main()
-                    a = "hello world" + chr(10) + "I am multiline"
+                    a = ("hello world" + chr(10) + "I am multiline")
                 end sub
             `);
         });
@@ -203,7 +203,7 @@ describe('TemplateStringExpression', () => {
                 end sub
             `, `
                 sub main()
-                    a = chr(10)
+                    a = (chr(10))
                 end sub
             `);
         });
@@ -215,7 +215,7 @@ describe('TemplateStringExpression', () => {
                 end sub
             `, `
                 sub main()
-                    a = chr(13) + chr(10)
+                    a = (chr(13) + chr(10))
                 end sub
             `);
         });
@@ -345,6 +345,56 @@ describe('TemplateStringExpression', () => {
                 `);
             });
 
+            it('wraps result in parens when we have at least one expression', () => {
+                testTranspile(`
+                    sub main()
+                        print \`hello \${1}\`
+                    end sub
+                `, `
+                    sub main()
+                        print ("hello " + bslib_toString(1))
+                    end sub
+                `);
+            });
+
+            it('wraps result in parens when we have at least one escaped char', () => {
+                testTranspile(`
+                    sub main()
+                        print \`hello \\nworld\`
+                    end sub
+                `, `
+                    sub main()
+                        print ("hello " + chr(10) + "world")
+                    end sub
+                `);
+            });
+
+            it('wraps result in parens when we have an expression and at least one escaped char', () => {
+                testTranspile(`
+                    sub main()
+                        num = 1
+                        print \`hello \${num} \\nworld\`
+                    end sub
+                `, `
+                    sub main()
+                        num = 1
+                        print ("hello " + bslib_toString(num) + " " + chr(10) + "world")
+                    end sub
+                `);
+            });
+
+            it('does not wrap a plain string with parens', () => {
+                testTranspile(`
+                    sub main()
+                        print \`hello world\`
+                    end sub
+                `, `
+                    sub main()
+                        print "hello world"
+                    end sub
+                `);
+            });
+
             it('can be concatenated with regular string', () => {
                 testTranspile(`
                     sub main()