@@ -26,6 +26,7 @@ public class CommentWriter {
26
26
private final List <TokenInfo > tokensWithInfo ;
27
27
private final Set <Comment > pendingComments = new HashSet <>();
28
28
private final Map <ASTNode , List <Comment >> attachedComments = new HashMap <>();
29
+ private final Map <ASTNode , Set <Comment >> writtenComments = new HashMap <>();
29
30
30
31
private final Map <ASTNode , List <Comment >> leadingComments = new HashMap <>();
31
32
private final Map <ASTNode , Map <String , List <Comment >>> withinComments = new HashMap <>();
@@ -73,11 +74,10 @@ public String toString() {
73
74
}
74
75
}
75
76
77
+ String indent = " " ;
76
78
77
- public String toNFComments () {
78
- var header = "// CommentWriter with " + commentTokens .size () + " comment tokens" ;
79
- var unattachedHeader = "// Unattached comments:" ;
80
- var indent = " " ;
79
+ public String writeUnattached () {
80
+ var unattachedHeader = "Unattached comments:" ;
81
81
var unattachedText = unattachedComments .stream ()
82
82
.map (t -> {
83
83
var line = t .getToken ().getLine ();
@@ -88,27 +88,35 @@ public String toNFComments() {
88
88
var attachedTo = t .getAttachedTo ();
89
89
var attachedToText = attachedTo != null ? attachedTo .getText () : "null" ;
90
90
return (
91
- "// " + indent + line + ":" + column + "{\n " +
92
- "// " + indent + indent + "content: " + text + "\n " +
93
- "// " + indent + indent + "attach: " + attachedToText + "\n " +
94
- "// " + indent + "}\n "
91
+ indent + line + ":" + column + "{\n " +
92
+ indent + indent + "content: " + text + "\n " +
93
+ indent + indent + "attach: " + attachedToText + "\n " +
94
+ indent + "}\n "
95
95
);
96
96
})
97
97
.collect (Collectors .joining ("\n " ));
98
- var pendingHeader = "// Pending comments:" ;
98
+ return unattachedHeader + unattachedText ;
99
+ }
100
+
101
+ public String writePending () {
102
+ var pendingHeader = "Pending comments:" ;
99
103
var pendingText = pendingComments .stream ()
100
104
.map (t -> {
101
105
var line = t .getToken ().getLine ();
102
106
var column = t .getToken ().getCharPositionInLine ();
103
107
var text = t .getToken ().getText ().replaceAll ("\n " , "\\ n" );
104
108
return (
105
- "// " + indent + line + ":" + column + "{\n " +
106
- "// " + indent + indent + "content: " + text + "\n " +
107
- "// " + indent + "}\n "
109
+ indent + line + ":" + column + "{\n " +
110
+ indent + indent + "content: " + text + "\n " +
111
+ indent + "}\n "
108
112
);
109
113
})
110
114
.collect (Collectors .joining ("\n " ));
111
- var attachedHeader = "// Attached comments:" ;
115
+ return pendingHeader + pendingText ;
116
+ }
117
+
118
+ public String writeAttached () {
119
+ var attachedHeader = "Attached comments:" ;
112
120
var attachedText = attachedComments .values ()
113
121
.stream ()
114
122
.flatMap (List ::stream )
@@ -129,17 +137,63 @@ public String toNFComments() {
129
137
(t .isTrailing () ? "trailing " : "" )
130
138
);
131
139
return (
132
- "// " + indent + line + ":" + column + "{\n " +
133
- "// " + indent + indent + "content : " + text + "\n " +
134
- "// " + indent + indent + "attached to: " + attachedToText + "\n " +
135
- "// " + indent + indent + "token : " + t .getPositionInfo () + "\n " +
136
- "// " + indent + indent + "written : " + t .isWritten () + "\n " +
137
- "// " + indent + indent + "rel. pos. : " + relPos + "\n " +
138
- "// " + indent + "}\n "
140
+ indent + line + ":" + column + "{\n " +
141
+ indent + indent + "content : " + text + "\n " +
142
+ indent + indent + "attached to: " + attachedToText + "\n " +
143
+ indent + indent + "token : " + t .getPositionInfo () + "\n " +
144
+ indent + indent + "written : " + t .isWritten () + "\n " +
145
+ indent + indent + "rel. pos. : " + relPos + "\n " +
146
+ indent + "}\n "
147
+ );
148
+ })
149
+ .collect (Collectors .joining ("\n " ));
150
+ return attachedHeader + attachedText ;
151
+ }
152
+
153
+ public String writeWritten () {
154
+ var writtenHeader = "Written comments:" ;
155
+ var writtenText = writtenComments .values ()
156
+ .stream ()
157
+ .flatMap (Set ::stream )
158
+ .map (t -> {
159
+ var line = t .getToken ().getLine ();
160
+ var column = t .getToken ().getCharPositionInLine ();
161
+ var text = t .getToken ().getText ().replaceAll ("\n " , "\\ n" );
162
+ var isLeading = t .isLeading ();
163
+ var isTrailing = t .isTrailing ();
164
+ ASTNode attachedTo = t .getAttachedTo ();
165
+ var simpleName = attachedTo != null ? attachedTo .getClass ().getSimpleName () : null ;
166
+ var maybeText = attachedTo != null ? attachedTo .getText (): null ;
167
+ var attachToCode = maybeText != null ? maybeText .replaceAll ("\n " , "\\ n" ) : "null" ;
168
+ var attachedToText = attachedTo != null ? simpleName + " " + attachToCode : "null" ;
169
+ var relPos = (
170
+ (t .isWithin () ? "within " : "" )+
171
+ (t .isLeading () ? "leading " : "" ) +
172
+ (t .isTrailing () ? "trailing " : "" )
173
+ );
174
+ return (
175
+ indent + line + ":" + column + "{\n " +
176
+ indent + indent + "content : " + text + "\n " +
177
+ indent + indent + "attached to: " + attachedToText + "\n " +
178
+ indent + indent + "token : " + t .getPositionInfo () + "\n " +
179
+ indent + indent + "written : " + t .isWritten () + "\n " +
180
+ indent + indent + "rel. pos. : " + relPos + "\n " +
181
+ indent + "}\n "
139
182
);
140
183
})
141
184
.collect (Collectors .joining ("\n " ));
142
- return header + "\n " + unattachedHeader + "\n " + unattachedText + "\n " + pendingHeader + "\n " + pendingText + "\n " + attachedHeader + "\n " + attachedText ;
185
+ return writtenHeader + writtenText ;
186
+ }
187
+
188
+
189
+ public String writeUnWritten () {
190
+ var header = "CommentWriter with " + commentTokens .size () + " comment tokens" ;
191
+ return header + "\n " + writeUnattached () + "\n " + writePending () + "\n " + writeAttached () + "\n " ;
192
+ }
193
+
194
+ public String writeAll () {
195
+ var header = "CommentWriter with " + commentTokens .size () + " comment tokens" ;
196
+ return header + "\n " + writeUnattached () + "\n " + writePending () + "\n " + writeUnattached () + "\n " + writeWritten ();
143
197
}
144
198
145
199
public Map <String , List <Comment >> getAttachedComments (ASTNode node ) {
@@ -300,6 +354,23 @@ public Map<String, List<Comment>> getTrailingComments(ASTNode node) {
300
354
return trailingComments .getOrDefault (node , new HashMap <>());
301
355
}
302
356
357
+ public boolean verifyAllWritten () {
358
+ if (
359
+ !(
360
+ unattachedComments .size () == 0 &&
361
+ pendingComments .size () == 0 &&
362
+ attachedComments .size () == 0
363
+ )
364
+ ) {
365
+ // Likely replace this error message with an exception
366
+ System .err .println ("The following comments are left to be written" );
367
+ System .err .println (writeUnWritten ());
368
+ return false ;
369
+ } else {
370
+ return true ;
371
+ }
372
+ }
373
+
303
374
public class Comment {
304
375
private final Token token ;
305
376
private boolean isLeading = false ;
@@ -417,6 +488,19 @@ public Tuple2<String, Boolean> write() {
417
488
throw new IllegalStateException (this + " already written" );
418
489
}
419
490
isWritten = true ;
491
+
492
+ writtenComments .computeIfAbsent (attachedTo , k -> new HashSet <>()).add (this );
493
+ var attachedNodeComments = attachedComments .get (attachedTo );
494
+ if (attachedNodeComments .contains (this )) {
495
+ if (attachedNodeComments .size () == 1 ) {
496
+ attachedComments .remove (attachedTo );
497
+ } else {
498
+ attachedNodeComments .remove (this );
499
+ }
500
+ } else {
501
+ throw new IllegalStateException (this + " was not attached to " + attachedTo );
502
+ }
503
+
420
504
return new Tuple2 <>(token .getText (), token .getType () == ScriptLexer .SL_COMMENT );
421
505
}
422
506
0 commit comments