diff --git a/platform/lang-api/src/com/intellij/execution/filters/CompositeFilter.java b/platform/lang-api/src/com/intellij/execution/filters/CompositeFilter.java index 335b039546b4..4c77cbbf99ee 100644 --- a/platform/lang-api/src/com/intellij/execution/filters/CompositeFilter.java +++ b/platform/lang-api/src/com/intellij/execution/filters/CompositeFilter.java @@ -70,7 +70,7 @@ public class CompositeFilter implements Filter, FilterMixin { //noinspection ForLoopReplaceableByForEach for (int i = 0; i < count; i++) { Filter filter = filters.get(i); - if (! (filter instanceof FilterMixin)) continue; + if (! (filter instanceof FilterMixin) || !((FilterMixin)filter).shouldRunHeavy()) continue; if (!dumb || DumbService.isDumbAware(filter)) { ((FilterMixin) filter).applyHeavyFilter(copiedFragment, startOffset, startLineNumber, consumer); } diff --git a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java index 0a6f6b508feb..a9db26f1d957 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java @@ -48,6 +48,7 @@ import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter; import com.intellij.openapi.wm.ex.ToolWindowManagerEx; import com.intellij.ui.content.*; +import com.intellij.ui.content.impl.ContentImpl; import com.intellij.ui.docking.DockManager; import com.intellij.util.concurrency.Semaphore; import com.intellij.util.containers.ContainerUtil; @@ -279,7 +280,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { getSyncPublisher().contentRemoved(oldDescriptor, executor); oldDescriptor.dispose(); // is of the same category, can be reused } - else if (descriptor.getAttachedContent() == null) { + else if (descriptor.getAttachedContent() == null || !descriptor.getAttachedContent().isValid() ) { content = createNewContent(contentManager, descriptor, executor); final Icon icon = descriptor.getIcon(); content.setIcon(icon == null ? executor.getToolWindowIcon() : icon); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java index 292b75d536f8..cad6d94b8e2a 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java @@ -32,15 +32,14 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; import com.intellij.util.net.IOExceptionDialog; import org.jetbrains.annotations.NotNull; import javax.swing.event.HyperlinkEvent; import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import java.util.*; /** * @author lloix @@ -121,19 +120,23 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { getPluginTable().updateUI(); final InstalledPluginsTableModel pluginsModel = (InstalledPluginsTableModel)installed.getPluginsModel(); final Set disabled = new HashSet(); + final Set disabledDependants = new HashSet(); for (PluginNode node : list) { final PluginId pluginId = node.getPluginId(); if (pluginsModel.isDisabled(pluginId)) { disabled.add(node); } - } - if (!disabled.isEmpty()) { - String message = "Updated plugin" + (disabled.size() > 1 ? "s are " : " is ") + "disabled. Would you like to enable " + (disabled.size() > 1 ? "them" : "it") + "?"; - if (Messages.showOkCancelDialog(host.pluginTable, message, CommonBundle.getWarningTitle(), Messages.getQuestionIcon()) == - DialogWrapper.OK_EXIT_CODE) { - pluginsModel.enableRows(disabled.toArray(new IdeaPluginDescriptor[disabled.size()]), true); + final List depends = node.getDepends(); + if (depends != null) { + for (PluginId dependantId : depends) { + final IdeaPluginDescriptor pluginDescriptor = PluginManager.getPlugin(dependantId); + if (pluginDescriptor != null && pluginsModel.isDisabled(dependantId)) { + disabledDependants.add(pluginDescriptor); + } + } } } + suggestToEnableInstalledPlugins(pluginsModel, disabled, disabledDependants, list); } else { notifyPluginsWereInstalled(); @@ -150,6 +153,60 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { } } + private static void suggestToEnableInstalledPlugins(final InstalledPluginsTableModel pluginsModel, + final Set disabled, + final Set disabledDependants, + final ArrayList list) { + if (!disabled.isEmpty() || !disabledDependants.isEmpty()) { + String message = ""; + if (disabled.size() == 1) { + message = "Updated plugin '" + disabled.iterator().next().getName() + "' is disabled"; + } else if (!disabled.isEmpty()) { + message = "Updated plugins " + StringUtil.join(disabled, new Function() { + @Override + public String fun(IdeaPluginDescriptor pluginDescriptor) { + return pluginDescriptor.getName(); + } + }, ", ") + " are disabled."; + } + + if (!disabledDependants.isEmpty()) { + if (!message.isEmpty()) { + message += "\n"; + } + message += "Updated plugin" + (list.size() > 1 ? "s depend " : " depends ") + "on disabled"; + if (disabledDependants.size() == 1) { + message += " plugin '" + disabledDependants.iterator().next().getName() + "'."; + } else { + message += " plugins " + StringUtil.join(disabledDependants, new Function() { + @Override + public String fun(IdeaPluginDescriptor pluginDescriptor) { + return pluginDescriptor.getName(); + } + }, ", ") + "."; + } + } + message += "\nWould you like to enable plugins with dependencies?"; + + int result; + if (!disabled.isEmpty() && !disabledDependants.isEmpty()) { + result = + Messages.showYesNoCancelDialog(message, CommonBundle.getWarningTitle(), "Enable all", + "Enable updated plugin" + (disabled.size() > 1 ? "s" : ""), CommonBundle.getCancelButtonText(), + Messages.getQuestionIcon()); + } else { + result = Messages.showOkCancelDialog(message, CommonBundle.getWarningTitle(), "Enable", CommonBundle.getCancelButtonText(), Messages.getQuestionIcon()); + } + + if (result == DialogWrapper.OK_EXIT_CODE) { + disabled.addAll(disabledDependants); + pluginsModel.enableRows(disabled.toArray(new IdeaPluginDescriptor[disabled.size()]), true); + } else if (result == DialogWrapper.CANCEL_EXIT_CODE && !disabled.isEmpty()) { + pluginsModel.enableRows(disabled.toArray(new IdeaPluginDescriptor[disabled.size()]), true); + } + } + } + private void installedPluginsToModel(ArrayList list) { for (PluginNode pluginNode : list) { final String idString = pluginNode.getPluginId().getIdString(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockMemberContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockMemberContributor.java index 3cad6a8569de..9061beb5ff0b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockMemberContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockMemberContributor.java @@ -8,6 +8,7 @@ import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder; import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint; @@ -26,25 +27,33 @@ public class SpockMemberContributor extends NonCodeMembersContributor { GroovyPsiElement place, ResolveState state) { ClassHint classHint = processor.getHint(ClassHint.KEY); - if (classHint != null && !classHint.shouldProcess(ClassHint.ResolveKind.PROPERTY)) return; + if (classHint == null || classHint.shouldProcess(ClassHint.ResolveKind.PROPERTY)) { + GrMethod method = PsiTreeUtil.getParentOfType(place, GrMethod.class); + if (method == null) return; - GrMethod method = PsiTreeUtil.getParentOfType(place, GrMethod.class); - if (method == null) return; + if (aClass != method.getContainingClass()) return; - if (aClass != method.getContainingClass()) return; + Map cachedValue = SpockUtils.getVariableMap(method); - Map cachedValue = SpockUtils.getVariableMap(method); - - String nameHint = ResolveUtil.getNameHint(processor); - if (nameHint == null) { - for (SpockVariableDescriptor spockVar : cachedValue.values()) { - if (!processor.execute(spockVar.getVariable(), state)) return; + String nameHint = ResolveUtil.getNameHint(processor); + if (nameHint == null) { + for (SpockVariableDescriptor spockVar : cachedValue.values()) { + if (!processor.execute(spockVar.getVariable(), state)) return; + } + } + else { + SpockVariableDescriptor spockVar = cachedValue.get(nameHint); + if (spockVar != null && spockVar.getNavigationElement() != place) { + if (!processor.execute(spockVar.getVariable(), state)) return; + } } } - else { - SpockVariableDescriptor spockVar = cachedValue.get(nameHint); - if (spockVar != null && spockVar.getNavigationElement() != place) { - if (!processor.execute(spockVar.getVariable(), state)) return; + + if (classHint == null || classHint.shouldProcess(ClassHint.ResolveKind.METHOD)) { + if ("get_".equals(ResolveUtil.getNameHint(processor))) { + GrLightMethodBuilder m = new GrLightMethodBuilder(aClass.getManager(), "get_"); + m.setReturnType(null); + if (!processor.execute(m, state)) return; } } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/spock/SpockTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/spock/SpockTest.groovy index af6500eb819d..526c9ba3825c 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/spock/SpockTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/spock/SpockTest.groovy @@ -7,6 +7,8 @@ import com.intellij.psi.PsiFile import com.intellij.psi.PsiVariable import com.intellij.psi.CommonClassNames +import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection +import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GroovyUnresolvedAccessInspection /** * @author Sergey Evdokimov @@ -198,5 +200,35 @@ class FooSpec extends spock.lang.Specification { assertEmpty("Some completion variants are missed", missedVariants); } + public void testVariable_resolved() { + myFixture.enableInspections(GroovyAssignabilityCheckInspection, GroovyUnresolvedAccessInspection) + + myFixture.configureByText("FooSpec.groovy", """ +class FooSpec extends spock.lang.Specification { + def "foo test"() { + String subscriber = Mock() + then: (0.._) * subscriber.concat(_) + subscriber.concat(asdasdasd) + subscriber.concat(23) + } +} +""") + + myFixture.checkHighlighting(true, false, true) + } + + public void testVariable_NotExistingInCompletion() { + myFixture.configureByText("FooSpec.groovy", """ +class FooSpec extends spock.lang.Specification { + def "foo test"() { + String subscriber = Mock() + then: (0.._) * subscriber.concat() + } +} +""") + myFixture.completeBasic() + def elements = myFixture.getLookupElementStrings() + assert !elements.contains("_") + } } diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlUnusedNamespaceInspection.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlUnusedNamespaceInspection.java index c49be1b8653f..ca59bb366f21 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlUnusedNamespaceInspection.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlUnusedNamespaceInspection.java @@ -127,9 +127,11 @@ public class XmlUnusedNamespaceInspection extends XmlSuppressableInspectionTool private static void checkUnusedLocations(XmlAttribute attribute, ProblemsHolder holder) { if (XmlUtil.XML_SCHEMA_INSTANCE_URI.equals(attribute.getNamespace())) { + XmlRefCountHolder refCountHolder = XmlRefCountHolder.getRefCountHolder(attribute); + if (refCountHolder == null) return; + if (XmlUtil.NO_NAMESPACE_SCHEMA_LOCATION_ATT.equals(attribute.getLocalName())) { - XmlRefCountHolder refCountHolder = XmlRefCountHolder.getRefCountHolder(attribute); - if (refCountHolder == null || refCountHolder.isInUse("")) return; + if (refCountHolder.isInUse("")) return; holder.registerProblem(attribute, NAMESPACE_LOCATION_IS_NEVER_USED, ProblemHighlightType.LIKE_UNUSED_SYMBOL, new RemoveNamespaceLocationFix("")); } @@ -141,7 +143,7 @@ public class XmlUnusedNamespaceInspection extends XmlSuppressableInspectionTool PsiReference reference = references[i]; if (reference instanceof URLReference) { String ns = getNamespaceFromReference(reference); - if (ArrayUtil.indexOf(attribute.getParent().knownNamespaces(), ns) == -1) { + if (ArrayUtil.indexOf(attribute.getParent().knownNamespaces(), ns) == -1 && !refCountHolder.isUsedNamespace(ns)) { if (!XmlHighlightVisitor.hasBadResolve(reference, false)) { holder.registerProblemForReference(reference, ProblemHighlightType.LIKE_UNUSED_SYMBOL, NAMESPACE_LOCATION_IS_NEVER_USED, new RemoveNamespaceLocationFix(ns)); diff --git a/xml/impl/src/com/intellij/xml/util/XmlRefCountHolder.java b/xml/impl/src/com/intellij/xml/util/XmlRefCountHolder.java index abc213158bb1..0a43ad190e36 100644 --- a/xml/impl/src/com/intellij/xml/util/XmlRefCountHolder.java +++ b/xml/impl/src/com/intellij/xml/util/XmlRefCountHolder.java @@ -68,6 +68,7 @@ public class XmlRefCountHolder { private final Set myAdditionallyDeclaredIds = new HashSet(); private final Set myDoNotValidateParentsList = new HashSet(); private final Set myUsedPrefixes = new HashSet(); + private final Set myUsedNamespaces = new HashSet(); @Nullable public static XmlRefCountHolder getRefCountHolder(final XmlElement element) { @@ -140,6 +141,10 @@ public class XmlRefCountHolder { return myUsedPrefixes.contains(prefix); } + public boolean isUsedNamespace(String ns) { + return myUsedNamespaces.contains(ns); + } + private static class IdGatheringRecursiveVisitor extends XmlRecursiveElementVisitor { private final XmlRefCountHolder myHolder; @@ -192,6 +197,7 @@ public class XmlRefCountHolder { @Override public void visitXmlTag(XmlTag tag) { myHolder.addUsedPrefix(tag.getNamespacePrefix()); + myHolder.addUsedNamespace(tag.getNamespace()); String text = tag.getValue().getTrimmedText(); detectPrefix(text); super.visitXmlTag(tag); @@ -202,6 +208,7 @@ public class XmlRefCountHolder { if (!attribute.isNamespaceDeclaration()) { myHolder.addUsedPrefix(attribute.getNamespacePrefix()); } + myHolder.addUsedNamespace(attribute.getNamespace()); super.visitXmlAttribute(attribute); } @@ -269,4 +276,8 @@ public class XmlRefCountHolder { private void addUsedPrefix(String prefix) { myUsedPrefixes.add(prefix); } + + private void addUsedNamespace(String ns) { + myUsedNamespaces.add(ns); + } }