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

rokucommunity / brighterscript / #13903

11 Oct 2024 04:57PM UTC coverage: 88.99% (+0.8%) from 88.149%
#13903

push

TwitchBronBron
Better settings reload functionality

7194 of 8520 branches covered (84.44%)

Branch coverage included in aggregate %.

34 of 35 new or added lines in 2 files covered. (97.14%)

274 existing lines in 18 files now uncovered.

9601 of 10353 relevant lines covered (92.74%)

1780.31 hits per line

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

77.05
/src/astUtils/creators.ts
1
import type { Range } from 'vscode-languageserver';
2
import type { Identifier, Token } from '../lexer/Token';
3
import { TokenKind } from '../lexer/TokenKind';
1✔
4
import type { Expression } from '../parser/AstNode';
5
import { LiteralExpression, CallExpression, DottedGetExpression, VariableExpression, FunctionExpression } from '../parser/Expression';
1✔
6
import type { SGAttribute } from '../parser/SGTypes';
7
import { Block, MethodStatement } from '../parser/Statement';
1✔
8

9
/**
10
 * A range that points to the beginning of the file. Used to give non-null ranges to programmatically-added source code.
11
 * (Hardcoded range to prevent circular dependency issue in `../util.ts`)
12
 * @deprecated don't use this, it screws up sourcemaps. Just set range to null
13
 */
14
export const interpolatedRange = {
1✔
15
    start: {
16
        line: 0,
17
        character: 0
18
    },
19
    end: {
20
        line: 0,
21
        character: 0
22
    }
23
} as Range;
24

25
const tokenDefaults = {
1✔
26
    [TokenKind.BackTick]: '`',
27
    [TokenKind.Backslash]: '\\',
28
    [TokenKind.BackslashEqual]: '\\=',
29
    [TokenKind.Callfunc]: '@.',
30
    [TokenKind.Caret]: '^',
31
    [TokenKind.Colon]: ':',
32
    [TokenKind.Comma]: ',',
33
    [TokenKind.Comment]: '\'',
34
    [TokenKind.Dollar]: '$',
35
    [TokenKind.Dot]: '.',
36
    [TokenKind.EndClass]: 'end class',
37
    [TokenKind.EndEnum]: 'end enum',
38
    [TokenKind.EndFor]: 'end for',
39
    [TokenKind.EndFunction]: 'end function',
40
    [TokenKind.EndIf]: 'end if',
41
    [TokenKind.EndInterface]: 'end interface',
42
    [TokenKind.EndNamespace]: 'end namespace',
43
    [TokenKind.EndSub]: 'end sub',
44
    [TokenKind.EndTry]: 'end try',
45
    [TokenKind.EndWhile]: 'end while',
46
    [TokenKind.Equal]: '=',
47
    [TokenKind.Greater]: '>',
48
    [TokenKind.GreaterEqual]: '>=',
49
    [TokenKind.LeftCurlyBrace]: '{',
50
    [TokenKind.LeftParen]: '(',
51
    [TokenKind.LeftShift]: '<<',
52
    [TokenKind.LeftShiftEqual]: '<<=',
53
    [TokenKind.LeftSquareBracket]: '[',
54
    [TokenKind.Less]: '<',
55
    [TokenKind.LessEqual]: '<=',
56
    [TokenKind.LessGreater]: '<>',
57
    [TokenKind.LineNumLiteral]: 'LINE_NUM',
58
    [TokenKind.Minus]: '-',
59
    [TokenKind.MinusEqual]: '-=',
60
    [TokenKind.MinusMinus]: '--',
61
    [TokenKind.Newline]: '\n',
62
    [TokenKind.PkgLocationLiteral]: 'PKG_LOCATION',
63
    [TokenKind.PkgPathLiteral]: 'PKG_PATH',
64
    [TokenKind.Plus]: '+',
65
    [TokenKind.PlusEqual]: '+=',
66
    [TokenKind.PlusPlus]: '++',
67
    [TokenKind.Question]: '?',
68
    [TokenKind.QuestionQuestion]: '??',
69
    [TokenKind.RightCurlyBrace]: '}',
70
    [TokenKind.RightParen]: ')',
71
    [TokenKind.RightShift]: '>>',
72
    [TokenKind.RightShiftEqual]: '>>=',
73
    [TokenKind.RightSquareBracket]: ']',
74
    [TokenKind.Semicolon]: ';',
75
    [TokenKind.SourceFilePathLiteral]: 'SOURCE_FILE_PATH',
76
    [TokenKind.SourceFunctionNameLiteral]: 'SOURCE_FUNCTION_NAME',
77
    [TokenKind.SourceLineNumLiteral]: 'SOURCE_LINE_NUM',
78
    [TokenKind.SourceLocationLiteral]: 'SOURCE_LOCATION',
79
    [TokenKind.Star]: '*',
80
    [TokenKind.StarEqual]: '*=',
81
    [TokenKind.Tab]: '\t',
82
    [TokenKind.TemplateStringExpressionBegin]: '${',
83
    [TokenKind.TemplateStringExpressionEnd]: '}',
84
    [TokenKind.Whitespace]: ' '
85
};
86

87
export function createToken<T extends TokenKind>(kind: T, text?: string, range?: Range): Token & { kind: T } {
1✔
88
    return {
342✔
89
        kind: kind,
90
        text: text ?? tokenDefaults[kind as string] ?? kind.toString().toLowerCase(),
2,030✔
91
        isReserved: !text || text === kind.toString(),
512✔
92
        range: range,
93
        leadingWhitespace: ''
94
    };
95
}
96

97
export function createIdentifier(name: string, range?: Range): Identifier {
1✔
98
    return {
35✔
99
        kind: TokenKind.Identifier,
100
        text: name,
101
        isReserved: false,
102
        range: range,
103
        leadingWhitespace: ''
104
    };
105
}
106

107
export function createVariableExpression(ident: string, range?: Range): VariableExpression {
1✔
108
    return new VariableExpression(createToken(TokenKind.Identifier, ident, range));
5✔
109
}
110

111
export function createDottedIdentifier(path: string[], range?: Range): DottedGetExpression {
1✔
UNCOV
112
    const ident = path.pop();
×
UNCOV
113
    const obj = path.length > 1 ? createDottedIdentifier(path, range) : createVariableExpression(path[0], range);
×
114
    return new DottedGetExpression(obj, createToken(TokenKind.Identifier, ident, range), createToken(TokenKind.Dot, '.', range));
×
115
}
116

117
/**
118
 * Create a StringLiteralExpression. The TokenKind.StringLiteral token value includes the leading and trailing doublequote during lexing.
119
 * Since brightscript doesn't support strings with quotes in them, we can safely auto-detect and wrap the value in quotes in this function.
120
 * @param value - the string value. (value will be wrapped in quotes if they are missing)
121
 */
122
export function createStringLiteral(value: string, range?: Range) {
1✔
123
    //wrap the value in double quotes
124
    if (!value.startsWith('"') && !value.endsWith('"')) {
12✔
125
        value = '"' + value + '"';
9✔
126
    }
127
    return new LiteralExpression(createToken(TokenKind.StringLiteral, value, range));
12✔
128
}
129
export function createIntegerLiteral(value: string, range?: Range) {
1✔
UNCOV
130
    return new LiteralExpression(createToken(TokenKind.IntegerLiteral, value, range));
×
131
}
132
export function createFloatLiteral(value: string, range?: Range) {
1✔
UNCOV
133
    return new LiteralExpression(createToken(TokenKind.FloatLiteral, value, range));
×
134
}
135
export function createInvalidLiteral(value?: string, range?: Range) {
1✔
136
    return new LiteralExpression(createToken(TokenKind.Invalid, value, range));
2✔
137
}
138
export function createBooleanLiteral(value: 'true' | 'false', range?: Range) {
1✔
UNCOV
139
    return new LiteralExpression(createToken(value === 'true' ? TokenKind.True : TokenKind.False, value, range));
×
140
}
141
export function createFunctionExpression(kind: TokenKind.Sub | TokenKind.Function) {
1✔
142
    return new FunctionExpression(
35✔
143
        [],
144
        new Block([]),
145
        createToken(kind),
146
        kind === TokenKind.Sub ? createToken(TokenKind.EndSub) : createToken(TokenKind.EndFunction),
35!
147
        createToken(TokenKind.LeftParen),
148
        createToken(TokenKind.RightParen)
149
    );
150
}
151

152
export function createMethodStatement(name: string, kind: TokenKind.Sub | TokenKind.Function = TokenKind.Function, modifiers?: Token[]) {
1!
153
    return new MethodStatement(
35✔
154
        modifiers,
155
        createIdentifier(name),
156
        createFunctionExpression(kind),
157
        null
158
    );
159
}
160

161
/**
162
 * @deprecated use `createMethodStatement`
163
 */
164
export function createClassMethodStatement(name: string, kind: TokenKind.Sub | TokenKind.Function = TokenKind.Function, accessModifier?: Token) {
1!
UNCOV
165
    return createMethodStatement(name, kind, [accessModifier]);
×
166
}
167

168
export function createCall(callee: Expression, args?: Expression[]) {
1✔
169
    return new CallExpression(
3✔
170
        callee,
171
        createToken(TokenKind.LeftParen, '('),
172
        createToken(TokenKind.RightParen, ')'),
173
        args || []
6✔
174
    );
175
}
176

177
/**
178
 * Create an SGAttribute without any ranges
179
 */
180
export function createSGAttribute(keyName: string, value: string) {
1✔
181
    return {
1✔
182
        key: {
183
            text: keyName
184
        },
185
        value: {
186
            text: value
187
        }
188
    } as SGAttribute;
189
}
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