2
2
// Licensed under the MIT License.
3
3
4
4
using System ;
5
+ using System . Collections ;
5
6
using System . Collections . Generic ;
6
7
using System . Collections . Immutable ;
7
8
using System . Linq ;
@@ -77,7 +78,7 @@ private static IEnumerable<CodeFragment> FragmentsOverlappingWithRange(this File
77
78
if ( file == null || range ? . Start == null || range . End == null ) return Enumerable . Empty < CodeFragment > ( ) ;
78
79
var ( start , end ) = ( range . Start . Line , range . End . Line ) ;
79
80
80
- var fragAtStart = file . TryGetFragmentAt ( range ? . Start , out var _ , includeEnd : true ) ;
81
+ var fragAtStart = file . TryGetFragmentAt ( range . Start , out var _ , includeEnd : true ) ;
81
82
var inRange = file . GetTokenizedLine ( start ) . Select ( t => t . WithUpdatedLineNumber ( start ) ) . Where ( ContextBuilder . TokensAfter ( range . Start ) ) ; // does not include fragAtStart
82
83
inRange = start == end
83
84
? inRange . Where ( ContextBuilder . TokensStartingBefore ( range . End ) )
@@ -408,17 +409,31 @@ WorkspaceEdit SuggestedRemoval(Position pos)
408
409
{
409
410
var overlapping = file ? . FragmentsOverlappingWithRange ( range ) ;
410
411
var fragment = overlapping ? . FirstOrDefault ( ) ;
411
- if ( fragment ? . Kind == null || overlapping . Count ( ) > 1 ) return Enumerable . Empty < ( string , WorkspaceEdit ) > ( ) ; // only suggest doc comment directly on the declaration
412
+ if ( fragment ? . Kind == null || overlapping . Count ( ) != 1 ) return Enumerable . Empty < ( string , WorkspaceEdit ) > ( ) ; // only suggest doc comment directly on the declaration
412
413
413
414
var ( nsDecl , callableDecl , typeDecl ) = ( fragment . Kind . DeclaredNamespace ( ) , fragment . Kind . DeclaredCallable ( ) , fragment . Kind . DeclaredType ( ) ) ;
414
415
var declSymbol = nsDecl . IsValue ? nsDecl . Item . Item1 . Symbol
415
416
: callableDecl . IsValue ? callableDecl . Item . Item1 . Symbol
416
417
: typeDecl . IsValue ? typeDecl . Item . Item1 . Symbol : null ;
417
- var declRange = fragment ? . GetRange ( ) ;
418
- if ( declSymbol == null || file . DocumentingComments ( declRange . Start ) . Any ( ) ) return Enumerable . Empty < ( string , WorkspaceEdit ) > ( ) ;
418
+ var declStart = fragment . GetRange ( ) . Start ;
419
+ if ( declSymbol == null || file . DocumentingComments ( declStart ) . Any ( ) ) return Enumerable . Empty < ( string , WorkspaceEdit ) > ( ) ;
420
+
421
+ // set declStart to the position of the first attribute attached to the declaration
422
+ bool EmptyOrFirstAttribute ( IEnumerable < CodeFragment > line , out CodeFragment att )
423
+ {
424
+ att = line ? . Reverse ( ) . TakeWhile ( t => t . Kind is QsFragmentKind . DeclarationAttribute ) . LastOrDefault ( ) ;
425
+ return att != null || ( line != null && ! line . Any ( ) ) ;
426
+ }
427
+ var preceding = file . GetTokenizedLine ( declStart . Line ) . TakeWhile ( ContextBuilder . TokensUpTo ( new Position ( 0 , declStart . Character ) ) ) ;
428
+ for ( var lineNr = declStart . Line ; EmptyOrFirstAttribute ( preceding , out var precedingAttribute ) ; )
429
+ {
430
+ if ( precedingAttribute != null )
431
+ { declStart = precedingAttribute . GetRange ( ) . Start . WithUpdatedLineNumber ( lineNr ) ; }
432
+ preceding = lineNr -- > 0 ? file . GetTokenizedLine ( lineNr ) : ( IEnumerable < CodeFragment > ) null ;
433
+ }
419
434
420
435
var docPrefix = "/// " ;
421
- var endLine = $ "{ Environment . NewLine } { file . GetLine ( declRange . Start . Line ) . Text . Substring ( 0 , declRange . Start . Character ) } ";
436
+ var endLine = $ "{ Environment . NewLine } { file . GetLine ( declStart . Line ) . Text . Substring ( 0 , declStart . Character ) } ";
422
437
var docString = $ "{ docPrefix } # Summary{ endLine } { docPrefix } { endLine } ";
423
438
424
439
var ( argTuple , typeParams ) =
@@ -441,7 +456,7 @@ WorkspaceEdit SuggestedRemoval(Position pos)
441
456
) ;
442
457
443
458
var whichDecl = $ " for { declSymbol . AsDeclarationName ( null ) } ";
444
- var suggestedEdit = file . GetWorkspaceEdit ( new TextEdit { Range = new Range { Start = declRange . Start , End = declRange . Start } , NewText = docString } ) ;
459
+ var suggestedEdit = file . GetWorkspaceEdit ( new TextEdit { Range = new Range { Start = declStart , End = declStart } , NewText = docString } ) ;
445
460
return new [ ] { ( $ "Add documentation{ whichDecl } .", suggestedEdit ) } ;
446
461
}
447
462
}
0 commit comments