Repository: rokucommunity/brighterscript
Pull request #914 (2023-09-22 20:18:32)

Fix UnaryExpression transpile for ns and const
Fix a bug transpiling UnaryExpression when referencing namespaces and consts.

**Source:**
```brighterscript
const foo = 1
sub main()
    bar = -foo
end sub
```

***transpiles to: BEFORE***

```brighterscript
sub main()
    bar = -foo 'oops, that should be 1
end sub
```

***transpiles to: AFTER***
```brighterscript
sub main()
    bar = - 1
end sub
```


Patch:
diff --git a/src/bscPlugin/transpile/BrsFilePreTranspileProcessor.ts b/src/bscPlugin/transpile/BrsFilePreTranspileProcessor.ts
index eedfb12e..51416d2d 100644
--- a/src/bscPlugin/transpile/BrsFilePreTranspileProcessor.ts
+++ b/src/bscPlugin/transpile/BrsFilePreTranspileProcessor.ts
@@ -1,5 +1,5 @@
 import { createToken } from '../../astUtils/creators';
-import { isBrsFile, isDottedGetExpression, isLiteralExpression, isVariableExpression } from '../../astUtils/reflection';
+import { isBrsFile, isDottedGetExpression, isLiteralExpression, isUnaryExpression, isVariableExpression } from '../../astUtils/reflection';
 import type { BrsFile } from '../../files/BrsFile';
 import type { BeforeFileTranspileEvent } from '../../interfaces';
 import { TokenKind } from '../../lexer/TokenKind';
@@ -25,7 +25,11 @@ export class BrsFilePreTranspileProcessor {
         const scope = this.event.program.getFirstScopeForFile(this.event.file);
         for (let expression of this.event.file.parser.references.expressions) {
             if (expression) {
-                this.processExpression(expression, scope);
+                if (isUnaryExpression(expression)) {
+                    this.processExpression(expression.right, scope);
+                } else {
+                    this.processExpression(expression, scope);
+                }
             }
         }
     }


Test patch:
diff --git a/src/parser/tests/statement/ConstStatement.spec.ts b/src/parser/tests/statement/ConstStatement.spec.ts
index 89e93270..f8b59589 100644
--- a/src/parser/tests/statement/ConstStatement.spec.ts
+++ b/src/parser/tests/statement/ConstStatement.spec.ts
@@ -209,6 +209,34 @@ describe('ConstStatement', () => {
             );
         });
 
+        it('transpiles simple const in a unary expression', () => {
+            testTranspile(`
+                const foo = 1
+                sub main()
+                    bar = -foo
+                end sub
+            `, `
+                sub main()
+                    bar = - 1
+                end sub
+            `, undefined, 'source/main.bs');
+        });
+
+        it('transpiles complex const in a unary expression', () => {
+            testTranspile(`
+                namespace some.consts
+                    const foo = 1
+                end namespace
+                sub main()
+                    bar = -some.consts.foo
+                end sub
+            `, `
+                sub main()
+                    bar = - 1
+                end sub
+            `, undefined, 'source/main.bs');
+        });
+
         it('shows up in namespace completions', () => {
             program.setFile('source/main.bs', `
                 namespace constants
diff --git a/src/parser/tests/statement/Enum.spec.ts b/src/parser/tests/statement/Enum.spec.ts
index 80299ae7..a12bcec8 100644
--- a/src/parser/tests/statement/Enum.spec.ts
+++ b/src/parser/tests/statement/Enum.spec.ts
@@ -933,107 +933,139 @@ describe('EnumStatement', () => {
                 kind: CompletionItemKind.Enum
             }]);
         });
+    });
 
-        it('handles both sides of a logical expression', () => {
-            testTranspile(`
-                sub main()
-                    dir = m.direction = Direction.up
-                    dir = Direction.up = m.direction
-                end sub
-                enum Direction
-                    up = "up"
-                    down = "down"
-                end enum
-            `, `
-                sub main()
-                    dir = m.direction = "up"
-                    dir = "up" = m.direction
-                end sub
-            `);
-        });
+    it('transpiles simple enum in a unary expression', () => {
+        testTranspile(`
+            enum SomeEnum
+                foo = 1
+            end enum
+            sub main()
+                bar = -SomeEnum.foo
+            end sub
+        `, `
+            sub main()
+                bar = - 1
+            end sub
+        `, undefined, 'source/main.bs');
+    });
 
-        it('handles when found in boolean expressions', () => {
-            testTranspile(`
-                sub main()
-                    result = Direction.up = "up" or Direction.down = "down" and Direction.up = Direction.down
-                end sub
-                enum Direction
-                    up = "up"
-                    down = "down"
+    it('transpiles comples enum in a unary expression', () => {
+        testTranspile(`
+            namespace name.space
+                enum SomeEnum
+                    foo = 1
                 end enum
-            `, `
-                sub main()
-                    result = "up" = "up" or "down" = "down" and "up" = "down"
-                end sub
-            `);
-        });
+            end namespace
+            sub main()
+                bar = -name.space.SomeEnum.foo
+            end sub
+        `, `
+            sub main()
+                bar = - 1
+            end sub
+        `, undefined, 'source/main.bs');
+    });
 
-        it('replaces enum values in if statements', () => {
-            testTranspile(`
-                sub main()
-                    if m.direction = Direction.up
-                        print Direction.up
-                    end if
-                end sub
-                enum Direction
-                    up = "up"
-                    down = "down"
-                end enum
-            `, `
-                sub main()
-                    if m.direction = "up"
-                        print "up"
-                    end if
-                end sub
-            `);
-        });
+    it('handles both sides of a logical expression', () => {
+        testTranspile(`
+            sub main()
+                dir = m.direction = Direction.up
+                dir = Direction.up = m.direction
+            end sub
+            enum Direction
+                up = "up"
+                down = "down"
+            end enum
+        `, `
+            sub main()
+                dir = m.direction = "up"
+                dir = "up" = m.direction
+            end sub
+        `);
+    });
 
-        it('replaces enum values in function default parameter value expressions', () => {
-            testTranspile(`
-                sub speak(dir = Direction.up)
-                end sub
-                enum Direction
-                    up = "up"
-                end enum
-            `, `
-                sub speak(dir = "up")
-                end sub
-            `);
-        });
+    it('handles when found in boolean expressions', () => {
+        testTranspile(`
+            sub main()
+                result = Direction.up = "up" or Direction.down = "down" and Direction.up = Direction.down
+            end sub
+            enum Direction
+                up = "up"
+                down = "down"
+            end enum
+        `, `
+            sub main()
+                result = "up" = "up" or "down" = "down" and "up" = "down"
+            end sub
+        `);
+    });
 
-        it('replaces enum values in for loops', () => {
-            testTranspile(`
-                sub main()
-                    for i = Loop.start to Loop.end step Loop.step
-                    end for
-                end sub
-                enum Loop
-                    start = 0
-                    end = 10
-                    step = 1
-                end enum
-            `, `
-                sub main()
-                    for i = 0 to 10 step 1
-                    end for
-                end sub
-            `);
-        });
+    it('replaces enum values in if statements', () => {
+        testTranspile(`
+            sub main()
+                if m.direction = Direction.up
+                    print Direction.up
+                end if
+            end sub
+            enum Direction
+                up = "up"
+                down = "down"
+            end enum
+        `, `
+            sub main()
+                if m.direction = "up"
+                    print "up"
+                end if
+            end sub
+        `);
+    });
 
-        it('transpiles enum values when used in complex expressions', () => {
-            testTranspile(`
-                sub main()
-                    print Direction.up.toStr()
-                end sub
-                enum Direction
-                    up = "up"
-                    down = "down"
-                end enum
-            `, `
-                sub main()
-                    print "up".toStr()
-                end sub
-            `);
-        });
+    it('replaces enum values in function default parameter value expressions', () => {
+        testTranspile(`
+            sub speak(dir = Direction.up)
+            end sub
+            enum Direction
+                up = "up"
+            end enum
+        `, `
+            sub speak(dir = "up")
+            end sub
+        `);
+    });
+
+    it('replaces enum values in for loops', () => {
+        testTranspile(`
+            sub main()
+                for i = Loop.start to Loop.end step Loop.step
+                end for
+            end sub
+            enum Loop
+                start = 0
+                end = 10
+                step = 1
+            end enum
+        `, `
+            sub main()
+                for i = 0 to 10 step 1
+                end for
+            end sub
+        `);
+    });
+
+    it('transpiles enum values when used in complex expressions', () => {
+        testTranspile(`
+            sub main()
+                print Direction.up.toStr()
+            end sub
+            enum Direction
+                up = "up"
+                down = "down"
+            end enum
+        `, `
+            sub main()
+                print "up".toStr()
+            end sub
+        `);
     });
 });