From e2016d703cf188484ca33b8752e1f3c29d26f448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20C=C3=A9bron?= Date: Mon, 24 Aug 2015 11:57:25 +0200 Subject: [PATCH 1/7] IDEA-143835 Resolve/Find usages for action/group in --- plugins/devkit/src/dom/Action.java | 6 +- plugins/devkit/src/dom/ActionOrGroup.java | 31 +++ plugins/devkit/src/dom/Actions.java | 5 +- plugins/devkit/src/dom/Group.java | 12 +- plugins/devkit/src/dom/IdeaPlugin.java | 1 + plugins/devkit/src/dom/Reference.java | 16 +- .../impl/ActionOrGroupResolveConverter.java | 178 ++++++++++++++++++ .../src/dom/impl/IdeaPluginConverter.java | 22 ++- .../dom/impl/PluginXmlDomFileDescription.java | 2 +- .../codeInsight/ActionHighlighting.xml | 28 +++ .../pluginXmlDomStubs/pluginXmlStubs.xml | 12 +- .../codeInsight/PluginXmlDomStubsTest.java | 16 +- .../PluginXmlFunctionalTest.groovy | 10 + 13 files changed, 307 insertions(+), 32 deletions(-) create mode 100644 plugins/devkit/src/dom/ActionOrGroup.java create mode 100644 plugins/devkit/src/dom/impl/ActionOrGroupResolveConverter.java create mode 100644 plugins/devkit/testData/codeInsight/ActionHighlighting.xml diff --git a/plugins/devkit/src/dom/Action.java b/plugins/devkit/src/dom/Action.java index e28f2d13b9b4..18710077852c 100644 --- a/plugins/devkit/src/dom/Action.java +++ b/plugins/devkit/src/dom/Action.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -29,7 +29,7 @@ import java.util.List; /** * plugin.dtd:action interface. */ -public interface Action extends DomElement { +public interface Action extends ActionOrGroup { /** * Returns the value of the popup child. @@ -78,6 +78,7 @@ public interface Action extends DomElement { * @return the value of the text child. */ @NotNull + @Stubbed GenericAttributeValue getText(); /** @@ -87,6 +88,7 @@ public interface Action extends DomElement { */ @NotNull @Required + @Stubbed GenericAttributeValue getId(); ///** diff --git a/plugins/devkit/src/dom/ActionOrGroup.java b/plugins/devkit/src/dom/ActionOrGroup.java new file mode 100644 index 000000000000..aa30658148df --- /dev/null +++ b/plugins/devkit/src/dom/ActionOrGroup.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2015 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. + */ +package org.jetbrains.idea.devkit.dom; + +import com.intellij.util.xml.*; +import org.jetbrains.annotations.NotNull; + +/** + * @since 15 + */ +public interface ActionOrGroup extends DomElement { + + @NotNull + @NameValue + @Stubbed + @Required(value = false, nonEmpty = true) + GenericAttributeValue getId(); +} diff --git a/plugins/devkit/src/dom/Actions.java b/plugins/devkit/src/dom/Actions.java index 3fa4320c2596..a6f4ff3e0432 100644 --- a/plugins/devkit/src/dom/Actions.java +++ b/plugins/devkit/src/dom/Actions.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -20,6 +20,7 @@ package org.jetbrains.idea.devkit.dom; import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.Stubbed; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -27,12 +28,14 @@ import java.util.List; public interface Actions extends DomElement { @NotNull + @Stubbed List getActions(); Action addAction(); @NotNull + @Stubbed List getGroups(); Group addGroup(); diff --git a/plugins/devkit/src/dom/Group.java b/plugins/devkit/src/dom/Group.java index 1f2489b3e1e5..fd9b84b1cf6d 100644 --- a/plugins/devkit/src/dom/Group.java +++ b/plugins/devkit/src/dom/Group.java @@ -19,6 +19,7 @@ package org.jetbrains.idea.devkit.dom; +import com.intellij.ide.presentation.Presentation; import com.intellij.psi.PsiClass; import com.intellij.util.xml.*; import org.jetbrains.annotations.NotNull; @@ -29,7 +30,8 @@ import java.util.List; /** * plugin.dtd:group interface. */ -public interface Group extends Actions { +@Presentation(icon = "AllIcons.Actions.GroupByPackage") +public interface Group extends Actions, ActionOrGroup { /** * Returns the value of the popup child. @@ -87,14 +89,6 @@ public interface Group extends Actions { @NotNull GenericAttributeValue getText(); - /** - * Returns the value of the id child. - * Attribute id - * @return the value of the id child. - */ - @NotNull - GenericAttributeValue getId(); - ///** // * Returns the value of the overrides child. // * Attribute overrides diff --git a/plugins/devkit/src/dom/IdeaPlugin.java b/plugins/devkit/src/dom/IdeaPlugin.java index 0be5e9853988..a6515f572f8f 100644 --- a/plugins/devkit/src/dom/IdeaPlugin.java +++ b/plugins/devkit/src/dom/IdeaPlugin.java @@ -134,6 +134,7 @@ public interface IdeaPlugin extends DomElement { @NotNull @SubTagList("actions") + @Stubbed List getActions(); Actions addActions(); diff --git a/plugins/devkit/src/dom/Reference.java b/plugins/devkit/src/dom/Reference.java index 57f1beac6748..ed8081a117dc 100644 --- a/plugins/devkit/src/dom/Reference.java +++ b/plugins/devkit/src/dom/Reference.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -19,9 +19,11 @@ package org.jetbrains.idea.devkit.dom; +import com.intellij.util.xml.Convert; import com.intellij.util.xml.DomElement; import com.intellij.util.xml.GenericAttributeValue; import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.devkit.dom.impl.ActionOrGroupResolveConverter; import java.util.Collection; @@ -30,17 +32,13 @@ import java.util.Collection; */ public interface Reference extends DomElement { - /** - * Returns the value of the id child. - * Attribute id - * - * @return the value of the id child. - */ @NotNull - GenericAttributeValue getRef(); + @Convert(ActionOrGroupResolveConverter.class) + GenericAttributeValue getRef(); @NotNull - GenericAttributeValue getId(); + @Convert(ActionOrGroupResolveConverter.class) + GenericAttributeValue getId(); @NotNull Collection getAddToGroups(); diff --git a/plugins/devkit/src/dom/impl/ActionOrGroupResolveConverter.java b/plugins/devkit/src/dom/impl/ActionOrGroupResolveConverter.java new file mode 100644 index 000000000000..29bc2beb271b --- /dev/null +++ b/plugins/devkit/src/dom/impl/ActionOrGroupResolveConverter.java @@ -0,0 +1,178 @@ +/* + * Copyright 2000-2015 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. + */ +package org.jetbrains.idea.devkit.dom.impl; + +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import com.intellij.psi.xml.XmlFile; +import com.intellij.util.ObjectUtils; +import com.intellij.util.PairProcessor; +import com.intellij.util.xml.ConvertContext; +import com.intellij.util.xml.DomUtil; +import com.intellij.util.xml.ElementPresentationManager; +import com.intellij.util.xml.ResolvingConverter; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.devkit.dom.*; + +import java.util.*; + +public class ActionOrGroupResolveConverter extends ResolvingConverter { + + @NotNull + @Override + public Collection getVariants(ConvertContext context) { + final List variants = new ArrayList(); + PairProcessor collectProcessor = new PairProcessor() { + @Override + public boolean process(String s, ActionOrGroup actionOrGroup) { + variants.add(actionOrGroup); + return true; + } + }; + processActionOrGroup(context, collectProcessor); + return variants; + } + + @Nullable + @Override + public ActionOrGroup fromString(@Nullable @NonNls final String value, ConvertContext context) { + if (StringUtil.isEmptyOrSpaces(value)) return null; + + final ActionOrGroup[] result = {null}; + PairProcessor findProcessor = new PairProcessor() { + @Override + public boolean process(String s, ActionOrGroup actionOrGroup) { + if (Comparing.strEqual(value, s)) { + result[0] = actionOrGroup; + return false; + } + return true; + } + }; + processActionOrGroup(context, findProcessor); + return result[0]; + } + + @Nullable + @Override + public String toString(@Nullable ActionOrGroup group, ConvertContext context) { + return group == null ? null : getName(group); + } + + @Override + public String getErrorMessage(@Nullable String s, ConvertContext context) { + return "Cannot resolve action or group '" + s + "'"; + } + + @Nullable + @Override + public LookupElement createLookupElement(ActionOrGroup actionOrGroup) { + if (actionOrGroup instanceof Action) { + Action action = (Action)actionOrGroup; + final PsiElement element = getPsiElement(actionOrGroup); + if (element == null) { + throw new IllegalStateException(action.getId().getStringValue() + " in " + DomUtil.getFile(action) + " " + action.isValid() + " "); + } + + LookupElementBuilder builder = + LookupElementBuilder.create(ObjectUtils.assertNotNull(element), + ObjectUtils.assertNotNull(getName(action))); + + final String text = action.getText().getStringValue(); + if (StringUtil.isNotEmpty(text)) { + String withoutMnemonic = StringUtil.replace(text, "_", ""); + builder = builder.withTailText(" \"" + withoutMnemonic + "\"", true); + } + + return builder; + } + + return super.createLookupElement(actionOrGroup); + } + + private static boolean processActionOrGroup(ConvertContext context, PairProcessor processor) { + final Project project = context.getProject(); + + Module module = context.getModule(); + if (module == null) { + final Collection plugins = IdeaPluginConverter.getAllPlugins(project); + return processPlugins(plugins, processor); + } + + final Collection modulePlugins = IdeaPluginConverter.getPlugins(project, module.getModuleScope(false)); + if (!processPlugins(modulePlugins, processor)) return false; + + final Collection dependenciesAndLibs = + IdeaPluginConverter.getPlugins(project, module.getModuleWithDependenciesAndLibrariesScope(false)); + return processPlugins(dependenciesAndLibs, processor); + } + + private static boolean processPlugins(Collection plugins, PairProcessor processor) { + for (IdeaPlugin plugin : plugins) { + final Map forFile = collectForFile(plugin); + for (Map.Entry entry : forFile.entrySet()) { + if (!processor.process(entry.getKey(), entry.getValue())) return false; + } + } + return true; + } + + private static Map collectForFile(final IdeaPlugin plugin) { + final XmlFile xmlFile = DomUtil.getFile(plugin); + return CachedValuesManager.getCachedValue(xmlFile, new CachedValueProvider>() { + @Nullable + @Override + public Result> compute() { + Map result = new HashMap(); + for (Actions actions : plugin.getActions()) { + collectRecursive(result, actions); + } + + return Result.create(result, xmlFile); + } + }); + } + + private static void collectRecursive(Map result, Actions actions) { + for (Action action : actions.getActions()) { + final String name = getName(action); + if (!StringUtil.isEmptyOrSpaces(name)) { + result.put(name, action); + } + } + for (Group group : actions.getGroups()) { + final String name = getName(group); + if (!StringUtil.isEmptyOrSpaces(name)) { + result.put(name, group); + } + collectRecursive(result, group); + } + } + + @Nullable + private static String getName(@NotNull ActionOrGroup actionOrGroup) { + return ElementPresentationManager.getElementName(actionOrGroup); + } +} diff --git a/plugins/devkit/src/dom/impl/IdeaPluginConverter.java b/plugins/devkit/src/dom/impl/IdeaPluginConverter.java index 9bd31e1e24b2..613bebc4d536 100644 --- a/plugins/devkit/src/dom/impl/IdeaPluginConverter.java +++ b/plugins/devkit/src/dom/impl/IdeaPluginConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -118,13 +118,19 @@ public class IdeaPluginConverter extends ResolvingConverter { public Result> compute() { GlobalSearchScope scope = GlobalSearchScopesCore.projectProductionScope(project). union(ProjectScope.getLibrariesScope(project)); - List> files = DomService.getInstance().getFileElements(IdeaPlugin.class, project, scope); - final Collection pluginList = ContainerUtil.map(files, new Function, IdeaPlugin>() { - public IdeaPlugin fun(DomFileElement ideaPluginDomFileElement) { - return ideaPluginDomFileElement.getRootElement(); - } - }); - return Result.create(pluginList, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); + return Result.create(getPlugins(project, scope), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); + } + }); + } + + @NotNull + public static Collection getPlugins(Project project, GlobalSearchScope scope) { + if (DumbService.isDumb(project)) return Collections.emptyList(); + + List> files = DomService.getInstance().getFileElements(IdeaPlugin.class, project, scope); + return ContainerUtil.map(files, new Function, IdeaPlugin>() { + public IdeaPlugin fun(DomFileElement ideaPluginDomFileElement) { + return ideaPluginDomFileElement.getRootElement(); } }); } diff --git a/plugins/devkit/src/dom/impl/PluginXmlDomFileDescription.java b/plugins/devkit/src/dom/impl/PluginXmlDomFileDescription.java index d55248376888..2f5eb8a00d6b 100644 --- a/plugins/devkit/src/dom/impl/PluginXmlDomFileDescription.java +++ b/plugins/devkit/src/dom/impl/PluginXmlDomFileDescription.java @@ -43,6 +43,6 @@ public class PluginXmlDomFileDescription extends DomFileDescription @Override public int getStubVersion() { - return 4; + return 5; } } diff --git a/plugins/devkit/testData/codeInsight/ActionHighlighting.xml b/plugins/devkit/testData/codeInsight/ActionHighlighting.xml new file mode 100644 index 000000000000..d2f1d704b847 --- /dev/null +++ b/plugins/devkit/testData/codeInsight/ActionHighlighting.xml @@ -0,0 +1,28 @@ + + + + + + + + + ""/> + + java.lang.String"/> + + "" class="foo.bar.BarAction"/> + java.lang.String" /> + + + + + + INVALID_VALUE"/> + + + + + + INVALID_VALUE"/> + + \ No newline at end of file diff --git a/plugins/devkit/testData/pluginXmlDomStubs/pluginXmlStubs.xml b/plugins/devkit/testData/pluginXmlDomStubs/pluginXmlStubs.xml index d05f6d47ff4a..c062769df6a2 100644 --- a/plugins/devkit/testData/pluginXmlDomStubs/pluginXmlStubs.xml +++ b/plugins/devkit/testData/pluginXmlDomStubs/pluginXmlStubs.xml @@ -7,7 +7,7 @@ - + @@ -15,4 +15,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/plugins/devkit/testSources/codeInsight/PluginXmlDomStubsTest.java b/plugins/devkit/testSources/codeInsight/PluginXmlDomStubsTest.java index ecea03a9c204..72ebc477c5b3 100644 --- a/plugins/devkit/testSources/codeInsight/PluginXmlDomStubsTest.java +++ b/plugins/devkit/testSources/codeInsight/PluginXmlDomStubsTest.java @@ -43,7 +43,21 @@ public class PluginXmlDomStubsTest extends DomStubTest { " Attribute:beanClass:BeanClass\n" + " Element:extensions\n" + " Attribute:defaultExtensionNs:defaultExtensionNs\n" + - " Attribute:xmlns:extensionXmlNs\n"); + " Attribute:xmlns:extensionXmlNs\n" + + " Element:actions\n" + + " Element:action\n" + + " Attribute:id:actionId\n" + + " Attribute:text:actionText\n" + + " Element:group\n" + + " Attribute:id:groupId\n" + + " Element:action\n" + + " Attribute:id:groupAction\n" + + " Attribute:text:groupActionText\n" + + " Element:group\n" + + " Attribute:id:nestedGroup\n" + + " Element:action\n" + + " Attribute:id:nestedGroupActionId\n" + + " Attribute:text:nestedGroupActionText\n"); } public void testXInclude() throws Exception { diff --git a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy index b816180c5c34..09cf1eacbe12 100644 --- a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy +++ b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy @@ -281,4 +281,14 @@ public class PluginXmlFunctionalTest extends JavaCodeInsightFixtureTestCase { myFixture.launchAction(myFixture.findSingleIntention("Define class attribute")) myFixture.checkResultByFile(getTestName(true) + "_after.xml") } + + public void testActionHighlighting() { + configureByFile() + myFixture.addClass("package com.intellij.openapi.actionSystem; public class AnAction { }"); + myFixture.addClass("package foo.bar; public class BarAction extends com.intellij.openapi.actionSystem.AnAction { }"); + + myFixture.addClass("package com.intellij.openapi.actionSystem; public class ActionGroup { }") + myFixture.addClass("package foo.bar; public class BarGroup extends com.intellij.openapi.actionSystem.ActionGroup { }"); + myFixture.testHighlighting() + } } From b1469833424b9146b8217be0ebc364265ff70cd2 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 24 Aug 2015 00:08:00 +0200 Subject: [PATCH 2/7] make IG test light --- .../OverlyStrongTypeCast.java | 8 ++--- .../overly_strong_type_cast/expected.xml | 30 ------------------- .../OverlyStrongTypeCastInspectionTest.java | 21 ++++++++----- 3 files changed, 18 insertions(+), 41 deletions(-) delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/expected.xml diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java index 255af72562f2..fbfeb59b8ccf 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java @@ -14,21 +14,21 @@ interface TestInter{} public class OverlyStrongTypeCast { void iterate(Object o) { - for (Object object : (ArrayList) o) {} - for (String s : (ArrayList) o) {} + for (Object object : (ArrayList) o) {} + for (String s : (ArrayList) o) {} } void optional(Object foo) { if (foo instanceof SubClass2) { ((SubClass2)foo).doSmth(); } - ((SubClass2)foo).doSmth(); + ((SubClass2)foo).doSmth(); } public static void main(String[] args) { List bar = new ArrayList(); - AbstractList foo = (ArrayList) bar; + AbstractList foo = (ArrayList) bar; List foo2 = (ArrayList) bar; double x = (double)3.0f; } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/expected.xml deleted file mode 100644 index ddccdf841d1a..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/expected.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - OverlyStrongTypeCast.java - 17 - Overly strong type cast - Cast to <code>ArrayList</code> can be weakened to 'Iterable' #loc - - - - OverlyStrongTypeCast.java - 18 - Overly strong type cast - Cast to <code>ArrayList<String></code> can be weakened to 'Iterable<String>' #loc - - - - OverlyStrongTypeCast.java - 25 - Overly strong type cast - Cast to <code>SubClass2</code> can be weakened to 'SuperClass' #loc - - - - OverlyStrongTypeCast.java - 31 - Overly strong type cast - Cast to <code>ArrayList</code> can be weakened to 'AbstractList' #loc - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspectionTest.java index e2b54f8c6a1d..94a17ac0638e 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspectionTest.java @@ -1,13 +1,20 @@ package com.siyeh.ig.abstraction; -import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; -import com.siyeh.ig.IGInspectionTestCase; +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; -public class OverlyStrongTypeCastInspectionTest extends IGInspectionTestCase { +public class OverlyStrongTypeCastInspectionTest extends LightInspectionTestCase { - public void test() throws Exception { - final OverlyStrongTypeCastInspection tool = new OverlyStrongTypeCastInspection(); - tool.ignoreInMatchingInstanceof = true; - doTest("com/siyeh/igtest/abstraction/overly_strong_type_cast", new LocalInspectionToolWrapper(tool), "java 1.8"); + public void testOverlyStrongTypeCast() throws Exception { + doTest(); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + final OverlyStrongTypeCastInspection inspection = new OverlyStrongTypeCastInspection(); + inspection.ignoreInMatchingInstanceof = true; + return inspection; } } \ No newline at end of file From 6dc797f0bfec9d727a1fd70bd97554c0e574e2b9 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 24 Aug 2015 11:57:38 +0200 Subject: [PATCH 3/7] IG: JUnit inspections belong under Java in tree --- .../src/META-INF/InspectionGadgets.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml index 157a0f134713..4a9038f73108 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml @@ -1436,11 +1436,11 @@ key="junit4.test.method.in.class.extending.junit3.testcase.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.junit.issues" enabledByDefault="true" level="WARNING" implementationClass="com.siyeh.ig.junit.JUnit4AnnotatedMethodInJUnit3TestCaseInspection"/> - - From 5b88c8c41de7fa6e61289e3a7435b7ba5bfaf97e Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 24 Aug 2015 11:59:21 +0200 Subject: [PATCH 4/7] IDEA-136413 ("Overly strong type cast" warning should take into account checked exceptions) --- .../siyeh/ig/psiutils/ExpectedTypeUtils.java | 13 +++++++++++++ .../OverlyStrongTypeCast.java | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java index c9d04db31647..6c620472d2e7 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java @@ -15,6 +15,7 @@ */ package com.siyeh.ig.psiutils; +import com.intellij.codeInsight.ExceptionUtil; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; @@ -22,10 +23,12 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.HashSet; import java.util.Set; public class ExpectedTypeUtils { @@ -526,9 +529,12 @@ public class ExpectedTypeUtils { if (aClass == null) { return null; } + final PsiReferenceList throwsList = method.getThrowsList(); + final HashSet thrownTypes = ContainerUtil.newHashSet(throwsList.getReferencedTypes()); final PsiMethod[] superMethods = aClass.findMethodsBySignature(method, true); PsiMethod topSuper = null; PsiClass topSuperContainingClass = null; + methodLoop: for (PsiMethod superMethod : superMethods) { final PsiClass superClass = superMethod.getContainingClass(); if (superClass == null) { @@ -552,6 +558,13 @@ public class ExpectedTypeUtils { if (topSuper != null && superClass.isInheritor(topSuperContainingClass, true)) { continue; } + final PsiReferenceList superThrowsList = superMethod.getThrowsList(); + final PsiClassType[] superThrownTypes = superThrowsList.getReferencedTypes(); + for (PsiClassType superThrownType : superThrownTypes) { + if (!ExceptionUtil.isUncheckedException(superThrownType) && !thrownTypes.contains(superThrownType)) { + continue methodLoop; + } + } topSuper = superMethod; topSuperContainingClass = superClass; } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java index fbfeb59b8ccf..f1698ce5f7b5 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java @@ -70,4 +70,22 @@ class SAM { { Object runnable = (Runnable) () -> {}; } +} +class CloseableWarningTest { + private Object x = new Object(); + + public void example() { + //if (x instanceof SafeCloseable) { + ((SafeCloseable) x).close(); + //} + } +} + +interface SafeCloseable extends Closeable { + @Override + void close(); +} +interface Closeable extends AutoCloseable { + + public void close() throws java.io.IOException; } \ No newline at end of file From a3c4a6891a7272635b500193156c6a0be2707ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20C=C3=A9bron?= Date: Mon, 24 Aug 2015 13:02:30 +0200 Subject: [PATCH 5/7] ActionOrGroupResolveConverter: walk module dependencies (IDEA-143835) --- .../dom/impl/ActionOrGroupResolveConverter.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/plugins/devkit/src/dom/impl/ActionOrGroupResolveConverter.java b/plugins/devkit/src/dom/impl/ActionOrGroupResolveConverter.java index 29bc2beb271b..c86d11cda5ee 100644 --- a/plugins/devkit/src/dom/impl/ActionOrGroupResolveConverter.java +++ b/plugins/devkit/src/dom/impl/ActionOrGroupResolveConverter.java @@ -18,6 +18,7 @@ package org.jetbrains.idea.devkit.dom.impl; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; @@ -112,7 +113,7 @@ public class ActionOrGroupResolveConverter extends ResolvingConverter processor) { + private static boolean processActionOrGroup(ConvertContext context, final PairProcessor processor) { final Project project = context.getProject(); Module module = context.getModule(); @@ -121,12 +122,14 @@ public class ActionOrGroupResolveConverter extends ResolvingConverter modulePlugins = IdeaPluginConverter.getPlugins(project, module.getModuleScope(false)); - if (!processPlugins(modulePlugins, processor)) return false; - - final Collection dependenciesAndLibs = - IdeaPluginConverter.getPlugins(project, module.getModuleWithDependenciesAndLibrariesScope(false)); - return processPlugins(dependenciesAndLibs, processor); + return ModuleUtilCore.visitMeAndDependentModules(module, new ModuleUtilCore.ModuleVisitor() { + @Override + public boolean visit(Module module) { + final Collection dependenciesAndLibs = + IdeaPluginConverter.getPlugins(project, module.getModuleRuntimeScope(false)); + return processPlugins(dependenciesAndLibs, processor); + } + }); } private static boolean processPlugins(Collection plugins, PairProcessor processor) { From a4153566134abe1baa965e795d20ed8d42f14d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20C=C3=A9bron?= Date: Mon, 24 Aug 2015 13:08:49 +0200 Subject: [PATCH 6/7] IDEA-144069 DevKit: "use-shortcut-of" support --- plugins/devkit/src/dom/Action.java | 4 ++- .../impl/ActionOrGroupResolveConverter.java | 27 ++++++++++++++++--- .../codeInsight/ActionHighlighting.xml | 4 +++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/plugins/devkit/src/dom/Action.java b/plugins/devkit/src/dom/Action.java index 18710077852c..34b6a25585a6 100644 --- a/plugins/devkit/src/dom/Action.java +++ b/plugins/devkit/src/dom/Action.java @@ -22,6 +22,7 @@ package org.jetbrains.idea.devkit.dom; import com.intellij.psi.PsiClass; import com.intellij.util.xml.*; import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.devkit.dom.impl.ActionOrGroupResolveConverter; import org.jetbrains.idea.devkit.dom.impl.PluginPsiClassConverter; import java.util.List; @@ -163,7 +164,8 @@ public interface Action extends ActionOrGroup { AddToGroup addAddToGroup(); @NotNull - GenericAttributeValue getUseShortcutOf(); + @Convert(ActionOrGroupResolveConverter.OnlyActions.class) + GenericAttributeValue getUseShortcutOf(); @NotNull GenericAttributeValue getKeymap(); diff --git a/plugins/devkit/src/dom/impl/ActionOrGroupResolveConverter.java b/plugins/devkit/src/dom/impl/ActionOrGroupResolveConverter.java index c86d11cda5ee..9c2c2286752f 100644 --- a/plugins/devkit/src/dom/impl/ActionOrGroupResolveConverter.java +++ b/plugins/devkit/src/dom/impl/ActionOrGroupResolveConverter.java @@ -48,7 +48,9 @@ public class ActionOrGroupResolveConverter extends ResolvingConverter collectProcessor = new PairProcessor() { @Override public boolean process(String s, ActionOrGroup actionOrGroup) { - variants.add(actionOrGroup); + if (isRelevant(actionOrGroup)) { + variants.add(actionOrGroup); + } return true; } }; @@ -65,7 +67,8 @@ public class ActionOrGroupResolveConverter extends ResolvingConverter findProcessor = new PairProcessor() { @Override public boolean process(String s, ActionOrGroup actionOrGroup) { - if (Comparing.strEqual(value, s)) { + if (isRelevant(actionOrGroup) && + Comparing.strEqual(value, s)) { result[0] = actionOrGroup; return false; } @@ -78,8 +81,8 @@ public class ActionOrGroupResolveConverter extends ResolvingConverter processor) { final Project project = context.getProject(); diff --git a/plugins/devkit/testData/codeInsight/ActionHighlighting.xml b/plugins/devkit/testData/codeInsight/ActionHighlighting.xml index d2f1d704b847..c2ae8874cda6 100644 --- a/plugins/devkit/testData/codeInsight/ActionHighlighting.xml +++ b/plugins/devkit/testData/codeInsight/ActionHighlighting.xml @@ -13,6 +13,10 @@ "" class="foo.bar.BarAction"/> java.lang.String" /> + + myGroup"/> + INVALID_VALUE"/> + From bd65d4e453f3e3fcea9c4424575b935649e4a1a8 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Mon, 24 Aug 2015 14:12:42 +0300 Subject: [PATCH 7/7] code cleanup --- .../openapi/wm/impl/ToolWindowManagerImpl.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index 491c20689f86..1a6ce8b3e8e0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -1822,7 +1822,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } /** - * @see com.intellij.openapi.wm.impl.ToolWindowsPane#createAddDecoratorCmd + * @see ToolWindowsPane#createAddDecoratorCmd */ private void appendAddDecoratorCmd(final InternalDecorator decorator, final WindowInfoImpl info, @@ -1834,7 +1834,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } /** - * @see com.intellij.openapi.wm.impl.ToolWindowsPane#createRemoveDecoratorCmd + * @see ToolWindowsPane#createRemoveDecoratorCmd */ private void appendRemoveDecoratorCmd(final String id, final boolean dirtyMode, final List commandsList) { final FinalizableCommand command = myToolWindowsPane.createRemoveDecoratorCmd(id, dirtyMode, myWindowManager.getCommandProcessor()); @@ -1852,7 +1852,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } /** - * @see com.intellij.openapi.wm.impl.ToolWindowsPane#createAddButtonCmd + * @see ToolWindowsPane#createAddButtonCmd */ private void appendAddButtonCmd(final StripeButton button, final WindowInfoImpl info, final List commandsList) { final Comparator comparator = myLayout.comparator(info.getAnchor()); @@ -1862,7 +1862,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } /** - * @see com.intellij.openapi.wm.impl.ToolWindowsPane#createAddButtonCmd + * @see ToolWindowsPane#createAddButtonCmd */ private void appendRemoveButtonCmd(final String id, final List commandsList) { final FinalizableCommand command = myToolWindowsPane.createRemoveButtonCmd(id, myWindowManager.getCommandProcessor()); @@ -1886,7 +1886,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } /** - * @see com.intellij.openapi.wm.impl.ToolWindowsPane#createSetEditorComponentCmd + * @see ToolWindowsPane#createSetEditorComponentCmd */ public void appendSetEditorComponentCmd(@Nullable final JComponent component, final List commandsList) { final CommandProcessor commandProcessor = myWindowManager.getCommandProcessor();