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

rokucommunity / bslint / #882

16 May 2024 05:26PM CUT coverage: 92.085% (+0.2%) from 91.908%
#882

Pull #96

TwitchBronBron
1.0.0-alpha.30
Pull Request #96: v1

764 of 862 branches covered (88.63%)

Branch coverage included in aggregate %.

94 of 95 new or added lines in 10 files covered. (98.95%)

19 existing lines in 5 files now uncovered.

923 of 970 relevant lines covered (95.15%)

65.18 hits per line

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

91.04
/src/plugins/codeStyle/styleFixes.ts
1
import { BscFile, BsDiagnostic, FunctionExpression, GroupingExpression, IfStatement, isIfStatement, isVoidType, Position, Range, VoidType, WhileStatement, SymbolTypeFlag } 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
        }
UNCOV
16
        return true;
×
17
    });
18
}
19

20
export function getFixes(diagnostic: BsDiagnostic): ChangeEntry {
1✔
21
    switch (diagnostic.code) {
41!
22
        case CodeStyleError.FunctionKeywordExpected:
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
        default:
UNCOV
45
            return null;
×
46
    }
47
}
48

49
function addAAComma(diagnostic: BsDiagnostic) {
50
    const { range } = diagnostic;
6✔
51
    return {
6✔
52
        diagnostic,
53
        changes: [
54
            insertText(range.end, ',')
55
        ]
56
    };
57
}
58

59
function removeAAComma(diagnostic: BsDiagnostic) {
60
    const { range } = diagnostic;
9✔
61
    return {
9✔
62
        diagnostic,
63
        changes: [
64
            replaceText(range, '')
65
        ]
66
    };
67
}
68

69
function addConditionGroup(diagnostic: BsDiagnostic) {
70
    const stat: IfStatement | WhileStatement = diagnostic.data;
5✔
71
    const { start, end } = stat.condition.range;
5✔
72
    return {
5✔
73
        diagnostic,
74
        changes: [
75
            insertText(Position.create(start.line, start.character), '('),
76
            insertText(Position.create(end.line, end.character), ')')
77
        ]
78
    };
79
}
80

81
function removeConditionGroup(diagnostic: BsDiagnostic) {
82
    const stat: (IfStatement | WhileStatement) & { condition: GroupingExpression } = diagnostic.data;
5✔
83
    const { leftParen, rightParen } = stat.condition.tokens;
5✔
84
    const spaceBefore = leftParen.leadingWhitespace?.length > 0 ? '' : ' ';
5!
85
    let spaceAfter = '';
5✔
86
    if (isIfStatement(stat)) {
5✔
87
        spaceAfter = stat.isInline ? ' ' : '';
3✔
88
        if (stat.tokens.then) {
3✔
89
            spaceAfter = stat.tokens.then.leadingWhitespace?.length > 0 ? '' : ' ';
2!
90
        }
91
    }
92
    return {
5✔
93
        diagnostic,
94
        changes: [
95
            replaceText(leftParen.range, spaceBefore),
96
            replaceText(rightParen.range, spaceAfter)
97
        ]
98
    };
99
}
100

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

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

130
function replaceFunctionTokens(diagnostic: BsDiagnostic, token: string) {
131
    const fun: FunctionExpression = diagnostic.data;
6✔
132
    const space = fun.tokens.endFunctionType?.text.indexOf(' ') > 0 ? ' ' : '';
6!
133
    // sub/function keyword
134
    const keywordChanges = [
6✔
135
        replaceText(fun.tokens.functionType.range, token),
136
        replaceText(fun.tokens.endFunctionType?.range, `end${space}${token}`)
18!
137
    ];
138
    // remove `as void` in case of `sub`
139
    const returnType = fun.returnTypeExpression?.getType({ flags: SymbolTypeFlag.typetime }) ?? VoidType.instance;
6✔
140
    const returnChanges = token === 'sub' && fun.returnTypeExpression && isVoidType(returnType) ? [
6✔
141
        replaceText(Range.create(fun.tokens.rightParen.range.end, fun.returnTypeExpression.range.end), '')
142
    ] : [];
143
    return {
6✔
144
        diagnostic,
145
        changes: [
146
            ...keywordChanges,
147
            ...returnChanges
148
        ]
149
    };
150
}
151

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

166
function removeEolLast(diagnostic: BsDiagnostic): ChangeEntry {
167
    return {
1✔
168
        diagnostic,
169
        changes: [
170
            replaceText(diagnostic.range, '')
171
        ]
172
    };
173
}
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