• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rokucommunity / brighterscript / #13186

15 Oct 2024 11:38AM UTC coverage: 89.043% (+2.2%) from 86.831%
#13186

push

web-flow
Merge 2b9d8bd39 into 1519a87aa

7212 of 8538 branches covered (84.47%)

Branch coverage included in aggregate %.

10 of 10 new or added lines in 1 file covered. (100.0%)

539 existing lines in 53 files now uncovered.

9619 of 10364 relevant lines covered (92.81%)

1781.3 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.23
/src/astUtils/reflection.ts
1
import type { Body, AssignmentStatement, Block, ExpressionStatement, CommentStatement, ExitForStatement, ExitWhileStatement, FunctionStatement, IfStatement, IncrementStatement, PrintStatement, GotoStatement, LabelStatement, ReturnStatement, EndStatement, StopStatement, ForStatement, ForEachStatement, WhileStatement, DottedSetStatement, IndexedSetStatement, LibraryStatement, NamespaceStatement, ImportStatement, ClassFieldStatement, ClassMethodStatement, ClassStatement, InterfaceFieldStatement, InterfaceMethodStatement, InterfaceStatement, EnumStatement, EnumMemberStatement, TryCatchStatement, CatchStatement, ThrowStatement, MethodStatement, FieldStatement, ConstStatement, ContinueStatement, DimStatement } from '../parser/Statement';
2
import type { LiteralExpression, BinaryExpression, CallExpression, FunctionExpression, NamespacedVariableNameExpression, DottedGetExpression, XmlAttributeGetExpression, IndexedGetExpression, GroupingExpression, EscapedCharCodeLiteralExpression, ArrayLiteralExpression, AALiteralExpression, UnaryExpression, VariableExpression, SourceLiteralExpression, NewExpression, CallfuncExpression, TemplateStringQuasiExpression, TemplateStringExpression, TaggedTemplateStringExpression, AnnotationExpression, FunctionParameterExpression, AAMemberExpression, TypeCastExpression, TernaryExpression, NullCoalescingExpression } from '../parser/Expression';
3
import type { BrsFile } from '../files/BrsFile';
4
import type { XmlFile } from '../files/XmlFile';
5
import type { BscFile, File, TypedefProvider } from '../interfaces';
6
import { InvalidType } from '../types/InvalidType';
1✔
7
import { VoidType } from '../types/VoidType';
1✔
8
import { InternalWalkMode } from './visitors';
1✔
9
import { FunctionType } from '../types/FunctionType';
1✔
10
import { StringType } from '../types/StringType';
1✔
11
import { BooleanType } from '../types/BooleanType';
1✔
12
import { IntegerType } from '../types/IntegerType';
1✔
13
import { LongIntegerType } from '../types/LongIntegerType';
1✔
14
import { FloatType } from '../types/FloatType';
1✔
15
import { DoubleType } from '../types/DoubleType';
1✔
16
import { CustomType } from '../types/CustomType';
1✔
17
import type { Scope } from '../Scope';
18
import type { XmlScope } from '../XmlScope';
19
import { DynamicType } from '../types/DynamicType';
1✔
20
import type { InterfaceType } from '../types/InterfaceType';
21
import type { ObjectType } from '../types/ObjectType';
22
import type { AstNode, Expression, Statement } from '../parser/AstNode';
23

24
// File reflection
25

26
export function isBrsFile(file: BscFile | File | undefined): file is BrsFile {
1✔
27
    return file?.constructor.name === 'BrsFile';
31,896✔
28
}
29

30
export function isXmlFile(file: BscFile | undefined): file is XmlFile {
1✔
31
    return file?.constructor.name === 'XmlFile';
11,201✔
32
}
33

34
export function isXmlScope(scope: Scope | undefined): scope is XmlScope {
1✔
35
    return scope?.constructor.name === 'XmlScope';
134!
36
}
37

38

39
// Statements reflection
40

41
/**
42
 * Determine if the variable is a descendent of the Statement base class.
43
 * Due to performance restrictions, this expects all statements to
44
 * directly extend Statement or FunctionStatement,
45
 * so it only checks the immediate parent's class name.
46
 */
47
export function isStatement(element: AstNode | undefined): element is Statement {
1✔
48
    // eslint-disable-next-line no-bitwise
49
    return !!(element && element.visitMode & InternalWalkMode.visitStatements);
26✔
50
}
51

52
export function isBody(element: AstNode | undefined): element is Body {
1✔
53
    return element?.constructor?.name === 'Body';
1,014!
54
}
55
export function isAssignmentStatement(element: AstNode | undefined): element is AssignmentStatement {
1✔
56
    return element?.constructor?.name === 'AssignmentStatement';
166!
57
}
58
export function isBlock(element: AstNode | undefined): element is Block {
1✔
59
    return element?.constructor?.name === 'Block';
10!
60
}
61
export function isExpressionStatement(element: AstNode | undefined): element is ExpressionStatement {
1✔
62
    return element?.constructor?.name === 'ExpressionStatement';
17!
63
}
64
export function isCommentStatement(element: AstNode | undefined): element is CommentStatement {
1✔
65
    return element?.constructor?.name === 'CommentStatement';
2,249!
66
}
67
export function isExitForStatement(element: AstNode | undefined): element is ExitForStatement {
1✔
68
    return element?.constructor?.name === 'ExitForStatement';
2!
69
}
70
export function isExitWhileStatement(element: AstNode | undefined): element is ExitWhileStatement {
1✔
71
    return element?.constructor?.name === 'ExitWhileStatement';
2!
72
}
73
export function isFunctionStatement(element: AstNode | undefined): element is FunctionStatement {
1✔
74
    return element?.constructor?.name === 'FunctionStatement';
1,603!
75
}
76
export function isIfStatement(element: AstNode | undefined): element is IfStatement {
1✔
77
    return element?.constructor?.name === 'IfStatement';
302✔
78
}
79
export function isIncrementStatement(element: AstNode | undefined): element is IncrementStatement {
1✔
80
    return element?.constructor?.name === 'IncrementStatement';
8!
81
}
82
export function isPrintStatement(element: AstNode | undefined): element is PrintStatement {
1✔
83
    return element?.constructor?.name === 'PrintStatement';
33!
84
}
85
export function isGotoStatement(element: AstNode | undefined): element is GotoStatement {
1✔
86
    return element?.constructor?.name === 'GotoStatement';
2!
87
}
88
export function isLabelStatement(element: AstNode | undefined): element is LabelStatement {
1✔
89
    return element?.constructor?.name === 'LabelStatement';
2!
90
}
91
export function isReturnStatement(element: AstNode | undefined): element is ReturnStatement {
1✔
92
    return element?.constructor?.name === 'ReturnStatement';
7!
93
}
94
export function isTernaryExpression(element: AstNode | undefined): element is TernaryExpression {
1✔
95
    return element?.constructor?.name === 'TernaryExpression';
15!
96
}
97
export function isNullCoalescingExpression(element: AstNode | undefined): element is NullCoalescingExpression {
1✔
98
    return element?.constructor?.name === 'NullCoalescingExpression';
10!
99
}
100
export function isEndStatement(element: AstNode | undefined): element is EndStatement {
1✔
101
    return element?.constructor?.name === 'EndStatement';
2!
102
}
103
export function isStopStatement(element: AstNode | undefined): element is StopStatement {
1✔
104
    return element?.constructor?.name === 'StopStatement';
2!
105
}
106
export function isForStatement(element: AstNode | undefined): element is ForStatement {
1✔
107
    return element?.constructor?.name === 'ForStatement';
33!
108
}
109
export function isForEachStatement(element: AstNode | undefined): element is ForEachStatement {
1✔
110
    return element?.constructor?.name === 'ForEachStatement';
22!
111
}
112
export function isWhileStatement(element: AstNode | undefined): element is WhileStatement {
1✔
113
    return element?.constructor?.name === 'WhileStatement';
28!
114
}
115
export function isDimStatement(element: AstNode | undefined): element is DimStatement {
1✔
116
    return element?.constructor?.name === 'DimStatement';
8!
117
}
118
export function isDottedSetStatement(element: AstNode | undefined): element is DottedSetStatement {
1✔
119
    return element?.constructor?.name === 'DottedSetStatement';
85!
120
}
121
export function isIndexedSetStatement(element: AstNode | undefined): element is IndexedSetStatement {
1✔
122
    return element?.constructor?.name === 'IndexedSetStatement';
87!
123
}
124
export function isLibraryStatement(element: AstNode | undefined): element is LibraryStatement {
1✔
125
    return element?.constructor?.name === 'LibraryStatement';
806!
126
}
127
export function isNamespaceStatement(element: AstNode | undefined): element is NamespaceStatement {
1✔
128
    return element?.constructor?.name === 'NamespaceStatement';
21,341✔
129
}
130
export function isClassStatement(element: AstNode | undefined): element is ClassStatement {
1✔
131
    return element?.constructor?.name === 'ClassStatement';
1,781!
132
}
133
export function isImportStatement(element: AstNode | undefined): element is ImportStatement {
1✔
134
    return element?.constructor?.name === 'ImportStatement';
828!
135
}
136
export function isMethodStatement(element: AstNode | undefined): element is MethodStatement {
1✔
137
    const name = element?.constructor.name;
1,104✔
138
    return name === 'MethodStatement' || name === 'ClassMethodStatement';
1,104✔
139
}
140
/**
141
 * @deprecated use `isMethodStatement`
142
 */
143
export function isClassMethodStatement(element: AstNode | undefined): element is ClassMethodStatement {
1✔
UNCOV
144
    return isMethodStatement(element);
×
145
}
146
export function isFieldStatement(element: AstNode | undefined): element is FieldStatement {
1✔
147
    const name = element?.constructor.name;
809✔
148
    return name === 'FieldStatement' || name === 'ClassFieldStatement';
809✔
149
}
150
/**
151
 * @deprecated use `isFieldStatement`
152
 */
153
export function isClassFieldStatement(element: AstNode | undefined): element is ClassFieldStatement {
1✔
UNCOV
154
    return isFieldStatement(element);
×
155
}
156
export function isInterfaceStatement(element: AstNode | undefined): element is InterfaceStatement {
1✔
157
    return element?.constructor.name === 'InterfaceStatement';
110!
158
}
159
export function isInterfaceMethodStatement(element: AstNode | undefined): element is InterfaceMethodStatement {
1✔
160
    return element?.constructor.name === 'InterfaceMethodStatement';
27!
161
}
162
export function isInterfaceFieldStatement(element: AstNode | undefined): element is InterfaceFieldStatement {
1✔
163
    return element?.constructor.name === 'InterfaceFieldStatement';
13!
164
}
165
export function isEnumStatement(element: AstNode | undefined): element is EnumStatement {
1✔
166
    return element?.constructor.name === 'EnumStatement';
269!
167
}
168
export function isEnumMemberStatement(element: AstNode | undefined): element is EnumMemberStatement {
1✔
169
    return element?.constructor.name === 'EnumMemberStatement';
570!
170
}
171
export function isConstStatement(element: AstNode | undefined): element is ConstStatement {
1✔
172
    return element?.constructor.name === 'ConstStatement';
97!
173
}
174
export function isContinueStatement(element: AstNode | undefined): element is ContinueStatement {
1✔
175
    return element?.constructor.name === 'ContinueStatement';
27!
176
}
177
export function isTryCatchStatement(element: AstNode | undefined): element is TryCatchStatement {
1✔
178
    return element?.constructor.name === 'TryCatchStatement';
10!
179
}
180
export function isCatchStatement(element: AstNode | undefined): element is CatchStatement {
1✔
181
    return element?.constructor.name === 'CatchStatement';
10!
182
}
183
export function isThrowStatement(element: AstNode | undefined): element is ThrowStatement {
1✔
184
    return element?.constructor.name === 'ThrowStatement';
6!
185
}
186

187
// Expressions reflection
188
/**
189
 * Determine if the variable is a descendent of the Expression base class.
190
 * Due to performance restrictions, this expects all statements to directly extend Expression,
191
 * so it only checks the immediate parent's class name. For example:
192
 * this will work for StringLiteralExpression -> Expression,
193
 * but will not work CustomStringLiteralExpression -> StringLiteralExpression -> Expression
194
 */
195
export function isExpression(element: AstNode | undefined): element is Expression {
1✔
196
    // eslint-disable-next-line no-bitwise
197
    return !!(element && element.visitMode & InternalWalkMode.visitExpressions);
1,463✔
198
}
199

200
export function isBinaryExpression(element: AstNode | undefined): element is BinaryExpression {
1✔
201
    return element?.constructor.name === 'BinaryExpression';
736!
202
}
203
export function isCallExpression(element: AstNode | undefined): element is CallExpression {
1✔
204
    return element?.constructor.name === 'CallExpression';
6,025!
205
}
206
export function isFunctionExpression(element: AstNode | undefined): element is FunctionExpression {
1✔
207
    return element?.constructor.name === 'FunctionExpression';
25,029!
208
}
209
export function isNamespacedVariableNameExpression(element: AstNode | undefined): element is NamespacedVariableNameExpression {
1✔
210
    return element?.constructor.name === 'NamespacedVariableNameExpression';
3,706!
211
}
212
export function isDottedGetExpression(element: AstNode | undefined): element is DottedGetExpression {
1✔
213
    return element?.constructor.name === 'DottedGetExpression';
7,594!
214
}
215
export function isXmlAttributeGetExpression(element: AstNode | undefined): element is XmlAttributeGetExpression {
1✔
216
    return element?.constructor.name === 'XmlAttributeGetExpression';
4,198!
217
}
218
export function isIndexedGetExpression(element: AstNode | undefined): element is IndexedGetExpression {
1✔
219
    return element?.constructor.name === 'IndexedGetExpression';
4,660!
220
}
221
export function isGroupingExpression(element: AstNode | undefined): element is GroupingExpression {
1✔
222
    return element?.constructor.name === 'GroupingExpression';
7!
223
}
224
export function isLiteralExpression(element: AstNode | undefined): element is LiteralExpression {
1✔
225
    return element?.constructor.name === 'LiteralExpression';
1,109✔
226
}
227
export function isEscapedCharCodeLiteralExpression(element: AstNode | undefined): element is EscapedCharCodeLiteralExpression {
1✔
228
    return element?.constructor.name === 'EscapedCharCodeLiteralExpression';
17!
229
}
230
export function isArrayLiteralExpression(element: AstNode | undefined): element is ArrayLiteralExpression {
1✔
231
    return element?.constructor.name === 'ArrayLiteralExpression';
23!
232
}
233
export function isAALiteralExpression(element: AstNode | undefined): element is AALiteralExpression {
1✔
234
    return element?.constructor.name === 'AALiteralExpression';
20!
235
}
236
export function isAAMemberExpression(element: AstNode | undefined): element is AAMemberExpression {
1✔
237
    return element?.constructor.name === 'AAMemberExpression';
22!
238
}
239
export function isUnaryExpression(element: AstNode | undefined): element is UnaryExpression {
1✔
240
    return element?.constructor.name === 'UnaryExpression';
1,467✔
241
}
242
export function isVariableExpression(element: AstNode | undefined): element is VariableExpression {
1✔
243
    return element?.constructor.name === 'VariableExpression';
10,164✔
244
}
245
export function isSourceLiteralExpression(element: AstNode | undefined): element is SourceLiteralExpression {
1✔
246
    return element?.constructor.name === 'SourceLiteralExpression';
2!
247
}
248
export function isNewExpression(element: AstNode | undefined): element is NewExpression {
1✔
249
    return element?.constructor.name === 'NewExpression';
2,655!
250
}
251
export function isCallfuncExpression(element: AstNode | undefined): element is CallfuncExpression {
1✔
252
    return element?.constructor.name === 'CallfuncExpression';
4,483!
253
}
254
export function isTemplateStringQuasiExpression(element: AstNode | undefined): element is TemplateStringQuasiExpression {
1✔
255
    return element?.constructor.name === 'TemplateStringQuasiExpression';
14!
256
}
257
export function isTemplateStringExpression(element: AstNode | undefined): element is TemplateStringExpression {
1✔
258
    return element?.constructor.name === 'TemplateStringExpression';
26!
259
}
260
export function isTaggedTemplateStringExpression(element: AstNode | undefined): element is TaggedTemplateStringExpression {
1✔
261
    return element?.constructor.name === 'TaggedTemplateStringExpression';
22!
262
}
263
export function isFunctionParameterExpression(element: AstNode | undefined): element is FunctionParameterExpression {
1✔
264
    return element?.constructor.name === 'FunctionParameterExpression';
40!
265
}
266
export function isAnnotationExpression(element: AstNode | undefined): element is AnnotationExpression {
1✔
267
    return element?.constructor.name === 'AnnotationExpression';
26,026!
268
}
269
export function isTypedefProvider(element: any): element is TypedefProvider {
1✔
270
    return 'getTypedef' in element;
75✔
271
}
272
export function isTypeCastExpression(element: any): element is TypeCastExpression {
1✔
273
    return element?.constructor.name === 'TypeCastExpression';
17!
274
}
275

276
// BscType reflection
277
export function isStringType(value: any): value is StringType {
1✔
278
    return value?.constructor.name === StringType.name;
751!
279
}
280
export function isFunctionType(e: any): e is FunctionType {
1✔
281
    return e?.constructor.name === FunctionType.name;
877!
282
}
283
export function isBooleanType(e: any): e is BooleanType {
1✔
284
    return e?.constructor.name === BooleanType.name;
3!
285
}
286
export function isIntegerType(e: any): e is IntegerType {
1✔
287
    return e?.constructor.name === IntegerType.name;
12!
288
}
289
export function isLongIntegerType(e: any): e is LongIntegerType {
1✔
UNCOV
290
    return e?.constructor.name === LongIntegerType.name;
×
291
}
292
export function isFloatType(e: any): e is FloatType {
1✔
UNCOV
293
    return e?.constructor.name === FloatType.name;
×
294
}
295
export function isDoubleType(e: any): e is DoubleType {
1✔
UNCOV
296
    return e?.constructor.name === DoubleType.name;
×
297
}
298
export function isInvalidType(e: any): e is InvalidType {
1✔
299
    return e?.constructor.name === InvalidType.name;
10!
300
}
301
export function isVoidType(e: any): e is VoidType {
1✔
302
    return e?.constructor.name === VoidType.name;
9!
303
}
304
export function isCustomType(e: any): e is CustomType {
1✔
305
    return e?.constructor.name === CustomType.name;
1,418!
306
}
307
export function isDynamicType(e: any): e is DynamicType {
1✔
308
    return e?.constructor.name === DynamicType.name;
3!
309
}
310
export function isInterfaceType(e: any): e is InterfaceType {
1✔
311
    return e?.constructor.name === 'InterfaceType';
22!
312
}
313
export function isObjectType(e: any): e is ObjectType {
1✔
314
    return e?.constructor.name === 'ObjectType';
2!
315
}
316

317
const numberConstructorNames = [
1✔
318
    IntegerType.name,
319
    LongIntegerType.name,
320
    FloatType.name,
321
    DoubleType.name
322
];
323
export function isNumberType(e: any): e is IntegerType | LongIntegerType | FloatType | DoubleType {
1✔
324
    return numberConstructorNames.includes(e?.constructor.name);
15!
325
}
326

327
// Literal reflection
328

329
export function isLiteralInvalid(e: any): e is LiteralExpression & { type: InvalidType } {
1✔
UNCOV
330
    return isLiteralExpression(e) && isInvalidType(e.type);
×
331
}
332
export function isLiteralBoolean(e: any): e is LiteralExpression & { type: BooleanType } {
1✔
333
    return isLiteralExpression(e) && isBooleanType(e.type);
13✔
334
}
335
export function isLiteralString(e: any): e is LiteralExpression & { type: StringType } {
1✔
336
    return isLiteralExpression(e) && isStringType(e.type);
30✔
337
}
338
export function isLiteralNumber(e: any): e is LiteralExpression & { type: IntegerType | LongIntegerType | FloatType | DoubleType } {
1✔
339
    return isLiteralExpression(e) && isNumberType(e.type);
25✔
340
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc