@@ -3,6 +3,7 @@ use emmylua_parser::{
3
3
LuaAstNode , LuaDocDescription , LuaKind , LuaSyntaxElement , LuaTokenData , LuaTokenKind , Reader ,
4
4
SourceRange ,
5
5
} ;
6
+ use rowan:: Direction ;
6
7
use std:: cmp:: min;
7
8
use std:: sync:: LazyLock ;
8
9
@@ -20,29 +21,34 @@ pub fn desc_to_lines(
20
21
let mut skip_current_line_content = false ;
21
22
let mut seen_doc_comments = false ;
22
23
23
- for child in desc . syntax ( ) . children_with_tokens ( ) {
24
- let LuaSyntaxElement :: Token ( token) = child else {
25
- continue ;
24
+ let mut handle_token = | token : & LuaSyntaxElement | {
25
+ let LuaSyntaxElement :: Token ( token) = token else {
26
+ return ;
26
27
} ;
27
28
28
29
match token. kind ( ) {
29
30
LuaKind :: Token ( LuaTokenKind :: TkDocDetail ) => {
30
31
if skip_current_line_content {
31
- continue ;
32
+ return ;
32
33
}
33
34
34
35
let range: SourceRange = token. text_range ( ) . into ( ) ;
35
36
if line. end_offset ( ) == range. start_offset {
36
37
line. length += range. length ;
37
38
} else {
38
39
if line != SourceRange :: EMPTY {
39
- seen_doc_comments |= !token. text ( ) . trim_end ( ) . chars ( ) . all ( |c| c == '-' ) ;
40
+ seen_doc_comments |= !text[ line. start_offset ..line. end_offset ( ) ]
41
+ . chars ( )
42
+ . all ( |c| c == '-' ) ;
40
43
lines. push ( line) ;
41
44
}
42
45
line = range;
43
46
}
44
47
}
45
48
LuaKind :: Token ( LuaTokenKind :: TkEndOfLine ) => {
49
+ seen_doc_comments |= !text[ line. start_offset ..line. end_offset ( ) ]
50
+ . chars ( )
51
+ . all ( |c| c == '-' ) ;
46
52
lines. push ( line) ;
47
53
line = SourceRange :: EMPTY ;
48
54
skip_current_line_content = false
@@ -68,6 +74,21 @@ pub fn desc_to_lines(
68
74
}
69
75
_ => { }
70
76
}
77
+ } ;
78
+
79
+ let prev_token = desc
80
+ . syntax ( )
81
+ . siblings_with_tokens ( Direction :: Prev )
82
+ . skip ( 1 )
83
+ . skip_while ( |tk| tk. kind ( ) == LuaTokenKind :: TkWhitespace . into ( ) )
84
+ . next ( ) ;
85
+ if let Some ( prev_token) = prev_token {
86
+ if prev_token. kind ( ) == LuaTokenKind :: TkNormalStart . into ( ) {
87
+ handle_token ( & prev_token) ;
88
+ }
89
+ }
90
+ for child in desc. syntax ( ) . children_with_tokens ( ) {
91
+ handle_token ( & child) ;
71
92
}
72
93
73
94
if !line. is_empty ( ) {
@@ -118,7 +139,7 @@ pub fn desc_to_lines(
118
139
119
140
// Find and remove comment indentation.
120
141
let mut common_indent = None ;
121
- for line in lines. iter ( ) . skip ( 1 ) {
142
+ for line in lines. iter ( ) {
122
143
let text = & text[ line. start_offset ..line. end_offset ( ) ] ;
123
144
124
145
if is_blank ( text) {
@@ -134,7 +155,7 @@ pub fn desc_to_lines(
134
155
135
156
let common_indent = common_indent. unwrap_or_default ( ) ;
136
157
if common_indent > 0 {
137
- for line in lines. iter_mut ( ) . skip ( 1 ) {
158
+ for line in lines. iter_mut ( ) {
138
159
if line. length >= common_indent {
139
160
line. start_offset += common_indent;
140
161
line. length -= common_indent;
@@ -350,3 +371,134 @@ pub fn sort_result(items: &mut Vec<DescItem>) {
350
371
)
351
372
} ) ;
352
373
}
374
+
375
+ #[ cfg( test) ]
376
+ mod tests {
377
+ use super :: * ;
378
+ use emmylua_parser:: { LuaParser , ParserConfig } ;
379
+
380
+ fn get_desc ( code : & str ) -> LuaDocDescription {
381
+ LuaParser :: parse ( code, ParserConfig :: default ( ) )
382
+ . get_chunk_node ( )
383
+ . descendants :: < LuaDocDescription > ( )
384
+ . next ( )
385
+ . unwrap ( )
386
+ }
387
+
388
+ fn run_desc_to_lines ( code : & str ) -> Vec < & str > {
389
+ let desc = get_desc ( code) ;
390
+ let lines = desc_to_lines ( code, desc, None ) ;
391
+ lines
392
+ . iter ( )
393
+ . map ( |range| & code[ range. start_offset ..range. end_offset ( ) ] )
394
+ . collect ( )
395
+ }
396
+
397
+ #[ test]
398
+ fn test_desc_to_lines ( ) {
399
+ assert_eq ! (
400
+ run_desc_to_lines(
401
+ r#"
402
+ -- Desc
403
+ "#
404
+ ) ,
405
+ vec![ "" ; 0 ]
406
+ ) ;
407
+
408
+ assert_eq ! (
409
+ run_desc_to_lines(
410
+ r#"
411
+ ----------
412
+ -- Desc --
413
+ ----------
414
+ "#
415
+ ) ,
416
+ vec![ "" ; 0 ]
417
+ ) ;
418
+
419
+ assert_eq ! (
420
+ run_desc_to_lines(
421
+ r#"
422
+ ----------
423
+ -- Desc --
424
+ ----------
425
+ -- Desc --
426
+ ----------
427
+ "#
428
+ ) ,
429
+ vec![ "" ; 0 ]
430
+ ) ;
431
+
432
+ assert_eq ! (
433
+ run_desc_to_lines(
434
+ r#"
435
+ --- Desc
436
+ "#
437
+ ) ,
438
+ vec![ "Desc" ]
439
+ ) ;
440
+
441
+ assert_eq ! (
442
+ run_desc_to_lines(
443
+ r#"
444
+ --------
445
+ --- Desc
446
+ --------
447
+ "#
448
+ ) ,
449
+ vec![ "Desc" ]
450
+ ) ;
451
+
452
+ assert_eq ! (
453
+ run_desc_to_lines(
454
+ r#"
455
+ --------
456
+ --- Desc
457
+ --------
458
+ --- Desc
459
+ --------
460
+ "#
461
+ ) ,
462
+ vec![ " Desc" , "-----" , " Desc" ]
463
+ ) ;
464
+
465
+ assert_eq ! (
466
+ run_desc_to_lines(
467
+ r#"
468
+ --- Desc
469
+ ---Desc 2
470
+ "#
471
+ ) ,
472
+ vec![ " Desc" , "Desc 2" ]
473
+ ) ;
474
+
475
+ assert_eq ! (
476
+ run_desc_to_lines(
477
+ r#"
478
+ ---Desc
479
+ --- Desc 2
480
+ "#
481
+ ) ,
482
+ vec![ "Desc" , " Desc 2" ]
483
+ ) ;
484
+
485
+ assert_eq ! (
486
+ run_desc_to_lines(
487
+ r#"
488
+ --- Desc
489
+ --- Desc 2
490
+ "#
491
+ ) ,
492
+ vec![ "Desc" , "Desc 2" ]
493
+ ) ;
494
+
495
+ assert_eq ! (
496
+ run_desc_to_lines(
497
+ r#"
498
+ --- @param x int Desc
499
+ "#
500
+ ) ,
501
+ vec![ "Desc" ]
502
+ ) ;
503
+ }
504
+ }
0 commit comments