diff --git a/check_api/src/main/java/com/google/errorprone/fixes/SuggestedFixes.java b/check_api/src/main/java/com/google/errorprone/fixes/SuggestedFixes.java index ab627fcc064..51e951b817e 100644 --- a/check_api/src/main/java/com/google/errorprone/fixes/SuggestedFixes.java +++ b/check_api/src/main/java/com/google/errorprone/fixes/SuggestedFixes.java @@ -55,6 +55,7 @@ import com.google.errorprone.apply.SourceFile; import com.google.errorprone.fixes.SuggestedFixes.FixCompiler.Result; import com.google.errorprone.util.ASTHelpers; +import com.google.errorprone.util.ErrorProneComment; import com.google.errorprone.util.ErrorProneToken; import com.google.errorprone.util.FindIdentifiers; import com.sun.source.doctree.DocTree; @@ -96,7 +97,6 @@ import com.sun.tools.javac.code.Types.DefaultTypeVisitor; import com.sun.tools.javac.main.Arguments; import com.sun.tools.javac.parser.Tokens; -import com.sun.tools.javac.parser.Tokens.Comment; import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.tree.DCTree; import com.sun.tools.javac.tree.DCTree.DCDocComment; @@ -1689,9 +1689,9 @@ public static SuggestedFix replaceIncludingComments( if (tokens.get(0).comments().isEmpty()) { return SuggestedFix.replace(tokens.get(0).pos(), state.getEndPosition(tree), replacement); } - ImmutableList comments = + ImmutableList comments = ImmutableList.sortedCopyOf( - Comparator.comparingInt(c -> c.getSourcePos(0)).reversed(), + Comparator.comparingInt(c -> c.getSourcePos(0)).reversed(), tokens.get(0).comments()); int startPos = getStartPosition(tree); // This can happen for desugared expressions like `int a, b;`. @@ -1700,7 +1700,7 @@ public static SuggestedFix replaceIncludingComments( } // Delete backwards for comments which are not separated from our target by a blank line. CharSequence sourceCode = state.getSourceCode(); - for (Comment comment : comments) { + for (ErrorProneComment comment : comments) { int endOfCommentPos = comment.getSourcePos(comment.getText().length() - 1); CharSequence stringBetweenComments = sourceCode.subSequence(endOfCommentPos, startPos); if (stringBetweenComments.chars().filter(c -> c == '\n').count() > 1) { diff --git a/check_api/src/main/java/com/google/errorprone/util/Commented.java b/check_api/src/main/java/com/google/errorprone/util/Commented.java index 3b1282142cd..509db54d114 100644 --- a/check_api/src/main/java/com/google/errorprone/util/Commented.java +++ b/check_api/src/main/java/com/google/errorprone/util/Commented.java @@ -20,7 +20,6 @@ import com.google.common.collect.ImmutableList; import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.sun.source.tree.Tree; -import com.sun.tools.javac.parser.Tokens.Comment; /** Class to hold AST nodes annotated with the comments that are associated with them */ @AutoValue @@ -35,9 +34,9 @@ public enum Position { public abstract T tree(); - public abstract ImmutableList beforeComments(); + public abstract ImmutableList beforeComments(); - public abstract ImmutableList afterComments(); + public abstract ImmutableList afterComments(); static Builder builder() { return new AutoValue_Commented.Builder(); @@ -48,14 +47,14 @@ abstract static class Builder { abstract Builder setTree(T tree); - protected abstract ImmutableList.Builder beforeCommentsBuilder(); + protected abstract ImmutableList.Builder beforeCommentsBuilder(); - protected abstract ImmutableList.Builder afterCommentsBuilder(); + protected abstract ImmutableList.Builder afterCommentsBuilder(); @CanIgnoreReturnValue Builder addComment( - Comment comment, int nodePosition, int tokenizingOffset, Position position) { - OffsetComment offsetComment = new OffsetComment(comment, tokenizingOffset); + ErrorProneComment comment, int nodePosition, int tokenizingOffset, Position position) { + ErrorProneComment offsetComment = comment.withOffset(tokenizingOffset); if (comment.getSourcePos(0) < nodePosition) { if (position.equals(Position.BEFORE) || position.equals(Position.ANY)) { @@ -71,11 +70,11 @@ Builder addComment( @CanIgnoreReturnValue Builder addAllComment( - Iterable comments, + Iterable comments, int nodePosition, int tokenizingOffset, Position position) { - for (Comment comment : comments) { + for (ErrorProneComment comment : comments) { addComment(comment, nodePosition, tokenizingOffset, position); } return this; diff --git a/check_api/src/main/java/com/google/errorprone/util/Comments.java b/check_api/src/main/java/com/google/errorprone/util/Comments.java index bd0c81166ce..3b7ae68fc20 100644 --- a/check_api/src/main/java/com/google/errorprone/util/Comments.java +++ b/check_api/src/main/java/com/google/errorprone/util/Comments.java @@ -25,7 +25,6 @@ import com.google.common.collect.TreeRangeSet; import com.google.errorprone.VisitorState; import com.google.errorprone.util.Commented.Position; -import com.google.errorprone.util.ErrorProneTokens.CommentWithTextAndPosition; import com.sun.source.tree.BlockTree; import com.sun.source.tree.ClassTree; import com.sun.source.tree.ExpressionTree; @@ -34,7 +33,6 @@ import com.sun.source.tree.Tree; import com.sun.source.util.TreePath; import com.sun.source.util.TreeScanner; -import com.sun.tools.javac.parser.Tokens.Comment; import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.util.Position.LineMap; import java.util.Iterator; @@ -92,7 +90,7 @@ public static ImmutableList> findCommentsForArguments( * *

TODO(andrewrice) Update this method to handle block comments properly if we find the need */ - public static String getTextFromComment(Comment comment) { + public static String getTextFromComment(ErrorProneComment comment) { switch (comment.getStyle()) { case BLOCK: return comment.getText().replaceAll("^\\s*/\\*\\s*(.*?)\\s*\\*/\\s*", "$1"); @@ -152,29 +150,25 @@ private static ImmutableList> findCommentsForArguments if (tokenTracker.atStartOfLine() && !tokenTracker.wasPreviousLineEmpty()) { // if the token is at the start of a line it could still have a comment attached which was // on the previous line - for (Comment c : token.comments()) { - if (!(c instanceof CommentWithTextAndPosition)) { - continue; - } - CommentWithTextAndPosition comment = (CommentWithTextAndPosition) c; + for (ErrorProneComment comment : token.comments()) { int commentStart = comment.getPos(); int commentEnd = comment.getEndPos(); if (exclude.intersects(Range.closedOpen(commentStart, commentEnd))) { continue; } - if (tokenTracker.isCommentOnPreviousLine(c) + if (tokenTracker.isCommentOnPreviousLine(comment) && token.pos() <= argumentTracker.currentArgumentStartPosition && argumentTracker.isPreviousArgumentOnPreviousLine()) { // token was on the previous line so therefore we should add it to the previous comment // unless the previous argument was not on the previous line with it - argumentTracker.addCommentToPreviousArgument(c, Position.ANY); + argumentTracker.addCommentToPreviousArgument(comment, Position.ANY); } else { // if the comment comes after the end of the invocation and it's not on the same line // as the final argument then we need to ignore it if (commentStart <= invocationEnd || lineMap.getLineNumber(commentStart) <= lineMap.getLineNumber(argumentTracker.currentArgumentEndPosition)) { - argumentTracker.addCommentToCurrentArgument(c, Position.ANY); + argumentTracker.addCommentToCurrentArgument(comment, Position.ANY); } } } @@ -366,7 +360,7 @@ void advance(ErrorProneToken token) { } } - boolean isCommentOnPreviousLine(Comment c) { + boolean isCommentOnPreviousLine(ErrorProneComment c) { int tokenLine = lineMap.getLineNumber(c.getSourcePos(0)); return tokenLine == currentLineNumber - 1; } @@ -447,15 +441,15 @@ boolean isPreviousArgumentOnPreviousLine() { == lineMap.getLineNumber(currentArgumentStartPosition) - 1; } - void addCommentToPreviousArgument(Comment c, Position position) { + void addCommentToPreviousArgument(ErrorProneComment c, Position position) { previousCommentedResultBuilder.addComment(c, previousArgumentEndPosition, offset, position); } - void addCommentToCurrentArgument(Comment c, Position position) { + void addCommentToCurrentArgument(ErrorProneComment c, Position position) { currentCommentedResultBuilder.addComment(c, currentArgumentStartPosition, offset, position); } - void addAllCommentsToCurrentArgument(Iterable comments, Position position) { + void addAllCommentsToCurrentArgument(Iterable comments, Position position) { currentCommentedResultBuilder.addAllComment( comments, currentArgumentStartPosition, offset, position); } diff --git a/check_api/src/main/java/com/google/errorprone/util/ErrorProneComment.java b/check_api/src/main/java/com/google/errorprone/util/ErrorProneComment.java new file mode 100644 index 00000000000..ffc6b76fcf1 --- /dev/null +++ b/check_api/src/main/java/com/google/errorprone/util/ErrorProneComment.java @@ -0,0 +1,91 @@ +/* + * Copyright 2019 The Error Prone Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.errorprone.util; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.sun.tools.javac.parser.Tokens.Comment; +import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; + +/** Wraps a {@link Comment} to allow an offset source position to be reported. */ +public final class ErrorProneComment { + + private final int pos; + private final int endPos; + private final int offset; + private final Supplier text; + private final CommentStyle style; + + ErrorProneComment(int pos, int endPos, int offset, Supplier text, CommentStyle style) { + this.pos = pos; + this.endPos = endPos; + this.offset = offset; + this.text = Suppliers.memoize(text); + this.style = style; + } + + public ErrorProneComment withOffset(int offset) { + return new ErrorProneComment(pos, endPos, offset, text, style); + } + + public int getPos() { + return pos + offset; + } + + public int getEndPos() { + return endPos + offset; + } + + /** + * Returns the source position of the character at index {@code index} in the comment text. + * + *

The handling of javadoc comments in javac has more logic to skip over leading whitespace and + * '*' characters when indexing into doc comments, but we don't need any of that. + */ + public int getSourcePos(int index) { + checkArgument( + 0 <= index && index < (endPos - pos), + "Expected %s in the range [0, %s)", + index, + endPos - pos); + return pos + index + offset; + } + + public CommentStyle getStyle() { + return style; + } + + public String getText() { + return text.get(); + } + + /** + * We don't care about {@code @deprecated} javadoc tags (see the DepAnn check). + * + * @return false + */ + public boolean isDeprecated() { + return false; + } + + @Override + public String toString() { + return String.format("Comment: '%s'", getText()); + } +} diff --git a/check_api/src/main/java/com/google/errorprone/util/ErrorProneToken.java b/check_api/src/main/java/com/google/errorprone/util/ErrorProneToken.java index 3d21a1fcc88..2ec0430f16e 100644 --- a/check_api/src/main/java/com/google/errorprone/util/ErrorProneToken.java +++ b/check_api/src/main/java/com/google/errorprone/util/ErrorProneToken.java @@ -16,24 +16,23 @@ package com.google.errorprone.util; -import static java.util.stream.Collectors.toList; +import static com.google.common.collect.ImmutableList.toImmutableList; -import com.google.common.collect.Lists; -import com.sun.tools.javac.parser.Tokens.Comment; +import com.google.common.collect.ImmutableList; import com.sun.tools.javac.parser.Tokens.Token; import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.util.Name; -import java.util.Collections; -import java.util.List; /** Wraps a javac {@link Token} to return comments in declaration order. */ public class ErrorProneToken { - private final int offset; private final Token token; + private final int offset; + private final ImmutableList comments; - ErrorProneToken(Token token, int offset) { + ErrorProneToken(Token token, int offset, ImmutableList comments) { this.token = token; this.offset = offset; + this.comments = comments; } public TokenKind kind() { @@ -48,17 +47,8 @@ public int endPos() { return offset + token.endPos; } - public List comments() { - // javac stores the comments in reverse declaration order because appending to linked - // lists is expensive - if (token.comments == null) { - return Collections.emptyList(); - } - if (offset == 0) { - return Lists.reverse(token.comments); - } - return Lists.reverse( - token.comments.stream().map(c -> new OffsetComment(c, offset)).collect(toList())); + public ImmutableList comments() { + return comments.stream().map(c -> c.withOffset(offset)).collect(toImmutableList()); } public boolean hasName() { diff --git a/check_api/src/main/java/com/google/errorprone/util/ErrorProneTokens.java b/check_api/src/main/java/com/google/errorprone/util/ErrorProneTokens.java index 22601df048a..b94bb10d801 100644 --- a/check_api/src/main/java/com/google/errorprone/util/ErrorProneTokens.java +++ b/check_api/src/main/java/com/google/errorprone/util/ErrorProneTokens.java @@ -16,7 +16,7 @@ package com.google.errorprone.util; -import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.collect.ImmutableList.toImmutableList; import com.google.common.collect.ImmutableList; import com.sun.tools.javac.parser.JavaTokenizer; @@ -24,11 +24,14 @@ import com.sun.tools.javac.parser.ScannerFactory; import com.sun.tools.javac.parser.Tokens.Comment; import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; +import com.sun.tools.javac.parser.Tokens.Token; import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.parser.UnicodeReader; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Position.LineMap; +import java.util.HashMap; +import java.util.Map; /** A utility for tokenizing and preserving comments. */ public class ErrorProneTokens { @@ -60,7 +63,10 @@ public ImmutableList getTokens() { ImmutableList.Builder tokens = ImmutableList.builder(); do { scanner.nextToken(); - tokens.add(new ErrorProneToken(scanner.token(), offset)); + Token token = scanner.token(); + tokens.add( + new ErrorProneToken( + token, offset, getComments(token, commentSavingTokenizer.comments()))); } while (scanner.token().kind != TokenKind.EOF); return tokens.build(); } finally { @@ -68,6 +74,16 @@ public ImmutableList getTokens() { } } + private static final ImmutableList getComments( + Token token, Map comments) { + if (token.comments == null) { + return ImmutableList.of(); + } + // javac stores the comments in reverse declaration order because appending to linked + // lists is expensive + return token.comments.stream().map(comments::get).collect(toImmutableList()).reverse(); + } + /** Returns the tokens for the given source text, including comments. */ public static ImmutableList getTokens(String source, Context context) { return getTokens(source, 0, context); @@ -84,15 +100,27 @@ public static ImmutableList getTokens( /** A {@link JavaTokenizer} that saves comments. */ static class CommentSavingTokenizer extends JavaTokenizer { + + private final Map comments = new HashMap<>(); + CommentSavingTokenizer(ScannerFactory fac, char[] buffer, int length) { super(fac, buffer, length); } + public Map comments() { + return comments; + } + @Override protected Comment processComment(int pos, int endPos, CommentStyle style) { char[] buf = getRawCharactersReflectively(pos, endPos); - return new CommentWithTextAndPosition( - pos, endPos, new AccessibleReader(fac, buf, buf.length), style); + Comment comment = super.processComment(pos, endPos, style); + AccessibleReader reader = new AccessibleReader(fac, buf, buf.length); + ErrorProneComment errorProneComment = + new ErrorProneComment( + pos, endPos, /* offset= */ 0, () -> new String(reader.getRawCharacters()), style); + comments.put(comment, errorProneComment); + return comment; } private char[] getRawCharactersReflectively(int beginIndex, int endIndex) { @@ -114,78 +142,6 @@ private char[] getRawCharactersReflectively(int beginIndex, int endIndex) { } } - /** A {@link Comment} that saves its text and start position. */ - static class CommentWithTextAndPosition implements Comment { - - private final int pos; - private final int endPos; - private final AccessibleReader reader; - private final CommentStyle style; - - private String text = null; - - public CommentWithTextAndPosition( - int pos, int endPos, AccessibleReader reader, CommentStyle style) { - this.pos = pos; - this.endPos = endPos; - this.reader = reader; - this.style = style; - } - - public int getPos() { - return pos; - } - - public int getEndPos() { - return endPos; - } - - /** - * Returns the source position of the character at index {@code index} in the comment text. - * - *

The handling of javadoc comments in javac has more logic to skip over leading whitespace - * and '*' characters when indexing into doc comments, but we don't need any of that. - */ - @Override - public int getSourcePos(int index) { - checkArgument( - 0 <= index && index < (endPos - pos), - "Expected %s in the range [0, %s)", - index, - endPos - pos); - return pos + index; - } - - @Override - public CommentStyle getStyle() { - return style; - } - - @Override - public String getText() { - String text = this.text; - if (text == null) { - this.text = text = new String(reader.getRawCharacters()); - } - return text; - } - - /** - * We don't care about {@code @deprecated} javadoc tags (see the DepAnn check). - * - * @return false - */ - @Override - public boolean isDeprecated() { - return false; - } - - @Override - public String toString() { - return String.format("Comment: '%s'", getText()); - } - } - // Scanner(ScannerFactory, JavaTokenizer) is package-private static class AccessibleScanner extends Scanner { protected AccessibleScanner(ScannerFactory fac, JavaTokenizer tokenizer) { diff --git a/check_api/src/main/java/com/google/errorprone/util/OffsetComment.java b/check_api/src/main/java/com/google/errorprone/util/OffsetComment.java deleted file mode 100644 index 1eeb5533fa0..00000000000 --- a/check_api/src/main/java/com/google/errorprone/util/OffsetComment.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2019 The Error Prone Authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.errorprone.util; - -import com.sun.tools.javac.parser.Tokens.Comment; - -/** Wraps a {@link Comment} to allow an offset source position to be reported. */ -final class OffsetComment implements Comment { - - private final Comment wrapped; - private final int offset; - - OffsetComment(Comment wrapped, int offset) { - this.wrapped = wrapped; - this.offset = offset; - } - - @Override - public String getText() { - return wrapped.getText(); - } - - @Override - public int getSourcePos(int i) { - return wrapped.getSourcePos(i) + offset; - } - - @Override - public CommentStyle getStyle() { - return wrapped.getStyle(); - } - - @Override - public boolean isDeprecated() { - return false; - } -} diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AnnotationPosition.java b/core/src/main/java/com/google/errorprone/bugpatterns/AnnotationPosition.java index 6fabb0d39f5..719695adcd0 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AnnotationPosition.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AnnotationPosition.java @@ -42,6 +42,7 @@ import com.google.errorprone.fixes.SuggestedFix; import com.google.errorprone.matchers.Description; import com.google.errorprone.util.ASTHelpers; +import com.google.errorprone.util.ErrorProneComment; import com.google.errorprone.util.ErrorProneToken; import com.sun.source.tree.AnnotationTree; import com.sun.source.tree.ClassTree; @@ -52,7 +53,6 @@ import com.sun.tools.javac.api.JavacTrees; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.TypeAnnotations.AnnotationType; -import com.sun.tools.javac.parser.Tokens.Comment; import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; @@ -116,7 +116,7 @@ private Description handle(Tree tree, Name name, ModifiersTree modifiers, Visito int treePos = getStartPosition(tree); List tokens = annotationTokens(tree, state, treePos); - Comment danglingJavadoc = findOrphanedJavadoc(name, tokens); + ErrorProneComment danglingJavadoc = findOrphanedJavadoc(name, tokens); ImmutableList modifierTokens = tokens.stream().filter(t -> MODIFIERS.contains(t.kind())).collect(toImmutableList()); @@ -190,7 +190,7 @@ private static List annotationTokens( private Description checkAnnotations( Tree tree, List annotations, - Comment danglingJavadoc, + ErrorProneComment danglingJavadoc, int firstModifierPos, int lastModifierPos, VisitorState state) { @@ -314,7 +314,7 @@ private static String joinSource(VisitorState state, Iterable mo } private static String removeJavadoc( - VisitorState state, Comment danglingJavadoc, SuggestedFix.Builder builder) { + VisitorState state, ErrorProneComment danglingJavadoc, SuggestedFix.Builder builder) { int javadocStart = danglingJavadoc.getSourcePos(0); int javadocEnd = javadocStart + danglingJavadoc.getText().length(); // Capturing an extra newline helps the formatter. @@ -326,9 +326,9 @@ private static String removeJavadoc( } @Nullable - private static Comment findOrphanedJavadoc(Name name, List tokens) { + private static ErrorProneComment findOrphanedJavadoc(Name name, List tokens) { for (ErrorProneToken token : tokens) { - for (Comment comment : token.comments()) { + for (ErrorProneComment comment : token.comments()) { if (comment.getText().startsWith("/**")) { return comment; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ParameterComment.java b/core/src/main/java/com/google/errorprone/bugpatterns/ParameterComment.java index 8993cf56b33..ff31240d54c 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ParameterComment.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ParameterComment.java @@ -32,13 +32,13 @@ import com.google.errorprone.fixes.SuggestedFix; import com.google.errorprone.matchers.Description; import com.google.errorprone.util.Commented; +import com.google.errorprone.util.ErrorProneComment; import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.NewClassTree; import com.sun.source.tree.Tree; import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol; -import com.sun.tools.javac.parser.Tokens.Comment; import java.util.stream.Stream; /** A {@link BugChecker}; see the associated {@link BugPattern} annotation for details. */ @@ -78,7 +78,7 @@ private Description matchNewClassOrMethodInvocation( getTextFromComment(c).replace(" ", "").equals(param.getSimpleName() + "="))) { return; } - ImmutableList comments = + ImmutableList comments = commented.afterComments().isEmpty() ? commented.beforeComments() : commented.afterComments(); @@ -90,12 +90,15 @@ private Description matchNewClassOrMethodInvocation( return fix.isEmpty() ? NO_MATCH : describeMatch(tree, fix.build()); } - private static boolean matchingParamComment(Comment c, VarSymbol param) { + private static boolean matchingParamComment(ErrorProneComment c, VarSymbol param) { return param.getSimpleName().contentEquals(getTextFromComment(c).replaceAll("\\s*=\\s*$", "")); } private static void fixParamComment( - SuggestedFix.Builder fix, Commented commented, VarSymbol param, Comment c) { + SuggestedFix.Builder fix, + Commented commented, + VarSymbol param, + ErrorProneComment c) { fix.prefixWith(commented.tree(), String.format("/* %s= */ ", param.getSimpleName())) .replace(c.getSourcePos(0), c.getSourcePos(0) + c.getText().length(), ""); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ParameterName.java b/core/src/main/java/com/google/errorprone/bugpatterns/ParameterName.java index baf7fd384eb..8cd6485ab3d 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ParameterName.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ParameterName.java @@ -37,6 +37,7 @@ import com.google.errorprone.matchers.Description; import com.google.errorprone.util.ASTHelpers; import com.google.errorprone.util.Comments; +import com.google.errorprone.util.ErrorProneComment; import com.google.errorprone.util.ErrorProneToken; import com.google.errorprone.util.ErrorProneTokens; import com.sun.source.tree.ExpressionTree; @@ -45,7 +46,6 @@ import com.sun.source.tree.Tree; import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol; -import com.sun.tools.javac.parser.Tokens.Comment; import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; import com.sun.tools.javac.util.Position; import java.util.ArrayDeque; @@ -185,12 +185,12 @@ abstract static class FixInfo { abstract boolean isNameCorrect(); - abstract Comment comment(); + abstract ErrorProneComment comment(); abstract String name(); static FixInfo create( - boolean isFormatCorrect, boolean isNameCorrect, Comment comment, String name) { + boolean isFormatCorrect, boolean isNameCorrect, ErrorProneComment comment, String name) { return new AutoValue_ParameterName_FixInfo(isFormatCorrect, isNameCorrect, comment, name); } } @@ -198,7 +198,7 @@ static FixInfo create( private void checkArgument( VarSymbol formal, ExpressionTree actual, ErrorProneToken token, VisitorState state) { List matches = new ArrayList<>(); - for (Comment comment : token.comments()) { + for (ErrorProneComment comment : token.comments()) { if (comment.getStyle().equals(CommentStyle.LINE)) { // These are usually not intended as a parameter comment, and we don't want to flag if they // happen to match the parameter comment format. @@ -271,7 +271,7 @@ private void checkArgument( } } - private static SuggestedFix rewriteComment(Comment comment, String format) { + private static SuggestedFix rewriteComment(ErrorProneComment comment, String format) { int replacementStartPos = comment.getSourcePos(0); int replacementEndPos = comment.getSourcePos(comment.getText().length() - 1) + 1; return SuggestedFix.replace(replacementStartPos, replacementEndPos, format); @@ -279,7 +279,7 @@ private static SuggestedFix rewriteComment(Comment comment, String format) { // complains on parameter name comments on varargs past the first one private void checkComment(ExpressionTree arg, ErrorProneToken token, VisitorState state) { - for (Comment comment : token.comments()) { + for (ErrorProneComment comment : token.comments()) { Matcher m = NamedParameterComment.PARAMETER_COMMENT_PATTERN.matcher( Comments.getTextFromComment(comment)); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/SuppressWarningsWithoutExplanation.java b/core/src/main/java/com/google/errorprone/bugpatterns/SuppressWarningsWithoutExplanation.java index 1c121c27c6c..0b663077864 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/SuppressWarningsWithoutExplanation.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/SuppressWarningsWithoutExplanation.java @@ -36,13 +36,13 @@ import com.google.errorprone.matchers.Description; import com.google.errorprone.matchers.Matcher; import com.google.errorprone.util.ASTHelpers; +import com.google.errorprone.util.ErrorProneComment; import com.google.errorprone.util.ErrorProneToken; import com.google.errorprone.util.ErrorProneTokens; import com.sun.source.tree.AnnotationTree; import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.LineMap; import com.sun.source.tree.Tree; -import com.sun.tools.javac.parser.Tokens.Comment; /** * Finds occurrences of {@code @SuppressWarnings} where there is definitely no explanation for why @@ -115,7 +115,7 @@ private static ImmutableRangeSet linesWithComments(VisitorState state) { ErrorProneTokens tokens = new ErrorProneTokens(state.getSourceCode().toString(), state.context); LineMap lineMap = tokens.getLineMap(); for (ErrorProneToken token : tokens.getTokens()) { - for (Comment comment : token.comments()) { + for (ErrorProneComment comment : token.comments()) { lines.add( Range.closed( lineMap.getLineNumber(comment.getSourcePos(0)), diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NamedParameterComment.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NamedParameterComment.java index 27fea564fc3..e14f50c6470 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NamedParameterComment.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NamedParameterComment.java @@ -21,9 +21,9 @@ import com.google.common.collect.Streams; import com.google.errorprone.util.Commented; import com.google.errorprone.util.Comments; +import com.google.errorprone.util.ErrorProneComment; import com.sun.source.tree.ExpressionTree; import com.sun.tools.javac.code.Symbol.MethodSymbol; -import com.sun.tools.javac.parser.Tokens.Comment; import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; import java.util.Arrays; import java.util.Optional; @@ -67,46 +67,21 @@ enum MatchType { @AutoValue abstract static class MatchedComment { - abstract Comment comment(); + abstract Optional comment(); abstract MatchType matchType(); - static MatchedComment create(Comment comment, MatchType matchType) { + static MatchedComment create(Optional comment, MatchType matchType) { return new AutoValue_NamedParameterComment_MatchedComment(comment, matchType); } static MatchedComment notAnnotated() { return new AutoValue_NamedParameterComment_MatchedComment( - new Comment() { - @Override - public String getText() { - throw new IllegalArgumentException( - "Attempt to call getText on comment when in NOT_ANNOTATED state"); - } - - @Override - public int getSourcePos(int i) { - throw new IllegalArgumentException( - "Attempt to call getText on comment when in NOT_ANNOTATED state"); - } - - @Override - public CommentStyle getStyle() { - throw new IllegalArgumentException( - "Attempt to call getText on comment when in NOT_ANNOTATED state"); - } - - @Override - public boolean isDeprecated() { - throw new IllegalArgumentException( - "Attempt to call getText on comment when in NOT_ANNOTATED state"); - } - }, - MatchType.NOT_ANNOTATED); + Optional.empty(), MatchType.NOT_ANNOTATED); } } - private static boolean isApproximateMatchingComment(Comment comment, String formal) { + private static boolean isApproximateMatchingComment(ErrorProneComment comment, String formal) { switch (comment.getStyle()) { case BLOCK: case LINE: @@ -130,7 +105,7 @@ private static boolean isApproximateMatchingComment(Comment comment, String form * parameter name. */ static MatchedComment match(Commented actual, String formal) { - Optional lastBlockComment = + Optional lastBlockComment = Streams.findLast( actual.beforeComments().stream().filter(c -> c.getStyle() == CommentStyle.BLOCK)); @@ -139,12 +114,12 @@ static MatchedComment match(Commented actual, String formal) { PARAMETER_COMMENT_PATTERN.matcher(Comments.getTextFromComment(lastBlockComment.get())); if (m.matches()) { return MatchedComment.create( - lastBlockComment.get(), + lastBlockComment, m.group(1).equals(formal) ? MatchType.EXACT_MATCH : MatchType.BAD_MATCH); } } - Optional approximateMatchComment = + Optional approximateMatchComment = Stream.concat(actual.beforeComments().stream(), actual.afterComments().stream()) .filter(comment -> isApproximateMatchingComment(comment, formal)) .findFirst(); @@ -158,7 +133,7 @@ static MatchedComment match(Commented actual, String formal) { CharMatcher.anyOf("=:") .trimTrailingFrom(Comments.getTextFromComment(approximateMatchComment.get()).trim()); return MatchedComment.create( - approximateMatchComment.get(), + approximateMatchComment, text.equals(formal) ? MatchType.EXACT_MATCH : MatchType.APPROXIMATE_MATCH); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/AlmostJavadoc.java b/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/AlmostJavadoc.java index 1f8f18dbbd3..c021b51b8df 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/AlmostJavadoc.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/AlmostJavadoc.java @@ -33,6 +33,7 @@ import com.google.errorprone.fixes.SuggestedFix; import com.google.errorprone.matchers.Description; import com.google.errorprone.util.ASTHelpers; +import com.google.errorprone.util.ErrorProneComment; import com.google.errorprone.util.ErrorProneToken; import com.google.errorprone.util.ErrorProneTokens; import com.sun.source.tree.ClassTree; @@ -41,7 +42,6 @@ import com.sun.source.tree.NewClassTree; import com.sun.source.tree.Tree; import com.sun.source.tree.VariableTree; -import com.sun.tools.javac.parser.Tokens.Comment; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -78,7 +78,7 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s ImmutableMap javadocableTrees = getJavadocableTrees(tree, state); for (ErrorProneToken token : ErrorProneTokens.getTokens(state.getSourceCode().toString(), state.context)) { - for (Comment comment : token.comments()) { + for (ErrorProneComment comment : token.comments()) { if (!javadocableTrees.containsKey(token.pos())) { continue; } @@ -95,7 +95,7 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s return NO_MATCH; } - private static Optional generateFix(Comment comment) { + private static Optional generateFix(ErrorProneComment comment) { String text = comment.getText(); if (text.startsWith("/*") && !text.startsWith("/**") && HAS_TAG.matcher(text).find()) { int pos = comment.getSourcePos(1); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/NotJavadoc.java b/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/NotJavadoc.java index d0bcc9a09d8..2e91989e091 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/NotJavadoc.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/NotJavadoc.java @@ -34,6 +34,7 @@ import com.google.errorprone.bugpatterns.BugChecker.CompilationUnitTreeMatcher; import com.google.errorprone.matchers.Description; import com.google.errorprone.util.ASTHelpers; +import com.google.errorprone.util.ErrorProneComment; import com.google.errorprone.util.ErrorProneToken; import com.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; @@ -45,7 +46,6 @@ import com.sun.source.tree.VariableTree; import com.sun.source.util.TreePathScanner; import com.sun.tools.javac.code.Symbol.MethodSymbol; -import com.sun.tools.javac.parser.Tokens.Comment; import java.util.HashMap; import java.util.Map; import javax.lang.model.element.ElementKind; @@ -61,7 +61,7 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s ImmutableMap javadocableTrees = getJavadoccableTrees(tree); ImmutableRangeSet suppressedRegions = suppressedRegions(state); for (ErrorProneToken token : getTokens(state.getSourceCode().toString(), state.context)) { - for (Comment comment : token.comments()) { + for (ErrorProneComment comment : token.comments()) { if (!comment.getStyle().equals(JAVADOC) || comment.getText().equals("/**/")) { continue; }