mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
DevKit: cross-language ComponentNotRegisteredInspection + minor refactoring
This commit is contained in:
@@ -71,7 +71,7 @@
|
||||
<localInspection language="XML" shortName="PluginXmlValidity" displayName="Plugin.xml Validity" applyToDialects="false"
|
||||
groupKey="inspections.group.name" enabledByDefault="true" level="ERROR"
|
||||
implementationClass="org.jetbrains.idea.devkit.inspections.PluginXmlDomInspection"/>
|
||||
<localInspection language="JAVA" shortName="ComponentNotRegistered"
|
||||
<localInspection language="JVM" shortName="ComponentNotRegistered"
|
||||
key="inspections.component.not.registered.name" groupKey="inspections.group.name" enabledByDefault="true"
|
||||
level="WARNING" implementationClass="org.jetbrains.idea.devkit.inspections.ComponentNotRegisteredInspection"/>
|
||||
<localInspection language="JAVA" shortName="InspectionDescriptionNotFoundInspection" displayName="Inspection Description Checker"
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
package org.jetbrains.idea.devkit.inspections;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.lang.jvm.DefaultJvmElementVisitor;
|
||||
import com.intellij.lang.jvm.JvmClass;
|
||||
import com.intellij.lang.jvm.JvmElementVisitor;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.components.BaseComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -48,10 +48,17 @@ import javax.swing.event.ChangeListener;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class ComponentNotRegisteredInspection extends DevKitInspectionBase {
|
||||
public class ComponentNotRegisteredInspection extends DevKitJvmInspection {
|
||||
public boolean CHECK_ACTIONS = true;
|
||||
public boolean IGNORE_NON_PUBLIC = true;
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("org.jetbrains.idea.devkit.inspections.ComponentNotRegisteredInspection");
|
||||
private static final Map<ComponentType, RegistrationCheckerUtil.RegistrationType> COMPONENT_TYPE_TO_REGISTRATION_TYPE =
|
||||
ContainerUtil.<ComponentType, RegistrationCheckerUtil.RegistrationType>immutableMapBuilder()
|
||||
.put(ComponentType.APPLICATION, RegistrationCheckerUtil.RegistrationType.APPLICATION_COMPONENT)
|
||||
.put(ComponentType.PROJECT, RegistrationCheckerUtil.RegistrationType.PROJECT_COMPONENT)
|
||||
.put(ComponentType.MODULE, RegistrationCheckerUtil.RegistrationType.MODULE_COMPONENT)
|
||||
.build();
|
||||
|
||||
@Nullable
|
||||
public JComponent createOptionsPanel() {
|
||||
@@ -84,90 +91,87 @@ public class ComponentNotRegisteredInspection extends DevKitInspectionBase {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ProblemDescriptor[] checkClass(@NotNull PsiClass checkedClass, @NotNull InspectionManager manager, boolean isOnTheFly) {
|
||||
PsiIdentifier classIdentifier = checkedClass.getNameIdentifier();
|
||||
if (classIdentifier != null &&
|
||||
checkedClass.getQualifiedName() != null &&
|
||||
checkedClass.getContainingFile().getVirtualFile() != null &&
|
||||
!checkedClass.hasModifierProperty(PsiModifier.ABSTRACT) &&
|
||||
!checkedClass.isEnum() &&
|
||||
!PsiUtil.isInnerClass(checkedClass)) {
|
||||
|
||||
GlobalSearchScope scope = checkedClass.getResolveScope();
|
||||
|
||||
if (shouldCheckActionClass(checkedClass)) {
|
||||
PsiClass actionClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(AnAction.class.getName(), scope);
|
||||
if (actionClass == null) {
|
||||
// stop if action class cannot be found (non-devkit module/project)
|
||||
return null;
|
||||
}
|
||||
if (checkedClass.isInheritor(actionClass, true)) {
|
||||
if (!isActionRegistered(checkedClass) && canFix(checkedClass)) {
|
||||
LocalQuickFix fix = new RegisterActionFix(org.jetbrains.idea.devkit.util.PsiUtil.createPointer(checkedClass));
|
||||
ProblemDescriptor problem =
|
||||
manager.createProblemDescriptor(classIdentifier,
|
||||
DevKitBundle.message("inspections.component.not.registered.message",
|
||||
DevKitBundle.message("new.menu.action.text")),
|
||||
fix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly);
|
||||
return new ProblemDescriptor[]{problem};
|
||||
}
|
||||
// action IS registered, stop here
|
||||
@Override
|
||||
protected JvmElementVisitor<Boolean> buildVisitor(@NotNull Project project, @NotNull HighlightSink sink, boolean isOnTheFly) {
|
||||
return new DefaultJvmElementVisitor<Boolean>() {
|
||||
@Override
|
||||
public Boolean visitClass(@NotNull JvmClass clazz) {
|
||||
PsiElement sourceElement = clazz.getSourceElement();
|
||||
if (!(sourceElement instanceof PsiClass)) {
|
||||
return null;
|
||||
}
|
||||
checkClass(project, (PsiClass)sourceElement, sink);
|
||||
return false;
|
||||
}
|
||||
|
||||
PsiClass compClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(BaseComponent.class.getName(), scope);
|
||||
if (compClass == null) {
|
||||
// stop if component class cannot be found (non-devkit module/project)
|
||||
return null;
|
||||
}
|
||||
if (!checkedClass.isInheritor(compClass, true)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (ComponentType componentType : ComponentType.values()) {
|
||||
if (!InheritanceUtil.isInheritor(checkedClass, componentType.myClassName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (findRegistrationType(checkedClass, COMPONENT_TYPE_TO_REGISTRATION_TYPE.get(componentType)) != null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!canFix(checkedClass)) {
|
||||
return null;
|
||||
}
|
||||
LocalQuickFix fix = new RegisterComponentFix(componentType, org.jetbrains.idea.devkit.util.PsiUtil.createPointer(checkedClass));
|
||||
ProblemDescriptor problem =
|
||||
manager.createProblemDescriptor(classIdentifier,
|
||||
DevKitBundle.message("inspections.component.not.registered.message",
|
||||
DevKitBundle.message(componentType.myPropertyKey)),
|
||||
fix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly);
|
||||
return new ProblemDescriptor[]{problem};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
private static final Map<ComponentType, RegistrationCheckerUtil.RegistrationType> COMPONENT_TYPE_TO_REGISTRATION_TYPE =
|
||||
ContainerUtil.<ComponentType, RegistrationCheckerUtil.RegistrationType>immutableMapBuilder()
|
||||
.put(ComponentType.APPLICATION, RegistrationCheckerUtil.RegistrationType.APPLICATION_COMPONENT)
|
||||
.put(ComponentType.PROJECT, RegistrationCheckerUtil.RegistrationType.PROJECT_COMPONENT)
|
||||
.put(ComponentType.MODULE, RegistrationCheckerUtil.RegistrationType.MODULE_COMPONENT)
|
||||
.build();
|
||||
private void checkClass(@NotNull Project project, @NotNull PsiClass checkedClass, @NotNull HighlightSink sink) {
|
||||
if (checkedClass.getQualifiedName() == null ||
|
||||
checkedClass.getContainingFile().getVirtualFile() == null ||
|
||||
checkedClass.hasModifierProperty(PsiModifier.ABSTRACT) ||
|
||||
checkedClass.isEnum() ||
|
||||
PsiUtil.isInnerClass(checkedClass) ||
|
||||
!shouldCheckActionClass(checkedClass)) {
|
||||
return;
|
||||
}
|
||||
|
||||
private static PsiClass findRegistrationType(@Nullable PsiClass checkedClass, RegistrationCheckerUtil.RegistrationType type) {
|
||||
GlobalSearchScope scope = checkedClass.getResolveScope();
|
||||
PsiClass actionClass = JavaPsiFacade.getInstance(project).findClass(AnAction.class.getName(), scope);
|
||||
if (actionClass == null) {
|
||||
// stop if action class cannot be found (non-devkit module/project)
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkedClass.isInheritor(actionClass, true)) {
|
||||
if (!isActionRegistered(checkedClass) && canFix(checkedClass)) {
|
||||
LocalQuickFix fix = new RegisterActionFix(org.jetbrains.idea.devkit.util.PsiUtil.createPointer(checkedClass));
|
||||
sink.highlight(DevKitBundle.message("inspections.component.not.registered.message",
|
||||
DevKitBundle.message("new.menu.action.text")), fix);
|
||||
}
|
||||
// action IS registered, stop here
|
||||
return;
|
||||
}
|
||||
|
||||
PsiClass compClass = JavaPsiFacade.getInstance(project).findClass(BaseComponent.class.getName(), scope);
|
||||
if (compClass == null) {
|
||||
// stop if component class cannot be found (non-devkit module/project)
|
||||
return;
|
||||
}
|
||||
if (!checkedClass.isInheritor(compClass, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ComponentType componentType : ComponentType.values()) {
|
||||
if (!InheritanceUtil.isInheritor(checkedClass, componentType.myClassName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (findRegistrationType(checkedClass, COMPONENT_TYPE_TO_REGISTRATION_TYPE.get(componentType)) != null) {
|
||||
return;
|
||||
}
|
||||
if (!canFix(checkedClass)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LocalQuickFix fix = new RegisterComponentFix(componentType, org.jetbrains.idea.devkit.util.PsiUtil.createPointer(checkedClass));
|
||||
sink.highlight(DevKitBundle.message("inspections.component.not.registered.message",
|
||||
DevKitBundle.message(componentType.myPropertyKey)), fix);
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiClass findRegistrationType(@NotNull PsiClass checkedClass, @NotNull RegistrationCheckerUtil.RegistrationType type) {
|
||||
final Set<PsiClass> types = RegistrationCheckerUtil.getRegistrationTypes(checkedClass, type);
|
||||
return ContainerUtil.getFirstItem(types);
|
||||
}
|
||||
|
||||
private boolean shouldCheckActionClass(PsiClass psiClass) {
|
||||
private boolean shouldCheckActionClass(@NotNull PsiClass psiClass) {
|
||||
if (!CHECK_ACTIONS) return false;
|
||||
if (IGNORE_NON_PUBLIC && !psiClass.hasModifierProperty(PsiModifier.PUBLIC)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isActionRegistered(PsiClass actionClass) {
|
||||
private static boolean isActionRegistered(@NotNull PsiClass actionClass) {
|
||||
final PsiClass registrationType = findRegistrationType(actionClass, RegistrationCheckerUtil.RegistrationType.ACTION);
|
||||
if (registrationType != null) {
|
||||
return true;
|
||||
@@ -197,7 +201,7 @@ public class ComponentNotRegisteredInspection extends DevKitInspectionBase {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean canFix(PsiClass psiClass) {
|
||||
private static boolean canFix(@NotNull PsiClass psiClass) {
|
||||
Project project = psiClass.getProject();
|
||||
PsiFile psiFile = psiClass.getContainingFile();
|
||||
LOG.assertTrue(psiFile != null);
|
||||
|
||||
+3
-144
@@ -15,159 +15,18 @@
|
||||
*/
|
||||
package org.jetbrains.idea.devkit.inspections;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.devkit.DevkitJavaTestsUtil;
|
||||
import org.jetbrains.idea.devkit.dom.Anchor;
|
||||
import org.jetbrains.idea.devkit.inspections.quickfix.RegisterActionFix;
|
||||
import org.jetbrains.idea.devkit.util.ActionData;
|
||||
import org.jetbrains.idea.devkit.util.PsiUtil;
|
||||
|
||||
@TestDataPath("$CONTENT_ROOT/testData/inspections/componentNotRegistered")
|
||||
public class ComponentNotRegisteredInspectionTest extends PluginModuleTestCase {
|
||||
|
||||
public class ComponentNotRegisteredInspectionTest extends ComponentNotRegisteredInspectionTestBase {
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return DevkitJavaTestsUtil.TESTDATA_PATH + "inspections/componentNotRegistered";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
myFixture.addClass("package com.intellij.openapi.actionSystem; public class AnAction {}");
|
||||
myFixture.addClass("package com.intellij.openapi.components; public interface BaseComponent {}");
|
||||
myFixture.addClass("package com.intellij.openapi.components; public interface ApplicationComponent extends BaseComponent {}");
|
||||
|
||||
myFixture.enableInspections(new ComponentNotRegisteredInspection());
|
||||
}
|
||||
|
||||
public void testRegisteredAction() {
|
||||
setPluginXml("registeredAction-plugin.xml");
|
||||
myFixture.testHighlighting("RegisteredAction.java");
|
||||
}
|
||||
|
||||
public void testRegisteredActionInIDEAProject() {
|
||||
PsiUtil.markAsIdeaProject(getProject(), true);
|
||||
|
||||
try {
|
||||
myFixture.copyFileToProject("registeredAction-plugin.xml", "someOtherPluginXmlName.xml");
|
||||
myFixture.testHighlighting("RegisteredAction.java");
|
||||
}
|
||||
finally {
|
||||
PsiUtil.markAsIdeaProject(getProject(), false);
|
||||
}
|
||||
}
|
||||
|
||||
public void testRegisteredActionInOptionalPluginDescriptor() {
|
||||
setPluginXml("registeredActionInOptionalPluginDescriptor-plugin.xml");
|
||||
myFixture.copyFileToProject("registeredActionInOptionalPluginDescriptor-optional-plugin.xml",
|
||||
"META-INF/optional-plugin.xml");
|
||||
|
||||
myFixture.testHighlighting("RegisteredAction.java");
|
||||
}
|
||||
|
||||
public void testRegisteredInIncludedFileAction() {
|
||||
setPluginXml("ActionXInclude.xml");
|
||||
myFixture.copyFileToProject("ActionXInclude_included.xml", "META-INF/ActionXInclude_included.xml");
|
||||
myFixture.testHighlighting("ActionXInclude.java");
|
||||
}
|
||||
|
||||
public void testUnregisteredAction() {
|
||||
setPluginXml("unregisteredAction-plugin.xml");
|
||||
myFixture.testHighlighting("UnregisteredAction.java");
|
||||
|
||||
RegisterActionFix.ourTestActionData = new MyActionData("UnregisteredAction");
|
||||
final IntentionAction registerAction = myFixture.findSingleIntention("Register Action");
|
||||
myFixture.launchAction(registerAction);
|
||||
|
||||
myFixture.checkResultByFile("META-INF/plugin.xml", "unregisteredAction-plugin_after.xml", true);
|
||||
}
|
||||
|
||||
public void testUnregisteredActionUsedViaConstructor() {
|
||||
myFixture.testHighlighting("UnregisteredActionUsedViaConstructor.java");
|
||||
}
|
||||
|
||||
public void testRegisteredApplicationComponent() {
|
||||
setPluginXml("registeredApplicationComponent-plugin.xml");
|
||||
myFixture.testHighlighting("RegisteredApplicationComponent.java");
|
||||
}
|
||||
|
||||
public void testUnregisteredAbstractApplicationComponent() {
|
||||
myFixture.testHighlighting("UnregisteredAbstractApplicationComponent.java");
|
||||
}
|
||||
|
||||
public void testUnregisteredApplicationComponentWithoutPluginXml() {
|
||||
myFixture.testHighlighting("UnregisteredApplicationComponent.java",
|
||||
"UnregisteredApplicationComponentInterface.java");
|
||||
}
|
||||
|
||||
public void testUnregisteredApplicationComponentWithRegisterFix() {
|
||||
setPluginXml("unregisteredApplicationComponent-plugin.xml");
|
||||
|
||||
myFixture.testHighlighting("UnregisteredApplicationComponent.java",
|
||||
"UnregisteredApplicationComponentInterface.java");
|
||||
final IntentionAction registerAction = myFixture.findSingleIntention("Register Application Component");
|
||||
myFixture.launchAction(registerAction);
|
||||
|
||||
myFixture.checkResultByFile("META-INF/plugin.xml", "unregisteredApplicationComponent-plugin_after.xml", true);
|
||||
}
|
||||
|
||||
|
||||
private static class MyActionData implements ActionData {
|
||||
private final String myActionClassFqn;
|
||||
|
||||
public MyActionData(String actionClassFqn) {
|
||||
myActionClassFqn = actionClassFqn;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getActionId() {
|
||||
return StringUtil.getShortName(myActionClassFqn);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getActionText() {
|
||||
return "Action Text " + myActionClassFqn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActionDescription() {
|
||||
return "Description " + myActionClassFqn;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getSelectedGroupId() {
|
||||
return getActionId() + "Group";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getSelectedActionId() {
|
||||
return getActionId() + "SelectedAction";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectedAnchor() {
|
||||
return Anchor.before.name();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getFirstKeyStroke() {
|
||||
return "1st Key " + getActionId();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getSecondKeyStroke() {
|
||||
return "2nd Key " + getActionId();
|
||||
}
|
||||
protected String getSourceFileExtension() {
|
||||
return "java";
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
class ActionXInclude : com.intellij.openapi.actionSystem.AnAction()
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<xi:include href="/META-INF/ActionXInclude_included.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
</idea-plugin>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<idea-plugin>
|
||||
<actions>
|
||||
<action id="smth" class="ActionXInclude"/>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
|
||||
class RegisteredAction : AnAction() {
|
||||
|
||||
class InnerAction : AnAction()
|
||||
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import com.intellij.openapi.components.ApplicationComponent
|
||||
|
||||
class RegisteredApplicationComponent : ApplicationComponent {
|
||||
|
||||
class InnerStaticClassApplicationContext : ApplicationComponent
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import com.intellij.openapi.components.ApplicationComponent
|
||||
|
||||
abstract class UnregisteredAbstractApplicationComponent : ApplicationComponent
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
|
||||
class <warning descr="Action is not registered in plugin.xml">Unregistered<caret>Action</warning> : AnAction() {
|
||||
class <warning descr="Action is not registered in plugin.xml">InnerAction</warning> : AnAction()
|
||||
|
||||
protected class NonPublicIsIgnored : AnAction()
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
@file:Suppress("UNUSED_VARIABLE")
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
|
||||
class UnregisteredActionUsedViaConstructor : AnAction()
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val mine = UnregisteredActionUsedViaConstructor()
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import com.intellij.openapi.components.ApplicationComponent
|
||||
|
||||
class <warning descr="Application Component is not registered in plugin.xml">Unregistered<caret>ApplicationComponent</warning>
|
||||
: ApplicationComponent, UnregisteredApplicationComponentInterface {
|
||||
|
||||
class <warning descr="Application Component is not registered in plugin.xml">InnerStaticClassApplicationContext</warning>
|
||||
: ApplicationComponent
|
||||
|
||||
inner class InnerClassApplicationContextIsNotChecked : ApplicationComponent
|
||||
|
||||
fun getInstance() : UnregisteredApplicationComponentInterface? = null
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
interface UnregisteredApplicationComponentInterface
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<idea-plugin>
|
||||
<actions>
|
||||
<action id="registeredAction" class="RegisteredAction"/>
|
||||
<group id="group">
|
||||
<group id="nestedGroup">
|
||||
<action id="registeredInnerAction" class="RegisteredAction$InnerAction"/>
|
||||
</group>
|
||||
</group>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<idea-plugin>
|
||||
<actions>
|
||||
<action id="registeredAction" class="RegisteredAction"/>
|
||||
<action id="registeredInnerAction" class="RegisteredAction.InnerAction"/>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<idea-plugin>
|
||||
<!-- registeredActionInOptionalPluginDescriptor-optional-plugin.xml -->
|
||||
<depends optional="true" config-file="optional-plugin.xml"/>
|
||||
<depends optional="true" config-file="optional-plugin.xml"/>
|
||||
</idea-plugin>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<idea-plugin>
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>RegisteredApplicationComponent</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>RegisteredApplicationComponent$InnerStaticClassApplicationContext</implementation-class>
|
||||
</component>
|
||||
</application-components>
|
||||
|
||||
</idea-plugin>
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
<idea-plugin>
|
||||
</idea-plugin>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<idea-plugin>
|
||||
<actions>
|
||||
<action id="UnregisteredAction" class="UnregisteredAction" text="Action Text UnregisteredAction"
|
||||
description="Description UnregisteredAction">
|
||||
<add-to-group group-id="UnregisteredActionGroup" anchor="before"
|
||||
relative-to-action="UnregisteredActionSelectedAction"/>
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="1st Key UnregisteredAction"
|
||||
second-keystroke="2nd Key UnregisteredAction"/>
|
||||
</action>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<idea-plugin>
|
||||
|
||||
</idea-plugin>
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<idea-plugin>
|
||||
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>UnregisteredApplicationComponent</implementation-class>
|
||||
<interface-class>UnregisteredApplicationComponentInterface</interface-class>
|
||||
</component>
|
||||
</application-components>
|
||||
</idea-plugin>
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Copyright 2000-2018 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 org.jetbrains.idea.devkit.kotlin.inspections;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import kotlin.KotlinVersion;
|
||||
import org.jetbrains.idea.devkit.inspections.ComponentNotRegisteredInspectionTestBase;
|
||||
import org.jetbrains.idea.devkit.kotlin.DevkitKtTestsUtil;
|
||||
import org.junit.Assume;
|
||||
|
||||
@TestDataPath("$CONTENT_ROOT/testData/inspections/componentNotRegistered")
|
||||
public class KtComponentNotRegisteredInspectionTest extends ComponentNotRegisteredInspectionTestBase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
Assume.assumeTrue(KotlinVersion.CURRENT.isAtLeast(1, 2, 50));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSourceFileExtension() {
|
||||
return "kt";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return DevkitKtTestsUtil.TESTDATA_PATH + "inspections/componentNotRegistered";
|
||||
}
|
||||
}
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
// Copyright 2000-2018 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 org.jetbrains.idea.devkit.inspections;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.devkit.dom.Anchor;
|
||||
import org.jetbrains.idea.devkit.inspections.quickfix.RegisterActionFix;
|
||||
import org.jetbrains.idea.devkit.util.ActionData;
|
||||
import org.jetbrains.idea.devkit.util.PsiUtil;
|
||||
|
||||
public abstract class ComponentNotRegisteredInspectionTestBase extends PluginModuleTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
myFixture.addClass("package com.intellij.openapi.actionSystem; public class AnAction {}");
|
||||
myFixture.addClass("package com.intellij.openapi.components; public interface BaseComponent {}");
|
||||
myFixture.addClass("package com.intellij.openapi.components; public interface ApplicationComponent extends BaseComponent {}");
|
||||
|
||||
myFixture.enableInspections(new ComponentNotRegisteredInspection());
|
||||
}
|
||||
|
||||
protected abstract String getSourceFileExtension();
|
||||
|
||||
|
||||
public void testRegisteredAction() {
|
||||
setPluginXml("registeredAction-plugin.xml");
|
||||
myFixture.testHighlighting("RegisteredAction." + getSourceFileExtension());
|
||||
}
|
||||
|
||||
public void testRegisteredActionInIDEAProject() {
|
||||
PsiUtil.markAsIdeaProject(getProject(), true);
|
||||
|
||||
try {
|
||||
myFixture.copyFileToProject("registeredAction-plugin.xml", "someOtherPluginXmlName.xml");
|
||||
myFixture.testHighlighting("RegisteredAction." + getSourceFileExtension());
|
||||
}
|
||||
finally {
|
||||
PsiUtil.markAsIdeaProject(getProject(), false);
|
||||
}
|
||||
}
|
||||
|
||||
public void testRegisteredActionInOptionalPluginDescriptor() {
|
||||
setPluginXml("registeredActionInOptionalPluginDescriptor-plugin.xml");
|
||||
myFixture.copyFileToProject("registeredActionInOptionalPluginDescriptor-optional-plugin.xml",
|
||||
"META-INF/optional-plugin.xml");
|
||||
|
||||
myFixture.testHighlighting("RegisteredAction." + getSourceFileExtension());
|
||||
}
|
||||
|
||||
public void testRegisteredInIncludedFileAction() {
|
||||
setPluginXml("ActionXInclude.xml");
|
||||
myFixture.copyFileToProject("ActionXInclude_included.xml", "META-INF/ActionXInclude_included.xml");
|
||||
myFixture.testHighlighting("ActionXInclude." + getSourceFileExtension());
|
||||
}
|
||||
|
||||
@SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod")
|
||||
public void testUnregisteredAction() {
|
||||
setPluginXml("unregisteredAction-plugin.xml");
|
||||
myFixture.testHighlighting("UnregisteredAction." + getSourceFileExtension());
|
||||
|
||||
RegisterActionFix.ourTestActionData = new MyActionData("UnregisteredAction");
|
||||
try {
|
||||
final IntentionAction registerAction = myFixture.findSingleIntention("Register Action");
|
||||
myFixture.launchAction(registerAction);
|
||||
|
||||
myFixture.checkResultByFile("META-INF/plugin.xml", "unregisteredAction-plugin_after.xml", true);
|
||||
} finally {
|
||||
RegisterActionFix.ourTestActionData = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void testUnregisteredActionUsedViaConstructor() {
|
||||
myFixture.testHighlighting("UnregisteredActionUsedViaConstructor." + getSourceFileExtension());
|
||||
}
|
||||
|
||||
public void testRegisteredApplicationComponent() {
|
||||
setPluginXml("registeredApplicationComponent-plugin.xml");
|
||||
myFixture.testHighlighting("RegisteredApplicationComponent." + getSourceFileExtension());
|
||||
}
|
||||
|
||||
public void testUnregisteredAbstractApplicationComponent() {
|
||||
myFixture.testHighlighting("UnregisteredAbstractApplicationComponent." + getSourceFileExtension());
|
||||
}
|
||||
|
||||
public void testUnregisteredApplicationComponentWithoutPluginXml() {
|
||||
myFixture.testHighlighting("UnregisteredApplicationComponent." + getSourceFileExtension(),
|
||||
"UnregisteredApplicationComponentInterface." + getSourceFileExtension());
|
||||
}
|
||||
|
||||
public void testUnregisteredApplicationComponentWithRegisterFix() {
|
||||
setPluginXml("unregisteredApplicationComponent-plugin.xml");
|
||||
|
||||
myFixture.testHighlighting("UnregisteredApplicationComponent." + getSourceFileExtension(),
|
||||
"UnregisteredApplicationComponentInterface." + getSourceFileExtension());
|
||||
final IntentionAction registerAction = myFixture.findSingleIntention("Register Application Component");
|
||||
myFixture.launchAction(registerAction);
|
||||
|
||||
myFixture.checkResultByFile("META-INF/plugin.xml", "unregisteredApplicationComponent-plugin_after.xml", true);
|
||||
}
|
||||
|
||||
|
||||
public static class MyActionData implements ActionData {
|
||||
private final String myActionClassFqn;
|
||||
|
||||
public MyActionData(String actionClassFqn) {
|
||||
myActionClassFqn = actionClassFqn;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getActionId() {
|
||||
return StringUtil.getShortName(myActionClassFqn);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getActionText() {
|
||||
return "Action Text " + myActionClassFqn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActionDescription() {
|
||||
return "Description " + myActionClassFqn;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getSelectedGroupId() {
|
||||
return getActionId() + "Group";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getSelectedActionId() {
|
||||
return getActionId() + "SelectedAction";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectedAnchor() {
|
||||
return Anchor.before.name();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getFirstKeyStroke() {
|
||||
return "1st Key " + getActionId();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getSecondKeyStroke() {
|
||||
return "2nd Key " + getActionId();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user