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

rokucommunity / brighterscript / #12837

24 Jul 2024 05:52PM UTC coverage: 87.936% (+2.3%) from 85.65%
#12837

push

TwitchBronBron
0.67.4

6069 of 7376 branches covered (82.28%)

Branch coverage included in aggregate %.

8793 of 9525 relevant lines covered (92.31%)

1741.63 hits per line

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

82.01
/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 } 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 } 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';
28,336✔
28
}
29

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

34
export function isXmlScope(scope: Scope | undefined): scope is XmlScope {
1✔
35
    return scope?.constructor.name === 'XmlScope';
111!
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';
938!
54
}
55
export function isAssignmentStatement(element: AstNode | undefined): element is AssignmentStatement {
1✔
56
    return element?.constructor?.name === 'AssignmentStatement';
162!
57
}
58
export function isBlock(element: AstNode | undefined): element is Block {
1✔
59
    return element?.constructor?.name === 'Block';
4!
60
}
61
export function isExpressionStatement(element: AstNode | undefined): element is ExpressionStatement {
1✔
62
    return element?.constructor?.name === 'ExpressionStatement';
13!
63
}
64
export function isCommentStatement(element: AstNode | undefined): element is CommentStatement {
1✔
65
    return element?.constructor?.name === 'CommentStatement';
2,157!
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,496!
75
}
76
export function isIfStatement(element: AstNode | undefined): element is IfStatement {
1✔
77
    return element?.constructor?.name === 'IfStatement';
266✔
78
}
79
export function isIncrementStatement(element: AstNode | undefined): element is IncrementStatement {
1✔
80
    return element?.constructor?.name === 'IncrementStatement';
2!
81
}
82
export function isPrintStatement(element: AstNode | undefined): element is PrintStatement {
1✔
83
    return element?.constructor?.name === 'PrintStatement';
25!
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';
3!
93
}
94
export function isEndStatement(element: AstNode | undefined): element is EndStatement {
1✔
95
    return element?.constructor?.name === 'EndStatement';
2!
96
}
97
export function isStopStatement(element: AstNode | undefined): element is StopStatement {
1✔
98
    return element?.constructor?.name === 'StopStatement';
2!
99
}
100
export function isForStatement(element: AstNode | undefined): element is ForStatement {
1✔
101
    return element?.constructor?.name === 'ForStatement';
17!
102
}
103
export function isForEachStatement(element: AstNode | undefined): element is ForEachStatement {
1✔
104
    return element?.constructor?.name === 'ForEachStatement';
14!
105
}
106
export function isWhileStatement(element: AstNode | undefined): element is WhileStatement {
1✔
107
    return element?.constructor?.name === 'WhileStatement';
20!
108
}
109
export function isDottedSetStatement(element: AstNode | undefined): element is DottedSetStatement {
1✔
110
    return element?.constructor?.name === 'DottedSetStatement';
77!
111
}
112
export function isIndexedSetStatement(element: AstNode | undefined): element is IndexedSetStatement {
1✔
113
    return element?.constructor?.name === 'IndexedSetStatement';
67!
114
}
115
export function isLibraryStatement(element: AstNode | undefined): element is LibraryStatement {
1✔
116
    return element?.constructor?.name === 'LibraryStatement';
737!
117
}
118
export function isNamespaceStatement(element: AstNode | undefined): element is NamespaceStatement {
1✔
119
    return element?.constructor?.name === 'NamespaceStatement';
20,293✔
120
}
121
export function isClassStatement(element: AstNode | undefined): element is ClassStatement {
1✔
122
    return element?.constructor?.name === 'ClassStatement';
1,753!
123
}
124
export function isImportStatement(element: AstNode | undefined): element is ImportStatement {
1✔
125
    return element?.constructor?.name === 'ImportStatement';
760!
126
}
127
export function isMethodStatement(element: AstNode | undefined): element is MethodStatement {
1✔
128
    const name = element?.constructor.name;
1,073!
129
    return name === 'MethodStatement' || name === 'ClassMethodStatement';
1,073✔
130
}
131
/**
132
 * @deprecated use `isMethodStatement`
133
 */
134
export function isClassMethodStatement(element: AstNode | undefined): element is ClassMethodStatement {
1✔
135
    return isMethodStatement(element);
×
136
}
137
export function isFieldStatement(element: AstNode | undefined): element is FieldStatement {
1✔
138
    const name = element?.constructor.name;
800!
139
    return name === 'FieldStatement' || name === 'ClassFieldStatement';
800✔
140
}
141
/**
142
 * @deprecated use `isFieldStatement`
143
 */
144
export function isClassFieldStatement(element: AstNode | undefined): element is ClassFieldStatement {
1✔
145
    return isFieldStatement(element);
×
146
}
147
export function isInterfaceStatement(element: AstNode | undefined): element is InterfaceStatement {
1✔
148
    return element?.constructor.name === 'InterfaceStatement';
105!
149
}
150
export function isInterfaceMethodStatement(element: AstNode | undefined): element is InterfaceMethodStatement {
1✔
151
    return element?.constructor.name === 'InterfaceMethodStatement';
21!
152
}
153
export function isInterfaceFieldStatement(element: AstNode | undefined): element is InterfaceFieldStatement {
1✔
154
    return element?.constructor.name === 'InterfaceFieldStatement';
11!
155
}
156
export function isEnumStatement(element: AstNode | undefined): element is EnumStatement {
1✔
157
    return element?.constructor.name === 'EnumStatement';
257!
158
}
159
export function isEnumMemberStatement(element: AstNode | undefined): element is EnumMemberStatement {
1✔
160
    return element?.constructor.name === 'EnumMemberStatement';
564!
161
}
162
export function isConstStatement(element: AstNode | undefined): element is ConstStatement {
1✔
163
    return element?.constructor.name === 'ConstStatement';
93!
164
}
165
export function isContinueStatement(element: AstNode | undefined): element is ContinueStatement {
1✔
166
    return element?.constructor.name === 'ContinueStatement';
27!
167
}
168
export function isTryCatchStatement(element: AstNode | undefined): element is TryCatchStatement {
1✔
169
    return element?.constructor.name === 'TryCatchStatement';
2!
170
}
171
export function isCatchStatement(element: AstNode | undefined): element is CatchStatement {
1✔
172
    return element?.constructor.name === 'CatchStatement';
2!
173
}
174
export function isThrowStatement(element: AstNode | undefined): element is ThrowStatement {
1✔
175
    return element?.constructor.name === 'ThrowStatement';
2!
176
}
177

178
// Expressions reflection
179
/**
180
 * Determine if the variable is a descendent of the Expression base class.
181
 * Due to performance restrictions, this expects all statements to directly extend Expression,
182
 * so it only checks the immediate parent's class name. For example:
183
 * this will work for StringLiteralExpression -> Expression,
184
 * but will not work CustomStringLiteralExpression -> StringLiteralExpression -> Expression
185
 */
186
export function isExpression(element: AstNode | undefined): element is Expression {
1✔
187
    // eslint-disable-next-line no-bitwise
188
    return !!(element && element.visitMode & InternalWalkMode.visitExpressions);
1,235✔
189
}
190

191
export function isBinaryExpression(element: AstNode | undefined): element is BinaryExpression {
1✔
192
    return element?.constructor.name === 'BinaryExpression';
718!
193
}
194
export function isCallExpression(element: AstNode | undefined): element is CallExpression {
1✔
195
    return element?.constructor.name === 'CallExpression';
5,668!
196
}
197
export function isFunctionExpression(element: AstNode | undefined): element is FunctionExpression {
1✔
198
    return element?.constructor.name === 'FunctionExpression';
3,635!
199
}
200
export function isNamespacedVariableNameExpression(element: AstNode | undefined): element is NamespacedVariableNameExpression {
1✔
201
    return element?.constructor.name === 'NamespacedVariableNameExpression';
3,654!
202
}
203
export function isDottedGetExpression(element: AstNode | undefined): element is DottedGetExpression {
1✔
204
    return element?.constructor.name === 'DottedGetExpression';
7,506!
205
}
206
export function isXmlAttributeGetExpression(element: AstNode | undefined): element is XmlAttributeGetExpression {
1✔
207
    return element?.constructor.name === 'XmlAttributeGetExpression';
4,129!
208
}
209
export function isIndexedGetExpression(element: AstNode | undefined): element is IndexedGetExpression {
1✔
210
    return element?.constructor.name === 'IndexedGetExpression';
4,568!
211
}
212
export function isGroupingExpression(element: AstNode | undefined): element is GroupingExpression {
1✔
213
    return element?.constructor.name === 'GroupingExpression';
2!
214
}
215
export function isLiteralExpression(element: AstNode | undefined): element is LiteralExpression {
1✔
216
    return element?.constructor.name === 'LiteralExpression';
1,059✔
217
}
218
export function isEscapedCharCodeLiteralExpression(element: AstNode | undefined): element is EscapedCharCodeLiteralExpression {
1✔
219
    return element?.constructor.name === 'EscapedCharCodeLiteralExpression';
17!
220
}
221
export function isArrayLiteralExpression(element: AstNode | undefined): element is ArrayLiteralExpression {
1✔
222
    return element?.constructor.name === 'ArrayLiteralExpression';
9!
223
}
224
export function isAALiteralExpression(element: AstNode | undefined): element is AALiteralExpression {
1✔
225
    return element?.constructor.name === 'AALiteralExpression';
7!
226
}
227
export function isAAMemberExpression(element: AstNode | undefined): element is AAMemberExpression {
1✔
228
    return element?.constructor.name === 'AAMemberExpression';
16!
229
}
230
export function isUnaryExpression(element: AstNode | undefined): element is UnaryExpression {
1✔
231
    return element?.constructor.name === 'UnaryExpression';
1,446✔
232
}
233
export function isVariableExpression(element: AstNode | undefined): element is VariableExpression {
1✔
234
    return element?.constructor.name === 'VariableExpression';
9,211✔
235
}
236
export function isSourceLiteralExpression(element: AstNode | undefined): element is SourceLiteralExpression {
1✔
237
    return element?.constructor.name === 'SourceLiteralExpression';
2!
238
}
239
export function isNewExpression(element: AstNode | undefined): element is NewExpression {
1✔
240
    return element?.constructor.name === 'NewExpression';
2,594!
241
}
242
export function isCallfuncExpression(element: AstNode | undefined): element is CallfuncExpression {
1✔
243
    return element?.constructor.name === 'CallfuncExpression';
4,415!
244
}
245
export function isTemplateStringQuasiExpression(element: AstNode | undefined): element is TemplateStringQuasiExpression {
1✔
246
    return element?.constructor.name === 'TemplateStringQuasiExpression';
2!
247
}
248
export function isTemplateStringExpression(element: AstNode | undefined): element is TemplateStringExpression {
1✔
249
    return element?.constructor.name === 'TemplateStringExpression';
2!
250
}
251
export function isTaggedTemplateStringExpression(element: AstNode | undefined): element is TaggedTemplateStringExpression {
1✔
252
    return element?.constructor.name === 'TaggedTemplateStringExpression';
2!
253
}
254
export function isFunctionParameterExpression(element: AstNode | undefined): element is FunctionParameterExpression {
1✔
255
    return element?.constructor.name === 'FunctionParameterExpression';
40!
256
}
257
export function isAnnotationExpression(element: AstNode | undefined): element is AnnotationExpression {
1✔
258
    return element?.constructor.name === 'AnnotationExpression';
4,669!
259
}
260
export function isTypedefProvider(element: any): element is TypedefProvider {
1✔
261
    return 'getTypedef' in element;
75✔
262
}
263
export function isTypeCastExpression(element: any): element is TypeCastExpression {
1✔
264
    return element?.constructor.name === 'TypeCastExpression';
12!
265
}
266

267
// BscType reflection
268
export function isStringType(value: any): value is StringType {
1✔
269
    return value?.constructor.name === StringType.name;
744!
270
}
271
export function isFunctionType(e: any): e is FunctionType {
1✔
272
    return e?.constructor.name === FunctionType.name;
871!
273
}
274
export function isBooleanType(e: any): e is BooleanType {
1✔
275
    return e?.constructor.name === BooleanType.name;
2!
276
}
277
export function isIntegerType(e: any): e is IntegerType {
1✔
278
    return e?.constructor.name === IntegerType.name;
7!
279
}
280
export function isLongIntegerType(e: any): e is LongIntegerType {
1✔
281
    return e?.constructor.name === LongIntegerType.name;
×
282
}
283
export function isFloatType(e: any): e is FloatType {
1✔
284
    return e?.constructor.name === FloatType.name;
×
285
}
286
export function isDoubleType(e: any): e is DoubleType {
1✔
287
    return e?.constructor.name === DoubleType.name;
×
288
}
289
export function isInvalidType(e: any): e is InvalidType {
1✔
290
    return e?.constructor.name === InvalidType.name;
10!
291
}
292
export function isVoidType(e: any): e is VoidType {
1✔
293
    return e?.constructor.name === VoidType.name;
9!
294
}
295
export function isCustomType(e: any): e is CustomType {
1✔
296
    return e?.constructor.name === CustomType.name;
1,381!
297
}
298
export function isDynamicType(e: any): e is DynamicType {
1✔
299
    return e?.constructor.name === DynamicType.name;
3!
300
}
301
export function isInterfaceType(e: any): e is InterfaceType {
1✔
302
    return e?.constructor.name === 'InterfaceType';
22!
303
}
304
export function isObjectType(e: any): e is ObjectType {
1✔
305
    return e?.constructor.name === 'ObjectType';
2!
306
}
307

308
const numberConstructorNames = [
1✔
309
    IntegerType.name,
310
    LongIntegerType.name,
311
    FloatType.name,
312
    DoubleType.name
313
];
314
export function isNumberType(e: any): e is IntegerType | LongIntegerType | FloatType | DoubleType {
1✔
315
    return numberConstructorNames.includes(e?.constructor.name);
9!
316
}
317

318
// Literal reflection
319

320
export function isLiteralInvalid(e: any): e is LiteralExpression & { type: InvalidType } {
1✔
321
    return isLiteralExpression(e) && isInvalidType(e.type);
×
322
}
323
export function isLiteralBoolean(e: any): e is LiteralExpression & { type: BooleanType } {
1✔
324
    return isLiteralExpression(e) && isBooleanType(e.type);
8✔
325
}
326
export function isLiteralString(e: any): e is LiteralExpression & { type: StringType } {
1✔
327
    return isLiteralExpression(e) && isStringType(e.type);
19✔
328
}
329
export function isLiteralNumber(e: any): e is LiteralExpression & { type: IntegerType | LongIntegerType | FloatType | DoubleType } {
1✔
330
    return isLiteralExpression(e) && isNumberType(e.type);
15✔
331
}
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