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

rokucommunity / brighterscript / #13779

29 Feb 2024 09:40PM UTC coverage: 88.196% (+0.2%) from 87.991%
#13779

push

TwitchBronBron
0.65.23

5893 of 7167 branches covered (82.22%)

Branch coverage included in aggregate %.

8737 of 9421 relevant lines covered (92.74%)

1688.27 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';
27,736✔
28
}
29

30
export function isXmlFile(file: BscFile | undefined): file is XmlFile {
1✔
31
    return file?.constructor.name === 'XmlFile';
9,777✔
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';
913!
54
}
55
export function isAssignmentStatement(element: AstNode | undefined): element is AssignmentStatement {
1✔
56
    return element?.constructor?.name === 'AssignmentStatement';
160!
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,000!
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,469!
75
}
76
export function isIfStatement(element: AstNode | undefined): element is IfStatement {
1✔
77
    return element?.constructor?.name === 'IfStatement';
262✔
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';
15!
102
}
103
export function isForEachStatement(element: AstNode | undefined): element is ForEachStatement {
1✔
104
    return element?.constructor?.name === 'ForEachStatement';
13!
105
}
106
export function isWhileStatement(element: AstNode | undefined): element is WhileStatement {
1✔
107
    return element?.constructor?.name === 'WhileStatement';
18!
108
}
109
export function isDottedSetStatement(element: AstNode | undefined): element is DottedSetStatement {
1✔
110
    return element?.constructor?.name === 'DottedSetStatement';
67!
111
}
112
export function isIndexedSetStatement(element: AstNode | undefined): element is IndexedSetStatement {
1✔
113
    return element?.constructor?.name === 'IndexedSetStatement';
57!
114
}
115
export function isLibraryStatement(element: AstNode | undefined): element is LibraryStatement {
1✔
116
    return element?.constructor?.name === 'LibraryStatement';
718!
117
}
118
export function isNamespaceStatement(element: AstNode | undefined): element is NamespaceStatement {
1✔
119
    return element?.constructor?.name === 'NamespaceStatement';
19,119✔
120
}
121
export function isClassStatement(element: AstNode | undefined): element is ClassStatement {
1✔
122
    return element?.constructor?.name === 'ClassStatement';
1,736!
123
}
124
export function isImportStatement(element: AstNode | undefined): element is ImportStatement {
1✔
125
    return element?.constructor?.name === 'ImportStatement';
742!
126
}
127
export function isMethodStatement(element: AstNode | undefined): element is MethodStatement {
1✔
128
    const name = element?.constructor.name;
1,066!
129
    return name === 'MethodStatement' || name === 'ClassMethodStatement';
1,066✔
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;
794!
139
    return name === 'FieldStatement' || name === 'ClassFieldStatement';
794✔
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';
98!
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';
246!
158
}
159
export function isEnumMemberStatement(element: AstNode | undefined): element is EnumMemberStatement {
1✔
160
    return element?.constructor.name === 'EnumMemberStatement';
527!
161
}
162
export function isConstStatement(element: AstNode | undefined): element is ConstStatement {
1✔
163
    return element?.constructor.name === 'ConstStatement';
90!
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,142✔
189
}
190

191
export function isBinaryExpression(element: AstNode | undefined): element is BinaryExpression {
1✔
192
    return element?.constructor.name === 'BinaryExpression';
702!
193
}
194
export function isCallExpression(element: AstNode | undefined): element is CallExpression {
1✔
195
    return element?.constructor.name === 'CallExpression';
5,225!
196
}
197
export function isFunctionExpression(element: AstNode | undefined): element is FunctionExpression {
1✔
198
    return element?.constructor.name === 'FunctionExpression';
3,507!
199
}
200
export function isNamespacedVariableNameExpression(element: AstNode | undefined): element is NamespacedVariableNameExpression {
1✔
201
    return element?.constructor.name === 'NamespacedVariableNameExpression';
3,305!
202
}
203
export function isDottedGetExpression(element: AstNode | undefined): element is DottedGetExpression {
1✔
204
    return element?.constructor.name === 'DottedGetExpression';
7,046!
205
}
206
export function isXmlAttributeGetExpression(element: AstNode | undefined): element is XmlAttributeGetExpression {
1✔
207
    return element?.constructor.name === 'XmlAttributeGetExpression';
3,773!
208
}
209
export function isIndexedGetExpression(element: AstNode | undefined): element is IndexedGetExpression {
1✔
210
    return element?.constructor.name === 'IndexedGetExpression';
4,196!
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,010✔
217
}
218
export function isEscapedCharCodeLiteralExpression(element: AstNode | undefined): element is EscapedCharCodeLiteralExpression {
1✔
219
    return element?.constructor.name === 'EscapedCharCodeLiteralExpression';
15!
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,399✔
232
}
233
export function isVariableExpression(element: AstNode | undefined): element is VariableExpression {
1✔
234
    return element?.constructor.name === 'VariableExpression';
9,070✔
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,272!
241
}
242
export function isCallfuncExpression(element: AstNode | undefined): element is CallfuncExpression {
1✔
243
    return element?.constructor.name === 'CallfuncExpression';
4,051!
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';
39!
256
}
257
export function isAnnotationExpression(element: AstNode | undefined): element is AnnotationExpression {
1✔
258
    return element?.constructor.name === 'AnnotationExpression';
4,500!
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';
10!
265
}
266

267
// BscType reflection
268
export function isStringType(value: any): value is StringType {
1✔
269
    return value?.constructor.name === StringType.name;
679!
270
}
271
export function isFunctionType(e: any): e is FunctionType {
1✔
272
    return e?.constructor.name === FunctionType.name;
654!
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,163!
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