1515package com .google .googlejavaformat .java ;
1616
1717import static com .google .common .base .Preconditions .checkArgument ;
18+ import static com .google .common .collect .ImmutableList .toImmutableList ;
1819
1920import com .google .common .collect .ImmutableList ;
20- import com .google .common .collect .Lists ;
2121import com .sun .tools .javac .parser .JavaTokenizer ;
2222import com .sun .tools .javac .parser .Scanner ;
2323import com .sun .tools .javac .parser .ScannerFactory ;
2424import com .sun .tools .javac .parser .Tokens .Comment ;
2525import com .sun .tools .javac .parser .Tokens .Comment .CommentStyle ;
2626import com .sun .tools .javac .parser .Tokens .Token ;
2727import com .sun .tools .javac .parser .Tokens .TokenKind ;
28- import com .sun .tools .javac .parser .UnicodeReader ;
2928import com .sun .tools .javac .util .Context ;
29+ import java .util .HashMap ;
30+ import java .util .Map ;
3031import java .util .Set ;
3132
3233/** A wrapper around javac's lexer. */
@@ -79,16 +80,16 @@ public static ImmutableList<RawTok> getTokens(
7980 }
8081 ScannerFactory fac = ScannerFactory .instance (context );
8182 char [] buffer = (source + EOF_COMMENT ).toCharArray ();
82- Scanner scanner =
83- new AccessibleScanner (fac , new CommentSavingTokenizer ( fac , buffer , buffer . length ) );
83+ CommentSavingTokenizer tokenizer = new CommentSavingTokenizer ( fac , buffer , buffer . length );
84+ Scanner scanner = new AccessibleScanner (fac , tokenizer );
8485 ImmutableList .Builder <RawTok > tokens = ImmutableList .builder ();
8586 int end = source .length ();
8687 int last = 0 ;
8788 do {
8889 scanner .nextToken ();
8990 Token t = scanner .token ();
9091 if (t .comments != null ) {
91- for (Comment c : Lists . reverse ( t .comments )) {
92+ for (CommentWithTextAndPosition c : getComments ( t , tokenizer .comments () )) {
9293 if (last < c .getSourcePos (0 )) {
9394 tokens .add (new RawTok (null , null , last , c .getSourcePos (0 )));
9495 }
@@ -120,17 +121,36 @@ public static ImmutableList<RawTok> getTokens(
120121 return tokens .build ();
121122 }
122123
124+ private static ImmutableList <CommentWithTextAndPosition > getComments (
125+ Token token , Map <Comment , CommentWithTextAndPosition > comments ) {
126+ if (token .comments == null ) {
127+ return ImmutableList .of ();
128+ }
129+ // javac stores the comments in reverse declaration order
130+ return token .comments .stream ().map (comments ::get ).collect (toImmutableList ()).reverse ();
131+ }
132+
123133 /** A {@link JavaTokenizer} that saves comments. */
124134 static class CommentSavingTokenizer extends JavaTokenizer {
135+
136+ private final Map <Comment , CommentWithTextAndPosition > comments = new HashMap <>();
137+
125138 CommentSavingTokenizer (ScannerFactory fac , char [] buffer , int length ) {
126139 super (fac , buffer , length );
127140 }
128141
142+ Map <Comment , CommentWithTextAndPosition > comments () {
143+ return comments ;
144+ }
145+
129146 @ Override
130147 protected Comment processComment (int pos , int endPos , CommentStyle style ) {
131148 char [] buf = getRawCharactersReflectively (pos , endPos );
132- return new CommentWithTextAndPosition (
133- pos , endPos , new AccessibleReader (fac , buf , buf .length ), style );
149+ Comment comment = super .processComment (pos , endPos , style );
150+ CommentWithTextAndPosition commentWithTextAndPosition =
151+ new CommentWithTextAndPosition (pos , endPos , new String (buf ));
152+ comments .put (comment , commentWithTextAndPosition );
153+ return comment ;
134154 }
135155
136156 private char [] getRawCharactersReflectively (int beginIndex , int endIndex ) {
@@ -153,21 +173,16 @@ private char[] getRawCharactersReflectively(int beginIndex, int endIndex) {
153173 }
154174
155175 /** A {@link Comment} that saves its text and start position. */
156- static class CommentWithTextAndPosition implements Comment {
176+ static class CommentWithTextAndPosition {
157177
158178 private final int pos ;
159179 private final int endPos ;
160- private final AccessibleReader reader ;
161- private final CommentStyle style ;
162-
163- private String text = null ;
180+ private final String text ;
164181
165- public CommentWithTextAndPosition (
166- int pos , int endPos , AccessibleReader reader , CommentStyle style ) {
182+ public CommentWithTextAndPosition (int pos , int endPos , String text ) {
167183 this .pos = pos ;
168184 this .endPos = endPos ;
169- this .reader = reader ;
170- this .style = style ;
185+ this .text = text ;
171186 }
172187
173188 /**
@@ -176,7 +191,6 @@ public CommentWithTextAndPosition(
176191 * <p>The handling of javadoc comments in javac has more logic to skip over leading whitespace
177192 * and '*' characters when indexing into doc comments, but we don't need any of that.
178193 */
179- @ Override
180194 public int getSourcePos (int index ) {
181195 checkArgument (
182196 0 <= index && index < (endPos - pos ),
@@ -186,49 +200,22 @@ public int getSourcePos(int index) {
186200 return pos + index ;
187201 }
188202
189- @ Override
190- public CommentStyle getStyle () {
191- return style ;
192- }
193-
194- @ Override
195203 public String getText () {
196- String text = this .text ;
197- if (text == null ) {
198- this .text = text = new String (reader .getRawCharacters ());
199- }
200204 return text ;
201205 }
202206
203- /**
204- * We don't care about {@code @deprecated} javadoc tags (see the DepAnn check).
205- *
206- * @return false
207- */
208- @ Override
209- public boolean isDeprecated () {
210- return false ;
211- }
212-
213207 @ Override
214208 public String toString () {
215209 return String .format ("Comment: '%s'" , getText ());
216210 }
217211 }
218212
219- // Scanner(ScannerFactory, JavaTokenizer) is package-private
213+ // Scanner(ScannerFactory, JavaTokenizer) is protected
220214 static class AccessibleScanner extends Scanner {
221215 protected AccessibleScanner (ScannerFactory fac , JavaTokenizer tokenizer ) {
222216 super (fac , tokenizer );
223217 }
224218 }
225219
226- // UnicodeReader(ScannerFactory, char[], int) is package-private
227- static class AccessibleReader extends UnicodeReader {
228- protected AccessibleReader (ScannerFactory fac , char [] buffer , int length ) {
229- super (fac , buffer , length );
230- }
231- }
232-
233220 private JavacTokens () {}
234221}
0 commit comments