IDEA-322654 Devkit: Inspection description checker inspection - support IntentionAction with skipBeforeAfter=true

GitOrigin-RevId: 36ca4e229fa8a789969f300aa77921e2c6f1341a
This commit is contained in:
Yann Cébron
2023-06-15 18:42:35 +00:00
committed by intellij-monorepo-bot
parent 59018c357f
commit 77435029e9
6 changed files with 57 additions and 13 deletions
@@ -62,6 +62,10 @@ abstract class DescriptionNotFoundInspectionBase extends DevKitUastInspectionBas
protected abstract boolean skipIfNotRegistered(PsiClass epClass);
protected boolean skipOptionalBeforeAfter(PsiClass epClass) {
return false;
}
protected boolean checkDynamicDescription(ProblemsHolder holder, Module module, PsiClass psiClass) {
throw new IllegalStateException("must be implemented for " + getClass());
}
@@ -81,7 +85,8 @@ abstract class DescriptionNotFoundInspectionBase extends DevKitUastInspectionBas
final PsiFile descr = dir.findFile("description.html");
if (descr == null) continue;
if (!hasBeforeAndAfterTemplate(dir.getVirtualFile())) {
if (!hasBeforeAndAfterTemplate(dir.getVirtualFile()) &&
!skipOptionalBeforeAfter(psiClass)) {
ProblemHolderUtilKt.registerUProblem(holder, uClass, getHasNotBeforeAfterError());
}
return true;
@@ -1,19 +1,21 @@
// Copyright 2000-2020 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.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.idea.devkit.inspections;
import com.intellij.openapi.module.Module;
import com.intellij.psi.PsiClass;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomManager;
import com.intellij.util.xml.GenericDomValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.devkit.DevKitBundle;
import org.jetbrains.idea.devkit.dom.Extension;
import org.jetbrains.idea.devkit.util.DevKitDomUtil;
import org.jetbrains.idea.devkit.util.ExtensionCandidate;
import org.jetbrains.idea.devkit.util.ExtensionLocatorKt;
import java.util.List;
/**
* @author Konstantin Bulenkov
*/
public class IntentionDescriptionNotFoundInspection extends DescriptionNotFoundInspectionBase {
public final class IntentionDescriptionNotFoundInspection extends DescriptionNotFoundInspectionBase {
public IntentionDescriptionNotFoundInspection() {
super(DescriptionType.INTENTION);
@@ -21,8 +23,19 @@ public class IntentionDescriptionNotFoundInspection extends DescriptionNotFoundI
@Override
protected boolean skipIfNotRegistered(PsiClass epClass) {
final List<ExtensionCandidate> registrations = ExtensionLocatorKt.locateExtensionsByPsiClass(epClass);
return registrations.isEmpty();
return findCandidate(epClass) == null;
}
@Override
protected boolean skipOptionalBeforeAfter(PsiClass epClass) {
ExtensionCandidate candidate = findCandidate(epClass);
assert candidate != null;
DomElement domElement = DomManager.getDomManager(epClass.getProject()).getDomElement(candidate.pointer.getElement());
if (!(domElement instanceof Extension)) return false;
@SuppressWarnings("unchecked") GenericDomValue<Boolean> skipBeforeAfterValue =
(GenericDomValue<Boolean>)DevKitDomUtil.getTag(domElement, "skipBeforeAfter");
return skipBeforeAfterValue != null && Boolean.TRUE.equals(skipBeforeAfterValue.getValue());
}
@Override
@@ -36,4 +49,9 @@ public class IntentionDescriptionNotFoundInspection extends DescriptionNotFoundI
protected String getHasNotBeforeAfterError() {
return DevKitBundle.message("inspections.intention.description.no.before.after.template");
}
@Nullable
private static ExtensionCandidate findCandidate(PsiClass epClass) {
return ContainerUtil.getOnlyItem(ExtensionLocatorKt.locateExtensionsByPsiClass(epClass));
}
}
@@ -0,0 +1,14 @@
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Iconable;
import com.intellij.psi.PsiFile;
import com.intellij.util.IncorrectOperationException;
class MyIntentionActionOptionalBeforeAfter implements com.intellij.codeInsight.intention.IntentionAction {
public String getText() { return"text"; }
public String getFamilyName() { return"familyName"; }
public boolean isAvailable(Project project,Editor editor,PsiFile file) {return true; }
public void invoke(Project project,Editor editor,PsiFile file) throws IncorrectOperationException {}
public boolean startInWriteAction() { return true; }
}
@@ -10,6 +10,10 @@
<intentionAction>
<className>MyIntentionActionWithoutBeforeAfter</className>
</intentionAction>
<intentionAction>
<className>MyIntentionActionOptionalBeforeAfter</className>
<skipBeforeAfter>true</skipBeforeAfter>
</intentionAction>
<intentionAction>
<className>MyQuickFixIntentionAction</className>
</intentionAction>
@@ -3,7 +3,6 @@ package org.jetbrains.idea.devkit.inspections;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.IntentionActionBean;
import com.intellij.codeInspection.LocalInspectionEP;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Iconable;
@@ -15,8 +14,6 @@ import com.intellij.util.IncorrectOperationException;
import com.intellij.util.PathUtil;
import org.jetbrains.idea.devkit.DevkitJavaTestsUtil;
import java.nio.file.Paths;
@TestDataPath("$CONTENT_ROOT/testData/inspections/intentionDescription")
public class IntentionDescriptionNotFoundInspectionTest extends JavaCodeInsightFixtureTestCase {
@@ -59,6 +56,11 @@ public class IntentionDescriptionNotFoundInspectionTest extends JavaCodeInsightF
myFixture.testHighlighting("MyIntentionActionWithoutBeforeAfter.java");
}
public void testHighlightingOptionalBeforeAfter() {
myFixture.copyDirectoryToProject("intentionDescriptions", "intentionDescriptions");
myFixture.testHighlighting("MyIntentionActionOptionalBeforeAfter.java");
}
public void testQuickFix() {
myFixture.configureByFile("MyQuickFixIntentionAction.java");
IntentionAction item = myFixture.findSingleIntention("Create description file description.html");