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.
- package/dist/BusyStatusTracker.js +3 -0
- package/dist/BusyStatusTracker.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +6 -1
- package/dist/DiagnosticMessages.js +11 -2
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/LanguageServer.d.ts +1 -1
- package/dist/LanguageServer.js +1 -1
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +7 -7
- package/dist/Logger.js.map +1 -1
- package/dist/Program.d.ts +12 -5
- package/dist/Program.js +14 -3
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/RokuConstants.d.ts +37 -2
- package/dist/RokuConstants.js +32 -3
- package/dist/RokuConstants.js.map +1 -1
- package/dist/Scope.d.ts +3 -3
- package/dist/Scope.js.map +1 -1
- package/dist/ScopeNamespaceLookup.js.map +1 -1
- package/dist/Throttler.d.ts +1 -1
- package/dist/Throttler.js.map +1 -1
- package/dist/XmlScope.d.ts +2 -2
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +1 -1
- package/dist/astUtils/visitors.js +2 -0
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.js +4 -0
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -1
- package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +3 -3
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/definition/DefinitionProvider.d.ts +67 -2
- package/dist/bscPlugin/definition/DefinitionProvider.js +242 -4
- package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -1
- package/dist/bscPlugin/inlayHints/InlayHintProcessor.js.map +1 -1
- package/dist/bscPlugin/references/ReferencesProvider.js +7 -1
- package/dist/bscPlugin/references/ReferencesProvider.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +7 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js +17 -3
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/XmlFileValidator.d.ts +11 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js +31 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/common/Sequencer.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +1 -1
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/files/BrsFile.d.ts +2 -2
- package/dist/files/BrsFile.js +4 -0
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/XmlFile.js +1 -0
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/interfaces.d.ts +6 -3
- package/dist/lexer/Lexer.d.ts +26 -0
- package/dist/lexer/Lexer.js +147 -18
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +27 -0
- package/dist/lexer/TokenKind.js +77 -3
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/lsp/ActionQueue.js.map +1 -1
- package/dist/lsp/DocumentManager.js +4 -0
- package/dist/lsp/DocumentManager.js.map +1 -1
- package/dist/lsp/LspProject.d.ts +2 -2
- package/dist/lsp/Project.d.ts +2 -2
- package/dist/lsp/Project.js +2 -0
- package/dist/lsp/Project.js.map +1 -1
- package/dist/lsp/ProjectManager.d.ts +2 -2
- package/dist/lsp/ProjectManager.js +3 -1
- package/dist/lsp/ProjectManager.js.map +1 -1
- package/dist/lsp/worker/MessageHandler.js.map +1 -1
- package/dist/lsp/worker/WorkerThreadProject.d.ts +2 -2
- package/dist/lsp/worker/WorkerThreadProject.js +3 -1
- package/dist/lsp/worker/WorkerThreadProject.js.map +1 -1
- package/dist/parser/AstNode.d.ts +55 -1
- package/dist/parser/AstNode.js +56 -5
- package/dist/parser/AstNode.js.map +1 -1
- package/dist/parser/BrsTranspileState.d.ts +44 -0
- package/dist/parser/BrsTranspileState.js +49 -0
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +14 -0
- package/dist/parser/Expression.js +28 -0
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.d.ts +0 -5
- package/dist/parser/Parser.js +4 -8
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/SGParser.js +7 -2
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/Statement.d.ts +2 -2
- package/dist/parser/Statement.js +32 -2
- package/dist/parser/Statement.js.map +1 -1
- package/dist/preprocessor/Preprocessor.js.map +1 -1
- package/dist/util.d.ts +13 -2
- package/dist/util.js +24 -2
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +5 -4
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +1 -1
package/dist/parser/AstNode.d.ts
CHANGED
|
@@ -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():
|
|
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
|
}
|
package/dist/parser/AstNode.js
CHANGED
|
@@ -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":";;;AACA,mDAAgD;AAEhD,iEAAgE;AAChE,mDAAwD;AAKxD,kCAA2B;AAE3B;;GAEG;AACH,MAAsB,OAAO;IAA7B;QAeI;;WAEG;QACI,cAAS,GAAG,2BAAgB,CAAC,eAAe,CAAC;
|
|
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;
|
|
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.
|