Skip to content

Commit 3b8ffd6

Browse files
committed
feat: support block comments
1 parent cc5cef3 commit 3b8ffd6

File tree

4 files changed

+74
-12
lines changed

4 files changed

+74
-12
lines changed

src/commands/keep-sorted.test.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ run(
1010
'apple',
1111
'bar',
1212
'foo',
13-
]`
14-
15-
,
13+
]`,
1614
// Object property
1715
{
1816
code: d`
@@ -208,4 +206,32 @@ run(
208206
]`,
209207
errors: ['command-error'],
210208
},
209+
// Block comment
210+
{
211+
code: d`
212+
/**
213+
* Some JSdocs
214+
*
215+
* @keep-sorted
216+
* @description
217+
*/
218+
export const arr = [
219+
'foo',
220+
'bar',
221+
'apple',
222+
]`,
223+
output: d`
224+
/**
225+
* Some JSdocs
226+
*
227+
* @keep-sorted
228+
* @description
229+
*/
230+
export const arr = [
231+
'apple',
232+
'bar',
233+
'foo',
234+
]`,
235+
errors: ['command-fix'],
236+
},
211237
)

src/commands/keep-sorted.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@ export interface KeepSortedInlineOptions {
55
keys?: string[]
66
}
77

8+
const reLine = /^[\/@:]\s*(?:keep-sorted|sorted)\s*({.*})?$/
9+
const reBlock = /(?:\b|\s)@keep-sorted\s*({.*})?(?:\b|\s|$)/
10+
811
export const keepSorted: Command = {
912
name: 'keep-sorted',
10-
match: /^[\/@:]\s*(?:keep-sorted|sorted)\s*({.*})?$/,
13+
commentType: 'both',
14+
match: comment => comment.value.trim().match(comment.type === 'Line' ? reLine : reBlock),
1115
action(ctx) {
1216
const optionsRaw = ctx.matches[1] || '{}'
1317
let options: KeepSortedInlineOptions | null = null

src/rule.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,27 @@ export function createRuleWithCommands(commands: Command[]) {
2626
const comments = sc.getAllComments()
2727

2828
for (const comment of comments) {
29-
if (comment.type !== 'Line')
30-
continue
31-
3229
const commandRaw = comment.value.trim()
3330
for (const command of commands) {
34-
const matches = commandRaw.match(command.match)
35-
if (matches) {
36-
command.action(new CommandContext(context, comment, command, matches))
31+
const type = command.commentType ?? 'line'
32+
if (type === 'line' && comment.type !== 'Line')
33+
continue
34+
if (type === 'block' && comment.type !== 'Block')
3735
continue
38-
}
36+
37+
let matches = typeof command.match === 'function'
38+
? command.match(comment)
39+
: commandRaw.match(command.match)
40+
41+
if (!matches)
42+
continue
43+
44+
// create a dummy match for user provided function that returns `true`
45+
if (matches === true)
46+
matches = '__dummy__'.match('__dummy__')!
47+
48+
command.action(new CommandContext(context, comment, command, matches))
49+
break
3950
}
4051
}
4152
return {}

src/types.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,29 @@ export type RuleOptions = []
99
export type MessageIds = 'command-error' | 'command-error-cause' | 'command-fix' | 'command-removal'
1010

1111
export interface Command {
12-
match: RegExp
12+
/**
13+
* The name of the command
14+
* Used to identify the command in reported errors
15+
*/
1316
name: string
17+
/**
18+
* RegExp to match the comment, without the leading `//` or `/*`
19+
*/
20+
match: RegExp | ((comment: Tree.Comment) => RegExpMatchArray | boolean | undefined | null)
21+
/**
22+
* The type of the comment
23+
*
24+
* - `line` - `//`
25+
* - `block` - `/*`
26+
*
27+
* @default 'line'
28+
*/
29+
commentType?: 'line' | 'block' | 'both'
30+
/**
31+
* Main action of the command
32+
*
33+
* @param ctx The context of the command (per-file, per matched comment)
34+
*/
1435
action: (ctx: CommandContext) => void
1536
}
1637

0 commit comments

Comments
 (0)