Files
openide/java/java-analysis-impl/src/com/intellij/codeInspection/BlockMarkerCommentsInspection.java
Anna Kozlova abc4a9ae72 no need in overriding getDisplayName for inspections
in production InspectionEP#displayName should be used; highlighting tests just do not use default names

GitOrigin-RevId: f0c172e568219499e7b96982fe352c7d1d3acc69
2019-12-11 08:03:54 +00:00

97 lines
5.0 KiB
Java

// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.codeInspection;
import com.intellij.lang.Commenter;
import com.intellij.lang.LanguageCommenters;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PatternCondition;
import com.intellij.patterns.PsiJavaElementPattern;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import static com.intellij.patterns.PsiJavaPatterns.or;
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
/**
* @author Dmitry Batkovich
*/
public class BlockMarkerCommentsInspection extends AbstractBaseJavaLocalInspectionTool {
private static final PsiJavaElementPattern.Capture<PsiElement> ANONYMOUS_CLASS_MARKER_PATTERN = psiElement().
withParent(psiElement(PsiDeclarationStatement.class, PsiExpressionStatement.class))
.afterSiblingSkipping(or(psiElement(PsiWhiteSpace.class), psiElement(PsiJavaToken.class).with(new PatternCondition<PsiJavaToken>(null) {
@Override
public boolean accepts(@NotNull final PsiJavaToken psiJavaToken, final ProcessingContext context) {
return psiJavaToken.getTokenType().equals(JavaTokenType.SEMICOLON);
}
})),
psiElement(PsiLocalVariable.class, PsiAssignmentExpression.class)
.withChild(psiElement(PsiNewExpression.class).withChild(psiElement(PsiAnonymousClass.class))));
private static final PsiJavaElementPattern.Capture<PsiElement> CLASS_MARKER_PATTERN = psiElement().
withParent(PsiClass.class).
afterSiblingSkipping(psiElement(PsiWhiteSpace.class), psiElement(PsiJavaToken.class).with(new PatternCondition<PsiJavaToken>(null) {
@Override
public boolean accepts(@NotNull final PsiJavaToken token, final ProcessingContext context) {
return JavaTokenType.RBRACE.equals(token.getTokenType());
}
}));
private static final PsiJavaElementPattern.Capture<PsiElement> TRY_CATCH_MARKER_PATTERN = psiElement().
withParent(PsiTryStatement.class).
afterSiblingSkipping(psiElement(PsiWhiteSpace.class), psiElement(PsiCodeBlock.class, PsiCatchSection.class));
private static final PsiJavaElementPattern.Capture<PsiElement> LOOP_OR_IF_MARKER =
psiElement().afterSiblingSkipping(psiElement(PsiWhiteSpace.class), psiElement(PsiCodeBlock.class)).
withParent(psiElement(PsiBlockStatement.class).withParent(psiElement(PsiLoopStatement.class, PsiIfStatement.class)));
private static final PsiJavaElementPattern.Capture<PsiElement> METHOD_MARKER_PATTERN =
psiElement().withParent(PsiMethod.class).afterSiblingSkipping(psiElement(PsiWhiteSpace.class), psiElement(PsiCodeBlock.class));
private static final ElementPattern<PsiElement> MARKER_PATTERN = or(ANONYMOUS_CLASS_MARKER_PATTERN,
CLASS_MARKER_PATTERN,
TRY_CATCH_MARKER_PATTERN,
LOOP_OR_IF_MARKER,
METHOD_MARKER_PATTERN);
private static final String END_WORD = "end";
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
return new PsiElementVisitor() {
@Override
public void visitComment(@NotNull final PsiComment element) {
final IElementType tokenType = element.getTokenType();
if (!(tokenType.equals(JavaTokenType.END_OF_LINE_COMMENT))) {
return;
}
final Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(element.getLanguage());
String rawCommentText = element.getText();
final String prefix = commenter.getLineCommentPrefix();
if (prefix != null && rawCommentText.startsWith(prefix)) {
rawCommentText = rawCommentText.substring(prefix.length());
}
final String commentText = StringUtil.toLowerCase(rawCommentText.trim());
if (!commentText.startsWith(END_WORD) || StringUtil.split(commentText, " ").size() > 3) {
return;
}
if (MARKER_PATTERN.accepts(element)) {
holder.registerProblem(element, "Redundant block marker", new LocalQuickFix() {
@NotNull
@Override
public String getFamilyName() {
return "Remove block marker comments";
}
@Override
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
descriptor.getPsiElement().delete();
}
});
}
}
};
}
}