From 40e35d7a60ad6b897db9905b1bc084ee43b01c61 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 18 Jun 2012 12:05:52 +0400 Subject: [PATCH] enable fix all for file for annotator problems, should work for localQuickFixes only (IDEA-87100) --- .../quickFix/fixAllAnnotator/after1.java | 7 + .../quickFix/fixAllAnnotator/before1.java | 7 + .../quickFix/FixAllAnnotatorQuickfixTest.java | 124 ++++++++++++++++++ .../daemon/impl/HighlightInfo.java | 15 ++- ...efaultHighlightVisitorBasedInspection.java | 5 +- .../codeInspection/InspectionRunningUtil.java | 28 +++- .../actions/CleanupInspectionIntention.java | 27 ++-- 7 files changed, 189 insertions(+), 24 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/after1.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/before1.java create mode 100644 java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/FixAllAnnotatorQuickfixTest.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/after1.java new file mode 100644 index 000000000000..1a0aba5d40ef --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/after1.java @@ -0,0 +1,7 @@ +// "Fix all 'Annotator' problems" "true" +public class Test { + void fooF() { + } + + void barF(){} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/before1.java new file mode 100644 index 000000000000..8006731dbe32 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/before1.java @@ -0,0 +1,7 @@ +// "Fix all 'Annotator' problems" "true" +public class Test { + void foo() { + } + + void bar(){} +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/FixAllAnnotatorQuickfixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/FixAllAnnotatorQuickfixTest.java new file mode 100644 index 000000000000..001bb3764f4c --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/FixAllAnnotatorQuickfixTest.java @@ -0,0 +1,124 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * 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. + */ + +/* + * User: anna + * Date: 17-Jun-2007 + */ +package com.intellij.codeInsight.daemon.quickFix; + +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInspection.*; +import com.intellij.codeInspection.dataFlow.DataFlowInspection; +import com.intellij.lang.Language; +import com.intellij.lang.LanguageAnnotators; +import com.intellij.lang.annotation.Annotation; +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.Annotator; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.CodeInsightColors; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiMethod; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +public class FixAllAnnotatorQuickfixTest extends LightQuickFixTestCase { + public void testAnnotator() throws Exception { + Annotator annotator = new MyAnnotator(); + Language javaLanguage = StdFileTypes.JAVA.getLanguage(); + LanguageAnnotators.INSTANCE.addExplicitExtension(javaLanguage, annotator); + enableInspectionTool(new DefaultHighlightVisitorBasedInspection.AnnotatorBasedInspection()); + try { + doAllTests(); + } + finally { + LanguageAnnotators.INSTANCE.removeExplicitExtension(javaLanguage, annotator); + } + } + + @Override + protected boolean shouldBeAvailableAfterExecution() { + return true; + } + + @Override + @NonNls + protected String getBasePath() { + return "/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator"; + } + + public static class MyAnnotator implements Annotator { + @Override + public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { + if (element instanceof PsiMethod) { + Annotation annotation = holder.createErrorAnnotation(((PsiMethod)element).getNameIdentifier(), null); + annotation.registerFix(new MyFix()); + annotation.setTextAttributes(CodeInsightColors.DOC_COMMENT_TAG_VALUE); + } + } + + static class MyFix implements IntentionAction, LocalQuickFix { + + @NotNull + @Override + public String getText() { + return getName(); + } + + @NotNull + @Override + public String getName() { + return "MyFix"; + } + + @NotNull + @Override + public String getFamilyName() { + return getName(); + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + if (element != null) { + final PsiElement parent = element.getParent(); + if (parent instanceof PsiMethod) { + ((PsiMethod)parent).setName(((PsiMethod)parent).getName() + "F"); + } + } + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + return true; + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + fail(); + } + + @Override + public boolean startInWriteAction() { + return true; + } + } + } +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java index 7255f18995cf..6039146ee2ce 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java @@ -20,10 +20,7 @@ import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.intention.IntentionManager; -import com.intellij.codeInspection.CustomSuppressableInspectionTool; -import com.intellij.codeInspection.InspectionProfile; -import com.intellij.codeInspection.InspectionProfileEntry; -import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.*; import com.intellij.codeInspection.actions.CleanupInspectionIntention; import com.intellij.codeInspection.ex.GlobalInspectionToolWrapper; import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; @@ -405,7 +402,8 @@ public class HighlightInfo implements Segment { List fixes = annotation.getQuickFixes(); if (fixes != null) { for (final Annotation.QuickFixInfo quickFixInfo : fixes) { - QuickFixAction.registerQuickFixAction(info, fixedRange != null? fixedRange : quickFixInfo.textRange, quickFixInfo.quickFix, quickFixInfo.key); + QuickFixAction.registerQuickFixAction(info, fixedRange != null ? fixedRange : quickFixInfo.textRange, quickFixInfo.quickFix, + quickFixInfo.key != null ? quickFixInfo.key : HighlightDisplayKey.find(DefaultHighlightVisitorBasedInspection.AnnotatorBasedInspection.ANNOTATOR_SHORT_NAME)); } } return info; @@ -524,6 +522,13 @@ public class HighlightInfo implements Segment { newOptions.add(new CleanupInspectionIntention((LocalInspectionToolWrapper)tool, aClass)); } else if (tool instanceof GlobalInspectionToolWrapper) { wrappedTool = ((GlobalInspectionToolWrapper)tool).getTool(); + if (wrappedTool instanceof GlobalSimpleInspectionTool && (myAction instanceof LocalQuickFix || myAction instanceof QuickFixWrapper)) { + Class aClass = myAction.getClass(); + if (myAction instanceof QuickFixWrapper) { + aClass = ((QuickFixWrapper)myAction).getFix().getClass(); + } + newOptions.add(new CleanupInspectionIntention((GlobalInspectionToolWrapper)tool, aClass)); + } } if (wrappedTool instanceof CustomSuppressableInspectionTool) { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/DefaultHighlightVisitorBasedInspection.java b/platform/lang-impl/src/com/intellij/codeInspection/DefaultHighlightVisitorBasedInspection.java index 3fb18d97b96c..c7eeb50809c3 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/DefaultHighlightVisitorBasedInspection.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/DefaultHighlightVisitorBasedInspection.java @@ -49,6 +49,9 @@ public abstract class DefaultHighlightVisitorBasedInspection extends GlobalSimpl } public static class AnnotatorBasedInspection extends DefaultHighlightVisitorBasedInspection { + + public static final String ANNOTATOR_SHORT_NAME = "Annotator"; + public AnnotatorBasedInspection() { super(false, true); } @@ -62,7 +65,7 @@ public abstract class DefaultHighlightVisitorBasedInspection extends GlobalSimpl @NotNull @Override public String getShortName() { - return "Annotator"; + return ANNOTATOR_SHORT_NAME; } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/InspectionRunningUtil.java b/platform/lang-impl/src/com/intellij/codeInspection/InspectionRunningUtil.java index e940b4944649..c9a887d59d5a 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/InspectionRunningUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/InspectionRunningUtil.java @@ -15,13 +15,13 @@ */ package com.intellij.codeInspection; -import com.intellij.codeInspection.ex.GlobalInspectionContextImpl; -import com.intellij.codeInspection.ex.InspectionManagerEx; -import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; +import com.intellij.codeInspection.ex.*; import com.intellij.codeInspection.reference.RefManagerImpl; import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -31,17 +31,33 @@ import java.util.List; public class InspectionRunningUtil { public static List runInspectionOnFile(final PsiFile file, final LocalInspectionTool inspectionTool) { + return runInspectionOnFile(file, new LocalInspectionToolWrapper(inspectionTool)); + } + + public static List runInspectionOnFile(final PsiFile file, final InspectionTool tool) { final InspectionManagerEx managerEx = (InspectionManagerEx)InspectionManager.getInstance(file.getProject()); final GlobalInspectionContextImpl context = managerEx.createNewGlobalContext(false); - final LocalInspectionToolWrapper tool = new LocalInspectionToolWrapper(inspectionTool); tool.initialize(context); ((RefManagerImpl)context.getRefManager()).inspectionReadActionStarted(); try { - tool.processFile(file, true, managerEx, true); - return new ArrayList(tool.getProblemDescriptors()); + if (tool instanceof LocalInspectionToolWrapper) { + ((LocalInspectionToolWrapper)tool).processFile(file, true, managerEx, true); + return new ArrayList(((LocalInspectionToolWrapper)tool).getProblemDescriptors()); + } + else if (tool instanceof GlobalInspectionToolWrapper) { + final GlobalInspectionTool globalInspectionTool = ((GlobalInspectionToolWrapper)tool).getTool(); + if (globalInspectionTool instanceof GlobalSimpleInspectionTool) { + ProblemsHolder problemsHolder = new ProblemsHolder(managerEx, file, false); + ((GlobalSimpleInspectionTool)globalInspectionTool) + .checkFile(file, managerEx, problemsHolder, context, (GlobalInspectionToolWrapper)tool); + return new ArrayList(((GlobalInspectionToolWrapper)tool).getProblemDescriptors()); + } + } + return Collections.emptyList(); } finally { ((RefManagerImpl)context.getRefManager()).inspectionReadActionFinished(); + tool.cleanup(); context.cleanup(managerEx); } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java index 664c700be1f4..326e9d0ccae2 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java @@ -21,9 +21,7 @@ import com.intellij.codeInsight.intention.EmptyIntentionAction; import com.intellij.codeInsight.intention.HighPriorityAction; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.*; -import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; -import com.intellij.codeInspection.ex.ProblemDescriptorImpl; -import com.intellij.codeInspection.ex.UnfairLocalInspectionTool; +import com.intellij.codeInspection.ex.*; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -44,10 +42,10 @@ import java.util.List; * Date: 21-Feb-2006 */ public class CleanupInspectionIntention implements IntentionAction, HighPriorityAction { - private final LocalInspectionToolWrapper myTool; + private final InspectionToolWrapper myTool; private final Class myQuickfixClass; - public CleanupInspectionIntention(final LocalInspectionToolWrapper tool, Class quickFixClass) { + public CleanupInspectionIntention(final InspectionToolWrapper tool, Class quickFixClass) { myTool = tool; myQuickfixClass = quickFixClass; } @@ -64,12 +62,13 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException { if (!CodeInsightUtilBase.preparePsiElementForWrite(file)) return; - final List descriptions = ProgressManager.getInstance().runProcess(new Computable>() { - @Override - public List compute() { - return InspectionRunningUtil.runInspectionOnFile(file, myTool.getTool()); - } - }, new EmptyProgressIndicator()); + final List descriptions = + ProgressManager.getInstance().runProcess(new Computable>() { + @Override + public List compute() { + return InspectionRunningUtil.runInspectionOnFile(file, myTool); + } + }, new EmptyProgressIndicator()); Collections.sort(descriptions, new Comparator() { public int compare(final CommonProblemDescriptor o1, final CommonProblemDescriptor o2) { @@ -95,8 +94,12 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority } } + + + public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) { - return myQuickfixClass != null && myQuickfixClass != EmptyIntentionAction.class && !(myTool.isUnfair()); + return myQuickfixClass != null && myQuickfixClass != EmptyIntentionAction.class && !(myTool instanceof LocalInspectionToolWrapper && + ((LocalInspectionToolWrapper)myTool).isUnfair()); } public boolean startInWriteAction() {