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

rokucommunity / bslint / #722

18 Sep 2023 06:19PM UTC coverage: 86.935% (-4.4%) from 91.354%
#722

push

web-flow
Merge e615f8c65 into 3567a926a

726 of 872 branches covered (0.0%)

Branch coverage included in aggregate %.

96 of 96 new or added lines in 4 files covered. (100.0%)

871 of 965 relevant lines covered (90.26%)

52.26 hits per line

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

85.93
/src/plugins/codeStyle/styleFixes.ts
1
import { BscFile, BsDiagnostic, FunctionExpression, GroupingExpression, IfStatement, isIfStatement, Position, Range, TokenKind, WhileStatement } from 'brighterscript';
1✔
2
import { ChangeEntry, comparePos, insertText, replaceText } from '../../textEdit';
1✔
3
import { CodeStyleError } from './diagnosticMessages';
1✔
4
import { platform } from 'process';
1✔
5

6
export function extractFixes(
1✔
7
    addFixes: (file: BscFile, changes: ChangeEntry) => void,
8
    diagnostics: BsDiagnostic[]
9
): BsDiagnostic[] {
10
    return diagnostics.filter(diagnostic => {
12✔
11
        const fix = getFixes(diagnostic);
41✔
12
        if (fix) {
41!
13
            addFixes(diagnostic.file, fix);
41✔
14
            return false;
41✔
15
        }
16
        return true;
×
17
    });
18
}
19

20
export function getFixes(diagnostic: BsDiagnostic): ChangeEntry {
1✔
21
    switch (diagnostic.code) {
41✔
22
        case CodeStyleError.FunctionKeywordExpected:
45!
23
            return replaceFunctionTokens(diagnostic, 'function');
3✔
24
        case CodeStyleError.SubKeywordExpected:
25
            return replaceFunctionTokens(diagnostic, 'sub');
3✔
26
        case CodeStyleError.InlineIfThenFound:
27
        case CodeStyleError.BlockIfThenFound:
28
            return removeThenToken(diagnostic);
4✔
29
        case CodeStyleError.InlineIfThenMissing:
30
        case CodeStyleError.BlockIfThenMissing:
31
            return addThenToken(diagnostic);
3✔
32
        case CodeStyleError.ConditionGroupFound:
33
            return removeConditionGroup(diagnostic);
5✔
34
        case CodeStyleError.ConditionGroupMissing:
35
            return addConditionGroup(diagnostic);
5✔
36
        case CodeStyleError.AACommaFound:
37
            return removeAAComma(diagnostic);
9✔
38
        case CodeStyleError.AACommaMissing:
39
            return addAAComma(diagnostic);
6✔
40
        case CodeStyleError.EolLastMissing:
41
            return addEolLast(diagnostic);
2✔
42
        case CodeStyleError.EolLastFound:
43
            return removeEolLast(diagnostic);
1✔
44
        case CodeStyleError.ColorFormat:
45
        case CodeStyleError.ColorCase:
46
        case CodeStyleError.ColorAlpha:
47
        case CodeStyleError.ColorAlphaDefaults:
48
        case CodeStyleError.ColorCertCompliant:
49
            return expectedColorStyle(diagnostic);
×
50
        default:
51
            return null;
×
52
    }
53
}
54

55
function addAAComma(diagnostic: BsDiagnostic) {
56
    const { range } = diagnostic;
6✔
57
    return {
6✔
58
        diagnostic,
59
        changes: [
60
            insertText(range.end, ',')
61
        ]
62
    };
63
}
64

65
function removeAAComma(diagnostic: BsDiagnostic) {
66
    const { range } = diagnostic;
9✔
67
    return {
9✔
68
        diagnostic,
69
        changes: [
70
            replaceText(range, '')
71
        ]
72
    };
73
}
74

75
function addConditionGroup(diagnostic: BsDiagnostic) {
76
    const stat: IfStatement | WhileStatement = diagnostic.data;
5✔
77
    const { start, end } = stat.condition.range;
5✔
78
    return {
5✔
79
        diagnostic,
80
        changes: [
81
            insertText(Position.create(start.line, start.character), '('),
82
            insertText(Position.create(end.line, end.character), ')')
83
        ]
84
    };
85
}
86

87
function removeConditionGroup(diagnostic: BsDiagnostic) {
88
    const stat: (IfStatement | WhileStatement) & { condition: GroupingExpression } = diagnostic.data;
5✔
89
    const { left, right } = stat.condition.tokens;
5✔
90
    const spaceBefore = left.leadingWhitespace?.length > 0 ? '' : ' ';
5!
91
    let spaceAfter = '';
5✔
92
    if (isIfStatement(stat)) {
5✔
93
        spaceAfter = stat.isInline ? ' ' : '';
3✔
94
        if (stat.tokens.then) {
3✔
95
            spaceAfter = stat.tokens.then.leadingWhitespace?.length > 0 ? '' : ' ';
2!
96
        }
97
    }
98
    return {
5✔
99
        diagnostic,
100
        changes: [
101
            replaceText(left.range, spaceBefore),
102
            replaceText(right.range, spaceAfter)
103
        ]
104
    };
105
}
106

107
function addThenToken(diagnostic: BsDiagnostic) {
108
    const stat: IfStatement = diagnostic.data;
3✔
109
    const { end } = stat.condition.range;
3✔
110
    // const { start } = stat.thenBranch.range; // TODO: use when Block range bug is fixed
111
    const start = stat.thenBranch.statements[0]?.range.start;
3!
112
    const space = stat.isInline && comparePos(end, start) === 0 ? ' ' : '';
3✔
113
    return {
3✔
114
        diagnostic,
115
        changes: [
116
            insertText(end, ` then${space}`)
117
        ]
118
    };
119
}
120

121
function removeThenToken(diagnostic: BsDiagnostic) {
122
    const stat: IfStatement = diagnostic.data;
4✔
123
    const { then } = stat.tokens;
4✔
124
    const { line, character } = then.range.start;
4✔
125
    const range = Range.create(
4✔
126
        line, character - (then.leadingWhitespace?.length || 0), line, character + then.text.length
17!
127
    );
128
    return {
4✔
129
        diagnostic,
130
        changes: [
131
            replaceText(range, '')
132
        ]
133
    };
134
}
135

136
function replaceFunctionTokens(diagnostic: BsDiagnostic, token: string) {
137
    const fun: FunctionExpression = diagnostic.data;
6✔
138
    const space = fun.end?.text.indexOf(' ') > 0 ? ' ' : '';
6!
139
    // sub/function keyword
140
    const keywordChanges = [
6✔
141
        replaceText(fun.functionType.range, token),
142
        replaceText(fun.end?.range, `end${space}${token}`)
18!
143
    ];
144
    // remove `as void` in case of `sub`
145
    const returnChanges = token === 'sub' && fun.returnTypeToken?.kind === TokenKind.Void ? [
6✔
146
        replaceText(Range.create(fun.rightParen.range.end, fun.returnTypeToken.range.end), '')
147
    ] : [];
148
    return {
6✔
149
        diagnostic,
150
        changes: [
151
            ...keywordChanges,
152
            ...returnChanges
153
        ]
154
    };
155
}
156

157
function addEolLast(diagnostic: BsDiagnostic): ChangeEntry {
158
    return {
2✔
159
        diagnostic,
160
        changes: [
161
            insertText(
162
                diagnostic.range.end,
163
                // In single line files, the `preferredEol` cannot be determined
164
                // e.g: `sub foo() end sub\EOF`
165
                diagnostic.data.preferredEol ?? (platform.toString() === 'win32' ? '\r\n' : '\n')
7!
166
            )
167
        ]
168
    };
169
}
170

171
function removeEolLast(diagnostic: BsDiagnostic): ChangeEntry {
172
    return {
1✔
173
        diagnostic,
174
        changes: [
175
            replaceText(diagnostic.range, '')
176
        ]
177
    };
178
}
179

180
function expectedColorStyle(diagnostic: BsDiagnostic): ChangeEntry {
181
    return {
×
182
        diagnostic,
183
        changes: [
184
            replaceText(diagnostic.range, '')
185
        ]
186
    };
187
}
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

© 2025 Coveralls, Inc