Repository: rokucommunity/brighterscript
Pull request #1449 (2025-04-04 15:13:34)

Merge master (e8dca23) into v1
This includes the ternary transpile fix.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 201b64b3..10069b76 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -398,6 +398,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ## [0.66.0-alpha.0](https://github.com/rokucommunity/brighterscript/compare/v0.65.1...v0.66.0-alpha.0) - 2023-06-09
 ### Changed
  - all the type tracking stuff!
+## [0.69.5](https://github.com/rokucommunity/brighterscript/compare/v0.69.4...v0.69.5) - 2025-04-03
+### Fixed
+ - more safely wrap expressions for template string transpile ([#1445](https://github.com/rokucommunity/brighterscript/pull/1445))
+
+
+
 ## [0.69.4](https://github.com/rokucommunity/brighterscript/compare/v0.69.3...v0.69.4) - 2025-03-31
 ### Changed
  - Support plugin factory detecting brighterscript version ([#1438](https://github.com/rokucommunity/brighterscript/pull/1438))
diff --git a/src/parser/Expression.ts b/src/parser/Expression.ts
index a6b8b083..98c3e519 100644
--- a/src/parser/Expression.ts
+++ b/src/parser/Expression.ts
@@ -1888,7 +1888,8 @@ export class TemplateStringExpression extends Expression {
     }
 
     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 e321a3b5..7c597ea5 100644
--- a/src/parser/tests/expression/TemplateStringExpression.spec.ts
+++ b/src/parser/tests/expression/TemplateStringExpression.spec.ts
@@ -165,7 +165,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
             `);
         });
@@ -177,7 +177,7 @@ describe('TemplateStringExpression', () => {
                 end sub
             `, `
                 sub main()
-                    a = chr(2) + chr(987)
+                    a = (chr(2) + chr(987))
                 end sub
             `);
         });
@@ -189,7 +189,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
             `);
         });
@@ -201,7 +201,7 @@ describe('TemplateStringExpression', () => {
                 end sub
             `, `
                 sub main()
-                    a = chr(10)
+                    a = (chr(10))
                 end sub
             `);
         });
@@ -213,7 +213,7 @@ describe('TemplateStringExpression', () => {
                 end sub
             `, `
                 sub main()
-                    a = chr(13) + chr(10)
+                    a = (chr(13) + chr(10))
                 end sub
             `);
         });
@@ -343,6 +343,56 @@ describe('TemplateStringExpression', () => {
                 `);
             });
 
+            it('wraps result in parens when we have at least one expression', async () => {
+                await 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', async () => {
+                await 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', async () => {
+                await 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', async () => {
+                await testTranspile(`
+                    sub main()
+                        print \`hello world\`
+                    end sub
+                `, `
+                    sub main()
+                        print "hello world"
+                    end sub
+                `);
+            });
+
             it('can be concatenated with regular string', async () => {
                 await testTranspile(`
                     sub main()