1
1
using Microsoft . CodeAnalysis ;
2
- using Microsoft . CodeAnalysis . Text ;
2
+ using Semmle . Extraction . CSharp . Entities ;
3
3
using Semmle . Util ;
4
4
using System . Collections . Generic ;
5
5
using System . Linq ;
6
6
7
- namespace Semmle . Extraction . CommentProcessing
7
+ namespace Semmle . Extraction . CSharp
8
8
{
9
9
/// <summary>
10
10
/// Implements the comment processor for associating comments with program elements.
11
11
/// Registers locations of comments and program elements,
12
12
/// then generates binding information.
13
13
/// </summary>
14
- internal class CommentProcessor : ICommentGenerator
14
+ internal class CommentProcessor
15
15
{
16
- public void AddComment ( ICommentLine comment )
16
+ public void AddComment ( CommentLine comment )
17
17
{
18
18
comments [ comment . Location ] = comment ;
19
19
}
20
20
21
21
// Comments sorted by location.
22
- private readonly SortedDictionary < Location , ICommentLine > comments = new SortedDictionary < Location , ICommentLine > ( new LocationComparer ( ) ) ;
22
+ private readonly SortedDictionary < Location , CommentLine > comments = new SortedDictionary < Location , CommentLine > ( new LocationComparer ( ) ) ;
23
23
24
24
// Program elements sorted by location.
25
25
private readonly SortedDictionary < Location , Label > elements = new SortedDictionary < Location , Label > ( new LocationComparer ( ) ) ;
26
26
27
27
private readonly Dictionary < Label , Key > duplicationGuardKeys = new Dictionary < Label , Key > ( ) ;
28
28
29
- private Key ? GetDuplicationGuardKey ( Label label )
29
+ private Key GetDuplicationGuardKey ( Label label )
30
30
{
31
31
if ( duplicationGuardKeys . TryGetValue ( label , out var duplicationGuardKey ) )
32
32
return duplicationGuardKey ;
@@ -35,7 +35,7 @@ public void AddComment(ICommentLine comment)
35
35
36
36
private class LocationComparer : IComparer < Location >
37
37
{
38
- public int Compare ( Location ? l1 , Location ? l2 ) => CommentProcessor . Compare ( l1 , l2 ) ;
38
+ public int Compare ( Location l1 , Location l2 ) => CommentProcessor . Compare ( l1 , l2 ) ;
39
39
}
40
40
41
41
/// <summary>
@@ -44,7 +44,7 @@ private class LocationComparer : IComparer<Location>
44
44
/// <param name="l1">First location</param>
45
45
/// <param name="l2">Second location</param>
46
46
/// <returns><0 if l1 before l2, >0 if l1 after l2, else 0.</returns>
47
- private static int Compare ( Location ? l1 , Location ? l2 )
47
+ private static int Compare ( Location l1 , Location l2 )
48
48
{
49
49
if ( object . ReferenceEquals ( l1 , l2 ) )
50
50
return 0 ;
@@ -68,7 +68,7 @@ private static int Compare(Location? l1, Location? l2)
68
68
/// <param name="elementLabel">The label of the element in the trap file.</param>
69
69
/// <param name="duplicationGuardKey">The duplication guard key of the element, if any.</param>
70
70
/// <param name="loc">The location of the element.</param>
71
- public void AddElement ( Label elementLabel , Key ? duplicationGuardKey , Location loc )
71
+ public void AddElement ( Label elementLabel , Key duplicationGuardKey , Location loc )
72
72
{
73
73
if ( loc != null && loc . IsInSource )
74
74
elements [ loc ] = elementLabel ;
@@ -78,7 +78,7 @@ public void AddElement(Label elementLabel, Key? duplicationGuardKey, Location lo
78
78
79
79
// Ensure that commentBlock and element refer to the same file
80
80
// which can happen when processing multiple files.
81
- private static void EnsureSameFile ( ICommentBlock commentBlock , ref KeyValuePair < Location , Label > ? element )
81
+ private static void EnsureSameFile ( Comments . CommentBlock commentBlock , ref KeyValuePair < Location , Label > ? element )
82
82
{
83
83
if ( element != null && element . Value . Key . SourceTree != commentBlock . Location . SourceTree )
84
84
element = null ;
@@ -95,7 +95,7 @@ private static void EnsureSameFile(ICommentBlock commentBlock, ref KeyValuePair<
95
95
/// <param name="parentElement">The parent element of the comment block.</param>
96
96
/// <param name="callback">Output binding information.</param>
97
97
private void GenerateBindings (
98
- ICommentBlock commentBlock ,
98
+ Comments . CommentBlock commentBlock ,
99
99
KeyValuePair < Location , Label > ? previousElement ,
100
100
KeyValuePair < Location , Label > ? nextElement ,
101
101
KeyValuePair < Location , Label > ? parentElement ,
@@ -231,7 +231,7 @@ public void Push(KeyValuePair<Location, Label> value)
231
231
232
232
// Generate binding information for one CommentBlock.
233
233
private void GenerateBindings (
234
- ICommentBlock block ,
234
+ Comments . CommentBlock block ,
235
235
ElementStack elementStack ,
236
236
KeyValuePair < Location , Label > ? nextElement ,
237
237
CommentBindingCallback cb
@@ -259,25 +259,25 @@ CommentBindingCallback cb
259
259
/// <param name="cb">Where to send the results.</param>
260
260
/// <returns>true if there are more comments to process, false otherwise.</returns>
261
261
private bool GenerateBindings (
262
- IEnumerator < KeyValuePair < Location , ICommentLine > > commentEnumerator ,
262
+ IEnumerator < KeyValuePair < Location , CommentLine > > commentEnumerator ,
263
263
KeyValuePair < Location , Label > ? nextElement ,
264
264
ElementStack elementStack ,
265
265
CommentBindingCallback cb
266
266
)
267
267
{
268
- CommentBlock ? block = null ;
268
+ Comments . CommentBlock block = null ;
269
269
270
270
// Iterate comments until the commentEnumerator has gone past nextElement
271
271
while ( nextElement == null || Compare ( commentEnumerator . Current . Value . Location , nextElement . Value . Key ) < 0 )
272
272
{
273
273
if ( block is null )
274
- block = new CommentBlock ( commentEnumerator . Current . Value ) ;
274
+ block = new Comments . CommentBlock ( commentEnumerator . Current . Value ) ;
275
275
276
276
if ( ! block . CombinesWith ( commentEnumerator . Current . Value ) )
277
277
{
278
278
// Start of a new block, so generate the bindings for the old block first.
279
279
GenerateBindings ( block , elementStack , nextElement , cb ) ;
280
- block = new CommentBlock ( commentEnumerator . Current . Value ) ;
280
+ block = new Comments . CommentBlock ( commentEnumerator . Current . Value ) ;
281
281
}
282
282
else
283
283
{
@@ -320,7 +320,7 @@ public void GenerateBindings(CommentBindingCallback cb)
320
320
var elementStack = new ElementStack ( ) ;
321
321
322
322
using IEnumerator < KeyValuePair < Location , Label > > elementEnumerator = elements . GetEnumerator ( ) ;
323
- using IEnumerator < KeyValuePair < Location , ICommentLine > > commentEnumerator = comments . GetEnumerator ( ) ;
323
+ using IEnumerator < KeyValuePair < Location , CommentLine > > commentEnumerator = comments . GetEnumerator ( ) ;
324
324
if ( ! commentEnumerator . MoveNext ( ) )
325
325
{
326
326
// There are no comments to process.
@@ -343,54 +343,12 @@ public void GenerateBindings(CommentBindingCallback cb)
343
343
}
344
344
}
345
345
346
- internal class CommentBlock : ICommentBlock
347
- {
348
- private readonly List < ICommentLine > lines ;
349
-
350
- public IEnumerable < ICommentLine > CommentLines => lines ;
351
-
352
- public Location Location { get ; private set ; }
353
-
354
- public CommentBlock ( ICommentLine firstLine )
355
- {
356
- lines = new List < ICommentLine > { firstLine } ;
357
- Location = firstLine . Location ;
358
- }
359
-
360
- /// <summary>
361
- /// Determine whether commentlines should be merged.
362
- /// </summary>
363
- /// <param name="newLine">A comment line to be appended to this comment block.</param>
364
- /// <returns>Whether the new line should be appended to this block.</returns>
365
- public bool CombinesWith ( ICommentLine newLine )
366
- {
367
- if ( ! CommentLines . Any ( ) )
368
- return true ;
369
-
370
- var sameFile = Location . SourceTree == newLine . Location . SourceTree ;
371
- var sameRow = Location . EndLine ( ) == newLine . Location . StartLine ( ) ;
372
- var sameColumn = Location . EndLine ( ) + 1 == newLine . Location . StartLine ( ) ;
373
- var nextRow = Location . StartColumn ( ) == newLine . Location . StartColumn ( ) ;
374
- var adjacent = sameFile && ( sameRow || ( sameColumn && nextRow ) ) ;
375
-
376
- return
377
- newLine . Type == CommentLineType . MultilineContinuation ||
378
- adjacent ;
379
- }
380
-
381
- /// <summary>
382
- /// Adds a comment line to the this comment block.
383
- /// </summary>
384
- /// <param name="line">The line to add.</param>
385
- public void AddCommentLine ( ICommentLine line )
386
- {
387
- Location = ! lines . Any ( )
388
- ? line . Location
389
- : Location . Create (
390
- line . Location . SourceTree ! ,
391
- new TextSpan ( Location . SourceSpan . Start , line . Location . SourceSpan . End - Location . SourceSpan . Start ) ) ;
392
-
393
- lines . Add ( line ) ;
394
- }
395
- }
346
+ /// <summary>
347
+ /// Callback for generated comment associations.
348
+ /// </summary>
349
+ /// <param name="elementLabel">The label of the element</param>
350
+ /// <param name="duplicationGuardKey">The duplication guard key of the element, if any</param>
351
+ /// <param name="commentBlock">The comment block associated with the element</param>
352
+ /// <param name="binding">The relationship between the commentblock and the element</param>
353
+ internal delegate void CommentBindingCallback ( Label elementLabel , Key duplicationGuardKey , Comments . CommentBlock commentBlock , CommentBinding binding ) ;
396
354
}
0 commit comments