brighterscript 0.73.1 → 0.73.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/dist/BusyStatusTracker.js +3 -0
  2. package/dist/BusyStatusTracker.js.map +1 -1
  3. package/dist/DiagnosticMessages.d.ts +6 -1
  4. package/dist/DiagnosticMessages.js +11 -2
  5. package/dist/DiagnosticMessages.js.map +1 -1
  6. package/dist/LanguageServer.d.ts +1 -1
  7. package/dist/LanguageServer.js +1 -1
  8. package/dist/LanguageServer.js.map +1 -1
  9. package/dist/Logger.d.ts +7 -7
  10. package/dist/Logger.js.map +1 -1
  11. package/dist/Program.d.ts +12 -5
  12. package/dist/Program.js +14 -3
  13. package/dist/Program.js.map +1 -1
  14. package/dist/ProgramBuilder.js.map +1 -1
  15. package/dist/RokuConstants.d.ts +37 -2
  16. package/dist/RokuConstants.js +32 -3
  17. package/dist/RokuConstants.js.map +1 -1
  18. package/dist/Scope.d.ts +3 -3
  19. package/dist/Scope.js.map +1 -1
  20. package/dist/ScopeNamespaceLookup.js.map +1 -1
  21. package/dist/Throttler.d.ts +1 -1
  22. package/dist/Throttler.js.map +1 -1
  23. package/dist/XmlScope.d.ts +2 -2
  24. package/dist/astUtils/reflection.js.map +1 -1
  25. package/dist/astUtils/visitors.d.ts +1 -1
  26. package/dist/astUtils/visitors.js +2 -0
  27. package/dist/astUtils/visitors.js.map +1 -1
  28. package/dist/bscPlugin/BscPlugin.js +4 -0
  29. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  30. package/dist/bscPlugin/CallExpressionInfo.js.map +1 -1
  31. package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -1
  32. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +3 -3
  33. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  34. package/dist/bscPlugin/definition/DefinitionProvider.d.ts +67 -2
  35. package/dist/bscPlugin/definition/DefinitionProvider.js +242 -4
  36. package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -1
  37. package/dist/bscPlugin/inlayHints/InlayHintProcessor.js.map +1 -1
  38. package/dist/bscPlugin/references/ReferencesProvider.js +7 -1
  39. package/dist/bscPlugin/references/ReferencesProvider.js.map +1 -1
  40. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
  41. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -1
  42. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +7 -0
  43. package/dist/bscPlugin/validation/BrsFileValidator.js +17 -3
  44. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  45. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  46. package/dist/bscPlugin/validation/XmlFileValidator.d.ts +11 -0
  47. package/dist/bscPlugin/validation/XmlFileValidator.js +31 -0
  48. package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -1
  49. package/dist/cli.js.map +1 -1
  50. package/dist/common/Sequencer.js.map +1 -1
  51. package/dist/diagnosticUtils.d.ts +1 -1
  52. package/dist/diagnosticUtils.js.map +1 -1
  53. package/dist/files/BrsFile.d.ts +2 -2
  54. package/dist/files/BrsFile.js +4 -0
  55. package/dist/files/BrsFile.js.map +1 -1
  56. package/dist/files/XmlFile.js +1 -0
  57. package/dist/files/XmlFile.js.map +1 -1
  58. package/dist/interfaces.d.ts +6 -3
  59. package/dist/lexer/Lexer.d.ts +26 -0
  60. package/dist/lexer/Lexer.js +147 -18
  61. package/dist/lexer/Lexer.js.map +1 -1
  62. package/dist/lexer/TokenKind.d.ts +27 -0
  63. package/dist/lexer/TokenKind.js +77 -3
  64. package/dist/lexer/TokenKind.js.map +1 -1
  65. package/dist/lsp/ActionQueue.js.map +1 -1
  66. package/dist/lsp/DocumentManager.js +4 -0
  67. package/dist/lsp/DocumentManager.js.map +1 -1
  68. package/dist/lsp/LspProject.d.ts +2 -2
  69. package/dist/lsp/Project.d.ts +2 -2
  70. package/dist/lsp/Project.js +2 -0
  71. package/dist/lsp/Project.js.map +1 -1
  72. package/dist/lsp/ProjectManager.d.ts +2 -2
  73. package/dist/lsp/ProjectManager.js +3 -1
  74. package/dist/lsp/ProjectManager.js.map +1 -1
  75. package/dist/lsp/worker/MessageHandler.js.map +1 -1
  76. package/dist/lsp/worker/WorkerThreadProject.d.ts +2 -2
  77. package/dist/lsp/worker/WorkerThreadProject.js +3 -1
  78. package/dist/lsp/worker/WorkerThreadProject.js.map +1 -1
  79. package/dist/parser/AstNode.d.ts +55 -1
  80. package/dist/parser/AstNode.js +56 -5
  81. package/dist/parser/AstNode.js.map +1 -1
  82. package/dist/parser/BrsTranspileState.d.ts +44 -0
  83. package/dist/parser/BrsTranspileState.js +49 -0
  84. package/dist/parser/BrsTranspileState.js.map +1 -1
  85. package/dist/parser/Expression.d.ts +14 -0
  86. package/dist/parser/Expression.js +28 -0
  87. package/dist/parser/Expression.js.map +1 -1
  88. package/dist/parser/Parser.d.ts +0 -5
  89. package/dist/parser/Parser.js +4 -8
  90. package/dist/parser/Parser.js.map +1 -1
  91. package/dist/parser/SGParser.js +7 -2
  92. package/dist/parser/SGParser.js.map +1 -1
  93. package/dist/parser/Statement.d.ts +2 -2
  94. package/dist/parser/Statement.js +32 -2
  95. package/dist/parser/Statement.js.map +1 -1
  96. package/dist/preprocessor/Preprocessor.js.map +1 -1
  97. package/dist/util.d.ts +13 -2
  98. package/dist/util.js +24 -2
  99. package/dist/util.js.map +1 -1
  100. package/dist/validators/ClassValidator.d.ts +5 -4
  101. package/dist/validators/ClassValidator.js.map +1 -1
  102. package/package.json +1 -1
@@ -42,6 +42,7 @@ export declare abstract class AstNode {
42
42
  * @param matcher a function called for each node. If you return true, this function returns the specified node. If you return a node, that node is returned. all other return values continue the loop
43
43
  * The function's second parameter is a cancellation token. If you'd like to short-circuit the walk, call `cancellationToken.cancel()`, then this function will return `undefined`
44
44
  */
45
+ findAncestor<TNode extends AstNode = AstNode>(matcher: (node: AstNode) => node is TNode): TNode | undefined;
45
46
  findAncestor<TNode extends AstNode = AstNode>(matcher: (node: AstNode, cancellationToken: CancellationTokenSource) => boolean | AstNode | undefined | void): TNode | undefined;
46
47
  /**
47
48
  * Find the first child where the matcher evaluates to true.
@@ -56,11 +57,62 @@ export declare abstract class AstNode {
56
57
  * Links all child nodes to their parent AstNode, and the same with symbol tables. This performs a full AST walk, so you should use this sparingly
57
58
  */
58
59
  link(): void;
60
+ /**
61
+ * The previous step in this expression, or undefined if this node doesn't build on another
62
+ * expression. Overridden by dotted/indexed gets, calls, and other chaining nodes.
63
+ *
64
+ * Each node in a chain spans a whole prefix of the source, so this walks to the next-shorter
65
+ * prefix. Given `a.b.c`, there are only three nodes:
66
+ * ```
67
+ * a.b.c .previousInChain -> a.b
68
+ * a.b .previousInChain -> a
69
+ * a .previousInChain -> undefined
70
+ * ```
71
+ *
72
+ * This walks toward the AST *child*, since chains are stored inverted: the full expression is
73
+ * the top node and its base is the deepest descendant. It is not `parent` reversed though -
74
+ * arguments and index values have a `parent`, but are never anything's `previousInChain`,
75
+ * because they're separate expressions that merely sit inside this one:
76
+ * ```
77
+ * a.b(arg) //CallExpression.previousInChain is `a.b`, NOT `arg`
78
+ * a[i] //IndexedGetExpression.previousInChain is `a`, NOT `i`
79
+ * ```
80
+ */
81
+ get previousInChain(): AstNode | undefined;
82
+ /**
83
+ * Is this node a complete expression, rather than one step inside a longer one?
84
+ *
85
+ * True when nothing chains onto this node. Statements are always terminal. Use this to find
86
+ * whole expressions while walking, instead of also matching every prefix inside them.
87
+ *
88
+ * ```
89
+ * print a.b.c(arg)
90
+ *
91
+ * //a.b.c(arg) yes - the whole expression
92
+ * //a.b.c no - a.b.c(arg) chains onto it
93
+ * //a.b no - a.b.c chains onto it
94
+ * //a no - a.b chains onto it
95
+ * //arg yes - an argument, so an expression of its own
96
+ * ```
97
+ *
98
+ * An argument is terminal no matter how long it is, because nothing chains onto it. Both of
99
+ * these are terminal, even though they sit inside the call:
100
+ * ```
101
+ * print doSomething(x.y, 1 + 2)
102
+ *
103
+ * //x.y yes
104
+ * //1 + 2 yes
105
+ * ```
106
+ *
107
+ * Requires `parent` to be set, so the node must already be linked (see `link()`). An
108
+ * unlinked node has no parent, so it reports `true`.
109
+ */
110
+ isTerminal(): boolean;
59
111
  /**
60
112
  * Clone this node and all of its children. This creates a completely detached and identical copy of the AST.
61
113
  * All tokens, statements, expressions, range, and location are cloned.
62
114
  */
63
- abstract clone(): any;
115
+ abstract clone(): AstNode;
64
116
  /**
65
117
  * Helper function for creating a clone. This will clone any attached annotations, as well as reparent the cloned node's children to the clone
66
118
  */
@@ -77,6 +129,7 @@ export declare abstract class Statement extends AstNode {
77
129
  * Annotations for this statement
78
130
  */
79
131
  annotations: AnnotationExpression[] | undefined;
132
+ abstract clone(): Statement;
80
133
  }
81
134
  /** A BrightScript expression */
82
135
  export declare abstract class Expression extends AstNode {
@@ -84,4 +137,5 @@ export declare abstract class Expression extends AstNode {
84
137
  * When being considered by the walk visitor, this describes what type of element the current class is.
85
138
  */
86
139
  visitMode: InternalWalkMode;
140
+ abstract clone(): Expression;
87
141
  }
@@ -37,11 +37,6 @@ class AstNode {
37
37
  //but it is not so easy to convince the typechecker of this.
38
38
  return undefined;
39
39
  }
40
- /**
41
- * Walk upward and return the first node that results in `true` from the matcher.
42
- * @param matcher a function called for each node. If you return true, this function returns the specified node. If you return a node, that node is returned. all other return values continue the loop
43
- * The function's second parameter is a cancellation token. If you'd like to short-circuit the walk, call `cancellationToken.cancel()`, then this function will return `undefined`
44
- */
45
40
  findAncestor(matcher) {
46
41
  let node = this.parent;
47
42
  const cancel = new vscode_languageserver_1.CancellationTokenSource();
@@ -94,6 +89,62 @@ class AstNode {
94
89
  walkMode: visitors_1.WalkMode.visitAllRecursive
95
90
  });
96
91
  }
92
+ /**
93
+ * The previous step in this expression, or undefined if this node doesn't build on another
94
+ * expression. Overridden by dotted/indexed gets, calls, and other chaining nodes.
95
+ *
96
+ * Each node in a chain spans a whole prefix of the source, so this walks to the next-shorter
97
+ * prefix. Given `a.b.c`, there are only three nodes:
98
+ * ```
99
+ * a.b.c .previousInChain -> a.b
100
+ * a.b .previousInChain -> a
101
+ * a .previousInChain -> undefined
102
+ * ```
103
+ *
104
+ * This walks toward the AST *child*, since chains are stored inverted: the full expression is
105
+ * the top node and its base is the deepest descendant. It is not `parent` reversed though -
106
+ * arguments and index values have a `parent`, but are never anything's `previousInChain`,
107
+ * because they're separate expressions that merely sit inside this one:
108
+ * ```
109
+ * a.b(arg) //CallExpression.previousInChain is `a.b`, NOT `arg`
110
+ * a[i] //IndexedGetExpression.previousInChain is `a`, NOT `i`
111
+ * ```
112
+ */
113
+ get previousInChain() {
114
+ return undefined;
115
+ }
116
+ /**
117
+ * Is this node a complete expression, rather than one step inside a longer one?
118
+ *
119
+ * True when nothing chains onto this node. Statements are always terminal. Use this to find
120
+ * whole expressions while walking, instead of also matching every prefix inside them.
121
+ *
122
+ * ```
123
+ * print a.b.c(arg)
124
+ *
125
+ * //a.b.c(arg) yes - the whole expression
126
+ * //a.b.c no - a.b.c(arg) chains onto it
127
+ * //a.b no - a.b.c chains onto it
128
+ * //a no - a.b chains onto it
129
+ * //arg yes - an argument, so an expression of its own
130
+ * ```
131
+ *
132
+ * An argument is terminal no matter how long it is, because nothing chains onto it. Both of
133
+ * these are terminal, even though they sit inside the call:
134
+ * ```
135
+ * print doSomething(x.y, 1 + 2)
136
+ *
137
+ * //x.y yes
138
+ * //1 + 2 yes
139
+ * ```
140
+ *
141
+ * Requires `parent` to be set, so the node must already be linked (see `link()`). An
142
+ * unlinked node has no parent, so it reports `true`.
143
+ */
144
+ isTerminal() {
145
+ //walk up, then back down: if we don't land on ourselves, nothing chains onto us
146
+ return this.parent === undefined || this.parent.previousInChain !== this;
147
+ }
97
148
  /**
98
149
  * Helper function for creating a clone. This will clone any attached annotations, as well as reparent the cloned node's children to the clone
99
150
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AstNode.js","sourceRoot":"","sources":["../../src/parser/AstNode.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AstNode.js","sourceRoot":"","sources":["../../src/parser/AstNode.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import type { Range } from 'vscode-languageserver';
2
2
  import { AstEditor } from '../astUtils/AstEditor';
3
3
  import type { BrsFile } from '../files/BrsFile';
4
+ import type { FirmwareCapabilities } from '../RokuConstants';
4
5
  import type { ClassStatement } from './Statement';
5
6
  import { TranspileState } from './TranspileState';
6
7
  export declare class BrsTranspileState extends TranspileState {
@@ -25,4 +26,47 @@ export declare class BrsTranspileState extends TranspileState {
25
26
  * An AST editor that can be used by the AST nodes to do various transformations to the AST which will be reverted at the end of the transpile cycle
26
27
  */
27
28
  editor: AstEditor;
29
+ /**
30
+ * What the target firmware natively understands. Captured once when the state is created —
31
+ * capabilities are derived from config and cannot change partway through a transpile.
32
+ */
33
+ readonly firmwareCapabilities: FirmwareCapabilities;
34
+ /**
35
+ * Stack of loop-label trackers, one per enclosing loop currently being transpiled. Only used
36
+ * when `continue` must be rewritten as a `goto` for firmware older than
37
+ * CONTINUE_MIN_FIRMWARE_VERSION.
38
+ */
39
+ private loopLabels;
40
+ private loopLabelSequence;
41
+ /**
42
+ * Begin tracking a loop label for the loop about to be transpiled. The label is allocated
43
+ * eagerly but only emitted if a nested `continue` actually asks for it via `getLoopLabel()`.
44
+ * `blockDepth` records the depth the loop's own body block will occupy, so the block that
45
+ * emits the label can tell whether the label belongs to it or to a nested loop.
46
+ */
47
+ pushLoopLabel(): void;
48
+ /**
49
+ * Look at the innermost loop label without removing it. Used by Block.transpile to decide
50
+ * whether it owns the pending label.
51
+ */
52
+ peekLoopLabel(): {
53
+ label: string;
54
+ wasAccessed: boolean;
55
+ blockDepth: number;
56
+ };
57
+ /**
58
+ * Stop tracking the innermost loop label. Returns the tracker so the loop can decide whether
59
+ * it needs to emit the end-of-body label (i.e. when `wasAccessed` is true).
60
+ */
61
+ popLoopLabel(): {
62
+ label: string;
63
+ wasAccessed: boolean;
64
+ blockDepth: number;
65
+ };
66
+ /**
67
+ * Get the label marking the end of the innermost loop body, flagging it as needed so the
68
+ * enclosing loop knows to emit the label itself. Returns undefined when there is no enclosing
69
+ * loop (a `continue` outside a loop, which validation already flags as an error).
70
+ */
71
+ getLoopLabel(): string;
28
72
  }
@@ -16,7 +16,56 @@ class BrsTranspileState extends TranspileState_1.TranspileState {
16
16
  * An AST editor that can be used by the AST nodes to do various transformations to the AST which will be reverted at the end of the transpile cycle
17
17
  */
18
18
  this.editor = new AstEditor_1.AstEditor();
19
+ /**
20
+ * Stack of loop-label trackers, one per enclosing loop currently being transpiled. Only used
21
+ * when `continue` must be rewritten as a `goto` for firmware older than
22
+ * CONTINUE_MIN_FIRMWARE_VERSION.
23
+ */
24
+ this.loopLabels = [];
25
+ this.loopLabelSequence = 0;
19
26
  this.bslibPrefix = this.file.program.bslibPrefix;
27
+ this.firmwareCapabilities = this.file.program.firmwareCapabilities;
28
+ }
29
+ /**
30
+ * Begin tracking a loop label for the loop about to be transpiled. The label is allocated
31
+ * eagerly but only emitted if a nested `continue` actually asks for it via `getLoopLabel()`.
32
+ * `blockDepth` records the depth the loop's own body block will occupy, so the block that
33
+ * emits the label can tell whether the label belongs to it or to a nested loop.
34
+ */
35
+ pushLoopLabel() {
36
+ this.loopLabels.push({
37
+ label: `BRIGHTERSCRIPT_CONTINUE_${this.loopLabelSequence++}`,
38
+ wasAccessed: false,
39
+ //the loop body block increments blockDepth before emitting its statements
40
+ blockDepth: this.blockDepth + 1
41
+ });
42
+ }
43
+ /**
44
+ * Look at the innermost loop label without removing it. Used by Block.transpile to decide
45
+ * whether it owns the pending label.
46
+ */
47
+ peekLoopLabel() {
48
+ return this.loopLabels[this.loopLabels.length - 1];
49
+ }
50
+ /**
51
+ * Stop tracking the innermost loop label. Returns the tracker so the loop can decide whether
52
+ * it needs to emit the end-of-body label (i.e. when `wasAccessed` is true).
53
+ */
54
+ popLoopLabel() {
55
+ return this.loopLabels.pop();
56
+ }
57
+ /**
58
+ * Get the label marking the end of the innermost loop body, flagging it as needed so the
59
+ * enclosing loop knows to emit the label itself. Returns undefined when there is no enclosing
60
+ * loop (a `continue` outside a loop, which validation already flags as an error).
61
+ */
62
+ getLoopLabel() {
63
+ const loopLabel = this.loopLabels[this.loopLabels.length - 1];
64
+ if (!loopLabel) {
65
+ return undefined;
66
+ }
67
+ loopLabel.wasAccessed = true;
68
+ return loopLabel.label;
20
69
  }
21
70
  }
22
71
  exports.BrsTranspileState = BrsTranspileState;
@@ -1 +1 @@
1
- {"version":3,"file":"BrsTranspileState.js","sourceRoot":"","sources":["../../src/parser/BrsTranspileState.ts"],"names":[],"mappings":";;;AACA,qDAAkD;AAGlD,qDAAkD;AAElD,MAAa,iBAAkB,SAAQ,+BAAc;IACjD,YACW,IAAa;QAEpB,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAFnC,SAAI,GAAJ,IAAI,CAAS;QAWxB;;;WAGG;QACH,YAAO,GAAG,EAER,CAAC;QAOH;;WAEG;QACI,WAAM,GAAG,IAAI,qBAAS,EAAE,CAAC;QAxB5B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;IACrD,CAAC;CAwBJ;AA9BD,8CA8BC"}
1
+ {"version":3,"file":"BrsTranspileState.js","sourceRoot":"","sources":["../../src/parser/BrsTranspileState.ts"],"names":[],"mappings":";;;AACA,qDAAkD;AAIlD,qDAAkD;AAElD,MAAa,iBAAkB,SAAQ,+BAAc;IACjD,YACW,IAAa;QAEpB,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAFnC,SAAI,GAAJ,IAAI,CAAS;QAYxB;;;WAGG;QACH,YAAO,GAAG,EAER,CAAC;QAOH;;WAEG;QACI,WAAM,GAAG,IAAI,qBAAS,EAAE,CAAC;QAQhC;;;;WAIG;QACK,eAAU,GAAG,EAAwE,CAAC;QAEtF,sBAAiB,GAAG,CAAC,CAAC;QAxC1B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;QACjD,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC;IACvE,CAAC;IAwCD;;;;;OAKG;IACI,aAAa;QAChB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACjB,KAAK,EAAE,2BAA2B,IAAI,CAAC,iBAAiB,EAAE,EAAE;YAC5D,WAAW,EAAE,KAAK;YAClB,0EAA0E;YAC1E,UAAU,EAAE,IAAI,CAAC,UAAU,GAAG,CAAC;SAClC,CAAC,CAAC;IACP,CAAC;IAED;;;OAGG;IACI,aAAa;QAChB,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACI,YAAY;QACf,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACI,YAAY;QACf,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,SAAS,EAAE;YACZ,OAAO,SAAS,CAAC;SACpB;QACD,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC;QAC7B,OAAO,SAAS,CAAC,KAAK,CAAC;IAC3B,CAAC;CACJ;AA3FD,8CA2FC"}
@@ -41,6 +41,8 @@ export declare class CallExpression extends Expression {
41
41
  */
42
42
  openingParen: Token, closingParen: Token, args: Expression[], unused?: any);
43
43
  readonly range: Range | undefined;
44
+ /** `a.b()` -> `a.b` (not the args) */
45
+ get previousInChain(): Expression;
44
46
  /**
45
47
  * Get the name of the wrapping namespace (if it exists)
46
48
  * @deprecated use `.findAncestor(isNamespaceStatement)` instead.
@@ -121,6 +123,8 @@ export declare class NamespacedVariableNameExpression extends Expression {
121
123
  readonly expression: DottedGetExpression | VariableExpression;
122
124
  constructor(expression: DottedGetExpression | VariableExpression);
123
125
  range: Range | undefined;
126
+ /** unwraps to the `Alpha.Beta` inside */
127
+ get previousInChain(): DottedGetExpression | VariableExpression;
124
128
  transpile(state: BrsTranspileState): SourceNode[];
125
129
  getTypedef(state: any): any[];
126
130
  getNameParts(): string[];
@@ -141,6 +145,8 @@ export declare class DottedGetExpression extends Expression {
141
145
  */
142
146
  dot: Token);
143
147
  readonly range: Range | undefined;
148
+ /** `a.b` -> `a` */
149
+ get previousInChain(): Expression;
144
150
  transpile(state: BrsTranspileState): (string | SourceNode | TranspileResult)[];
145
151
  getTypedef(state: BrsTranspileState): (string | SourceNode | TranspileResult)[];
146
152
  walk(visitor: WalkVisitor, options: WalkOptions): void;
@@ -159,6 +165,8 @@ export declare class XmlAttributeGetExpression extends Expression {
159
165
  */
160
166
  at: Token);
161
167
  readonly range: Range | undefined;
168
+ /** `a@b` -> `a` */
169
+ get previousInChain(): Expression;
162
170
  transpile(state: BrsTranspileState): (string | SourceNode | TranspileResult)[];
163
171
  walk(visitor: WalkVisitor, options: WalkOptions): void;
164
172
  clone(): XmlAttributeGetExpression;
@@ -186,6 +194,8 @@ export declare class IndexedGetExpression extends Expression {
186
194
  */
187
195
  additionalIndexes?: Expression[]);
188
196
  readonly range: Range | undefined;
197
+ /** `a[i]` -> `a` (not the index) */
198
+ get previousInChain(): Expression;
189
199
  transpile(state: BrsTranspileState): any[];
190
200
  walk(visitor: WalkVisitor, options: WalkOptions): void;
191
201
  clone(): IndexedGetExpression;
@@ -337,6 +347,8 @@ export declare class NewExpression extends Expression {
337
347
  */
338
348
  get className(): NamespacedVariableNameExpression;
339
349
  readonly range: Range | undefined;
350
+ /** `new Alpha.Beta()` -> `Alpha.Beta()` */
351
+ get previousInChain(): CallExpression;
340
352
  transpile(state: BrsTranspileState): TranspileResult;
341
353
  walk(visitor: WalkVisitor, options: WalkOptions): void;
342
354
  clone(): NewExpression;
@@ -350,6 +362,8 @@ export declare class CallfuncExpression extends Expression {
350
362
  readonly closingParen: Token;
351
363
  constructor(callee: Expression, operator: Token, methodName: Identifier, openingParen: Token, args: Expression[], closingParen: Token);
352
364
  readonly range: Range | undefined;
365
+ /** `a@.b()` -> `a` (not the args) */
366
+ get previousInChain(): Expression;
353
367
  /**
354
368
  * Get the name of the wrapping namespace (if it exists)
355
369
  * @deprecated use `.findAncestor(isNamespaceStatement)` instead.
@@ -55,6 +55,10 @@ class CallExpression extends AstNode_1.Expression {
55
55
  this.args = args;
56
56
  this.range = util_1.default.createBoundingRange(this.callee, this.openingParen, ...args !== null && args !== void 0 ? args : [], this.closingParen);
57
57
  }
58
+ /** `a.b()` -> `a.b` (not the args) */
59
+ get previousInChain() {
60
+ return this.callee;
61
+ }
58
62
  /**
59
63
  * Get the name of the wrapping namespace (if it exists)
60
64
  * @deprecated use `.findAncestor(isNamespaceStatement)` instead.
@@ -378,6 +382,10 @@ class NamespacedVariableNameExpression extends AstNode_1.Expression {
378
382
  this.expression = expression;
379
383
  this.range = expression === null || expression === void 0 ? void 0 : expression.range;
380
384
  }
385
+ /** unwraps to the `Alpha.Beta` inside */
386
+ get previousInChain() {
387
+ return this.expression;
388
+ }
381
389
  transpile(state) {
382
390
  return [
383
391
  state.sourceNode(this, this.getName(Parser_1.ParseMode.BrightScript))
@@ -436,6 +444,10 @@ class DottedGetExpression extends AstNode_1.Expression {
436
444
  this.dot = dot;
437
445
  this.range = util_1.default.createBoundingRange(this.obj, this.dot, this.name);
438
446
  }
447
+ /** `a.b` -> `a` */
448
+ get previousInChain() {
449
+ return this.obj;
450
+ }
439
451
  transpile(state) {
440
452
  //if the callee starts with a namespace name, transpile the name
441
453
  if (state.file.calleeStartsWithNamespace(this)) {
@@ -480,6 +492,10 @@ class XmlAttributeGetExpression extends AstNode_1.Expression {
480
492
  this.at = at;
481
493
  this.range = util_1.default.createBoundingRange(this.obj, this.at, this.name);
482
494
  }
495
+ /** `a@b` -> `a` */
496
+ get previousInChain() {
497
+ return this.obj;
498
+ }
483
499
  transpile(state) {
484
500
  return [
485
501
  ...this.obj.transpile(state),
@@ -519,6 +535,10 @@ class IndexedGetExpression extends AstNode_1.Expression {
519
535
  this.range = util_1.default.createBoundingRange(this.obj, this.openingSquare, this.questionDotToken, this.openingSquare, this.index, this.closingSquare);
520
536
  (_a = this.additionalIndexes) !== null && _a !== void 0 ? _a : (this.additionalIndexes = []);
521
537
  }
538
+ /** `a[i]` -> `a` (not the index) */
539
+ get previousInChain() {
540
+ return this.obj;
541
+ }
522
542
  transpile(state) {
523
543
  var _a, _b;
524
544
  const result = [];
@@ -1017,6 +1037,10 @@ class NewExpression extends AstNode_1.Expression {
1017
1037
  //a NamespacedVariableNameExpression
1018
1038
  return this.call.callee;
1019
1039
  }
1040
+ /** `new Alpha.Beta()` -> `Alpha.Beta()` */
1041
+ get previousInChain() {
1042
+ return this.call;
1043
+ }
1020
1044
  transpile(state) {
1021
1045
  var _a;
1022
1046
  const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
@@ -1047,6 +1071,10 @@ class CallfuncExpression extends AstNode_1.Expression {
1047
1071
  this.closingParen = closingParen;
1048
1072
  this.range = util_1.default.createBoundingRange(callee, operator, methodName, openingParen, ...args !== null && args !== void 0 ? args : [], closingParen);
1049
1073
  }
1074
+ /** `a@.b()` -> `a` (not the args) */
1075
+ get previousInChain() {
1076
+ return this.callee;
1077
+ }
1050
1078
  /**
1051
1079
  * Get the name of the wrapping namespace (if it exists)
1052
1080
  * @deprecated use `.findAncestor(isNamespaceStatement)` instead.