From b7ffe2f1d7e4071a752e4bc8641a00199712d474 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Fri, 30 Jan 2015 17:15:46 +0300 Subject: [PATCH 01/22] IDEA-135537 Use light weight popup if owner has other owned windows --- .../ui/AbstractExpandableItemsHandler.java | 15 ++++++++++++--- .../src/com/intellij/ui/popup/MovablePopup.java | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java index 89e1b18c6bb2..a664161a5c8d 100644 --- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java +++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java @@ -276,10 +276,7 @@ public abstract class AbstractExpandableItemsHandler Date: Fri, 30 Jan 2015 17:20:37 +0300 Subject: [PATCH 02/22] IDEA-135537 Improve visual performance of moving an expansion hint --- .../intellij/ui/AbstractExpandableItemsHandler.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java index a664161a5c8d..7cc7305fe3b0 100644 --- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java +++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java @@ -267,6 +267,13 @@ public abstract class AbstractExpandableItemsHandler Date: Fri, 30 Jan 2015 14:43:53 +0300 Subject: [PATCH 03/22] Consider injection while retrieving intentions and their options in tests --- .../impl/CodeInsightTestFixtureImpl.java | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 9f3fbc17f8e8..42f40fbfd265 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -1701,14 +1701,23 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig descriptors.addAll(intentions.inspectionFixesToShow); descriptors.addAll(intentions.guttersToShow); - PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); + final int fileOffset = editor.getCaretModel().getOffset(); + PsiElement hostElement = file.getViewProvider().findElementAt(fileOffset, file.getLanguage()); + PsiElement injectedElement = InjectedLanguageUtil.findElementAtNoCommit(file, fileOffset); + + PsiFile injectedFile = injectedElement != null ? injectedElement.getContainingFile() : null; + Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile); + List result = new ArrayList(); List infos = DaemonCodeAnalyzerEx.getInstanceEx(file.getProject()).getFileLevelHighlights(file.getProject(), file); for (HighlightInfo info : infos) { for (Pair pair : info.quickFixActionRanges) { HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first; - if (actionInGroup.getAction().isAvailable(file.getProject(), editor, file)) { + final IntentionAction action = actionInGroup.getAction(); + + if (ShowIntentionActionsHandler.availableFor(file, editor, action) + || (injectedElement != null && hostElement != injectedElement && ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, action))) { descriptors.add(actionInGroup); } } @@ -1717,11 +1726,25 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig // add all intention options for simplicity for (HighlightInfo.IntentionActionDescriptor descriptor : descriptors) { result.add(descriptor.getAction()); - List options = descriptor.getOptions(element,editor); - if (options != null) { - for (IntentionAction option : options) { - if (option.isAvailable(file.getProject(), editor, file)) { - result.add(option); + + if (injectedElement != null && injectedElement != hostElement) { + List options = descriptor.getOptions(injectedElement, injectedEditor); + if (options != null) { + for (IntentionAction option : options) { + if (ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, option)) { + result.add(option); + } + } + } + } + + if (hostElement != null) { + List options = descriptor.getOptions(hostElement, editor); + if (options != null) { + for (IntentionAction option : options) { + if (ShowIntentionActionsHandler.availableFor(file, editor, option)) { + result.add(option); + } } } } From 024f3f5039eb7c17050ad4c2c6bbf4d9327fe571 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Fri, 30 Jan 2015 15:11:36 +0300 Subject: [PATCH 04/22] Provide suppression fixes in injections for suppressing inspection in host file --- .../InjectionAwareSuppressQuickFix.java | 18 +++++ .../InspectionProfileEntry.java | 81 ++++++++++++++----- ...BatchSuppressByNoInspectionCommentFix.java | 15 +++- .../SuppressIntentionActionFromFix.java | 11 ++- .../impl/ShowIntentionActionsHandler.java | 12 +++ 5 files changed, 112 insertions(+), 25 deletions(-) create mode 100644 platform/analysis-api/src/com/intellij/codeInspection/InjectionAwareSuppressQuickFix.java diff --git a/platform/analysis-api/src/com/intellij/codeInspection/InjectionAwareSuppressQuickFix.java b/platform/analysis-api/src/com/intellij/codeInspection/InjectionAwareSuppressQuickFix.java new file mode 100644 index 000000000000..27baddcd3220 --- /dev/null +++ b/platform/analysis-api/src/com/intellij/codeInspection/InjectionAwareSuppressQuickFix.java @@ -0,0 +1,18 @@ +package com.intellij.codeInspection; + +import com.intellij.psi.PsiElement; +import com.intellij.util.ThreeState; + +/** + * This kind of suppression fix allows to clients to specify whether the fix should + * be invoked on injected elements or on elements of host files. + *

+ * By default suppression fixes on injected elements are able to make suppression inside injection only. + * Whereas implementation of this interface will be provided for suppressing inside injection and in injection host. + * See {@link InspectionProfileEntry#getBatchSuppressActions(PsiElement)} for details. + */ +public interface InjectionAwareSuppressQuickFix extends SuppressQuickFix { + ThreeState isShouldBeAppliedToInjectionHost(); + + void setShouldBeAppliedToInjectionHost(ThreeState shouldBeAppliedToInjectionHost); +} diff --git a/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java index af1e65c67598..886d02aa55a2 100644 --- a/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java +++ b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java @@ -17,6 +17,7 @@ package com.intellij.codeInspection; import com.intellij.codeHighlighting.HighlightDisplayLevel; import com.intellij.lang.Language; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.InvalidDataException; @@ -24,8 +25,10 @@ import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider; import com.intellij.util.ResourceUtil; +import com.intellij.util.ThreeState; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xmlb.SerializationFilter; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; @@ -44,14 +47,16 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; /** * @author anna * @since 28-Nov-2005 */ -@SuppressWarnings("JavadocReference") -public abstract class InspectionProfileEntry implements BatchSuppressableTool{ +public abstract class InspectionProfileEntry implements BatchSuppressableTool { public static final String GENERAL_GROUP_NAME = InspectionsBundle.message("inspection.general.tools.group.name"); private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.InspectionProfileEntry"); @@ -93,22 +98,52 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ Set fixes = new THashSet(new TObjectHashingStrategy() { @Override public int computeHashCode(SuppressQuickFix object) { - return object.getName().hashCode(); + int result = object instanceof InjectionAwareSuppressQuickFix + ? ((InjectionAwareSuppressQuickFix)object).isShouldBeAppliedToInjectionHost().hashCode() + : 0; + return 31 * result + object.getName().hashCode(); } @Override public boolean equals(SuppressQuickFix o1, SuppressQuickFix o2) { + if (o1 instanceof InjectionAwareSuppressQuickFix && o2 instanceof InjectionAwareSuppressQuickFix) { + if (((InjectionAwareSuppressQuickFix)o1).isShouldBeAppliedToInjectionHost() != ((InjectionAwareSuppressQuickFix)o2).isShouldBeAppliedToInjectionHost()) { + return false; + } + } return o1.getName().equals(o2.getName()); } }); + Set suppressors = getSuppressors(element); + final PsiLanguageInjectionHost injectionHost = InjectedLanguageManager.getInstance(element.getProject()).getInjectionHost(element); + if (injectionHost != null) { + Set injectionHostSuppressors = getSuppressors(injectionHost); + for (InspectionSuppressor suppressor : injectionHostSuppressors) { + addAllSuppressActions(fixes, injectionHost, suppressor, ThreeState.YES, getShortName()); + } + } + for (InspectionSuppressor suppressor : suppressors) { - SuppressQuickFix[] actions = suppressor.getSuppressActions(element, getShortName()); - fixes.addAll(Arrays.asList(actions)); + addAllSuppressActions(fixes, element, suppressor, injectionHost != null ? ThreeState.NO : ThreeState.UNSURE, getShortName()); } return fixes.toArray(new SuppressQuickFix[fixes.size()]); } + private static void addAllSuppressActions(Set fixes, + PsiElement element, + InspectionSuppressor suppressor, + ThreeState appliedToInjectionHost, + String toolShortName) { + final SuppressQuickFix[] actions = suppressor.getSuppressActions(element, toolShortName); + for (SuppressQuickFix action : actions) { + if (action instanceof InjectionAwareSuppressQuickFix) { + ((InjectionAwareSuppressQuickFix)action).setShouldBeAppliedToInjectionHost(appliedToInjectionHost); + } + fixes.add(action); + } + } + private boolean isSuppressed(@NotNull String toolId, @NotNull InspectionSuppressor suppressor, @NotNull PsiElement element) { @@ -132,7 +167,9 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ ContainerUtil.addIfNotNull(suppressors, elementLanguageSuppressor); return suppressors; } - return elementLanguageSuppressor != null ? Collections.singleton(elementLanguageSuppressor) : Collections.emptySet(); + return elementLanguageSuppressor != null + ? Collections.singleton(elementLanguageSuppressor) + : Collections.emptySet(); } public void cleanup(Project project) { @@ -148,9 +185,9 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ protected volatile DefaultNameProvider myNameProvider = null; /** - * @see com.intellij.codeInspection.InspectionEP#groupDisplayName - * @see com.intellij.codeInspection.InspectionEP#groupKey - * @see com.intellij.codeInspection.InspectionEP#groupBundle + * @see InspectionEP#groupDisplayName + * @see InspectionEP#groupKey + * @see InspectionEP#groupBundle */ @Nls @NotNull @@ -166,7 +203,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ } /** - * @see com.intellij.codeInspection.InspectionEP#groupPath + * @see InspectionEP#groupPath */ @NotNull public String[] getGroupPath() { @@ -178,9 +215,9 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ } /** - * @see com.intellij.codeInspection.InspectionEP#displayName - * @see com.intellij.codeInspection.InspectionEP#key - * @see com.intellij.codeInspection.InspectionEP#bundle + * @see InspectionEP#displayName + * @see InspectionEP#key + * @see InspectionEP#bundle */ @Nls @NotNull @@ -198,7 +235,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ /** * DO NOT OVERRIDE this method. * - * @see com.intellij.codeInspection.InspectionEP#shortName + * @see InspectionEP#shortName */ @NonNls @NotNull @@ -214,13 +251,13 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ @NotNull public static String getShortName(@NotNull String className) { - return StringUtil.trimEnd(StringUtil.trimEnd(className, "Inspection"),"InspectionBase"); + return StringUtil.trimEnd(StringUtil.trimEnd(className, "Inspection"), "InspectionBase"); } /** * DO NOT OVERRIDE this method. * - * @see com.intellij.codeInspection.InspectionEP#level + * @see InspectionEP#level */ @NotNull public HighlightDisplayLevel getDefaultLevel() { @@ -230,7 +267,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ /** * DO NOT OVERRIDE this method. * - * @see com.intellij.codeInspection.InspectionEP#enabledByDefault + * @see InspectionEP#enabledByDefault */ public boolean isEnabledByDefault() { return false; @@ -238,6 +275,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ /** * This method is called each time UI is shown. + * * @return null if no UI options required. */ @Nullable @@ -348,7 +386,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ * Initialize inspection with project. Is called on project opened for all profiles as well as on profile creation. * * @param project to be associated with this entry - * @deprecated this won't work for inspections configured via {@link com.intellij.codeInspection.InspectionEP} + * @deprecated this won't work for inspections configured via {@link InspectionEP} */ public void projectOpened(@NotNull Project project) { } @@ -357,7 +395,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ * Cleanup inspection settings corresponding to the project. Is called on project closed for all profiles as well as on profile deletion. * * @param project to be disassociated from this entry - * @deprecated this won't work for inspections configured via {@link com.intellij.codeInspection.InspectionEP} + * @deprecated this won't work for inspections configured via {@link InspectionEP} */ public void projectClosed(@NotNull Project project) { } @@ -411,7 +449,8 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ if (descriptionUrl == null) return null; return ResourceUtil.loadText(descriptionUrl); } - catch (IOException ignored) { } + catch (IOException ignored) { + } return null; } diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/AbstractBatchSuppressByNoInspectionCommentFix.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/AbstractBatchSuppressByNoInspectionCommentFix.java index 7a8c3e3c6cde..6bc8511bd5b5 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/AbstractBatchSuppressByNoInspectionCommentFix.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/AbstractBatchSuppressByNoInspectionCommentFix.java @@ -17,9 +17,9 @@ package com.intellij.codeInsight.daemon.impl.actions; import com.intellij.codeInsight.FileModificationService; +import com.intellij.codeInspection.InjectionAwareSuppressQuickFix; import com.intellij.codeInspection.InspectionsBundle; import com.intellij.codeInspection.ProblemDescriptor; -import com.intellij.codeInspection.SuppressQuickFix; import com.intellij.codeInspection.SuppressionUtil; import com.intellij.icons.AllIcons; import com.intellij.lang.Language; @@ -32,6 +32,7 @@ import com.intellij.psi.PsiManager; import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ThreeState; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -43,9 +44,10 @@ import java.util.List; * @author Roman.Chernyatchik * @date Aug 13, 2009 */ -public abstract class AbstractBatchSuppressByNoInspectionCommentFix implements SuppressQuickFix, Iconable { +public abstract class AbstractBatchSuppressByNoInspectionCommentFix implements InjectionAwareSuppressQuickFix, Iconable { @NotNull protected final String myID; private final boolean myReplaceOtherSuppressionIds; + private ThreeState myShouldBeAppliedToInjectionHost = ThreeState.UNSURE; @Nullable public abstract PsiElement getContainer(final PsiElement context); @@ -60,6 +62,15 @@ public abstract class AbstractBatchSuppressByNoInspectionCommentFix implements S myReplaceOtherSuppressionIds = replaceOtherSuppressionIds; } + public void setShouldBeAppliedToInjectionHost(ThreeState shouldBeAppliedToInjectionHost) { + myShouldBeAppliedToInjectionHost = shouldBeAppliedToInjectionHost; + } + + @Override + public ThreeState isShouldBeAppliedToInjectionHost() { + return myShouldBeAppliedToInjectionHost; + } + @NotNull @Override public String getName() { diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java b/platform/analysis-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java index 3fc800e87879..d92101c386fb 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java @@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ThreeState; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -59,9 +60,15 @@ public class SuppressIntentionActionFromFix extends SuppressIntentionAction { } } + public ThreeState isShouldBeAppliedToInjectionHost() { + return myFix instanceof InjectionAwareSuppressQuickFix + ? ((InjectionAwareSuppressQuickFix)myFix).isShouldBeAppliedToInjectionHost() + : ThreeState.UNSURE; + } + public PsiElement getContainer(PsiElement element) { return myFix instanceof AbstractBatchSuppressByNoInspectionCommentFix - ? ((AbstractBatchSuppressByNoInspectionCommentFix )myFix).getContainer(element) : null; + ? ((AbstractBatchSuppressByNoInspectionCommentFix)myFix).getContainer(element) : null; } @Override @@ -72,7 +79,7 @@ public class SuppressIntentionActionFromFix extends SuppressIntentionAction { @NotNull @Override public String getText() { - return myFix.getName(); + return myFix.getName() + (isShouldBeAppliedToInjectionHost() == ThreeState.NO ? " in injection" : ""); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java index 8ddebd7c383f..31c1ecd533d1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java @@ -27,6 +27,7 @@ import com.intellij.codeInsight.lookup.LookupEx; import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; +import com.intellij.codeInspection.SuppressIntentionActionFromFix; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.featureStatistics.FeatureUsageTrackerImpl; import com.intellij.injected.editor.EditorWindow; @@ -45,6 +46,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.PairProcessor; +import com.intellij.util.ThreeState; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -107,6 +109,16 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler { private static boolean isAvailableHere(Editor editor, PsiFile psiFile, PsiElement psiElement, boolean inProject, IntentionAction action) { try { Project project = psiFile.getProject(); + if (action instanceof SuppressIntentionActionFromFix) { + final ThreeState shouldBeAppliedToInjectionHost = ((SuppressIntentionActionFromFix)action).isShouldBeAppliedToInjectionHost(); + if (editor instanceof EditorWindow && shouldBeAppliedToInjectionHost == ThreeState.YES) { + return false; + } + if (!(editor instanceof EditorWindow) && shouldBeAppliedToInjectionHost == ThreeState.NO) { + return false; + } + } + if (action instanceof PsiElementBaseIntentionAction) { if (!inProject || psiElement == null || !((PsiElementBaseIntentionAction)action).isAvailable(project, editor, psiElement)) return false; } From 772d3c27d30dc6b724bfeb2fd886c9555556c575 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Fri, 30 Jan 2015 15:12:44 +0300 Subject: [PATCH 05/22] Move injection suppressions down in intention list --- .../codeInsight/intention/impl/IntentionListStep.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java index 0700b6e1e1b2..491508e2c7a8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java @@ -27,6 +27,7 @@ import com.intellij.codeInsight.intention.impl.config.IntentionActionWrapper; import com.intellij.codeInsight.intention.impl.config.IntentionManagerSettings; import com.intellij.codeInspection.IntentionWrapper; import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.SuppressIntentionActionFromFix; import com.intellij.codeInspection.ex.QuickFixWrapper; import com.intellij.icons.AllIcons; import com.intellij.openapi.application.ApplicationManager; @@ -39,6 +40,7 @@ import com.intellij.openapi.util.Iconable; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.util.PsiUtilBase; +import com.intellij.util.ThreeState; import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import gnu.trove.TObjectHashingStrategy; @@ -321,6 +323,11 @@ class IntentionListStep implements ListPopupStep if (a instanceof LowPriorityAction) { return group - 3; } + if (a instanceof SuppressIntentionActionFromFix) { + if (((SuppressIntentionActionFromFix)a).isShouldBeAppliedToInjectionHost() == ThreeState.NO) { + return group - 1; + } + } if (a instanceof QuickFixWrapper) { final LocalQuickFix quickFix = ((QuickFixWrapper)a).getFix(); if (quickFix instanceof HighPriorityAction) { From 9968736a184cacb9ffa251942ea8e8005baac7e3 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Fri, 30 Jan 2015 15:13:40 +0300 Subject: [PATCH 06/22] Highlight scope on choosing suppression intention --- .../impl/IntentionHintComponent.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java index d71f60589150..436356065f2c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java @@ -28,10 +28,14 @@ import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.intention.impl.config.IntentionActionWrapper; import com.intellij.codeInsight.intention.impl.config.IntentionManagerSettings; import com.intellij.codeInsight.intention.impl.config.IntentionSettingsConfigurable; +import com.intellij.codeInsight.unwrap.ScopeHighlighter; +import com.intellij.codeInspection.SuppressIntentionActionFromFix; import com.intellij.icons.AllIcons; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -52,7 +56,9 @@ import com.intellij.openapi.ui.popup.ListPopup; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.refactoring.BaseRefactoringIntentionAction; import com.intellij.ui.HintHint; import com.intellij.ui.LightweightHint; @@ -61,6 +67,7 @@ import com.intellij.ui.RowIcon; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.Alarm; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ThreeState; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.EmptyIcon; import org.jetbrains.annotations.NotNull; @@ -69,11 +76,14 @@ import org.jetbrains.annotations.TestOnly; import javax.swing.*; import javax.swing.border.Border; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.Collections; import java.util.List; /** @@ -441,12 +451,52 @@ public class IntentionHintComponent extends JPanel implements Disposable, Scroll Disposer.dispose(myPopup); } myPopup = JBPopupFactory.getInstance().createListPopup(step); + + final PsiFile injectedFile = InjectedLanguageUtil.findInjectedPsiNoCommit(myFile, myEditor.getCaretModel().getOffset()); + final Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(myEditor, injectedFile); + + final ScopeHighlighter highlighter = new ScopeHighlighter(myEditor); + final ScopeHighlighter injectionHighlighter = new ScopeHighlighter(injectedEditor); + myPopup.addListener(new JBPopupListener.Adapter() { @Override public void onClosed(LightweightWindowEvent event) { + highlighter.dropHighlight(); + injectionHighlighter.dropHighlight(); myPopupShown = false; } }); + myPopup.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + final Object source = e.getSource(); + highlighter.dropHighlight(); + injectionHighlighter.dropHighlight(); + + if (source instanceof DataProvider) { + final Object selectedItem = PlatformDataKeys.SELECTED_ITEM.getData((DataProvider)source); + if (selectedItem instanceof IntentionActionWithTextCaching) { + final IntentionAction action = ((IntentionActionWithTextCaching)selectedItem).getAction(); + if (action instanceof SuppressIntentionActionFromFix) { + if (injectedFile != null && ((SuppressIntentionActionFromFix)action).isShouldBeAppliedToInjectionHost() == ThreeState.NO) { + final PsiElement at = injectedFile.findElementAt(injectedEditor.getCaretModel().getOffset()); + final PsiElement container = ((SuppressIntentionActionFromFix)action).getContainer(at); + if (container != null) { + injectionHighlighter.highlight(container, Collections.singletonList(container)); + } + } + else { + final PsiElement at = myFile.findElementAt(myEditor.getCaretModel().getOffset()); + final PsiElement container = ((SuppressIntentionActionFromFix)action).getContainer(at); + if (container != null) { + highlighter.highlight(container, Collections.singletonList(container)); + } + } + } + } + } + } + }); if (myEditor.isOneLineMode()) { // hide popup on combobox popup show From 5d41563ea64971dbaf7406f489e82314d5b0a9d9 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Fri, 30 Jan 2015 14:41:01 +0300 Subject: [PATCH 07/22] natural direction for previous/next on windows --- platform/platform-resources/src/META-INF/XmlActions.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/platform-resources/src/META-INF/XmlActions.xml b/platform/platform-resources/src/META-INF/XmlActions.xml index af42373b52a3..a7862132188f 100644 --- a/platform/platform-resources/src/META-INF/XmlActions.xml +++ b/platform/platform-resources/src/META-INF/XmlActions.xml @@ -104,13 +104,13 @@ - + - + From 4f240b2c90e6c978cc39d096e0913737b84f4b18 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Fri, 30 Jan 2015 15:28:27 +0300 Subject: [PATCH 08/22] multi cursor support for edit points --- .../emmet/actions/EmmetEditPointUtil.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java index 24fd7faaeee1..35169356fed6 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java @@ -17,6 +17,8 @@ package com.intellij.codeInsight.template.emmet.actions; import com.intellij.lang.Language; import com.intellij.lang.xml.XMLLanguage; +import com.intellij.openapi.editor.Caret; +import com.intellij.openapi.editor.CaretAction; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.text.StringUtil; @@ -33,14 +35,25 @@ import com.intellij.psi.xml.XmlTokenType; * @author Dennis.Ushakov */ public class EmmetEditPointUtil { - public static void moveForward(Editor editor, PsiFile file) { + public static void moveForward(final Editor editor, final PsiFile file) { if (!isApplicableFile(file)) return; - moveToNextPoint(editor, file, editor.getCaretModel().getOffset(), 1); + editor.getCaretModel().runForEachCaret(new CaretAction() { + @Override + public void perform(Caret caret) { + moveToNextPoint(editor, file, caret.getOffset(), 1); + } + }); + } - public static void moveBackward(Editor editor, PsiFile file) { + public static void moveBackward(final Editor editor, final PsiFile file) { if (!isApplicableFile(file)) return; - moveToNextPoint(editor, file, editor.getCaretModel().getOffset(), -1); + editor.getCaretModel().runForEachCaret(new CaretAction() { + @Override + public void perform(Caret caret) { + moveToNextPoint(editor, file, caret.getOffset(), -1); + } + }); } private static void moveToNextPoint(Editor editor, PsiFile file, int offset, int inc) { From 6d932ed7350c9f2341e2d5775010e0595d433da1 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Fri, 30 Jan 2015 16:44:56 +0300 Subject: [PATCH 09/22] move to EditorAction --- .../emmet/actions/EmmetEditPointUtil.java | 17 +------ .../emmet/actions/GoToEditPointAction.java | 48 ++++++++++--------- 2 files changed, 27 insertions(+), 38 deletions(-) diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java index 35169356fed6..f118115e20b1 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java @@ -17,8 +17,6 @@ package com.intellij.codeInsight.template.emmet.actions; import com.intellij.lang.Language; import com.intellij.lang.xml.XMLLanguage; -import com.intellij.openapi.editor.Caret; -import com.intellij.openapi.editor.CaretAction; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.text.StringUtil; @@ -37,23 +35,12 @@ import com.intellij.psi.xml.XmlTokenType; public class EmmetEditPointUtil { public static void moveForward(final Editor editor, final PsiFile file) { if (!isApplicableFile(file)) return; - editor.getCaretModel().runForEachCaret(new CaretAction() { - @Override - public void perform(Caret caret) { - moveToNextPoint(editor, file, caret.getOffset(), 1); - } - }); - + moveToNextPoint(editor, file, editor.getCaretModel().getOffset(), 1); } public static void moveBackward(final Editor editor, final PsiFile file) { if (!isApplicableFile(file)) return; - editor.getCaretModel().runForEachCaret(new CaretAction() { - @Override - public void perform(Caret caret) { - moveToNextPoint(editor, file, caret.getOffset(), -1); - } - }); + moveToNextPoint(editor, file, editor.getCaretModel().getOffset(), -1); } private static void moveToNextPoint(Editor editor, PsiFile file, int offset, int inc) { diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/GoToEditPointAction.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/GoToEditPointAction.java index f6c66a88931f..792524f02633 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/GoToEditPointAction.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/GoToEditPointAction.java @@ -15,45 +15,47 @@ */ package com.intellij.codeInsight.template.emmet.actions; -import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.project.DumbAware; import com.intellij.psi.PsiFile; -import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; +import org.jetbrains.annotations.Nullable; /** * @author Dennis.Ushakov */ -public abstract class GoToEditPointAction extends DumbAwareAction { - @Override - public void update(AnActionEvent e) { - final Editor editor = getEditor(e); - final PsiFile file = getFile(e); - final boolean isApplicable = editor != null && EmmetEditPointUtil.isApplicableFile(file); - e.getPresentation().setEnabledAndVisible(isApplicable); +public abstract class GoToEditPointAction extends EditorAction implements DumbAware { + protected GoToEditPointAction(EditorActionHandler defaultHandler) { + super(defaultHandler); } - private static PsiFile getFile(AnActionEvent e) { - return CommonDataKeys.PSI_FILE.getData(e.getDataContext()); - } - - private static Editor getEditor(AnActionEvent e) { - final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); - return editor != null ? InjectedLanguageUtil.getTopLevelEditor(editor) : null; + private static PsiFile getFile(DataContext context) { + return CommonDataKeys.PSI_FILE.getData(context); } public static class Forward extends GoToEditPointAction { - @Override - public void actionPerformed(AnActionEvent e) { - EmmetEditPointUtil.moveForward(getEditor(e), getFile(e)); + public Forward() { + super(new EditorActionHandler(true) { + @Override + protected void doExecute(Editor editor, @Nullable Caret caret, DataContext dataContext) { + EmmetEditPointUtil.moveForward(editor, getFile(dataContext)); + } + }); } } public static class Backward extends GoToEditPointAction { - @Override - public void actionPerformed(AnActionEvent e) { - EmmetEditPointUtil.moveBackward(getEditor(e), getFile(e)); + public Backward() { + super(new EditorActionHandler(true) { + @Override + protected void doExecute(Editor editor, @Nullable Caret caret, DataContext dataContext) { + EmmetEditPointUtil.moveBackward(editor, getFile(dataContext)); + } + }); } } } From 0b9dafe724a764296ff0943ac95c18474a78813d Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Fri, 30 Jan 2015 17:01:38 +0300 Subject: [PATCH 10/22] scroll to primary caret --- .../template/emmet/actions/EmmetEditPointUtil.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java index f118115e20b1..46e0c21a6450 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java @@ -17,8 +17,7 @@ package com.intellij.codeInsight.template.emmet.actions; import com.intellij.lang.Language; import com.intellij.lang.xml.XMLLanguage; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; @@ -68,8 +67,15 @@ public class EmmetEditPointUtil { private static boolean moveCaret(Editor editor, PsiElement current, int offset) { editor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, current.getContainingFile()); - if (editor.getCaretModel().getOffset() == offset) return false; - editor.getCaretModel().moveToOffset(offset); + final CaretModel caretModel = editor.getCaretModel(); + if (caretModel.getOffset() == offset) return false; + + caretModel.moveToOffset(offset); + final Caret caret = caretModel.getCurrentCaret(); + ScrollingModel scrollingModel = editor.getScrollingModel(); + if (caret == caretModel.getPrimaryCaret()) { + scrollingModel.scrollToCaret(ScrollType.RELATIVE); + } return true; } From 4766eecb0b1363093da58990ba9309eb37cbacfd Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Fri, 30 Jan 2015 17:58:13 +0300 Subject: [PATCH 11/22] handle multi-root files and JS --- .../emmet/actions/EmmetEditPointUtil.java | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java index 46e0c21a6450..d23114a1d243 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java @@ -19,14 +19,14 @@ import com.intellij.lang.Language; import com.intellij.lang.xml.XMLLanguage; import com.intellij.openapi.editor.*; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; +import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; +import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.XmlText; import com.intellij.psi.xml.XmlTokenType; +import com.intellij.util.ObjectUtils; /** * @author Dennis.Ushakov @@ -44,27 +44,36 @@ public class EmmetEditPointUtil { private static void moveToNextPoint(Editor editor, PsiFile file, int offset, int inc) { final Document doc = editor.getDocument(); + final TemplateLanguageFileViewProvider provider = ObjectUtils.tryCast(file.getViewProvider(), TemplateLanguageFileViewProvider.class); + final Language additionalLanguage = provider != null ? provider.getTemplateDataLanguage() : null; PsiDocumentManager.getInstance(file.getProject()).commitDocument(doc); for (int i = offset + inc; i < doc.getTextLength() && i >= 0; i += inc) { PsiElement current = InjectedLanguageUtil.findElementAtNoCommit(file, i); - if (current == null) continue; - - if (current.getParent() instanceof XmlText) { - final int line = doc.getLineNumber(i); - final int lineStart = doc.getLineStartOffset(line); - final int lineEnd = doc.getLineEndOffset(line); - if (lineEnd == offset) continue; - - final CharSequence text = doc.getCharsSequence().subSequence(lineStart, lineEnd); - if (StringUtil.isEmptyOrSpaces(text) && moveCaret(editor, current, lineEnd)) { - return; - } - } else if (isEmptyEditPoint(current) && moveCaret(editor, current, current.getTextRange().getStartOffset())) { - return; + if (checkAndMove(editor, doc, i, current)) return; + if (additionalLanguage != null) { + current = provider.findElementAt(i, additionalLanguage); + if (checkAndMove(editor, doc, i, current)) return; } } } + private static boolean checkAndMove(Editor editor, Document doc, int offset, PsiElement current) { + if (current == null) return false; + if (current.getParent() instanceof XmlText) { + final int line = doc.getLineNumber(offset); + final int lineStart = doc.getLineStartOffset(line); + final int lineEnd = doc.getLineEndOffset(line); + + final CharSequence text = doc.getCharsSequence().subSequence(lineStart, lineEnd); + if (StringUtil.isEmptyOrSpaces(text) && moveCaret(editor, current, lineEnd)) { + return true; + } + } else if (isEmptyEditPoint(current) && moveCaret(editor, current, current.getTextRange().getStartOffset())) { + return true; + } + return false; + } + private static boolean moveCaret(Editor editor, PsiElement current, int offset) { editor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, current.getContainingFile()); final CaretModel caretModel = editor.getCaretModel(); @@ -95,7 +104,7 @@ public class EmmetEditPointUtil { static boolean isApplicableFile(PsiFile file) { if (file == null) return false; for (Language language : file.getViewProvider().getLanguages()) { - if (language.isKindOf(XMLLanguage.INSTANCE)) return true; + if (language.isKindOf(XMLLanguage.INSTANCE) || "JavaScript".equals(language.getID())) return true; } return false; } From 3c5404b6ee8710997cdd6150866c9cdebf141e0f Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Fri, 30 Jan 2015 18:04:32 +0300 Subject: [PATCH 12/22] return visibility check --- .../template/emmet/actions/GoToEditPointAction.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/GoToEditPointAction.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/GoToEditPointAction.java index 792524f02633..840126aafa19 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/GoToEditPointAction.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/GoToEditPointAction.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.template.emmet.actions; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorAction; @@ -33,6 +34,15 @@ public abstract class GoToEditPointAction extends EditorAction implements DumbAw super(defaultHandler); } + @Override + public void update(Editor editor, Presentation presentation, DataContext dataContext) { + super.update(editor, presentation, dataContext); + final PsiFile file = getFile(dataContext); + if (!EmmetEditPointUtil.isApplicableFile(file)) { + presentation.setEnabledAndVisible(false); + } + } + private static PsiFile getFile(DataContext context) { return CommonDataKeys.PSI_FILE.getData(context); } From 668618e881502a7540521e2e7281cfb72bf145e1 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 30 Jan 2015 15:47:10 +0100 Subject: [PATCH 13/22] IDEA-135711 'Problems' icon not always highlighted when there is a problem --- .../compiler/impl/ProblemsViewImpl.java | 43 +++++++++---------- .../ide/errorTreeView/ErrorViewStructure.java | 24 +++++++++++ 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java index 68dce61619cb..63cf2cabb1c4 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java @@ -18,10 +18,10 @@ package com.intellij.compiler.impl; import com.intellij.compiler.ProblemsView; import com.intellij.icons.AllIcons; import com.intellij.ide.errorTreeView.ErrorTreeElement; +import com.intellij.ide.errorTreeView.ErrorTreeElementKind; import com.intellij.ide.errorTreeView.ErrorViewStructure; import com.intellij.ide.errorTreeView.GroupingElement; import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompileScope; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; @@ -40,6 +40,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.ide.PooledThreadExecutor; import javax.swing.*; +import java.util.EnumSet; import java.util.UUID; /** @@ -48,7 +49,8 @@ import java.util.UUID; */ public class ProblemsViewImpl extends ProblemsView{ private static final String PROBLEMS_TOOLWINDOW_ID = "Problems"; - + private static final EnumSet ALL_MESSAGE_KINDS = EnumSet.allOf(ErrorTreeElementKind.class); + private final ProblemsViewPanel myPanel; private final SequentialTaskExecutor myViewUpdater = new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE); private final Icon myActiveIcon = AllIcons.Toolwindows.Problems; @@ -70,7 +72,6 @@ public class ProblemsViewImpl extends ProblemsView{ return; } final ToolWindow tw = wm.registerToolWindow(PROBLEMS_TOOLWINDOW_ID, false, ToolWindowAnchor.BOTTOM, project, true); - updateIcon(false); final Content content = ContentFactory.SERVICE.getInstance().createContent(myPanel, "", false); // todo: setup content? tw.getContentManager().addContent(content); @@ -80,6 +81,7 @@ public class ProblemsViewImpl extends ProblemsView{ tw.getContentManager().removeAllContents(true); } }); + updateIcon(); } }); } @@ -89,19 +91,16 @@ public class ProblemsViewImpl extends ProblemsView{ myViewUpdater.execute(new Runnable() { @Override public void run() { - updateIcon(!cleanupChildrenRecursively(myPanel.getErrorViewStructure().getRootElement(), scope, currentSessionId)); + cleanupChildrenRecursively(myPanel.getErrorViewStructure().getRootElement(), scope, currentSessionId); + updateIcon(); myPanel.reload(); } }); } - private boolean cleanupChildrenRecursively(@NotNull final Object fromElement, final @Nullable CompileScope scope, @NotNull UUID currentSessionId) { + private void cleanupChildrenRecursively(@NotNull final Object fromElement, final @Nullable CompileScope scope, @NotNull UUID currentSessionId) { final ErrorViewStructure structure = myPanel.getErrorViewStructure(); - ErrorTreeElement[] elements = structure.getChildElements(fromElement); - if (elements.length ==0) return true; - - boolean result = false; - for (ErrorTreeElement element : elements) { + for (ErrorTreeElement element : structure.getChildElements(fromElement)) { if (element instanceof GroupingElement) { if (scope != null) { final VirtualFile file = ((GroupingElement)element).getFile(); @@ -111,20 +110,17 @@ public class ProblemsViewImpl extends ProblemsView{ } if (!currentSessionId.equals(element.getData())) { structure.removeElement(element); - result = true; } else { - result |= cleanupChildrenRecursively(element, scope, currentSessionId); + cleanupChildrenRecursively(element, scope, currentSessionId); } } else { if (!currentSessionId.equals(element.getData())) { structure.removeElement(element); - result = true; } } } - return result; } @Override @@ -139,7 +135,7 @@ public class ProblemsViewImpl extends ProblemsView{ public void run() { final ErrorViewStructure structure = myPanel.getErrorViewStructure(); final GroupingElement group = structure.lookupGroupingElement(groupName); - if (group != null && !sessionId.equals(group.getData())) { + if (group != null && sessionId != null && !sessionId.equals(group.getData())) { structure.removeElement(group); } if (navigatable != null) { @@ -148,21 +144,24 @@ public class ProblemsViewImpl extends ProblemsView{ else { myPanel.addMessage(type, text, null, -1, -1, sessionId); } - updateIcon(true); + updateIcon(); } }); } - private void updateIcon(final boolean active) { - ApplicationManager.getApplication().invokeLater(new Runnable() { + private void updateIcon() { + UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { - final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(PROBLEMS_TOOLWINDOW_ID); - if (tw != null) { - tw.setIcon(active ? myActiveIcon : myPassiveIcon); + if (!myProject.isDisposed()) { + final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(PROBLEMS_TOOLWINDOW_ID); + if (tw != null) { + final boolean active = myPanel.getErrorViewStructure().hasMessages(ALL_MESSAGE_KINDS); + tw.setIcon(active ? myActiveIcon : myPassiveIcon); + } } } - }, myProject.getDisposed()); + }); } @Override diff --git a/platform/platform-impl/src/com/intellij/ide/errorTreeView/ErrorViewStructure.java b/platform/platform-impl/src/com/intellij/ide/errorTreeView/ErrorViewStructure.java index b964f200fc41..e96b5baa092d 100644 --- a/platform/platform-impl/src/com/intellij/ide/errorTreeView/ErrorViewStructure.java +++ b/platform/platform-impl/src/com/intellij/ide/errorTreeView/ErrorViewStructure.java @@ -69,6 +69,30 @@ public class ErrorViewStructure extends AbstractTreeStructure { return myRoot; } + public boolean hasMessages(@NotNull Set kinds) { + synchronized (myLock) { + for (Map.Entry> entry : mySimpleMessages.entrySet()) { + if (kinds.contains(entry.getKey())) { + final List messages = entry.getValue(); + if (messages != null && !messages.isEmpty()) { + return true; + } + } + } + for (Map.Entry> entry : myGroupNameToMessagesMap.entrySet()) { + final List messages = entry.getValue(); + if (messages != null && !messages.isEmpty()) { + for (NavigatableMessageElement message : messages) { + if (kinds.contains(message.getKind())) { + return true; + } + } + } + } + } + return false; + } + @Override public ErrorTreeElement[] getChildElements(Object element) { if (element == myRoot) { From 5fea3b20828eb5f3ce29d06af7af759567478848 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 30 Jan 2015 18:39:11 +0300 Subject: [PATCH 14/22] DBE-1086 After installing new version of 0xDBE all inspections disappeared --- .../lang-impl/src/com/intellij/ide/scratch/ScratchRootType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchRootType.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchRootType.java index 937fee52279b..2f813722b91d 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchRootType.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchRootType.java @@ -69,7 +69,7 @@ public final class ScratchRootType extends RootType { } } - private static class MyFileType extends LanguageFileType implements FileTypeIdentifiableByVirtualFile, InternalFileType { + private static class MyFileType extends LanguageFileType implements FileTypeIdentifiableByVirtualFile { MyFileType() { super(PlainTextLanguage.INSTANCE); From 9bb37a8cf5f393f1de539b144e3407c7af26b832 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Fri, 30 Jan 2015 18:04:01 +0300 Subject: [PATCH 15/22] dots --- .../projectModel-impl/src/messages/ProjectBundle.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/projectModel-impl/src/messages/ProjectBundle.properties b/platform/projectModel-impl/src/messages/ProjectBundle.properties index b971ee325fec..4b31b4aaca45 100644 --- a/platform/projectModel-impl/src/messages/ProjectBundle.properties +++ b/platform/projectModel-impl/src/messages/ProjectBundle.properties @@ -114,7 +114,7 @@ jdk.combo.box.project.item= jdk.combo.box.none.item= jdk.combo.box.invalid.item={0} [Invalid] module.libraries.target.jdk.project.radio=&Project SDK:
This SDK is default for all project modules.
\ - A module specific SDK can be configured for each of the modules as required + A module specific SDK can be configured for each of the modules as required. module.libraries.target.jdk.module.radio=&Module SDK: module.libraries.target.jdk.select.title=Select Project SDK module.libraries.javadoc.url.button=Specify Documentation &URL... @@ -263,11 +263,11 @@ project.inherit.compile.output.path=Inherit project compile output path project.module.compile.output.path=Use module compile output path project.compiler.output=Project compiler output:
This path is used to store all project compilation results.
\ A directory corresponding to each module is created under this path.
This directory contains two subdirectories: Production and Test for production code and test sources, respectively.
\ - A module specific compiler output path can be configured for each of the modules as required + A module specific compiler output path can be configured for each of the modules as required. find.usages.action.text=Find Usages dependencies.used.in.popup.title=Used in project.language.level=Project language level:
This language level is default for all project modules.
\ - A module specific language level can be configured for each of the modules as required + A module specific language level can be configured for each of the modules as required. classpath.panel.analyze=Analyze classpath.panel.navigate.action.text=Navigate output.tab.title=Output From 7c7b47bcf982629c1cb6565686bda2e565e8c81c Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Fri, 30 Jan 2015 19:00:07 +0300 Subject: [PATCH 16/22] IDEA-47243 Project structure / Modules / a module / Sources tab: "Language level" combo does not react on assigned mnemonic 'L' --- .../roots/ui/configuration/LanguageLevelConfigurable.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java index 1ed84cda2c7f..a22242f4093a 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java @@ -46,7 +46,9 @@ public abstract class LanguageLevelConfigurable implements UnnamedConfigurable { }); myLanguageLevelCombo.insertItemAt(LanguageLevelCombo.USE_PROJECT_LANGUAGE_LEVEL, 0); - myPanel.add(new JLabel(ProjectBundle.message("module.module.language.level")), + JLabel label = new JLabel(ProjectBundle.message("module.module.language.level")); + label.setLabelFor(myLanguageLevelCombo); + myPanel.add(label, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(12, 6, 12, 0), 0, 0)); myPanel.add(myLanguageLevelCombo, new GridBagConstraints(1, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(6, 6, 12, 0), 0, 0)); From 4ee0f0013a13d2cf5a73a47731c4571b7dba6cb0 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 30 Jan 2015 19:19:15 +0300 Subject: [PATCH 17/22] Do not show popup in case of one script engine --- .../console/RunIdeConsoleAction.java | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/console/RunIdeConsoleAction.java b/platform/lang-impl/src/com/intellij/execution/console/RunIdeConsoleAction.java index 7a65062fe33c..78451fe4580e 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/RunIdeConsoleAction.java +++ b/platform/lang-impl/src/com/intellij/execution/console/RunIdeConsoleAction.java @@ -30,9 +30,9 @@ import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.TextEditor; -import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; @@ -58,7 +58,7 @@ import java.util.Map; /** * @author gregsh */ -public class RunIdeConsoleAction extends ActionGroup implements DumbAware { +public class RunIdeConsoleAction extends DumbAwareAction { private static final String DEFAULT_FILE_NAME = "ide-scripting"; private static final Key> CONSOLE_VIEW_KEY = Key.create("CONSOLE_VIEW_KEY"); @@ -84,26 +84,23 @@ public class RunIdeConsoleAction extends ActionGroup implements DumbAware { runConsole(e, ourEngines.values().iterator().next()); } else { - super.actionPerformed(e); - } - } - - @NotNull - @Override - public AnAction[] getChildren(@Nullable AnActionEvent e) { - if (e == null) return EMPTY_ARRAY; - return ContainerUtil.map2Array(ourEngines.values(), AnAction.class, new NotNullFunction() { - @NotNull - @Override - public AnAction fun(final ScriptEngineFactory engine) { - return new AnAction(engine.getLanguageName()) { + DefaultActionGroup actions = new DefaultActionGroup( + ContainerUtil.map(ourEngines.values(), new NotNullFunction() { + @NotNull @Override - public void actionPerformed(@NotNull AnActionEvent e) { - runConsole(e, engine); + public AnAction fun(final ScriptEngineFactory engine) { + return new AnAction(engine.getLanguageName()) { + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + runConsole(e, engine); + } + }; } - }; - } - }); + }) + ); + JBPopupFactory.getInstance().createActionGroupPopup("Script Engine", actions, e.getDataContext(), JBPopupFactory.ActionSelectionAid.NUMBERING, false). + showInBestPositionFor(e.getDataContext()); + } } protected void runConsole(@NotNull AnActionEvent e, @NotNull ScriptEngineFactory engine) { From a78c56c2a15bdd34dcd7c4dbef9c9f3242b1fa11 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 30 Jan 2015 19:38:39 +0300 Subject: [PATCH 18/22] proxy should be equal to itself --- platform/util/src/com/intellij/execution/rmi/RemoteUtil.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java b/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java index 9480a02ab81e..6ec4a1ef09a0 100644 --- a/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java +++ b/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java @@ -219,6 +219,8 @@ public class RemoteUtil { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getDeclaringClass() == Object.class) { + if ("equals".equals(method.getName())) return proxy == args[0]; + if ("hashCode".equals(method.getName())) return hashCode(); return method.invoke(myRemote, args); } else { From d972a0e47e05b91d056d04564a36fe7d1d8a1256 Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Fri, 30 Jan 2015 19:58:26 +0300 Subject: [PATCH 19/22] CPP-2091 Illogical behavior of copy-paste on the CMake page of the Settings/Preferences dialog --- .../execution/util/EnvVariablesTable.java | 16 ++-- .../execution/util/ListTableWithButtons.java | 75 ++++++++++++------- 2 files changed, 57 insertions(+), 34 deletions(-) diff --git a/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java b/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java index 8a355d263a07..552d7563a2f2 100644 --- a/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java +++ b/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java @@ -143,7 +143,7 @@ public class EnvVariablesTable extends ListTableWithButtons public void actionPerformed(@NotNull AnActionEvent e) { stopEditing(); StringBuilder sb = new StringBuilder(); - List variables = getEnvironmentVariables(); + List variables = getSelection(); for (EnvironmentVariable environmentVariable : variables) { if (environmentVariable.getIsPredefined() || isEmpty(environmentVariable)) continue; if (sb.length() > 0) sb.append('\n'); @@ -152,10 +152,16 @@ public class EnvVariablesTable extends ListTableWithButtons } CopyPasteManager.getInstance().setContents(new StringSelection(sb.toString())); } + + @Override + public boolean isEnabled() { + return super.isEnabled() && !getSelection().isEmpty(); + } }; AnActionButton pasteButton = new AnActionButton(ActionsBundle.message("action.EditorPaste.text"), AllIcons.Actions.Menu_paste) { @Override public void actionPerformed(@NotNull AnActionEvent e) { + removeSelected(); stopEditing(); String content = CopyPasteManager.getInstance().getContents(DataFlavor.stringFlavor); if (content == null || !content.contains("=")) return; @@ -172,13 +178,7 @@ public class EnvVariablesTable extends ListTableWithButtons StringUtil.unescapeStringCharacters(line.substring(pos + 1)), false)); } - List variables = - new ArrayList(ContainerUtil.filter(getEnvironmentVariables(), new Condition() { - @Override - public boolean value(EnvironmentVariable variable) { - return variable.getIsPredefined(); - } - })); + List variables = new ArrayList(getEnvironmentVariables()); variables.addAll(parsed); setValues(variables); } diff --git a/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java b/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java index 71ed67719cb9..5ea5a2ae5ac7 100644 --- a/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java +++ b/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java @@ -16,6 +16,7 @@ package com.intellij.execution.util; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.util.Condition; import com.intellij.ui.*; import com.intellij.ui.table.TableView; import com.intellij.util.containers.ContainerUtil; @@ -30,6 +31,7 @@ import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Observable; @@ -110,31 +112,19 @@ public abstract class ListTableWithButtons extends Observable { }).setRemoveAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { - myTableView.stopEditing(); - setModified(); - T selected = getSelection(); - if (selected != null) { - int selectedIndex = myElements.indexOf(selected); - myTableView.scrollRectToVisible(myTableView.getCellRect(selectedIndex, 0, true)); - myElements.remove(selected); - myTableView.getTableViewModel().setItems(myElements); - - int prev = selectedIndex - 1; - if (prev >= 0) { - myTableView.getComponent().getSelectionModel().setSelectionInterval(prev, prev); - } - else if (selectedIndex < myElements.size()) { - myTableView.getComponent().getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex); - } - } + removeSelected(); } }).disableUpDownActions().addExtraActions(createExtraActions()).createPanel(); ToolbarDecorator.findRemoveButton(myPanel).addCustomUpdater(new AnActionButtonUpdater() { @Override public boolean isEnabled(AnActionEvent e) { - T selection = getSelection(); - return selection != null && myIsEnabled && canDeleteElement(selection); + List selection = getSelection(); + if (selection.isEmpty() || !myIsEnabled) return false; + for (T t : selection) { + if (!canDeleteElement(t)) return false; + } + return true; } }); ToolbarDecorator.findAddButton(myPanel).addCustomUpdater(new AnActionButtonUpdater() { @@ -146,7 +136,33 @@ public abstract class ListTableWithButtons extends Observable { myActionsPanel = decorator.getActionsPanel(); - myTableView.getComponent().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myTableView.getComponent().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + } + + protected void removeSelected() { + List selected = getSelection(); + if (!selected.isEmpty()) { + myTableView.stopEditing(); + setModified(); + int selectedIndex = myTableView.getSelectionModel().getLeadSelectionIndex(); + myTableView.scrollRectToVisible(myTableView.getCellRect(selectedIndex, 0, true)); + selected = ContainerUtil.filter(selected, new Condition() { + @Override + public boolean value(T t) { + return canDeleteElement(t); + } + }); + myElements.removeAll(selected); + myTableView.getTableViewModel().setItems(myElements); + + int prev = selectedIndex - 1; + if (prev >= 0) { + myTableView.getComponent().getSelectionModel().setSelectionInterval(prev, prev); + } + else if (selectedIndex < myElements.size()) { + myTableView.getComponent().getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex); + } + } } @NotNull @@ -197,7 +213,9 @@ public abstract class ListTableWithButtons extends Observable { } protected void editSelection(int column) { - int row = myElements.indexOf(getSelection()); + List selection = getSelection(); + if (selection.size() != 1) return; + int row = myElements.indexOf(selection.get(0)); if (row != -1) { TableUtil.editCellAt(myTableView, row, column); } @@ -213,13 +231,18 @@ public abstract class ListTableWithButtons extends Observable { } - protected T getSelection() { - int selIndex = myTableView.getComponent().getSelectionModel().getMinSelectionIndex(); - if (selIndex < 0) { - return null; + @NotNull + protected List getSelection() { + int[] selection = myTableView.getComponent().getSelectedRows(); + if (selection.length == 0) { + return Collections.emptyList(); } else { - return myElements.get(selIndex); + List result = new ArrayList(selection.length); + for (int row : selection) { + result.add(myElements.get(row)); + } + return result; } } From b065d4c6d6db2d1682ec2d1c6ab54475062952b1 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 30 Jan 2015 17:53:25 +0100 Subject: [PATCH 20/22] IDEA-135805 help ID for the Problems wool window --- .../impl/src/com/intellij/compiler/impl/ProblemsViewPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewPanel.java b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewPanel.java index 618774541686..393b85f1424b 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewPanel.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewPanel.java @@ -21,7 +21,7 @@ import com.intellij.openapi.project.Project; public class ProblemsViewPanel extends NewErrorTreeViewPanel { public ProblemsViewPanel(Project project) { - super(project, null, false, true, null); + super(project, "reference.problems.tool.window", false, true, null); myTree.getEmptyText().setText("No compilation problems found"); } From 5d239ebe28a0648cbf4b042ccecf59f89c28135e Mon Sep 17 00:00:00 2001 From: Alexander Chernikov Date: Fri, 30 Jan 2015 20:30:42 +0300 Subject: [PATCH 21/22] JIRA 4 test server has been moved. --- .../com/intellij/tasks/integration/JiraIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java index a3d99c33228c..a91983706af7 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java @@ -47,7 +47,7 @@ public class JiraIntegrationTest extends TaskManagerTestCase { /** * JIRA 4.4.5, REST API 2.0.alpha1 */ - @NonNls private static final String JIRA_4_TEST_SERVER_URL = "http://trackers-tests.labs.intellij.net:8014"; + @NonNls private static final String JIRA_4_TEST_SERVER_URL = "http://idea-qa-task-2.labs.intellij.net:8014"; /** * JIRA 5.0.6, REST API 2.0 */ From 8790a30a92ecc15767e5028952f3db0c1926a5e8 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 30 Jan 2015 20:42:47 +0300 Subject: [PATCH 22/22] fire 'rootsChanged' event when project language level is changed --- .../daemon/impl/analysis/IncreaseLanguageLevelFix.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/IncreaseLanguageLevelFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/IncreaseLanguageLevelFix.java index e7c1e5b955a9..87867565f63a 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/IncreaseLanguageLevelFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/IncreaseLanguageLevelFix.java @@ -27,6 +27,8 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.JdkVersionUtil; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.PsiFile; @@ -96,6 +98,7 @@ public class IncreaseLanguageLevelFix implements IntentionAction { } else { LanguageLevelProjectExtension.getInstance(project).setLanguageLevel(myLevel); + ProjectRootManagerEx.getInstanceEx(project).makeRootsChange(EmptyRunnable.INSTANCE, false, true); } }