1
+ const string DoubleSlashCommentPrefix = "// " ;
2
+ const string TripleSlashCommentPrefix = "/// " ;
3
+ const string SummaryStart = "/// <summary>" ;
4
+ const string SummaryEnd = "/// </summary>" ;
5
+ const string FileFilter = "*.cs" ;
6
+
7
+ var folderPath = @"..\..\..\..\..\src\Box2D.NET\" ;
8
+
9
+ // Tests: B2BodySim, B2World, B2WorldId
10
+ var files = Directory . GetFiles ( folderPath , FileFilter , SearchOption . AllDirectories )
11
+ //.Where(w => w.Contains("B2WorldId"))
12
+ //.Take(50)
13
+ . ToList ( ) ;
14
+
15
+ Console . WriteLine ( $ "Found { files . Count } C# files in the folder: { folderPath } ") ;
16
+
17
+ foreach ( var filePath in files )
18
+ {
19
+ await ProcessFileAsync ( filePath ) ;
20
+ }
21
+
22
+ Console . WriteLine ( "*** Processing completed ***" ) ;
23
+
24
+ async Task ProcessFileAsync ( string filePath )
25
+ {
26
+ Console . WriteLine ( $ "\n Processing file: { filePath } ") ;
27
+
28
+ var content = await File . ReadAllTextAsync ( filePath ) ;
29
+ var lines = content . Split ( [ "\r \n " , "\n " ] , StringSplitOptions . None ) . ToList ( ) ;
30
+ var commentLineIndexes = ExtractCommentLineIndexes ( lines ) ;
31
+
32
+ RemovePreNamespaceComments ( lines , commentLineIndexes ) ;
33
+
34
+ if ( commentLineIndexes . Count == 0 )
35
+ {
36
+ Console . WriteLine ( "No comment lines found in the file." ) ;
37
+ return ;
38
+ }
39
+
40
+ var commentBlocks = ExtractCommentBlocks ( lines , commentLineIndexes ) ;
41
+
42
+ if ( commentBlocks . Count == 0 )
43
+ {
44
+ Console . WriteLine ( "No comment blocks found." ) ;
45
+ return ;
46
+ }
47
+
48
+ ConvertCommentsToTripleSlash ( lines , commentBlocks ) ;
49
+
50
+ WrapCommentsWithSummaryTags ( lines , commentBlocks ) ;
51
+
52
+ //File.WriteAllText(filePath.Replace(".cs", ".xmlcomments.cs"), string.Join(Environment.NewLine, lines));
53
+ File . WriteAllText ( filePath , string . Join ( Environment . NewLine , lines ) ) ;
54
+
55
+ Console . WriteLine ( $ "Output written to: { filePath } ") ;
56
+ }
57
+
58
+ static void RemovePreNamespaceComments ( List < string > lines , List < int > commentLineIndexes )
59
+ {
60
+ var namespaceLineIndex = lines . FindIndex ( line => line . TrimStart ( ) . StartsWith ( "namespace " ) ) ;
61
+
62
+ commentLineIndexes . RemoveAll ( index => index < namespaceLineIndex ) ;
63
+ }
64
+
65
+ static List < CommentBlock > ExtractCommentBlocks ( List < string > lines , List < int > commentLineIndexes )
66
+ {
67
+ var commentBlocks = new List < CommentBlock > ( ) ;
68
+ var startIndex = commentLineIndexes [ 0 ] ;
69
+ var endIndex = commentLineIndexes [ 0 ] ;
70
+
71
+ if ( commentLineIndexes . Count == 1 )
72
+ {
73
+ AddBlockIfFollowedByPublic ( startIndex , endIndex ) ;
74
+
75
+ return commentBlocks ;
76
+ }
77
+
78
+ for ( int i = 1 ; i < commentLineIndexes . Count ; i ++ )
79
+ {
80
+ var nextIndex = commentLineIndexes [ i ] ;
81
+
82
+ if ( nextIndex - endIndex != 1 )
83
+ {
84
+ AddBlockIfFollowedByPublic ( startIndex , endIndex ) ;
85
+ startIndex = nextIndex ;
86
+ }
87
+
88
+ endIndex = nextIndex ;
89
+
90
+ if ( i == commentLineIndexes . Count - 1 )
91
+ {
92
+ AddBlockIfFollowedByPublic ( startIndex , endIndex ) ;
93
+ }
94
+ }
95
+
96
+ return commentBlocks ;
97
+
98
+ void AddBlockIfFollowedByPublic ( int startIndex , int endIndex )
99
+ {
100
+ if ( endIndex + 1 < lines . Count && lines [ endIndex + 1 ] . Contains ( "public" ) )
101
+ {
102
+ commentBlocks . Add ( new CommentBlock ( startIndex , endIndex ) ) ;
103
+ }
104
+ }
105
+ }
106
+
107
+ static List < int > ExtractCommentLineIndexes ( List < string > lines )
108
+ {
109
+ HashSet < string > commentStarts = [ DoubleSlashCommentPrefix , TripleSlashCommentPrefix ] ;
110
+
111
+ return lines
112
+ . Select ( ( line , index ) => ( line , index ) )
113
+ . Where ( item => commentStarts . Any ( commentStart =>
114
+ item . line . TrimStart ( ) . StartsWith ( commentStart ) ) )
115
+ . Select ( item => item . index )
116
+ . ToList ( ) ;
117
+ }
118
+
119
+ static void ConvertCommentsToTripleSlash ( List < string > lines , List < CommentBlock > commentBlocks )
120
+ {
121
+ foreach ( var block in commentBlocks )
122
+ {
123
+ Console . WriteLine ( $ "Comment block from { block . StartIndex + 1 } to { block . EndIndex + 1 } (length: { block . Length } )") ;
124
+
125
+ for ( int i = 0 ; i < block . Length ; i ++ )
126
+ {
127
+ int lineIndex = block . StartIndex + i ;
128
+
129
+ if ( ! lines [ lineIndex ] . TrimStart ( ) . StartsWith ( TripleSlashCommentPrefix ) )
130
+ {
131
+ lines [ lineIndex ] = lines [ lineIndex ] . Replace ( DoubleSlashCommentPrefix , "/// " ) ;
132
+ }
133
+ }
134
+ }
135
+ }
136
+
137
+ void WrapCommentsWithSummaryTags ( List < string > lines , List < CommentBlock > commentBlocks )
138
+ {
139
+ for ( int i = commentBlocks . Count - 1 ; i >= 0 ; i -- )
140
+ {
141
+ var block = commentBlocks [ i ] ;
142
+ var indentation = GetIndentation ( lines [ block . StartIndex ] ) ;
143
+
144
+ lines . Insert ( block . EndIndex + 1 , $ "{ indentation } { SummaryEnd } ") ;
145
+ lines . Insert ( block . StartIndex , $ "{ indentation } { SummaryStart } ") ;
146
+ }
147
+
148
+ string GetIndentation ( string line ) => new ( ' ' , line . Length - line . TrimStart ( ) . Length ) ;
149
+ }
150
+
151
+ record class CommentBlock ( int StartIndex , int EndIndex )
152
+ {
153
+ public int Length => EndIndex - StartIndex + 1 ;
154
+ }
0 commit comments