kopytko-formatter 1.0.9 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/config.d.ts +4 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +3 -0
- package/dist/src/config.js.map +1 -1
- package/dist/src/cst-passes/aaThreshold.d.ts +4 -0
- package/dist/src/cst-passes/aaThreshold.d.ts.map +1 -0
- package/dist/src/cst-passes/aaThreshold.js +11 -0
- package/dist/src/cst-passes/aaThreshold.js.map +1 -0
- package/dist/src/cst-passes/alignAssignments.d.ts +4 -0
- package/dist/src/cst-passes/alignAssignments.d.ts.map +1 -0
- package/dist/src/cst-passes/alignAssignments.js +11 -0
- package/dist/src/cst-passes/alignAssignments.js.map +1 -0
- package/dist/src/cst-passes/blankLines.d.ts +19 -0
- package/dist/src/cst-passes/blankLines.d.ts.map +1 -0
- package/dist/src/cst-passes/blankLines.js +40 -0
- package/dist/src/cst-passes/blankLines.js.map +1 -0
- package/dist/src/cst-passes/casingPass.d.ts +12 -0
- package/dist/src/cst-passes/casingPass.d.ts.map +1 -0
- package/dist/src/cst-passes/casingPass.js +214 -0
- package/dist/src/cst-passes/casingPass.js.map +1 -0
- package/dist/src/cst-passes/commentNormalization.d.ts +24 -0
- package/dist/src/cst-passes/commentNormalization.d.ts.map +1 -0
- package/dist/src/cst-passes/commentNormalization.js +76 -0
- package/dist/src/cst-passes/commentNormalization.js.map +1 -0
- package/dist/src/cst-passes/commentWidth.d.ts +4 -0
- package/dist/src/cst-passes/commentWidth.d.ts.map +1 -0
- package/dist/src/cst-passes/commentWidth.js +50 -0
- package/dist/src/cst-passes/commentWidth.js.map +1 -0
- package/dist/src/cst-passes/elseOnNewLine.d.ts +4 -0
- package/dist/src/cst-passes/elseOnNewLine.d.ts.map +1 -0
- package/dist/src/cst-passes/elseOnNewLine.js +11 -0
- package/dist/src/cst-passes/elseOnNewLine.js.map +1 -0
- package/dist/src/cst-passes/emptyLinesBetweenMethods.d.ts +4 -0
- package/dist/src/cst-passes/emptyLinesBetweenMethods.d.ts.map +1 -0
- package/dist/src/cst-passes/emptyLinesBetweenMethods.js +11 -0
- package/dist/src/cst-passes/emptyLinesBetweenMethods.js.map +1 -0
- package/dist/src/cst-passes/endKeywordStyle.d.ts +21 -0
- package/dist/src/cst-passes/endKeywordStyle.d.ts.map +1 -0
- package/dist/src/cst-passes/endKeywordStyle.js +95 -0
- package/dist/src/cst-passes/endKeywordStyle.js.map +1 -0
- package/dist/src/cst-passes/fieldAccessConsistency.d.ts +4 -0
- package/dist/src/cst-passes/fieldAccessConsistency.d.ts.map +1 -0
- package/dist/src/cst-passes/fieldAccessConsistency.js +11 -0
- package/dist/src/cst-passes/fieldAccessConsistency.js.map +1 -0
- package/dist/src/cst-passes/functionVsSub.d.ts +13 -0
- package/dist/src/cst-passes/functionVsSub.d.ts.map +1 -0
- package/dist/src/cst-passes/functionVsSub.js +112 -0
- package/dist/src/cst-passes/functionVsSub.js.map +1 -0
- package/dist/src/cst-passes/importSorting.d.ts +25 -0
- package/dist/src/cst-passes/importSorting.d.ts.map +1 -0
- package/dist/src/cst-passes/importSorting.js +126 -0
- package/dist/src/cst-passes/importSorting.js.map +1 -0
- package/dist/src/cst-passes/indentation.d.ts +21 -0
- package/dist/src/cst-passes/indentation.d.ts.map +1 -0
- package/dist/src/cst-passes/indentation.js +115 -0
- package/dist/src/cst-passes/indentation.js.map +1 -0
- package/dist/src/cst-passes/index.d.ts +45 -0
- package/dist/src/cst-passes/index.d.ts.map +1 -0
- package/dist/src/cst-passes/index.js +77 -0
- package/dist/src/cst-passes/index.js.map +1 -0
- package/dist/src/cst-passes/infrastructure.d.ts +39 -0
- package/dist/src/cst-passes/infrastructure.d.ts.map +1 -0
- package/dist/src/cst-passes/infrastructure.js +63 -0
- package/dist/src/cst-passes/infrastructure.js.map +1 -0
- package/dist/src/cst-passes/lineCommentPosition.d.ts +4 -0
- package/dist/src/cst-passes/lineCommentPosition.d.ts.map +1 -0
- package/dist/src/cst-passes/lineCommentPosition.js +42 -0
- package/dist/src/cst-passes/lineCommentPosition.js.map +1 -0
- package/dist/src/cst-passes/mPrefixStyle.d.ts +4 -0
- package/dist/src/cst-passes/mPrefixStyle.d.ts.map +1 -0
- package/dist/src/cst-passes/mPrefixStyle.js +11 -0
- package/dist/src/cst-passes/mPrefixStyle.js.map +1 -0
- package/dist/src/cst-passes/observeFieldStyle.d.ts +6 -0
- package/dist/src/cst-passes/observeFieldStyle.d.ts.map +1 -0
- package/dist/src/cst-passes/observeFieldStyle.js +21 -0
- package/dist/src/cst-passes/observeFieldStyle.js.map +1 -0
- package/dist/src/cst-passes/paramAlignment.d.ts +4 -0
- package/dist/src/cst-passes/paramAlignment.d.ts.map +1 -0
- package/dist/src/cst-passes/paramAlignment.js +11 -0
- package/dist/src/cst-passes/paramAlignment.js.map +1 -0
- package/dist/src/cst-passes/parenthesisIfCase.d.ts +6 -0
- package/dist/src/cst-passes/parenthesisIfCase.d.ts.map +1 -0
- package/dist/src/cst-passes/parenthesisIfCase.js +42 -0
- package/dist/src/cst-passes/parenthesisIfCase.js.map +1 -0
- package/dist/src/cst-passes/printStatementRemoval.d.ts +20 -0
- package/dist/src/cst-passes/printStatementRemoval.d.ts.map +1 -0
- package/dist/src/cst-passes/printStatementRemoval.js +67 -0
- package/dist/src/cst-passes/printStatementRemoval.js.map +1 -0
- package/dist/src/cst-passes/spacing.d.ts +19 -0
- package/dist/src/cst-passes/spacing.d.ts.map +1 -0
- package/dist/src/cst-passes/spacing.js +81 -0
- package/dist/src/cst-passes/spacing.js.map +1 -0
- package/dist/src/cst-passes/splitArrayOpenBracket.d.ts +4 -0
- package/dist/src/cst-passes/splitArrayOpenBracket.d.ts.map +1 -0
- package/dist/src/cst-passes/splitArrayOpenBracket.js +11 -0
- package/dist/src/cst-passes/splitArrayOpenBracket.js.map +1 -0
- package/dist/src/cst-passes/stringConcatStyle.d.ts +4 -0
- package/dist/src/cst-passes/stringConcatStyle.d.ts.map +1 -0
- package/dist/src/cst-passes/stringConcatStyle.js +11 -0
- package/dist/src/cst-passes/stringConcatStyle.js.map +1 -0
- package/dist/src/cst-passes/stripCatchParens.d.ts +4 -0
- package/dist/src/cst-passes/stripCatchParens.d.ts.map +1 -0
- package/dist/src/cst-passes/stripCatchParens.js +29 -0
- package/dist/src/cst-passes/stripCatchParens.js.map +1 -0
- package/dist/src/cst-passes/thenStyle.d.ts +15 -0
- package/dist/src/cst-passes/thenStyle.d.ts.map +1 -0
- package/dist/src/cst-passes/thenStyle.js +140 -0
- package/dist/src/cst-passes/thenStyle.js.map +1 -0
- package/dist/src/cst-passes/trailingCommas.d.ts +13 -0
- package/dist/src/cst-passes/trailingCommas.d.ts.map +1 -0
- package/dist/src/cst-passes/trailingCommas.js +56 -0
- package/dist/src/cst-passes/trailingCommas.js.map +1 -0
- package/dist/src/cst-passes/trailingWhitespace.d.ts +13 -0
- package/dist/src/cst-passes/trailingWhitespace.d.ts.map +1 -0
- package/dist/src/cst-passes/trailingWhitespace.js +26 -0
- package/dist/src/cst-passes/trailingWhitespace.js.map +1 -0
- package/dist/src/cst-passes/wrapLongStrings.d.ts +4 -0
- package/dist/src/cst-passes/wrapLongStrings.d.ts.map +1 -0
- package/dist/src/cst-passes/wrapLongStrings.js +11 -0
- package/dist/src/cst-passes/wrapLongStrings.js.map +1 -0
- package/dist/src/formatter.d.ts +2 -1
- package/dist/src/formatter.d.ts.map +1 -1
- package/dist/src/formatter.js +74 -333
- package/dist/src/formatter.js.map +1 -1
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +11 -10
- package/dist/src/index.js.map +1 -1
- package/package.json +5 -2
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.elseOnNewLinePass = elseOnNewLinePass;
|
|
4
|
+
function elseOnNewLinePass(keepOnNewLine) {
|
|
5
|
+
if (keepOnNewLine)
|
|
6
|
+
return () => [];
|
|
7
|
+
return (_root, _source) => {
|
|
8
|
+
return [];
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=elseOnNewLine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elseOnNewLine.js","sourceRoot":"","sources":["../../../src/cst-passes/elseOnNewLine.ts"],"names":[],"mappings":";;AAGA,8CAKC;AALD,SAAgB,iBAAiB,CAAC,aAAsB;IACtD,IAAI,aAAa;QAAE,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC;IACnC,OAAO,CAAC,KAAiB,EAAE,OAAe,EAAc,EAAE;QACxD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SyntaxNode } from 'kopytko-brightscript-parser';
|
|
2
|
+
import { TextEdit } from './infrastructure';
|
|
3
|
+
export declare function emptyLinesBetweenMethodsPass(count: number): (root: SyntaxNode, source: string) => TextEdit[];
|
|
4
|
+
//# sourceMappingURL=emptyLinesBetweenMethods.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emptyLinesBetweenMethods.d.ts","sourceRoot":"","sources":["../../../src/cst-passes/emptyLinesBetweenMethods.ts"],"names":[],"mappings":"AAAsD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACpH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,KAAK,QAAQ,EAAE,CAK5G"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emptyLinesBetweenMethodsPass = emptyLinesBetweenMethodsPass;
|
|
4
|
+
function emptyLinesBetweenMethodsPass(count) {
|
|
5
|
+
if (count <= 0)
|
|
6
|
+
return () => [];
|
|
7
|
+
return (_root, _source) => {
|
|
8
|
+
return [];
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=emptyLinesBetweenMethods.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emptyLinesBetweenMethods.js","sourceRoot":"","sources":["../../../src/cst-passes/emptyLinesBetweenMethods.ts"],"names":[],"mappings":";;AAGA,oEAKC;AALD,SAAgB,4BAA4B,CAAC,KAAa;IACxD,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC;IAChC,OAAO,CAAC,KAAiB,EAAE,OAAe,EAAc,EAAE;QACxD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CST Pass: End keyword style.
|
|
3
|
+
*
|
|
4
|
+
* Converts between compact (`endif`, `endfor`) and spaced (`end if`, `end for`)
|
|
5
|
+
* forms of end keywords. This pass demonstrates the simplest CST transformation:
|
|
6
|
+
* finding specific tokens and replacing their text.
|
|
7
|
+
*
|
|
8
|
+
* Unlike the regex version, this pass:
|
|
9
|
+
* - Cannot accidentally match keywords inside string literals
|
|
10
|
+
* - Works correctly regardless of indentation or surrounding whitespace
|
|
11
|
+
* - Preserves all trivia (comments, whitespace) attached to the token
|
|
12
|
+
*/
|
|
13
|
+
import { SyntaxNode } from 'kopytko-brightscript-parser';
|
|
14
|
+
import { TextEdit } from './infrastructure';
|
|
15
|
+
/**
|
|
16
|
+
* Creates an end-keyword-style CST pass.
|
|
17
|
+
*
|
|
18
|
+
* @param style - 'spaced' converts `endif` → `end if`, 'compact' does the reverse.
|
|
19
|
+
*/
|
|
20
|
+
export declare function endKeywordStylePass(style: 'spaced' | 'compact'): (root: SyntaxNode, source: string) => TextEdit[];
|
|
21
|
+
//# sourceMappingURL=endKeywordStyle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endKeywordStyle.d.ts","sourceRoot":"","sources":["../../../src/cst-passes/endKeywordStyle.ts"],"names":[],"mappings":"CAAsD;;;;;;;;;;;GAWnD;AAEH,OAAO,EAAE,UAAU,EAAa,MAAM,6BAA6B,CAAC;AAEpE,OAAO,EAAE,QAAQ,EAAc,MAAM,kBAAkB,CAAC;AAgCxD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,KAAK,QAAQ,EAAE,CA2BjH"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */ /**
|
|
3
|
+
* CST Pass: End keyword style.
|
|
4
|
+
*
|
|
5
|
+
* Converts between compact (`endif`, `endfor`) and spaced (`end if`, `end for`)
|
|
6
|
+
* forms of end keywords. This pass demonstrates the simplest CST transformation:
|
|
7
|
+
* finding specific tokens and replacing their text.
|
|
8
|
+
*
|
|
9
|
+
* Unlike the regex version, this pass:
|
|
10
|
+
* - Cannot accidentally match keywords inside string literals
|
|
11
|
+
* - Works correctly regardless of indentation or surrounding whitespace
|
|
12
|
+
* - Preserves all trivia (comments, whitespace) attached to the token
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.endKeywordStylePass = endKeywordStylePass;
|
|
16
|
+
const kopytko_brightscript_parser_1 = require("kopytko-brightscript-parser");
|
|
17
|
+
const infrastructure_1 = require("./infrastructure");
|
|
18
|
+
/** Map from compact form to spaced form. */
|
|
19
|
+
const COMPACT_TO_SPACED = {
|
|
20
|
+
'endif': 'end if',
|
|
21
|
+
'endfunction': 'end function',
|
|
22
|
+
'endsub': 'end sub',
|
|
23
|
+
'endwhile': 'end while',
|
|
24
|
+
'endfor': 'end for',
|
|
25
|
+
'endtry': 'end try',
|
|
26
|
+
};
|
|
27
|
+
/** Map from spaced token text (lowercased) to compact form. */
|
|
28
|
+
const SPACED_TO_COMPACT = {
|
|
29
|
+
'end if': 'endif',
|
|
30
|
+
'end function': 'endfunction',
|
|
31
|
+
'end sub': 'endsub',
|
|
32
|
+
'end while': 'endwhile',
|
|
33
|
+
'end for': 'endfor',
|
|
34
|
+
'end try': 'endtry',
|
|
35
|
+
};
|
|
36
|
+
/** The token kinds that represent end keywords. */
|
|
37
|
+
const END_KEYWORD_KINDS = new Set([
|
|
38
|
+
kopytko_brightscript_parser_1.TokenKind.EndIf,
|
|
39
|
+
kopytko_brightscript_parser_1.TokenKind.EndFunction,
|
|
40
|
+
kopytko_brightscript_parser_1.TokenKind.EndSub,
|
|
41
|
+
kopytko_brightscript_parser_1.TokenKind.EndWhile,
|
|
42
|
+
kopytko_brightscript_parser_1.TokenKind.EndFor,
|
|
43
|
+
kopytko_brightscript_parser_1.TokenKind.EndTry,
|
|
44
|
+
]);
|
|
45
|
+
/**
|
|
46
|
+
* Creates an end-keyword-style CST pass.
|
|
47
|
+
*
|
|
48
|
+
* @param style - 'spaced' converts `endif` → `end if`, 'compact' does the reverse.
|
|
49
|
+
*/
|
|
50
|
+
function endKeywordStylePass(style) {
|
|
51
|
+
return (root, _source) => {
|
|
52
|
+
const edits = [];
|
|
53
|
+
(0, infrastructure_1.walkTokens)(root, (token) => {
|
|
54
|
+
if (!END_KEYWORD_KINDS.has(token.kind))
|
|
55
|
+
return;
|
|
56
|
+
const lower = token.text.toLowerCase();
|
|
57
|
+
if (style === 'spaced') {
|
|
58
|
+
const spaced = COMPACT_TO_SPACED[lower];
|
|
59
|
+
if (spaced) {
|
|
60
|
+
// Preserve original casing pattern: if original was "EndIf", produce "End If"
|
|
61
|
+
const newText = matchCasing(token.text, spaced);
|
|
62
|
+
edits.push({ pos: token.pos, end: token.end, newText });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
const compact = SPACED_TO_COMPACT[lower];
|
|
67
|
+
if (compact) {
|
|
68
|
+
const newText = matchCasing(token.text, compact);
|
|
69
|
+
edits.push({ pos: token.pos, end: token.end, newText });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return edits;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Produces the target string with casing that matches the original's pattern.
|
|
78
|
+
* If original is all-lowercase → target lowercase.
|
|
79
|
+
* If original starts with uppercase → capitalize first letter of each word in target.
|
|
80
|
+
* If original is all-uppercase → target uppercase.
|
|
81
|
+
*/
|
|
82
|
+
function matchCasing(original, target) {
|
|
83
|
+
if (original === original.toLowerCase())
|
|
84
|
+
return target.toLowerCase();
|
|
85
|
+
if (original === original.toUpperCase())
|
|
86
|
+
return target.toUpperCase();
|
|
87
|
+
// Title case: capitalize first letter of each word
|
|
88
|
+
return target.replace(/\b\w/g, (ch, idx) => {
|
|
89
|
+
// Match the casing of the corresponding position in the original
|
|
90
|
+
if (idx === 0)
|
|
91
|
+
return original[0] === original[0].toUpperCase() ? ch.toUpperCase() : ch.toLowerCase();
|
|
92
|
+
return ch.toUpperCase();
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=endKeywordStyle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endKeywordStyle.js","sourceRoot":"","sources":["../../../src/cst-passes/endKeywordStyle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SyntaxNode } from 'kopytko-brightscript-parser';
|
|
2
|
+
import { TextEdit } from './infrastructure';
|
|
3
|
+
export declare function fieldAccessConsistencyPass(style: string): (root: SyntaxNode, source: string) => TextEdit[];
|
|
4
|
+
//# sourceMappingURL=fieldAccessConsistency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldAccessConsistency.d.ts","sourceRoot":"","sources":["../../../src/cst-passes/fieldAccessConsistency.ts"],"names":[],"mappings":"AAAsD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACpH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,KAAK,QAAQ,EAAE,CAK1G"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fieldAccessConsistencyPass = fieldAccessConsistencyPass;
|
|
4
|
+
function fieldAccessConsistencyPass(style) {
|
|
5
|
+
if (style === 'preserve')
|
|
6
|
+
return () => [];
|
|
7
|
+
return (_root, _source) => {
|
|
8
|
+
return [];
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=fieldAccessConsistency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldAccessConsistency.js","sourceRoot":"","sources":["../../../src/cst-passes/fieldAccessConsistency.ts"],"names":[],"mappings":";;AAGA,gEAKC;AALD,SAAgB,0BAA0B,CAAC,KAAa;IACtD,IAAI,KAAK,KAAK,UAAU;QAAE,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC;IAC1C,OAAO,CAAC,KAAiB,EAAE,OAAe,EAAc,EAAE;QACxD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CST Pass: Function vs Sub for void.
|
|
3
|
+
*
|
|
4
|
+
* Converts between `function`/`sub` for void procedures:
|
|
5
|
+
* - 'sub': converts `function foo() as Void ... end function` to `sub foo() ... end sub`
|
|
6
|
+
* - 'function': converts `sub foo() ... end sub` to `function foo() as Void ... end function`
|
|
7
|
+
*/
|
|
8
|
+
import { SyntaxNode } from 'kopytko-brightscript-parser';
|
|
9
|
+
import { TextEdit } from './infrastructure';
|
|
10
|
+
type FuncVsSub = 'function' | 'sub' | 'preserve';
|
|
11
|
+
export declare function functionVsSubPass(style: FuncVsSub): (root: SyntaxNode, source: string) => TextEdit[];
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=functionVsSub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functionVsSub.d.ts","sourceRoot":"","sources":["../../../src/cst-passes/functionVsSub.ts"],"names":[],"mappings":"CAAsD;;;;;;GAMnD;AAEH,OAAO,EAAE,UAAU,EAA0C,MAAM,6BAA6B,CAAC;AAEjG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,KAAK,SAAS,GAAG,UAAU,GAAG,KAAK,GAAG,UAAU,CAAC;AAEjD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,KAAK,QAAQ,EAAE,CAkBpG"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */ /**
|
|
3
|
+
* CST Pass: Function vs Sub for void.
|
|
4
|
+
*
|
|
5
|
+
* Converts between `function`/`sub` for void procedures:
|
|
6
|
+
* - 'sub': converts `function foo() as Void ... end function` to `sub foo() ... end sub`
|
|
7
|
+
* - 'function': converts `sub foo() ... end sub` to `function foo() as Void ... end function`
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.functionVsSubPass = functionVsSubPass;
|
|
11
|
+
const kopytko_brightscript_parser_1 = require("kopytko-brightscript-parser");
|
|
12
|
+
function functionVsSubPass(style) {
|
|
13
|
+
if (style === 'preserve')
|
|
14
|
+
return () => [];
|
|
15
|
+
return (root, _source) => {
|
|
16
|
+
const edits = [];
|
|
17
|
+
function visit(node) {
|
|
18
|
+
if (node.kind === kopytko_brightscript_parser_1.SyntaxKind.FunctionDeclaration || node.kind === kopytko_brightscript_parser_1.SyntaxKind.FunctionExpression) {
|
|
19
|
+
processFunctionNode(node, edits, style);
|
|
20
|
+
}
|
|
21
|
+
for (const child of node.children) {
|
|
22
|
+
if ((0, kopytko_brightscript_parser_1.isNode)(child))
|
|
23
|
+
visit(child);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
visit(root);
|
|
27
|
+
return edits;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function processFunctionNode(node, edits, style) {
|
|
31
|
+
const funcToken = node.findToken(kopytko_brightscript_parser_1.TokenKind.Function);
|
|
32
|
+
const subToken = node.findToken(kopytko_brightscript_parser_1.TokenKind.Sub);
|
|
33
|
+
const keyword = funcToken ?? subToken;
|
|
34
|
+
if (!keyword)
|
|
35
|
+
return;
|
|
36
|
+
const isFunc = funcToken !== undefined;
|
|
37
|
+
const isSub = subToken !== undefined;
|
|
38
|
+
// Find end keyword
|
|
39
|
+
const endFuncToken = node.findToken(kopytko_brightscript_parser_1.TokenKind.EndFunction);
|
|
40
|
+
const endSubToken = node.findToken(kopytko_brightscript_parser_1.TokenKind.EndSub);
|
|
41
|
+
const endToken = endFuncToken ?? endSubToken;
|
|
42
|
+
// Check if it has a non-void return type
|
|
43
|
+
const returnTypeClause = node.findChild(kopytko_brightscript_parser_1.SyntaxKind.ReturnTypeClause);
|
|
44
|
+
const hasExplicitReturnType = returnTypeClause !== undefined;
|
|
45
|
+
let returnTypeName = '';
|
|
46
|
+
if (returnTypeClause) {
|
|
47
|
+
const tokens = returnTypeClause.childTokens;
|
|
48
|
+
if (tokens.length >= 2)
|
|
49
|
+
returnTypeName = tokens[1].text.toLowerCase();
|
|
50
|
+
}
|
|
51
|
+
const isVoid = !hasExplicitReturnType || returnTypeName === 'void';
|
|
52
|
+
// Check if body has `return <value>`
|
|
53
|
+
if (!isVoid)
|
|
54
|
+
return; // has explicit non-void return type — don't touch
|
|
55
|
+
const hasReturnValue = checkReturnWithValue(node);
|
|
56
|
+
if (hasReturnValue)
|
|
57
|
+
return; // returns a value — not a void function
|
|
58
|
+
if (style === 'sub' && isFunc && isVoid) {
|
|
59
|
+
// Convert function → sub: replace keyword, remove 'as Void' if present, replace end keyword
|
|
60
|
+
edits.push({ pos: keyword.pos, end: keyword.end, newText: 'sub' });
|
|
61
|
+
if (returnTypeClause) {
|
|
62
|
+
// Remove the return type clause text only (not trailing trivia/newline)
|
|
63
|
+
// Find the actual token end (not including trailing trivia)
|
|
64
|
+
const clauseTokens = returnTypeClause.childTokens;
|
|
65
|
+
const lastClauseToken = clauseTokens[clauseTokens.length - 1];
|
|
66
|
+
const clauseStart = returnTypeClause.pos;
|
|
67
|
+
const clauseEnd = lastClauseToken ? lastClauseToken.end : returnTypeClause.end;
|
|
68
|
+
// Also remove the space before 'as' (between closing paren and 'as')
|
|
69
|
+
const adjustedStart = clauseStart > 0 ? clauseStart - 1 : clauseStart;
|
|
70
|
+
edits.push({ pos: adjustedStart, end: clauseEnd, newText: '' });
|
|
71
|
+
}
|
|
72
|
+
if (endToken) {
|
|
73
|
+
const newEnd = endToken.text.toLowerCase().includes(' ') ? 'end sub' : 'endsub';
|
|
74
|
+
edits.push({ pos: endToken.pos, end: endToken.end, newText: newEnd });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else if (style === 'function' && isSub) {
|
|
78
|
+
// Convert sub → function: replace keyword, add 'as Void', replace end keyword
|
|
79
|
+
edits.push({ pos: keyword.pos, end: keyword.end, newText: 'function' });
|
|
80
|
+
// Insert ' as Void' after the parameter list closing paren
|
|
81
|
+
const paramList = node.findChild(kopytko_brightscript_parser_1.SyntaxKind.ParameterList);
|
|
82
|
+
if (paramList) {
|
|
83
|
+
const rParen = paramList.findToken(kopytko_brightscript_parser_1.TokenKind.RightParen);
|
|
84
|
+
if (rParen) {
|
|
85
|
+
edits.push({ pos: rParen.end, end: rParen.end, newText: ' as Void' });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (endToken) {
|
|
89
|
+
const newEnd = endToken.text.toLowerCase().includes(' ') ? 'end function' : 'endfunction';
|
|
90
|
+
edits.push({ pos: endToken.pos, end: endToken.end, newText: newEnd });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function checkReturnWithValue(node) {
|
|
95
|
+
for (const child of node.children) {
|
|
96
|
+
if ((0, kopytko_brightscript_parser_1.isNode)(child)) {
|
|
97
|
+
if (child.kind === kopytko_brightscript_parser_1.SyntaxKind.ReturnStatement) {
|
|
98
|
+
// Check if return has a value (more than just the 'return' token)
|
|
99
|
+
const childNodes = child.childNodes;
|
|
100
|
+
if (childNodes.length > 0)
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
// Don't recurse into nested functions
|
|
104
|
+
if (child.kind === kopytko_brightscript_parser_1.SyntaxKind.FunctionDeclaration || child.kind === kopytko_brightscript_parser_1.SyntaxKind.FunctionExpression)
|
|
105
|
+
continue;
|
|
106
|
+
if (checkReturnWithValue(child))
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=functionVsSub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functionVsSub.js","sourceRoot":"","sources":["../../../src/cst-passes/functionVsSub.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CST Pass: Import sorting.
|
|
3
|
+
*
|
|
4
|
+
* Sorts `' @import` and `' @mock` annotations at the top of the file.
|
|
5
|
+
* Groups: module imports (with `from`) first, then local imports.
|
|
6
|
+
* Within each group, sorts alphabetically.
|
|
7
|
+
*
|
|
8
|
+
* Unlike the regex version, this pass:
|
|
9
|
+
* - Uses trivia classification to identify import comments precisely
|
|
10
|
+
* - Works on the actual trivia text, not line-by-line matching
|
|
11
|
+
* - Preserves all non-import content exactly as-is
|
|
12
|
+
*/
|
|
13
|
+
import { SyntaxNode } from 'kopytko-brightscript-parser';
|
|
14
|
+
import { TextEdit } from './infrastructure';
|
|
15
|
+
interface ImportSortConfig {
|
|
16
|
+
sortImports: boolean;
|
|
17
|
+
emptyLineAfterImports: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Creates an import sorting CST pass.
|
|
21
|
+
* Operates on the leading trivia of the first token in the file.
|
|
22
|
+
*/
|
|
23
|
+
export declare function importSortingPass(config: ImportSortConfig): (root: SyntaxNode, source: string) => TextEdit[];
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=importSorting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importSorting.d.ts","sourceRoot":"","sources":["../../../src/cst-passes/importSorting.ts"],"names":[],"mappings":"CAAsD;;;;;;;;;;;GAWnD;AAEH,OAAO,EAAE,UAAU,EAA+B,MAAM,6BAA6B,CAAC;AAEtF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,UAAU,gBAAgB;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAOD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,KAAK,QAAQ,EAAE,CAgF5G"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */ /**
|
|
3
|
+
* CST Pass: Import sorting.
|
|
4
|
+
*
|
|
5
|
+
* Sorts `' @import` and `' @mock` annotations at the top of the file.
|
|
6
|
+
* Groups: module imports (with `from`) first, then local imports.
|
|
7
|
+
* Within each group, sorts alphabetically.
|
|
8
|
+
*
|
|
9
|
+
* Unlike the regex version, this pass:
|
|
10
|
+
* - Uses trivia classification to identify import comments precisely
|
|
11
|
+
* - Works on the actual trivia text, not line-by-line matching
|
|
12
|
+
* - Preserves all non-import content exactly as-is
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.importSortingPass = importSortingPass;
|
|
16
|
+
const kopytko_brightscript_parser_1 = require("kopytko-brightscript-parser");
|
|
17
|
+
const IMPORT_RE = /^\s*'\s*@import\s+/;
|
|
18
|
+
const MOCK_RE = /^\s*'\s*@mock\s+/;
|
|
19
|
+
const FROM_IMPORT_RE = /^\s*'\s*@import\s+(.*?)\s+from\s+(\S+)\s*$/;
|
|
20
|
+
const FROM_MOCK_RE = /^\s*'\s*@mock\s+(.*?)\s+from\s+(\S+)\s*$/;
|
|
21
|
+
/**
|
|
22
|
+
* Creates an import sorting CST pass.
|
|
23
|
+
* Operates on the leading trivia of the first token in the file.
|
|
24
|
+
*/
|
|
25
|
+
function importSortingPass(config) {
|
|
26
|
+
if (!config.sortImports && !config.emptyLineAfterImports) {
|
|
27
|
+
return () => [];
|
|
28
|
+
}
|
|
29
|
+
return (root, source) => {
|
|
30
|
+
// Find all import/mock comment lines at the top of the file.
|
|
31
|
+
// In our CST, these are trivia attached to the first token.
|
|
32
|
+
const firstToken = findFirstToken(root);
|
|
33
|
+
if (!firstToken)
|
|
34
|
+
return [];
|
|
35
|
+
// Collect consecutive import comments from leading trivia
|
|
36
|
+
const importTrivia = [];
|
|
37
|
+
let lastImportIdx = -1;
|
|
38
|
+
for (let i = 0; i < firstToken.leadingTrivia.length; i++) {
|
|
39
|
+
const t = firstToken.leadingTrivia[i];
|
|
40
|
+
if (t.kind === kopytko_brightscript_parser_1.TriviaKind.Comment) {
|
|
41
|
+
if (IMPORT_RE.test(t.text) || MOCK_RE.test(t.text)) {
|
|
42
|
+
importTrivia.push(t);
|
|
43
|
+
lastImportIdx = i;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// Non-import comment encountered — stop
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Skip whitespace and line breaks between imports
|
|
51
|
+
}
|
|
52
|
+
if (importTrivia.length === 0)
|
|
53
|
+
return [];
|
|
54
|
+
if (!config.sortImports)
|
|
55
|
+
return []; // Only sorting for now
|
|
56
|
+
// Sort imports
|
|
57
|
+
const moduleImports = [];
|
|
58
|
+
const localImports = [];
|
|
59
|
+
const moduleMocks = [];
|
|
60
|
+
const localMocks = [];
|
|
61
|
+
for (const t of importTrivia) {
|
|
62
|
+
if (MOCK_RE.test(t.text)) {
|
|
63
|
+
if (FROM_MOCK_RE.test(t.text))
|
|
64
|
+
moduleMocks.push(t.text);
|
|
65
|
+
else
|
|
66
|
+
localMocks.push(t.text);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
if (FROM_IMPORT_RE.test(t.text))
|
|
70
|
+
moduleImports.push(t.text);
|
|
71
|
+
else
|
|
72
|
+
localImports.push(t.text);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Sort each group
|
|
76
|
+
moduleImports.sort((a, b) => {
|
|
77
|
+
const am = FROM_IMPORT_RE.exec(a);
|
|
78
|
+
const bm = FROM_IMPORT_RE.exec(b);
|
|
79
|
+
const cmp = am[2].localeCompare(bm[2]);
|
|
80
|
+
return cmp !== 0 ? cmp : am[1].localeCompare(bm[1]);
|
|
81
|
+
});
|
|
82
|
+
localImports.sort();
|
|
83
|
+
moduleMocks.sort((a, b) => {
|
|
84
|
+
const am = FROM_MOCK_RE.exec(a);
|
|
85
|
+
const bm = FROM_MOCK_RE.exec(b);
|
|
86
|
+
const cmp = am[2].localeCompare(bm[2]);
|
|
87
|
+
return cmp !== 0 ? cmp : am[1].localeCompare(bm[1]);
|
|
88
|
+
});
|
|
89
|
+
localMocks.sort();
|
|
90
|
+
const sorted = [...moduleImports, ...localImports, ...moduleMocks, ...localMocks];
|
|
91
|
+
// Check if already sorted
|
|
92
|
+
const original = importTrivia.map(t => t.text);
|
|
93
|
+
if (arraysEqual(original, sorted))
|
|
94
|
+
return [];
|
|
95
|
+
// Build the replacement: sorted imports joined by newlines
|
|
96
|
+
const firstImport = importTrivia[0];
|
|
97
|
+
const lastImport = importTrivia[importTrivia.length - 1];
|
|
98
|
+
// Find the range covering all import trivia (from first import start to last import end)
|
|
99
|
+
const rangeStart = firstImport.pos;
|
|
100
|
+
const rangeEnd = lastImport.end;
|
|
101
|
+
const newText = sorted.join('\n');
|
|
102
|
+
return [{ pos: rangeStart, end: rangeEnd, newText }];
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function findFirstToken(node) {
|
|
106
|
+
for (const child of node.children) {
|
|
107
|
+
if ((0, kopytko_brightscript_parser_1.isToken)(child))
|
|
108
|
+
return child;
|
|
109
|
+
if ((0, kopytko_brightscript_parser_1.isNode)(child)) {
|
|
110
|
+
const found = findFirstToken(child);
|
|
111
|
+
if (found)
|
|
112
|
+
return found;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
function arraysEqual(a, b) {
|
|
118
|
+
if (a.length !== b.length)
|
|
119
|
+
return false;
|
|
120
|
+
for (let i = 0; i < a.length; i++) {
|
|
121
|
+
if (a[i] !== b[i])
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=importSorting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importSorting.js","sourceRoot":"","sources":["../../../src/cst-passes/importSorting.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CST Pass: Indentation.
|
|
3
|
+
*
|
|
4
|
+
* Applies consistent indentation based on nesting depth.
|
|
5
|
+
* Walks the CST structure to determine indent level and sets
|
|
6
|
+
* leading whitespace accordingly.
|
|
7
|
+
*/
|
|
8
|
+
import { SyntaxNode } from 'kopytko-brightscript-parser';
|
|
9
|
+
import { TextEdit } from './infrastructure';
|
|
10
|
+
interface IndentConfig {
|
|
11
|
+
indentSize: number;
|
|
12
|
+
useTabs: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Creates an indentation pass.
|
|
16
|
+
* Calculates depth by counting ancestor INDENT_OPENERS and sets
|
|
17
|
+
* leading whitespace for the first token of each line.
|
|
18
|
+
*/
|
|
19
|
+
export declare function indentationPass(config: IndentConfig): (root: SyntaxNode, source: string) => TextEdit[];
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=indentation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indentation.d.ts","sourceRoot":"","sources":["../../../src/cst-passes/indentation.ts"],"names":[],"mappings":"CAAsD;;;;;;GAMnD;AAEH,OAAO,EAAE,UAAU,EAA0C,MAAM,6BAA6B,CAAC;AAEjG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,UAAU,YAAY;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB;AAgBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,KAAK,QAAQ,EAAE,CAiCtG"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */ /**
|
|
3
|
+
* CST Pass: Indentation.
|
|
4
|
+
*
|
|
5
|
+
* Applies consistent indentation based on nesting depth.
|
|
6
|
+
* Walks the CST structure to determine indent level and sets
|
|
7
|
+
* leading whitespace accordingly.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.indentationPass = indentationPass;
|
|
11
|
+
const kopytko_brightscript_parser_1 = require("kopytko-brightscript-parser");
|
|
12
|
+
const INDENT_OPENERS = new Set([
|
|
13
|
+
kopytko_brightscript_parser_1.SyntaxKind.FunctionDeclaration,
|
|
14
|
+
kopytko_brightscript_parser_1.SyntaxKind.FunctionExpression,
|
|
15
|
+
kopytko_brightscript_parser_1.SyntaxKind.IfStatement,
|
|
16
|
+
kopytko_brightscript_parser_1.SyntaxKind.ElseIfClause,
|
|
17
|
+
kopytko_brightscript_parser_1.SyntaxKind.ElseClause,
|
|
18
|
+
kopytko_brightscript_parser_1.SyntaxKind.ForStatement,
|
|
19
|
+
kopytko_brightscript_parser_1.SyntaxKind.ForEachStatement,
|
|
20
|
+
kopytko_brightscript_parser_1.SyntaxKind.WhileStatement,
|
|
21
|
+
kopytko_brightscript_parser_1.SyntaxKind.TryStatement,
|
|
22
|
+
kopytko_brightscript_parser_1.SyntaxKind.CatchClause,
|
|
23
|
+
kopytko_brightscript_parser_1.SyntaxKind.ConditionalCompilation,
|
|
24
|
+
]);
|
|
25
|
+
/**
|
|
26
|
+
* Creates an indentation pass.
|
|
27
|
+
* Calculates depth by counting ancestor INDENT_OPENERS and sets
|
|
28
|
+
* leading whitespace for the first token of each line.
|
|
29
|
+
*/
|
|
30
|
+
function indentationPass(config) {
|
|
31
|
+
return (root, source) => {
|
|
32
|
+
const edits = [];
|
|
33
|
+
const indentChar = config.useTabs ? '\t' : ' '.repeat(config.indentSize);
|
|
34
|
+
const lines = source.split(/\r?\n/);
|
|
35
|
+
// Build a map: line number → expected indent depth
|
|
36
|
+
const lineDepths = new Map();
|
|
37
|
+
computeDepths(root, 0, lineDepths);
|
|
38
|
+
// For each line, check if the current indentation matches expected
|
|
39
|
+
let offset = 0;
|
|
40
|
+
for (let lineNum = 0; lineNum < lines.length; lineNum++) {
|
|
41
|
+
const line = lines[lineNum];
|
|
42
|
+
const currentIndent = line.match(/^(\s*)/)?.[1] ?? '';
|
|
43
|
+
const expectedDepth = lineDepths.get(lineNum);
|
|
44
|
+
if (expectedDepth !== undefined && expectedDepth >= 0) {
|
|
45
|
+
const expectedIndent = indentChar.repeat(expectedDepth);
|
|
46
|
+
if (currentIndent !== expectedIndent && line.trim() !== '') {
|
|
47
|
+
edits.push({
|
|
48
|
+
pos: offset,
|
|
49
|
+
end: offset + currentIndent.length,
|
|
50
|
+
newText: expectedIndent,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
offset += line.length + 1; // +1 for the newline character
|
|
55
|
+
}
|
|
56
|
+
return edits;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function computeDepths(node, depth, lineDepths) {
|
|
60
|
+
for (const child of node.children) {
|
|
61
|
+
if ((0, kopytko_brightscript_parser_1.isToken)(child)) {
|
|
62
|
+
// The first token of a line sets that line's depth
|
|
63
|
+
if (!lineDepths.has(child.line)) {
|
|
64
|
+
lineDepths.set(child.line, depth);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else if ((0, kopytko_brightscript_parser_1.isNode)(child)) {
|
|
68
|
+
const childDepth = INDENT_OPENERS.has(child.kind) ? depth + 1 : depth;
|
|
69
|
+
// For block openers, the first line (the keyword itself) stays at current depth
|
|
70
|
+
if (INDENT_OPENERS.has(child.kind)) {
|
|
71
|
+
// Opening keyword line stays at `depth`
|
|
72
|
+
const firstToken = findFirstToken(child);
|
|
73
|
+
if (firstToken) {
|
|
74
|
+
lineDepths.set(firstToken.line, depth);
|
|
75
|
+
}
|
|
76
|
+
// Closing keyword also stays at `depth`
|
|
77
|
+
const lastToken = findLastToken(child);
|
|
78
|
+
if (lastToken) {
|
|
79
|
+
lineDepths.set(lastToken.line, depth);
|
|
80
|
+
}
|
|
81
|
+
// Body is at depth + 1
|
|
82
|
+
computeDepths(child, depth + 1, lineDepths);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
computeDepths(child, depth, lineDepths);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function findFirstToken(node) {
|
|
91
|
+
for (const child of node.children) {
|
|
92
|
+
if ((0, kopytko_brightscript_parser_1.isToken)(child))
|
|
93
|
+
return child;
|
|
94
|
+
if ((0, kopytko_brightscript_parser_1.isNode)(child)) {
|
|
95
|
+
const found = findFirstToken(child);
|
|
96
|
+
if (found)
|
|
97
|
+
return found;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
function findLastToken(node) {
|
|
103
|
+
for (let i = node.children.length - 1; i >= 0; i--) {
|
|
104
|
+
const child = node.children[i];
|
|
105
|
+
if ((0, kopytko_brightscript_parser_1.isToken)(child))
|
|
106
|
+
return child;
|
|
107
|
+
if ((0, kopytko_brightscript_parser_1.isNode)(child)) {
|
|
108
|
+
const found = findLastToken(child);
|
|
109
|
+
if (found)
|
|
110
|
+
return found;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=indentation.js.map
|