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

rokucommunity / bslint / #1039

03 Oct 2024 07:42PM CUT coverage: 91.231% (-0.5%) from 91.746%
#1039

Pull #96

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

927 of 1061 branches covered (87.37%)

Branch coverage included in aggregate %.

231 of 240 new or added lines in 12 files covered. (96.25%)

11 existing lines in 3 files now uncovered.

1008 of 1060 relevant lines covered (95.09%)

68.84 hits per line

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

90.14
/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
    file: BscFile,
8
    addFixes: (file: BscFile, changes: ChangeEntry) => void,
9
    diagnostics: BsDiagnostic[]
10
): BsDiagnostic[] {
11
    return diagnostics.filter(diagnostic => {
24✔
12
        const fix = getFixes(diagnostic);
41✔
13
        if (fix) {
41!
14
            addFixes(file, fix);
41✔
15
            return false;
41✔
16
        }
17
        return true;
×
18
    });
19
}
20

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

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

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

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

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

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

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

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

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

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