From 9e6ffde4020cdd4685ce0df95e74232a734c7f61 Mon Sep 17 00:00:00 2001 From: Sergey Savenko Date: Tue, 29 Sep 2015 15:51:29 +0300 Subject: [PATCH 01/50] Extract an interface for search sessions (a facade for actions) --- .../find/FindInEditorMultiCaretTest.java | 4 +- .../intellij/find/EditorSearchSession.java | 88 +++++++------------ .../src/com/intellij/find/FindUtil.java | 11 +++ .../intellij/find/SearchReplaceComponent.java | 16 ++-- .../src/com/intellij/find/SearchSession.java | 38 ++++++++ .../EditorHeaderSetSearchContextAction.java | 6 +- .../EditorHeaderToggleAction.java | 10 +-- .../NextOccurrenceAction.java | 11 ++- .../PrevNextOccurrenceAction.java | 26 ++---- .../PrevOccurrenceAction.java | 11 ++- .../editorHeaderActions/StatusTextAction.java | 7 +- .../editorHeaderActions/ToggleMatchCase.java | 6 +- .../TogglePreserveCaseAction.java | 5 +- .../find/editorHeaderActions/ToggleRegex.java | 6 +- .../ToggleSelectionOnlyAction.java | 5 +- .../ToggleWholeWordsOnlyAction.java | 8 +- 16 files changed, 139 insertions(+), 119 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/find/SearchSession.java diff --git a/java/java-tests/testSrc/com/intellij/find/FindInEditorMultiCaretTest.java b/java/java-tests/testSrc/com/intellij/find/FindInEditorMultiCaretTest.java index 65d04a22dfb1..a8c4f255248b 100644 --- a/java/java-tests/testSrc/com/intellij/find/FindInEditorMultiCaretTest.java +++ b/java/java-tests/testSrc/com/intellij/find/FindInEditorMultiCaretTest.java @@ -148,11 +148,11 @@ public class FindInEditorMultiCaretTest extends LightPlatformCodeInsightFixtureT } private void nextOccurrence() { - executeHeaderAction(EditorSearchSession.createNextOccurrenceAction()); + executeHeaderAction(new NextOccurrenceAction()); } private void prevOccurrence() { - executeHeaderAction(EditorSearchSession.createPrevOccurrenceAction()); + executeHeaderAction(new PrevOccurrenceAction()); } private void addOccurrence() { diff --git a/platform/lang-impl/src/com/intellij/find/EditorSearchSession.java b/platform/lang-impl/src/com/intellij/find/EditorSearchSession.java index d3ac3f723c29..fb7c4f3237ab 100644 --- a/platform/lang-impl/src/com/intellij/find/EditorSearchSession.java +++ b/platform/lang-impl/src/com/intellij/find/EditorSearchSession.java @@ -51,7 +51,8 @@ import java.util.regex.Pattern; /** * @author max, andrey.zaytsev */ -public class EditorSearchSession implements DataProvider, +public class EditorSearchSession implements SearchSession, + DataProvider, SelectionListener, SearchResults.SearchResultsListener, SearchReplaceComponent.Listener { @@ -87,8 +88,8 @@ public class EditorSearchSession implements DataProvider, myComponent = SearchReplaceComponent .buildFor(project, myEditor.getContentComponent()) - .addPrimarySearchActions(createPrevOccurrenceAction(), - createNextOccurrenceAction(), + .addPrimarySearchActions(new PrevOccurrenceAction(), + new NextOccurrenceAction(), new FindAllAction(), new Separator(), new AddOccurrenceAction(), @@ -111,8 +112,8 @@ public class EditorSearchSession implements DataProvider, new ExcludeAction()) .addExtraReplaceAction(new TogglePreserveCaseAction(), new ToggleSelectionOnlyAction()) - .addReplaceFieldActions(createPrevOccurrenceAction(), - createNextOccurrenceAction()) + .addReplaceFieldActions(new PrevOccurrenceAction(), + new NextOccurrenceAction()) .withDataProvider(this) .withCloseAction(new Runnable() { @Override @@ -160,7 +161,7 @@ public class EditorSearchSession implements DataProvider, } updateUIWithFindModel(); updateResults(true); - syncFindModels(FindManager.getInstance(getProject()).getFindInFileModel(), myFindModel); + FindUtil.updateFindInFileModel(getProject(), myFindModel); } }); @@ -194,6 +195,7 @@ public class EditorSearchSession implements DataProvider, } @NotNull + @Override public SearchReplaceComponent getComponent() { return myComponent; } @@ -219,6 +221,9 @@ public class EditorSearchSession implements DataProvider, @Override @Nullable public Object getData(@NonNls final String dataId) { + if (SearchSession.KEY.is(dataId)) { + return this; + } if (SESSION_KEY.is(dataId)) { return this; } @@ -289,18 +294,27 @@ public class EditorSearchSession implements DataProvider, myFindModel.setMultiline(myComponent.isMultiline()); } + @NotNull + @Override public FindModel getFindModel() { return myFindModel; } - private static void syncFindModels(FindModel to, FindModel from) { - to.setCaseSensitive(from.isCaseSensitive()); - to.setWholeWordsOnly(from.isWholeWordsOnly()); - to.setRegularExpressions(from.isRegularExpressions()); - to.setSearchContext(from.getSearchContext()); - if (from.isReplaceState()) { - to.setPreserveCase(from.isPreserveCase()); - } + @Override + public boolean hasMatches() { + return mySearchResults != null && mySearchResults.hasMatches(); + } + + @Override + public void searchForward() { + moveCursor(SearchResults.Direction.DOWN); + addTextToRecent(myComponent.getSearchTextComponent()); + } + + @Override + public void searchBackward() { + moveCursor(SearchResults.Direction.UP); + addTextToRecent(myComponent.getSearchTextComponent()); } public void updateUIWithFindModel() { @@ -332,16 +346,6 @@ public class EditorSearchSession implements DataProvider, } } - public void searchBackward() { - moveCursor(SearchResults.Direction.UP); - addTextToRecent(myComponent.getSearchTextComponent()); - } - - public void searchForward() { - moveCursor(SearchResults.Direction.DOWN); - addTextToRecent(myComponent.getSearchTextComponent()); - } - public void addTextToRecent(JTextComponent textField) { myComponent.addTextToRecent(textField); } @@ -355,6 +359,7 @@ public class EditorSearchSession implements DataProvider, myLivePreviewController.moveCursor(direction); } + @Override public void close() { IdeFocusManager.getInstance(getProject()).requestFocus(myEditor.getContentComponent(), false); @@ -388,7 +393,7 @@ public class EditorSearchSession implements DataProvider, myComponent.setNotFoundBackground(); myClickToHighlightLabel.setVisible(false); mySearchResults.clear(); - myComponent.setStatusText("Incorrect regular expression"); + myComponent.setStatusText(INCORRECT_REGEX_MESSAGE); return; } } @@ -430,10 +435,6 @@ public class EditorSearchSession implements DataProvider, myFindModel.setStringToFind(text); } - public boolean hasMatches() { - return mySearchResults != null && mySearchResults.hasMatches(); - } - public void selectAllOccurrences() { FindUtil.selectSearchResultsInEditor(myEditor, mySearchResults.getOccurrences().iterator(), -1); } @@ -451,27 +452,6 @@ public class EditorSearchSession implements DataProvider, } - @NotNull - static NextOccurrenceAction createNextOccurrenceAction() { - return new NextOccurrenceAction(new PrevNextActionHandler() { - @Override - public void actionPerformed(AnActionEvent e) { - e.getRequiredData(SESSION_KEY).searchForward(); - } - }); - } - - @NotNull - static PrevOccurrenceAction createPrevOccurrenceAction() { - return new PrevOccurrenceAction(new PrevNextActionHandler() { - @Override - public void actionPerformed(AnActionEvent e) { - e.getRequiredData(SESSION_KEY).searchBackward(); - } - }); - } - - private static abstract class ButtonAction extends DumbAwareAction implements CustomComponentAction, ActionListener { private final String myTitle; private final char myMnemonic; @@ -565,12 +545,4 @@ public class EditorSearchSession implements DataProvider, moveCursor(SearchResults.Direction.DOWN); } } - - private static abstract class PrevNextActionHandler implements PrevNextOccurrenceAction.Handler { - @Override - public void update(AnActionEvent e) { - EditorSearchSession search = e.getData(SESSION_KEY); - e.getPresentation().setEnabled(search != null && search.hasMatches()); - } - } } diff --git a/platform/lang-impl/src/com/intellij/find/FindUtil.java b/platform/lang-impl/src/com/intellij/find/FindUtil.java index c70c98615c3e..9830fd669572 100644 --- a/platform/lang-impl/src/com/intellij/find/FindUtil.java +++ b/platform/lang-impl/src/com/intellij/find/FindUtil.java @@ -148,6 +148,17 @@ public class FindUtil { model.setPromptOnReplace(false); } + public static void updateFindInFileModel(@Nullable Project project, @NotNull FindModel with) { + FindModel model = FindManager.getInstance(project).getFindInFileModel(); + model.setCaseSensitive(with.isCaseSensitive()); + model.setWholeWordsOnly(with.isWholeWordsOnly()); + model.setRegularExpressions(with.isRegularExpressions()); + model.setSearchContext(with.getSearchContext()); + if (with.isReplaceState()) { + model.setPreserveCase(with.isPreserveCase()); + } + } + private enum Direction { UP, DOWN } diff --git a/platform/lang-impl/src/com/intellij/find/SearchReplaceComponent.java b/platform/lang-impl/src/com/intellij/find/SearchReplaceComponent.java index aa2ad6e3e504..063396621bf6 100644 --- a/platform/lang-impl/src/com/intellij/find/SearchReplaceComponent.java +++ b/platform/lang-impl/src/com/intellij/find/SearchReplaceComponent.java @@ -57,9 +57,6 @@ import java.util.EventListener; import java.util.List; public class SearchReplaceComponent extends EditorHeaderComponent implements DataProvider { - public static final DataKey COMPONENT_KEY = DataKey.create("search-replace-component"); - public static final DataKey STATUS_TEXT_KEY = DataKey.create("search-replace-status-text"); - private final EventDispatcher myEventDispatcher = EventDispatcher.create(Listener.class); private final MyTextComponentWrapper mySearchFieldWrapper; @@ -90,7 +87,7 @@ public class SearchReplaceComponent extends EditorHeaderComponent implements Dat private final DataProvider myDataProviderDelegate; private boolean myMultilineMode; - private String myStatusText; + private String myStatusText = ""; @NotNull public static Builder buildFor(@Nullable Project project, @NotNull JComponent component) { @@ -225,6 +222,11 @@ public class SearchReplaceComponent extends EditorHeaderComponent implements Dat myStatusText = status; } + @NotNull + public String getStatusText() { + return myStatusText; + } + public void replace() { if (myReplaceAction != null) { myReplaceAction.run(); @@ -258,12 +260,6 @@ public class SearchReplaceComponent extends EditorHeaderComponent implements Dat @Nullable @Override public Object getData(@NonNls String dataId) { - if (STATUS_TEXT_KEY.is(dataId)) { - return myStatusText; - } - if (COMPONENT_KEY.is(dataId)) { - return this; - } if (SpeedSearchSupply.SPEED_SEARCH_CURRENT_QUERY.is(dataId)) { return mySearchTextComponent.getText(); } diff --git a/platform/lang-impl/src/com/intellij/find/SearchSession.java b/platform/lang-impl/src/com/intellij/find/SearchSession.java new file mode 100644 index 000000000000..2f10e7767d3b --- /dev/null +++ b/platform/lang-impl/src/com/intellij/find/SearchSession.java @@ -0,0 +1,38 @@ +/* + * 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 com.intellij.find; + +import com.intellij.openapi.actionSystem.DataKey; +import org.jetbrains.annotations.NotNull; + +public interface SearchSession { + DataKey KEY = DataKey.create("search.replace.session"); + String INCORRECT_REGEX_MESSAGE = "Incorrect regular expression"; + + @NotNull + FindModel getFindModel(); + + @NotNull + SearchReplaceComponent getComponent(); + + boolean hasMatches(); + + void searchForward(); + + void searchBackward(); + + void close(); +} diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderSetSearchContextAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderSetSearchContextAction.java index e8f185a1ad93..022e82599a7b 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderSetSearchContextAction.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderSetSearchContextAction.java @@ -15,8 +15,8 @@ */ package com.intellij.find.editorHeaderActions; -import com.intellij.find.EditorSearchSession; import com.intellij.find.FindModel; +import com.intellij.find.SearchSession; import org.jetbrains.annotations.NotNull; public class EditorHeaderSetSearchContextAction extends EditorHeaderToggleAction { @@ -29,12 +29,12 @@ public class EditorHeaderSetSearchContextAction extends EditorHeaderToggleAction } @Override - protected boolean isSelected(@NotNull EditorSearchSession session) { + protected boolean isSelected(@NotNull SearchSession session) { return session.getFindModel().getSearchContext() == myContext; } @Override - protected void setSelected(@NotNull EditorSearchSession session, boolean selected) { + protected void setSelected(@NotNull SearchSession session, boolean selected) { session.getFindModel().setSearchContext(selected ? myContext : FindModel.SearchContext.ANY); } } diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderToggleAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderToggleAction.java index aea1f7b9a968..1d9af865a8fc 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderToggleAction.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderToggleAction.java @@ -1,6 +1,6 @@ package com.intellij.find.editorHeaderActions; -import com.intellij.find.EditorSearchSession; +import com.intellij.find.SearchSession; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.actionSystem.ex.CheckboxAction; @@ -34,19 +34,19 @@ public abstract class EditorHeaderToggleAction extends CheckboxAction implements @Override public boolean isSelected(AnActionEvent e) { - EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY); + SearchSession search = e.getData(SearchSession.KEY); return search != null && isSelected(search); } @Override public void setSelected(AnActionEvent e, boolean selected) { - EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY); + SearchSession search = e.getData(SearchSession.KEY); if (search != null) { setSelected(search, selected); } } - protected abstract boolean isSelected(@NotNull EditorSearchSession session); + protected abstract boolean isSelected(@NotNull SearchSession session); - protected abstract void setSelected(@NotNull EditorSearchSession session, boolean selected); + protected abstract void setSelected(@NotNull SearchSession session, boolean selected); } diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/NextOccurrenceAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/NextOccurrenceAction.java index 3d393b71ac06..6b97875e1bb8 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/NextOccurrenceAction.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/NextOccurrenceAction.java @@ -15,6 +15,8 @@ */ package com.intellij.find.editorHeaderActions; +import com.intellij.find.SearchSession; +import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonShortcuts; import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.actionSystem.Shortcut; @@ -24,8 +26,13 @@ import org.jetbrains.annotations.NotNull; import java.util.List; public final class NextOccurrenceAction extends PrevNextOccurrenceAction { - public NextOccurrenceAction(@NotNull Handler handler) { - super(IdeActions.ACTION_NEXT_OCCURENCE, handler); + public NextOccurrenceAction() { + super(IdeActions.ACTION_NEXT_OCCURENCE); + } + + @Override + public void actionPerformed(AnActionEvent e) { + e.getRequiredData(SearchSession.KEY).searchForward(); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevNextOccurrenceAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevNextOccurrenceAction.java index 0848c7ec728f..2ca45259c1ae 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevNextOccurrenceAction.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevNextOccurrenceAction.java @@ -15,7 +15,7 @@ */ package com.intellij.find.editorHeaderActions; -import com.intellij.find.SearchReplaceComponent; +import com.intellij.find.SearchSession; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.util.containers.ContainerUtil; @@ -25,28 +25,21 @@ import org.jetbrains.annotations.Nullable; import java.util.List; public abstract class PrevNextOccurrenceAction extends DumbAwareAction implements ContextAwareShortcutProvider { - private final Handler myHandler; - - PrevNextOccurrenceAction(@NotNull String templateActionId, @NotNull Handler handler) { + PrevNextOccurrenceAction(@NotNull String templateActionId) { copyFrom(ActionManager.getInstance().getAction(templateActionId)); - myHandler = handler; } @Override public final void update(AnActionEvent e) { - myHandler.update(e); - } - - @Override - public final void actionPerformed(AnActionEvent e) { - myHandler.actionPerformed(e); + SearchSession search = e.getData(SearchSession.KEY); + e.getPresentation().setEnabled(search != null && search.hasMatches()); } @Nullable @Override public final ShortcutSet getShortcut(@NotNull DataContext context) { - SearchReplaceComponent searchComponent = SearchReplaceComponent.COMPONENT_KEY.getData(context); - boolean singleLine = searchComponent != null && !searchComponent.isMultiline(); + SearchSession search = SearchSession.KEY.getData(context); + boolean singleLine = search != null && !search.getFindModel().isMultiline(); return Utils.shortcutSetOf(singleLine ? ContainerUtil.concat(getDefaultShortcuts(), getSingleLineShortcuts()) : getDefaultShortcuts()); } @@ -55,11 +48,4 @@ public abstract class PrevNextOccurrenceAction extends DumbAwareAction implement @NotNull protected abstract List getSingleLineShortcuts(); - - - public interface Handler { - void update(AnActionEvent e); - - void actionPerformed(AnActionEvent e); - } } diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevOccurrenceAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevOccurrenceAction.java index 69fdb153005a..fd2b8264c3ae 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevOccurrenceAction.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevOccurrenceAction.java @@ -15,6 +15,8 @@ */ package com.intellij.find.editorHeaderActions; +import com.intellij.find.SearchSession; +import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.actionSystem.KeyboardShortcut; import com.intellij.openapi.actionSystem.Shortcut; @@ -27,8 +29,13 @@ import java.awt.event.KeyEvent; import java.util.List; public final class PrevOccurrenceAction extends PrevNextOccurrenceAction { - public PrevOccurrenceAction(@NotNull Handler handler) { - super(IdeActions.ACTION_PREVIOUS_OCCURENCE, handler); + public PrevOccurrenceAction() { + super(IdeActions.ACTION_PREVIOUS_OCCURENCE); + } + + @Override + public void actionPerformed(AnActionEvent e) { + e.getRequiredData(SearchSession.KEY).searchBackward(); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/StatusTextAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/StatusTextAction.java index 0e0141c9384e..98d440856b2c 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/StatusTextAction.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/StatusTextAction.java @@ -15,7 +15,7 @@ */ package com.intellij.find.editorHeaderActions; -import com.intellij.find.SearchReplaceComponent; +import com.intellij.find.SearchSession; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.actionSystem.ex.CustomComponentAction; @@ -29,10 +29,11 @@ import java.awt.*; public class StatusTextAction extends DumbAwareAction implements CustomComponentAction { @Override public void update(AnActionEvent e) { - String statusText = e.getData(SearchReplaceComponent.STATUS_TEXT_KEY); + SearchSession search = e.getData(SearchSession.KEY); + String statusText = search == null ? "" : search.getComponent().getStatusText(); JLabel label = (JLabel)e.getPresentation().getClientProperty(CUSTOM_COMPONENT_PROPERTY); if (label != null) { - label.setText(StringUtil.notNullize(statusText)); + label.setText(statusText); label.setVisible(StringUtil.isNotEmpty(statusText)); } } diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleMatchCase.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleMatchCase.java index 62ef6a42803a..69e9bdf9a411 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleMatchCase.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleMatchCase.java @@ -15,8 +15,8 @@ */ package com.intellij.find.editorHeaderActions; -import com.intellij.find.EditorSearchSession; import com.intellij.find.FindSettings; +import com.intellij.find.SearchSession; import org.jetbrains.annotations.NotNull; public class ToggleMatchCase extends EditorHeaderToggleAction { @@ -25,12 +25,12 @@ public class ToggleMatchCase extends EditorHeaderToggleAction { } @Override - protected boolean isSelected(@NotNull EditorSearchSession session) { + protected boolean isSelected(@NotNull SearchSession session) { return session.getFindModel().isCaseSensitive(); } @Override - protected void setSelected(@NotNull EditorSearchSession session, boolean selected) { + protected void setSelected(@NotNull SearchSession session, boolean selected) { session.getFindModel().setCaseSensitive(selected); FindSettings.getInstance().setLocalCaseSensitive(selected); } diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/TogglePreserveCaseAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/TogglePreserveCaseAction.java index 60b4df84521b..9412d6380966 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/TogglePreserveCaseAction.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/TogglePreserveCaseAction.java @@ -17,6 +17,7 @@ package com.intellij.find.editorHeaderActions; import com.intellij.find.EditorSearchSession; import com.intellij.find.FindModel; +import com.intellij.find.SearchSession; import com.intellij.openapi.actionSystem.AnActionEvent; import org.jetbrains.annotations.NotNull; @@ -35,12 +36,12 @@ public class TogglePreserveCaseAction extends EditorHeaderToggleAction { } @Override - protected boolean isSelected(@NotNull EditorSearchSession session) { + protected boolean isSelected(@NotNull SearchSession session) { return session.getFindModel().isPreserveCase(); } @Override - protected void setSelected(@NotNull EditorSearchSession session, boolean selected) { + protected void setSelected(@NotNull SearchSession session, boolean selected) { session.getFindModel().setPreserveCase(selected); } } diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleRegex.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleRegex.java index adbfb1678173..8eae08363699 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleRegex.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleRegex.java @@ -15,9 +15,9 @@ */ package com.intellij.find.editorHeaderActions; -import com.intellij.find.EditorSearchSession; import com.intellij.find.FindModel; import com.intellij.find.FindSettings; +import com.intellij.find.SearchSession; import org.jetbrains.annotations.NotNull; public class ToggleRegex extends EditorHeaderToggleAction { @@ -26,12 +26,12 @@ public class ToggleRegex extends EditorHeaderToggleAction { } @Override - protected boolean isSelected(@NotNull EditorSearchSession session) { + protected boolean isSelected(@NotNull SearchSession session) { return session.getFindModel().isRegularExpressions(); } @Override - protected void setSelected(@NotNull EditorSearchSession session, boolean selected) { + protected void setSelected(@NotNull SearchSession session, boolean selected) { FindModel findModel = session.getFindModel(); findModel.setRegularExpressions(selected); if (selected) { diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleSelectionOnlyAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleSelectionOnlyAction.java index a07dca65159e..098efd68238a 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleSelectionOnlyAction.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleSelectionOnlyAction.java @@ -1,6 +1,7 @@ package com.intellij.find.editorHeaderActions; import com.intellij.find.EditorSearchSession; +import com.intellij.find.SearchSession; import com.intellij.openapi.actionSystem.AnActionEvent; import org.jetbrains.annotations.NotNull; @@ -18,12 +19,12 @@ public class ToggleSelectionOnlyAction extends EditorHeaderToggleAction { } @Override - protected boolean isSelected(@NotNull EditorSearchSession session) { + protected boolean isSelected(@NotNull SearchSession session) { return !session.getFindModel().isGlobal(); } @Override - protected void setSelected(@NotNull EditorSearchSession session, boolean selected) { + protected void setSelected(@NotNull SearchSession session, boolean selected) { session.getFindModel().setGlobal(!selected); } } diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleWholeWordsOnlyAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleWholeWordsOnlyAction.java index 266ec757a895..32dedf0ccef4 100644 --- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleWholeWordsOnlyAction.java +++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleWholeWordsOnlyAction.java @@ -1,7 +1,7 @@ package com.intellij.find.editorHeaderActions; -import com.intellij.find.EditorSearchSession; import com.intellij.find.FindSettings; +import com.intellij.find.SearchSession; import com.intellij.openapi.actionSystem.AnActionEvent; import org.jetbrains.annotations.NotNull; @@ -14,18 +14,18 @@ public class ToggleWholeWordsOnlyAction extends EditorHeaderToggleAction { public void update(AnActionEvent e) { super.update(e); - EditorSearchSession session = e.getData(EditorSearchSession.SESSION_KEY); + SearchSession session = e.getData(SearchSession.KEY); e.getPresentation().setEnabled(session != null && !session.getFindModel().isRegularExpressions()); e.getPresentation().setVisible(session != null && !session.getFindModel().isMultiline()); } @Override - protected boolean isSelected(@NotNull EditorSearchSession session) { + protected boolean isSelected(@NotNull SearchSession session) { return session.getFindModel().isWholeWordsOnly(); } @Override - protected void setSelected(@NotNull EditorSearchSession session, boolean selected) { + protected void setSelected(@NotNull SearchSession session, boolean selected) { FindSettings.getInstance().setLocalWholeWordsOnly(selected); session.getFindModel().setWholeWordsOnly(selected); } From 5a32361145260380f6b6faf19b79bf4b01c6e54a Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 29 Sep 2015 16:55:18 +0300 Subject: [PATCH 02/50] IDEA-142224 fix colored progress bar for people with red-green color blindness --- .../progress/util/ColorProgressBar.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java index 616d3ec0014b..562c9c60d80a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java @@ -15,12 +15,15 @@ */ package com.intellij.openapi.progress.util; +import com.intellij.ide.ui.UISettings; import com.intellij.openapi.ui.GraphicsConfig; import com.intellij.ui.ColorUtil; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; +import com.intellij.util.NotNullProducer; import com.intellij.util.ui.GraphicsUtil; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; @@ -36,8 +39,26 @@ import java.awt.geom.Rectangle2D; public class ColorProgressBar extends JComponent { private static final Dimension PREFERRED_SIZE = new Dimension(146, 17); - public static final Color GREEN = new JBColor(new Color(0x6cad74), new Color(0x4a8c53)); - public static final Color RED = new JBColor(new Color(0xd67b76), new Color(0xe55757)); + public static final Color GREEN = new JBColor(new NotNullProducer() { + @NotNull + @Override + public Color produce() { + UISettings settings = UISettings.getInstance(); + return settings == null || null == settings.COLOR_BLINDNESS + ? new JBColor(new Color(0x6cad74), new Color(0x4a8c53)) + : new JBColor(new Color(0x6ca69c), new Color(0x639990)); + } + }); + public static final Color RED = new JBColor(new NotNullProducer() { + @NotNull + @Override + public Color produce() { + UISettings settings = UISettings.getInstance(); + return settings == null || null == settings.COLOR_BLINDNESS + ? new JBColor(new Color(0xd67b76), new Color(0xe55757)) + : new JBColor(new Color(0xcc7447), new Color(0xcc7447)); + } + }); public static final Color RED_TEXT = new JBColor(new Color(0xb81708), new Color(0xdb5c5c)); public static final Color BLUE = new JBColor(new Color(1, 68, 208), JBColor.blue); public static final Color YELLOW = new JBColor(new Color(0xa67a21), new Color(0x91703a)); From 5f0bd072dfbab4a1d486d1c62d6d237faa0a9a09 Mon Sep 17 00:00:00 2001 From: "Vladimir.Orlov" Date: Tue, 29 Sep 2015 17:04:08 +0300 Subject: [PATCH 03/50] cleanup --- bin/scripts/unix/idea.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/scripts/unix/idea.sh b/bin/scripts/unix/idea.sh index b8f92069856c..934b38612f70 100755 --- a/bin/scripts/unix/idea.sh +++ b/bin/scripts/unix/idea.sh @@ -194,7 +194,7 @@ LD_LIBRARY_PATH="$IDE_BIN_HOME:$LD_LIBRARY_PATH" "$JAVA_BIN" \ EC=$? test $EC -ne 88 && exit $EC if [ -x "$HOME/.@@system_selector@@/restart/restarter.sh" ]; then - $HOME/.@@system_selector@@/restart/restarter.sh + "$HOME/.@@system_selector@@/restart/restarter.sh" "$RM" -f "$HOME/.@@system_selector@@/restart/restarter.sh" fi exec "$0" "$@" From 7cdb72ebadc327cba2fd2a47c3c74938f9f5b122 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 29 Sep 2015 16:07:08 +0200 Subject: [PATCH 04/50] Cleanup (common code extracted) --- .../psi/impl/source/ClassInnerStuffCache.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/ClassInnerStuffCache.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/ClassInnerStuffCache.java index 544925856a52..b770f5839835 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/ClassInnerStuffCache.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/ClassInnerStuffCache.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. @@ -139,11 +139,8 @@ public class ClassInnerStuffCache { @Nullable @Override public Result compute() { - PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory(); String text = "public static " + myClass.getName() + "[] values() { }"; - PsiMethod physicalMethod = factory.createMethodFromText(text, myClass); - PsiMethod method = new LightMethod(myClass.getManager(), physicalMethod, myClass); - return new Result(method, OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker); + return new Result(getSyntheticMethod(text), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker); } }); } @@ -154,11 +151,8 @@ public class ClassInnerStuffCache { @Nullable @Override public Result compute() { - PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory(); String text = "public static " + myClass.getName() + " valueOf(java.lang.String name) throws java.lang.IllegalArgumentException { }"; - PsiMethod physicalMethod = factory.createMethodFromText(text, myClass); - PsiMethod method = new LightMethod(myClass.getManager(), physicalMethod, myClass); - return new Result(method, OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker); + return new Result(getSyntheticMethod(text), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker); } }); } @@ -236,6 +230,12 @@ public class ClassInnerStuffCache { return cachedInners; } + private PsiMethod getSyntheticMethod(String text) { + PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory(); + PsiMethod method = factory.createMethodFromText(text, myClass); + return new LightMethod(myClass.getManager(), method, myClass); + } + public void dropCaches() { myTracker.incModificationCount(); } From f9604de719049dce0c0cb55fcd5775cfa6f4a652 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Tue, 29 Sep 2015 17:13:12 +0300 Subject: [PATCH 05/50] OC-12377 Completion is missing for keywords inside guard statement --- .../com/intellij/patterns/PsiElementPattern.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/platform/core-api/src/com/intellij/patterns/PsiElementPattern.java b/platform/core-api/src/com/intellij/patterns/PsiElementPattern.java index 61904cf83ae7..5d4599feb32d 100644 --- a/platform/core-api/src/com/intellij/patterns/PsiElementPattern.java +++ b/platform/core-api/src/com/intellij/patterns/PsiElementPattern.java @@ -339,6 +339,19 @@ public abstract class PsiElementPattern("withLastChildSkipping") { + @Override + public boolean accepts(@NotNull T t, ProcessingContext context) { + PsiElement last = t.getLastChild(); + while (last != null && skip.accepts(last)) { + last = last.getPrevSibling(); + } + return pattern.accepts(last); + } + }); + } + public static class Capture extends PsiElementPattern> { protected Capture(final Class aClass) { From 959a005b0851767a4c96a74583aed6b5db56e1cf Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 29 Sep 2015 17:24:14 +0300 Subject: [PATCH 06/50] enabled thread blocked monitor --- .../debugger/engine/DebugProcessImpl.java | 4 +++- .../debugger/engine/ThreadBlockedMonitor.java | 23 +++++++++++++++---- .../util/resources/misc/registry.properties | 2 +- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java index 6e861e88b7ae..d78a9a07cf1b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -158,7 +158,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb myDebugProcessDispatcher.addListener(new DebugProcessAdapter() { @Override public void paused(SuspendContext suspendContext) { - myThreadBlockedMonitor.stopWatching(suspendContext.getThread()); + myThreadBlockedMonitor.stopWatching( + suspendContext.getSuspendPolicy() != EventRequest.SUSPEND_ALL ? suspendContext.getThread() : null); } }); } @@ -2143,6 +2144,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb // } //} + @NotNull public DebuggerContextImpl getDebuggerContext() { return mySession.getContextManager().getContext(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/ThreadBlockedMonitor.java b/java/debugger/impl/src/com/intellij/debugger/engine/ThreadBlockedMonitor.java index 7475e3bbd6da..43b0dd2cfc20 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/ThreadBlockedMonitor.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/ThreadBlockedMonitor.java @@ -24,6 +24,7 @@ import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; import com.intellij.notification.NotificationType; import com.intellij.openapi.Disposable; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.registry.Registry; import com.intellij.util.Alarm; import com.intellij.util.SingleAlarm; @@ -42,6 +43,8 @@ import java.util.HashSet; * @author egor */ public class ThreadBlockedMonitor { + private static final Logger LOG = Logger.getInstance(ThreadBlockedMonitor.class); + private final Collection myWatchedThreads = new HashSet(); private final SingleAlarm myAlarm; @@ -71,14 +74,17 @@ public class ThreadBlockedMonitor { if (thread != null) { myWatchedThreads.remove(thread); } + else { + myWatchedThreads.clear(); + } if (myWatchedThreads.isEmpty()) { myAlarm.cancel(); } } - private void onThreadBlocked(@NotNull final ThreadReference blockedThread, - @NotNull final ThreadReference blockingThread, - final DebugProcessImpl process) { + private static void onThreadBlocked(@NotNull final ThreadReference blockedThread, + @NotNull final ThreadReference blockingThread, + final DebugProcessImpl process) { XDebugSessionImpl.NOTIFICATION_GROUP.createNotification( DebuggerBundle.message("status.thread.blocked.by", blockedThread.name(), blockingThread.name()), DebuggerBundle.message("status.thread.blocked.by.resume", blockingThread.name()), @@ -101,6 +107,11 @@ public class ThreadBlockedMonitor { }).notify(process.getProject()); } + private ThreadReference getCurrentThread() { + ThreadReferenceProxyImpl threadProxy = myProcess.getDebuggerContext().getThreadProxy(); + return threadProxy != null ? threadProxy.getThreadReference() : null; + } + private void checkBlockingThread() { myProcess.getManagerThread().schedule(new DebuggerCommandImpl() { @Override @@ -115,14 +126,16 @@ public class ThreadBlockedMonitor { vmProxy.canGetCurrentContendedMonitor() ? thread.getThreadReference().currentContendedMonitor() : null; if (waitedMonitor != null && vmProxy.canGetMonitorInfo()) { ThreadReference blockingThread = waitedMonitor.owningThread(); - if (blockingThread != null) { + if (blockingThread != null + && blockingThread.suspendCount() > 1 + && getCurrentThread() != blockingThread) { onThreadBlocked(thread.getThreadReference(), blockingThread, myProcess); } } } } catch (IncompatibleThreadStateException e) { - e.printStackTrace(); + LOG.info(e); } finally { vmProxy.getVirtualMachine().resume(); diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 4313874d6b86..723472a0bd68 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -199,7 +199,7 @@ debugger.close.dialog.on.navigate=true debugger.close.dialog.on.navigate.description=Close evaluate dialog on Jump to (type) source action debugger.async.smart.step.into=true debugger.async.smart.step.into.description=Smart step into anonymous class methods in any thread -debugger.monitor.blocked.threads=false +debugger.monitor.blocked.threads=true debugger.monitor.blocked.threads.description=Watch if a thread we do stepping in is blocked by another suspended thread analyze.exceptions.on.the.fly=false From 45493adfd24c61ee2ea551435d0f138e8c3137bb Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 28 Sep 2015 17:36:51 +0300 Subject: [PATCH 07/50] set conda default location creating conda env --- .../python/sdk/AbstractCreateVirtualEnvDialog.java | 2 +- .../com/jetbrains/python/sdk/CreateCondaEnvDialog.java | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/sdk/AbstractCreateVirtualEnvDialog.java b/python/src/com/jetbrains/python/sdk/AbstractCreateVirtualEnvDialog.java index ec069ff17c47..fe0d9e50fc71 100644 --- a/python/src/com/jetbrains/python/sdk/AbstractCreateVirtualEnvDialog.java +++ b/python/src/com/jetbrains/python/sdk/AbstractCreateVirtualEnvDialog.java @@ -128,7 +128,7 @@ public abstract class AbstractCreateVirtualEnvDialog extends IdeaDialog { new LocationNameFieldsBinding(project, myDestination, myName, myInitialPath, "Select Location for Virtual Environment"); } - private void setInitialDestination() { + protected void setInitialDestination() { myInitialPath = ""; final VirtualFile file = VirtualEnvSdkFlavor.getDefaultLocation(); diff --git a/python/src/com/jetbrains/python/sdk/CreateCondaEnvDialog.java b/python/src/com/jetbrains/python/sdk/CreateCondaEnvDialog.java index e1f74649d843..37c9620424ab 100644 --- a/python/src/com/jetbrains/python/sdk/CreateCondaEnvDialog.java +++ b/python/src/com/jetbrains/python/sdk/CreateCondaEnvDialog.java @@ -20,9 +20,11 @@ import com.intellij.facet.ui.FacetValidatorsManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.ui.ComboBox; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.CollectionComboBoxModel; import com.intellij.ui.components.JBLabel; import com.jetbrains.python.packaging.PyCondaPackageManagerImpl; +import com.jetbrains.python.sdk.flavors.VirtualEnvSdkFlavor; import com.jetbrains.python.validation.UnsupportedFeaturesUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -55,6 +57,14 @@ public class CreateCondaEnvDialog extends AbstractCreateVirtualEnvDialog { checkValid(); } + @Override + protected void setInitialDestination() { + final List locations = VirtualEnvSdkFlavor.getCondaDefaultLocations(); + if (!locations.isEmpty()) { + myInitialPath = locations.get(0).getPath(); + } + } + protected void layoutPanel(final List allSdks) { final GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; From d9a2e8324cc6f4d6d15fed39f8c3d99e87202c62 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 28 Sep 2015 18:42:27 +0300 Subject: [PATCH 08/50] removed unused code --- .../python/packaging/ui/PyCondaManagementService.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/python/src/com/jetbrains/python/packaging/ui/PyCondaManagementService.java b/python/src/com/jetbrains/python/packaging/ui/PyCondaManagementService.java index 53ac6835f92a..3b96f2ac9550 100644 --- a/python/src/com/jetbrains/python/packaging/ui/PyCondaManagementService.java +++ b/python/src/com/jetbrains/python/packaging/ui/PyCondaManagementService.java @@ -18,7 +18,6 @@ package com.jetbrains.python.packaging.ui; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.util.CatchingConsumer; -import com.intellij.webcore.packaging.InstalledPackage; import com.intellij.webcore.packaging.PackageVersionComparator; import com.intellij.webcore.packaging.RepoPackage; import com.jetbrains.python.packaging.PyCondaPackageService; @@ -71,8 +70,4 @@ public class PyCondaManagementService extends PyPackageManagementService { consumer.consume(versions); } - @Override - public void uninstallPackages(List installedPackages, Listener listener) { - super.uninstallPackages(installedPackages, listener); - } } From 9dace3b92a5b947f1e15efe4b98f9feba51958e4 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 28 Sep 2015 18:45:01 +0300 Subject: [PATCH 09/50] can't find conda package location --- .../jetbrains/python/packaging/PyCondaPackageManagerImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/packaging/PyCondaPackageManagerImpl.java b/python/src/com/jetbrains/python/packaging/PyCondaPackageManagerImpl.java index ee9a62cd868d..30d6f9d2b8ce 100644 --- a/python/src/com/jetbrains/python/packaging/PyCondaPackageManagerImpl.java +++ b/python/src/com/jetbrains/python/packaging/PyCondaPackageManagerImpl.java @@ -147,7 +147,6 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl { } final String name = fields.get(0); final String version = fields.get(1); - final String location = fields.get(2); final List requirements = new ArrayList(); if (fields.size() >= 4) { final String requiresLine = fields.get(3); @@ -155,7 +154,7 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl { requirements.addAll(PyRequirement.parse(requiresSpec)); } if (!"Python".equals(name)) { - packages.add(new PyPackage(name, version, location, requirements)); + packages.add(new PyPackage(name, version, "", requirements)); } } return packages; From 96f4fad199007b265872a2fba434aed357c8ecac Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Tue, 29 Sep 2015 12:30:47 +0300 Subject: [PATCH 10/50] manage conda channels --- .../packaging/PyCondaPackageManagerImpl.java | 3 +- .../packaging/PyCondaPackageService.java | 16 ++++++ .../ui/PyCondaManagementService.java | 56 ++++++++++++++++++- .../python/sdk/PythonSdkDetailsStep.java | 4 +- 4 files changed, 73 insertions(+), 6 deletions(-) diff --git a/python/src/com/jetbrains/python/packaging/PyCondaPackageManagerImpl.java b/python/src/com/jetbrains/python/packaging/PyCondaPackageManagerImpl.java index 30d6f9d2b8ce..4b0357889f39 100644 --- a/python/src/com/jetbrains/python/packaging/PyCondaPackageManagerImpl.java +++ b/python/src/com/jetbrains/python/packaging/PyCondaPackageManagerImpl.java @@ -171,8 +171,7 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl { @NotNull public static String createVirtualEnv(@NotNull String destinationDir, String version) throws ExecutionException { - final String condaName = SystemInfo.isWindows ? "conda.exe" : "conda"; - final String condaExecutable = PyCondaPackageService.getCondaExecutable(condaName); + final String condaExecutable = PyCondaPackageService.getCondaExecutable(); if (condaExecutable == null) throw new PyExecutionException("Cannot find conda", "Conda", Collections.emptyList(), new ProcessOutput()); final ArrayList parameters = Lists.newArrayList(condaExecutable, "create", "-p", destinationDir, diff --git a/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java b/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java index ae79f64e5e5c..406be20c982f 100644 --- a/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java +++ b/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java @@ -79,12 +79,28 @@ public class PyCondaPackageService implements PersistentStateComponent parameters = Lists.newArrayList(conda, "config", "--add", "channels", repositoryUrl, "--force"); + final GeneralCommandLine commandLine = new GeneralCommandLine(parameters); + + try { + final Process process = commandLine.createProcess(); + final CapturingProcessHandler handler = new CapturingProcessHandler(process); + final ProcessOutput result = handler.runProcess(); + final int exitCode = result.getExitCode(); + if (exitCode != 0) { + final String message = StringUtil.isEmptyOrSpaces(result.getStdout()) && StringUtil.isEmptyOrSpaces(result.getStderr()) ? + "Permission denied" : "Non-zero exit code"; + LOG.warn("Failed to add repository " + message); + } + PyCondaPackageService.getInstance().addChannel(repositoryUrl); + } + catch (ExecutionException e) { + LOG.warn("Failed to add repository"); + } + + } + + @Override + public void removeRepository(String repositoryUrl) { + final String conda = PyCondaPackageService.getCondaExecutable(); + final ArrayList parameters = Lists.newArrayList(conda, "config", "--remove", "channels", repositoryUrl, "--force"); + final GeneralCommandLine commandLine = new GeneralCommandLine(parameters); + + try { + final Process process = commandLine.createProcess(); + final CapturingProcessHandler handler = new CapturingProcessHandler(process); + final ProcessOutput result = handler.runProcess(); + final int exitCode = result.getExitCode(); + if (exitCode != 0) { + final String message = StringUtil.isEmptyOrSpaces(result.getStdout()) && StringUtil.isEmptyOrSpaces(result.getStderr()) ? + "Permission denied" : "Non-zero exit code"; + LOG.warn("Failed to remove repository " + message); + } + PyCondaPackageService.getInstance().removeChannel(repositoryUrl); + } + catch (ExecutionException e) { + LOG.warn("Failed to remove repository"); + } + } + @Override public boolean canInstallToUser() { return false; diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java b/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java index bf16c4ee37bb..c66d491f6a7f 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java @@ -37,7 +37,6 @@ import com.intellij.openapi.ui.popup.ListSeparator; import com.intellij.openapi.ui.popup.PopupStep; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.SystemInfo; import com.intellij.util.NullableConsumer; import com.jetbrains.python.PyBundle; import com.jetbrains.python.packaging.PyCondaPackageService; @@ -110,8 +109,7 @@ public class PythonSdkDetailsStep extends BaseListPopupStep { options.add(REMOTE); } options.add(VIRTUALENV); - final String condaName = SystemInfo.isWindows ? "conda.exe" : "conda"; - if (PyCondaPackageService.getCondaExecutable(condaName) != null) { + if (PyCondaPackageService.getCondaExecutable() != null) { options.add(CONDA); } From c1ed72e7e8605d7b05ecd65372844f5779c024a3 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Tue, 29 Sep 2015 15:44:04 +0300 Subject: [PATCH 11/50] find conda on windows --- .../com/jetbrains/python/packaging/PyCondaPackageService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java b/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java index 406be20c982f..d7b8299825bf 100644 --- a/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java +++ b/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java @@ -129,7 +129,7 @@ public class PyCondaPackageService implements PersistentStateComponent Date: Tue, 29 Sep 2015 17:43:48 +0300 Subject: [PATCH 12/50] find conda on windows --- .../packaging/PyCondaPackageManagerImpl.java | 17 +++++++++-------- .../python/packaging/PyCondaPackageService.java | 10 +++++++--- .../python/packaging/PyPackageManagersImpl.java | 4 ++-- .../com/jetbrains/python/sdk/PythonSdkType.java | 2 +- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/python/src/com/jetbrains/python/packaging/PyCondaPackageManagerImpl.java b/python/src/com/jetbrains/python/packaging/PyCondaPackageManagerImpl.java index 4b0357889f39..f597917178f2 100644 --- a/python/src/com/jetbrains/python/packaging/PyCondaPackageManagerImpl.java +++ b/python/src/com/jetbrains/python/packaging/PyCondaPackageManagerImpl.java @@ -50,7 +50,7 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl { @Override public boolean hasManagement(boolean cachedOnly) throws ExecutionException { - return findCondaExecutable(mySdk) != null; + return isCondaVEnv(mySdk); } @Override @@ -74,7 +74,7 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl { } private ProcessOutput getCondaOutput(@NotNull final String command, List arguments) throws ExecutionException { - final String condaExecutable = findCondaExecutable(mySdk); + final String condaExecutable = PyCondaPackageService.getCondaExecutable(); final String path = getCondaDirectory(); if (path == null) throw new PyExecutionException("Empty conda name for " + mySdk, command, arguments); @@ -109,6 +109,7 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl { private String getCondaDirectory() { final VirtualFile homeDirectory = mySdk.getHomeDirectory(); if (homeDirectory == null) return null; + if (SystemInfo.isWindows) return homeDirectory.getParent().getPath(); return homeDirectory.getParent().getParent().getPath(); } @@ -160,13 +161,13 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl { return packages; } - @Nullable - public static String findCondaExecutable(Sdk sdk) { - final String condaName = SystemInfo.isWindows ? "conda.exe" : "conda"; + public static boolean isCondaVEnv(Sdk sdk) { + final String condaName = "conda-meta"; final VirtualFile homeDirectory = sdk.getHomeDirectory(); - if (homeDirectory == null) return null; - final VirtualFile condaExecutable = homeDirectory.getParent().findChild(condaName); - return condaExecutable != null ? condaExecutable.getPath() : null; + if (homeDirectory == null) return false; + final VirtualFile condaExecutable = SystemInfo.isWindows ? homeDirectory.getParent().findChild(condaName) : + homeDirectory.getParent().getParent().findChild(condaName); + return condaExecutable != null; } @NotNull diff --git a/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java b/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java index d7b8299825bf..c3355fa4c0d0 100644 --- a/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java +++ b/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java @@ -131,9 +131,13 @@ public class PyCondaPackageService implements PersistentStateComponent Date: Tue, 29 Sep 2015 17:42:41 +0300 Subject: [PATCH 13/50] [groovy-mvc] synchronizer: re-scheduleRunActions() if snapshot is not up-to-date --- .../plugins/groovy/mvc/MvcModuleStructureSynchronizer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java index c094dbd512ff..8bd5e1723fd6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java @@ -276,7 +276,7 @@ public class MvcModuleStructureSynchronizer extends AbstractProjectComponent { @Override public void computeInReadAction(@NotNull ProgressIndicator indicator) { if (!isUpToDate()) { - indicator.cancel(); + scheduleRunActions(); return; } From f8cdf9eaa16cd86f91251b702391a6997e007e78 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 29 Sep 2015 16:49:57 +0200 Subject: [PATCH 14/50] allow bg dumb mode from ChangeLibraryLevelAction (IDEA-145714) --- .../projectRoot/ChangeLibraryLevelAction.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ChangeLibraryLevelAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ChangeLibraryLevelAction.java index 9cd1fa67c5b4..979b9db7ded1 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ChangeLibraryLevelAction.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ChangeLibraryLevelAction.java @@ -17,6 +17,8 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.DumbModePermission; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.impl.libraries.LibraryEx; import com.intellij.openapi.roots.libraries.Library; @@ -56,18 +58,24 @@ public class ChangeLibraryLevelAction extends ChangeLibraryLevelActionBase { final LibraryProjectStructureElement libraryElement = (LibraryProjectStructureElement)selectedElement; final LibraryEx oldLibrary = (LibraryEx)context.getLibrary(libraryElement.getLibrary().getName(), mySourceConfigurable.getLevel()); LOG.assertTrue(oldLibrary != null); - final Library newLibrary = doCopy(oldLibrary); - if (newLibrary == null) return; - final Collection usages = context.getDaemonAnalyzer().getUsages(libraryElement); - for (ProjectStructureElementUsage usage : usages) { - usage.replaceElement(new LibraryProjectStructureElement(context, newLibrary)); - } + DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() { + @Override + public void run() { + final Library newLibrary = doCopy(oldLibrary); + if (newLibrary == null) return; - if (!myCopy) { - mySourceConfigurable.removeLibrary(libraryElement); - } - ProjectStructureConfigurable.getInstance(myProject).selectProjectOrGlobalLibrary(newLibrary, true); + final Collection usages = context.getDaemonAnalyzer().getUsages(libraryElement); + for (ProjectStructureElementUsage usage : usages) { + usage.replaceElement(new LibraryProjectStructureElement(context, newLibrary)); + } + + if (!myCopy) { + mySourceConfigurable.removeLibrary(libraryElement); + } + ProjectStructureConfigurable.getInstance(myProject).selectProjectOrGlobalLibrary(newLibrary, true); + } + }); } @Override From d9f45ce084fad22b4cf6fccbfd20f15b4587ad02 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 29 Sep 2015 12:20:46 +0200 Subject: [PATCH 15/50] =?UTF-8?q?remove=20deprecated=20methods=20getExtern?= =?UTF-8?q?alInfo/isLocal=20=E2=80=94=20the=20only=20external=20usage=20is?= =?UTF-8?q?=20qaplug=20(we=20in=20contact=20to=20publish=20fixed=20version?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../profile/DefaultProjectProfileManager.java | 23 +++-------------- .../src/com/intellij/profile/Profile.java | 10 +++++--- .../ex/InspectionProfileImpl.java | 10 +------- .../src/com/intellij/profile/ProfileEx.java | 25 +++++-------------- .../testSrc/SchemeManagerTest.kt | 3 --- .../openapi/options/ExternalizableScheme.java | 6 ----- .../options/ExternalizableSchemeAdapter.java | 7 ------ .../colors/impl/EditorColorsSchemeImpl.java | 7 ------ .../header/InspectionToolsConfigurable.java | 3 --- .../fileTypes/impl/AbstractFileType.java | 7 ------ .../vcs/changes/shelf/ShelvedChangeList.java | 12 ++------- 11 files changed, 20 insertions(+), 93 deletions(-) diff --git a/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java b/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java index 65b49bcd2aac..cfcf716c13e0 100644 --- a/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java +++ b/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java @@ -22,8 +22,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.WriteExternalException; import com.intellij.packageDependencies.DependencyValidationManager; import com.intellij.psi.search.scope.packageSet.NamedScopesHolder; import com.intellij.util.ArrayUtil; @@ -104,12 +102,7 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager final Profile projectProfile = myProfiles.get(profile); if (projectProfile != null) { Element profileElement = new Element(PROFILE); - try { - projectProfile.writeExternal(profileElement); - } - catch (WriteExternalException e) { - LOG.error(e); - } + projectProfile.writeExternal(profileElement); boolean hasSmthToSave = sortedProfiles.length > 1 || isCustomProfileUsed(); if (!hasSmthToSave) { for (Element child : profileElement.getChildren()) { @@ -141,16 +134,12 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager for (Element o : state.getChildren(PROFILE)) { Profile profile = myApplicationProfileManager.createProfile(); profile.setProfileManager(this); - try { - profile.readExternal(o); - } - catch (InvalidDataException e) { - LOG.error(e); - } + profile.readExternal(o); profile.setProjectLevel(true); if (profileKeys.contains(profile.getName())) { updateProfile(profile); - } else { + } + else { myProfiles.put(profile.getName(), profile); } } @@ -252,10 +241,6 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager }); } - public void removeProfilesListener(@NotNull ProfileChangeAdapter profilesListener) { - myProfilesListener.remove(profilesListener); - } - public static class ProfileStateSplitter extends MainConfigurationStateSplitter { @NotNull @Override diff --git a/platform/analysis-api/src/com/intellij/profile/Profile.java b/platform/analysis-api/src/com/intellij/profile/Profile.java index 64150f91fbad..7aa2370836b5 100644 --- a/platform/analysis-api/src/com/intellij/profile/Profile.java +++ b/platform/analysis-api/src/com/intellij/profile/Profile.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. @@ -16,14 +16,14 @@ package com.intellij.profile; import com.intellij.openapi.options.Scheme; -import com.intellij.openapi.util.JDOMExternalizable; +import org.jdom.Element; import org.jetbrains.annotations.NotNull; /** * User: anna * Date: 20-Nov-2005 */ -public interface Profile extends JDOMExternalizable, Comparable, Scheme { +public interface Profile extends Comparable, Scheme { void copyFrom(@NotNull Profile profile); void setLocal(boolean isLocal); @@ -48,4 +48,8 @@ public interface Profile extends JDOMExternalizable, Comparable, Scheme { @NotNull ProfileManager getProfileManager(); + + void readExternal(Element element); + + void writeExternal(Element element); } diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java index 263ba488e5e0..f3295fcd50e6 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.codeInspection.ex; import com.intellij.codeHighlighting.HighlightDisplayLevel; @@ -27,7 +26,6 @@ import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.options.ExternalInfo; import com.intellij.openapi.options.ExternalizableScheme; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; @@ -253,7 +251,7 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel, } @Override - public void readExternal(@NotNull Element element) throws InvalidDataException { + public void readExternal(@NotNull Element element) { super.readExternal(element); final String version = element.getAttributeValue(VERSION_TAG); @@ -868,12 +866,6 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel, } } - @Override - @Nullable - public ExternalInfo getExternalInfo() { - return null; - } - @NotNull public List getAllTools(Project project) { initInspectionTools(project); diff --git a/platform/analysis-impl/src/com/intellij/profile/ProfileEx.java b/platform/analysis-impl/src/com/intellij/profile/ProfileEx.java index dc7040e868c3..388a3c8eac12 100644 --- a/platform/analysis-impl/src/com/intellij/profile/ProfileEx.java +++ b/platform/analysis-impl/src/com/intellij/profile/ProfileEx.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. @@ -15,10 +15,7 @@ */ package com.intellij.profile; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.WriteExternalException; import com.intellij.util.xmlb.SmartSerializer; import com.intellij.util.xmlb.annotations.OptionTag; import com.intellij.util.xmlb.annotations.Transient; @@ -30,8 +27,6 @@ import org.jetbrains.annotations.NotNull; * Date: 01-Dec-2005 */ public abstract class ProfileEx implements Profile { - private static final Logger LOG = Logger.getInstance(ProfileEx.class); - public static final String SCOPE = "scope"; public static final String NAME = "name"; @@ -68,17 +63,9 @@ public abstract class ProfileEx implements Profile { @Override public void copyFrom(@NotNull Profile profile) { - try { - Element config = new Element("config"); - profile.writeExternal(config); - readExternal(config); - } - catch (WriteExternalException e) { - LOG.error(e); - } - catch (InvalidDataException e) { - LOG.error(e); - } + Element config = new Element("config"); + profile.writeExternal(config); + readExternal(config); } @Override @@ -121,7 +108,7 @@ public abstract class ProfileEx implements Profile { } @Override - public void readExternal(Element element) throws InvalidDataException { + public void readExternal(Element element) { mySerializer.readExternal(this, element); } @@ -130,7 +117,7 @@ public abstract class ProfileEx implements Profile { } @Override - public void writeExternal(Element element) throws WriteExternalException { + public void writeExternal(Element element) { serializeInto(element, true); } diff --git a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt index eec50f3c5811..af887d26a771 100644 --- a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt +++ b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt @@ -375,9 +375,6 @@ data class TestScheme(@field:Attribute private var name: String = "", @field:Att override @Transient fun setName(newName: String) { name = newName } - - @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") - override fun getExternalInfo() = null } open class TestSchemesProcessor : BaseSchemeProcessor() { diff --git a/platform/core-api/src/com/intellij/openapi/options/ExternalizableScheme.java b/platform/core-api/src/com/intellij/openapi/options/ExternalizableScheme.java index 25ef647ba133..59fb7f043335 100644 --- a/platform/core-api/src/com/intellij/openapi/options/ExternalizableScheme.java +++ b/platform/core-api/src/com/intellij/openapi/options/ExternalizableScheme.java @@ -16,13 +16,7 @@ package com.intellij.openapi.options; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public interface ExternalizableScheme extends Scheme { - @SuppressWarnings({"unused", "deprecation"}) - @Nullable - @Deprecated - ExternalInfo getExternalInfo(); - void setName(@NotNull String newName); } diff --git a/platform/core-api/src/com/intellij/openapi/options/ExternalizableSchemeAdapter.java b/platform/core-api/src/com/intellij/openapi/options/ExternalizableSchemeAdapter.java index 43caad945b52..d53eb269c504 100644 --- a/platform/core-api/src/com/intellij/openapi/options/ExternalizableSchemeAdapter.java +++ b/platform/core-api/src/com/intellij/openapi/options/ExternalizableSchemeAdapter.java @@ -16,17 +16,10 @@ package com.intellij.openapi.options; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public abstract class ExternalizableSchemeAdapter implements ExternalizableScheme { protected String myName; - @Override - @Nullable - public final ExternalInfo getExternalInfo() { - return null; - } - @Override @NotNull public final String getName() { diff --git a/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImpl.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImpl.java index 0503c7aa5d2f..784fb54d1b13 100644 --- a/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImpl.java +++ b/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImpl.java @@ -19,7 +19,6 @@ import com.intellij.openapi.editor.colors.ColorKey; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.editor.markup.TextAttributes; -import com.intellij.openapi.options.ExternalInfo; import com.intellij.openapi.options.ExternalizableScheme; import com.intellij.openapi.util.Comparing; import org.jetbrains.annotations.Nullable; @@ -83,10 +82,4 @@ public class EditorColorsSchemeImpl extends AbstractColorsScheme implements Exte newScheme.setName(getName()); return newScheme; } - - @Override - @Nullable - public ExternalInfo getExternalInfo() { - return null; - } } diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java index b5193eddcedf..105b63dba306 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java @@ -360,9 +360,6 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable } JDOMUtil.writeDocument(new Document(element), filePath, SystemProperties.getLineSeparator()); } - catch (WriteExternalException e1) { - LOG.error(e1); - } catch (IOException e1) { LOG.error(e1); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/AbstractFileType.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/AbstractFileType.java index 25b5963dd3b4..2bd5e6a6773c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/AbstractFileType.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/AbstractFileType.java @@ -22,7 +22,6 @@ import com.intellij.lang.Commenter; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileTypes.*; import com.intellij.openapi.fileTypes.ex.ExternalizableFileType; -import com.intellij.openapi.options.ExternalInfo; import com.intellij.openapi.options.ExternalizableScheme; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.util.*; @@ -415,10 +414,4 @@ public class AbstractFileType extends UserFileType implements public void setCommenter(final Commenter commenter) { myCommenter = commenter; } - - @Override - @Nullable - public ExternalInfo getExternalInfo() { - return null; - } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangeList.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangeList.java index a2bbf3618d7c..51a47d5b51d4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangeList.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangeList.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. @@ -24,7 +24,6 @@ package com.intellij.openapi.vcs.changes.shelf; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.impl.patch.FilePatch; -import com.intellij.openapi.options.ExternalInfo; import com.intellij.openapi.options.ExternalizableScheme; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.DefaultJDOMExternalizer; @@ -36,7 +35,6 @@ import com.intellij.openapi.vcs.FileStatus; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.ArrayList; @@ -90,7 +88,7 @@ public class ShelvedChangeList implements JDOMExternalizable, ExternalizableSche DATE = new Date(Long.parseLong(element.getAttributeValue(ATTRIBUTE_DATE))); myRecycled = Boolean.parseBoolean(element.getAttributeValue(ATTRIBUTE_RECYCLED_CHANGELIST)); //noinspection unchecked - final List children = (List)element.getChildren(ELEMENT_BINARY); + final List children = element.getChildren(ELEMENT_BINARY); myBinaryFiles = new ArrayList(children.size()); for (Element child : children) { ShelvedBinaryFile binaryFile = new ShelvedBinaryFile(); @@ -161,12 +159,6 @@ public class ShelvedChangeList implements JDOMExternalizable, ExternalizableSche return mySchemeName; } - @Nullable - @Override - public ExternalInfo getExternalInfo() { - return null; - } - @Override public void setName(@NotNull String newName) { mySchemeName = newName; From a226d78818a4fe2a6af10abfe71e3f025c34af27 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 29 Sep 2015 12:41:59 +0200 Subject: [PATCH 16/50] cleanup --- .../src/com/intellij/codeInspection/ex/ToolsImpl.java | 2 +- .../src/com/intellij/uiDesigner/palette/Palette.java | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java index d5b60c4b88a4..5f7e9014cf99 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java @@ -142,7 +142,7 @@ public class ToolsImpl implements Tools { return result; } - public void writeExternal(Element inspectionElement) throws WriteExternalException { + public void writeExternal(@NotNull Element inspectionElement) throws WriteExternalException { if (myTools != null) { for (ScopeToolState state : myTools) { final Element scopeElement = new Element("scope"); diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java index 4627efd195f0..e565b23d64b3 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 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. @@ -136,17 +136,18 @@ public final class Palette implements Disposable, PersistentStateComponent filter = null; if (name.equals(SwingProperties.LABEL_FOR)) { filter = new Condition() { + @Override public boolean value(final RadComponent t) { ComponentItem item = getItem(t.getComponentClassName()); return item != null && item.isCanAttachLabel(); @@ -811,6 +813,7 @@ public final class Palette implements Disposable, PersistentStateComponent Date: Tue, 29 Sep 2015 12:46:33 +0200 Subject: [PATCH 17/50] cleanup --- .../uiDesigner/binding/BoundIconRenderer.java | 7 +++- .../uiDesigner/palette/AddGroupAction.java | 13 ++++---- .../palette/ComponentItemDialog.java | 19 +++++++++-- .../uiDesigner/palette/EditGroupAction.java | 17 +++++----- .../intellij/uiDesigner/palette/Palette.java | 32 ++++++------------- 5 files changed, 48 insertions(+), 40 deletions(-) diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/BoundIconRenderer.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/BoundIconRenderer.java index 60f12b2489b6..dfdd6db8fa13 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/BoundIconRenderer.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/BoundIconRenderer.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. @@ -68,6 +68,7 @@ public class BoundIconRenderer extends GutterIconRenderer { } } + @Override @NotNull public Icon getIcon() { if (myIcon != null) { @@ -76,13 +77,16 @@ public class BoundIconRenderer extends GutterIconRenderer { return PlatformIcons.UI_FORM_ICON; } + @Override public boolean isNavigateAction() { return true; } + @Override @Nullable public AnAction getClickAction() { return new AnAction() { + @Override public void actionPerformed(AnActionEvent e) { List formFiles = getBoundFormFiles(); if (formFiles.size() > 0) { @@ -104,6 +108,7 @@ public class BoundIconRenderer extends GutterIconRenderer { }; } + @Override @Nullable public String getTooltipText() { List formFiles = getBoundFormFiles(); diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/AddGroupAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/AddGroupAction.java index 2d388652188f..4047d7e58b74 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/AddGroupAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/AddGroupAction.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. @@ -20,17 +20,18 @@ import com.intellij.CommonBundle; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.uiDesigner.UIDesignerBundle; import java.util.ArrayList; +import java.util.List; /** * @author yole */ public class AddGroupAction extends AnAction { + @Override public void actionPerformed(AnActionEvent e) { Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) return; @@ -41,15 +42,15 @@ public class AddGroupAction extends AnAction { UIDesignerBundle.message("title.add.group"), Messages.getQuestionIcon() ); - if(groupName == null){ + if (groupName == null) { return; } Palette palette = Palette.getInstance(project); // Check that name of the group is unique - final ArrayList groups = palette.getGroups(); - for(int i = groups.size() - 1; i >= 0; i--){ - if(groupName.equals(groups.get(i).getName())){ + List groups = palette.getGroups(); + for (int i = groups.size() - 1; i >= 0; i--) { + if (groupName.equals(groups.get(i).getName())) { Messages.showErrorDialog(project, UIDesignerBundle.message("error.group.name.unique"), CommonBundle.getErrorTitle()); diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.java index a3d66a914304..cbf5cccf19b1 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.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. @@ -53,7 +53,7 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; -import java.util.ArrayList; +import java.util.List; /** * @author Vladimir Kondratyev @@ -114,6 +114,7 @@ public final class ComponentItemDialog extends DialogWrapper { updateEnabledTextField(); myTfClassName.getChildComponent().addDocumentListener(new com.intellij.openapi.editor.event.DocumentAdapter() { + @Override public void documentChanged(com.intellij.openapi.editor.event.DocumentEvent e) { updateOKAction(); } @@ -128,12 +129,14 @@ public final class ComponentItemDialog extends DialogWrapper { UIDesignerBundle.message("add.component.choose.icon"))); myTfNestedForm.addActionListener(new MyChooseFileActionListener(project, new TreeFileChooser.PsiFileFilter() { + @Override public boolean accept(PsiFile file) { return file.getFileType().equals(StdFileTypes.GUI_DESIGNER_FORM); } }, myTfNestedForm, UIDesignerBundle.message("add.component.choose.form"))); myTfNestedForm.getTextField().getDocument().addDocumentListener(new DocumentAdapter() { + @Override protected void textChanged(DocumentEvent e) { updateOKAction(); } @@ -181,10 +184,11 @@ public final class ComponentItemDialog extends DialogWrapper { void showGroupChooser(GroupItem defaultGroup) { myGroupLabel.setVisible(true); myGroupComboBox.setVisible(true); - final ArrayList groups = Palette.getInstance(myProject).getGroups(); + List groups = Palette.getInstance(myProject).getGroups(); myGroupComboBox.setModel(new DefaultComboBoxModel(groups.toArray())); myGroupComboBox.setSelectedItem(defaultGroup); myGroupComboBox.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { updateOKAction(); } @@ -205,15 +209,18 @@ public final class ComponentItemDialog extends DialogWrapper { updateOKAction(); } + @Override @NotNull protected Action[] createActions() { return new Action[]{getOKAction(), getCancelAction(), getHelpAction()}; } + @Override protected void doHelpAction() { HelpManager.getInstance().invokeHelp("reference.dialogs.addEditPaletteComponent"); } + @Override protected void doOKAction() { // TODO[vova] implement validation if (myClassRadioButton.isSelected()) { @@ -294,6 +301,7 @@ public final class ComponentItemDialog extends DialogWrapper { return true; } + @Override protected String getDimensionServiceKey() { if (myOneOff) { return "#com.intellij.uiDesigner.palette.ComponentItemDialog.OneOff"; @@ -301,10 +309,12 @@ public final class ComponentItemDialog extends DialogWrapper { return "#com.intellij.uiDesigner.palette.ComponentItemDialog"; } + @Override public JComponent getPreferredFocusedComponent() { return myTfClassName.getChildComponent(); } + @Override protected JComponent createCenterPanel() { return myPanel; } @@ -365,6 +375,7 @@ public final class ComponentItemDialog extends DialogWrapper { myProject = project; } + @Override public void actionPerformed(final ActionEvent e) { final TreeClassChooserFactory factory = TreeClassChooserFactory.getInstance(myProject); final TreeClassChooser chooser = factory.createInheritanceClassChooser(UIDesignerBundle.message("title.choose.component.class"), @@ -394,6 +405,7 @@ public final class ComponentItemDialog extends DialogWrapper { myTitle = title; } + @Override public void actionPerformed(ActionEvent e) { final TreeClassChooserFactory factory = TreeClassChooserFactory.getInstance(myProject); PsiFile formFile = null; @@ -413,6 +425,7 @@ public final class ComponentItemDialog extends DialogWrapper { } private class MyRadioChangeListener implements ChangeListener { + @Override public void stateChanged(ChangeEvent e) { updateEnabledTextField(); } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java index 3bedd33a745a..d69437c7b204 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.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,17 +20,17 @@ import com.intellij.CommonBundle; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.uiDesigner.UIDesignerBundle; -import java.util.ArrayList; +import java.util.List; /** * @author yole */ public class EditGroupAction extends AnAction { + @Override public void actionPerformed(AnActionEvent e) { Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); GroupItem groupToBeEdited = GroupItem.DATA_KEY.getData(e.getDataContext()); @@ -45,14 +45,14 @@ public class EditGroupAction extends AnAction { groupToBeEdited.getName(), null ); - if(groupName == null || groupName.equals(groupToBeEdited.getName())){ + if (groupName == null || groupName.equals(groupToBeEdited.getName())) { return; } Palette palette = Palette.getInstance(project); - final ArrayList groups = palette.getGroups(); - for(int i = groups.size() - 1; i >= 0; i--){ - if(groupName.equals(groups.get(i).getName())){ + List groups = palette.getGroups(); + for (int i = groups.size() - 1; i >= 0; i--) { + if (groupName.equals(groups.get(i).getName())) { Messages.showErrorDialog(project, UIDesignerBundle.message("error.group.name.unique"), CommonBundle.getErrorTitle()); return; @@ -63,7 +63,8 @@ public class EditGroupAction extends AnAction { palette.fireGroupsChanged(); } - @Override public void update(AnActionEvent e) { + @Override + public void update(AnActionEvent e) { Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); GroupItem groupItem = GroupItem.DATA_KEY.getData(e.getDataContext()); e.getPresentation().setEnabled(project != null && groupItem != null && !groupItem.isReadOnly()); diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java index e565b23d64b3..9a1c9b3ae283 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java @@ -18,7 +18,6 @@ package com.intellij.uiDesigner.palette; import com.intellij.ide.ui.LafManager; import com.intellij.ide.ui.LafManagerListener; import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.components.*; import com.intellij.openapi.diagnostic.Logger; @@ -78,7 +77,7 @@ public final class Palette implements Disposable, PersistentStateComponent myClass2Properties; private final Map myClassName2Item; /*All groups in the palette*/ - private final ArrayList myGroups; + private final List myGroups; /*Listeners, etc*/ private final List myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); private final Project myProject; @@ -138,9 +137,9 @@ public final class Palette implements Disposable, PersistentStateComponentDO NOT MODIFY OR CACHE THIS LIST. */ - public ArrayList getGroups(){ + public List getGroups(){ return myGroups; } @@ -553,17 +545,13 @@ public final class Palette implements Disposable, PersistentStateComponent Date: Tue, 29 Sep 2015 12:47:30 +0200 Subject: [PATCH 18/50] cleanup --- .../intellij/uiDesigner/binding/FormClassAnnotator.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassAnnotator.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassAnnotator.java index 05c1bcb1b912..da243250d8ec 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassAnnotator.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassAnnotator.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. @@ -37,6 +37,7 @@ import java.util.List; public class FormClassAnnotator implements Annotator { private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.binding.FormClassAnnotator"); + @Override public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder) { if (psiElement instanceof PsiField) { PsiField field = (PsiField) psiElement; @@ -76,20 +77,24 @@ public class FormClassAnnotator implements Annotator { final String message = UIDesignerBundle.message("field.is.overwritten.by.generated.code", field.getName()); Annotation annotation = holder.createWarningAnnotation(field.getInitializer(), message); annotation.registerFix(new IntentionAction() { + @Override @NotNull public String getText() { return message; } + @Override @NotNull public String getFamilyName() { return UIBundle.message("remove.field.initializer.quick.fix"); } + @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { return field.getInitializer() != null; } + @Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { if (!FileModificationService.getInstance().preparePsiElementForWrite(field)) return; final PsiExpression initializer = field.getInitializer(); @@ -97,6 +102,7 @@ public class FormClassAnnotator implements Annotator { initializer.delete(); } + @Override public boolean startInWriteAction() { return true; } From 9b2970ef730fd4f6f96d30ff30220f331b733396 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 29 Sep 2015 12:52:38 +0200 Subject: [PATCH 19/50] =?UTF-8?q?cleanup,=20remove=20outdated=20comment=20?= =?UTF-8?q?=E2=80=94=C2=A0IDEA=20can=20call=20loadstate=20multiple=20time?= =?UTF-8?q?=20=E2=80=94=20state=20hotswap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../intellij/uiDesigner/palette/Palette.java | 164 +++++++++--------- 1 file changed, 81 insertions(+), 83 deletions(-) diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java index 9a1c9b3ae283..2fe60e396578 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java @@ -117,7 +117,9 @@ public final class Palette implements Disposable, PersistentStateComponentDO NOT MODIFY OR CACHE THIS LIST. */ - public List getGroups(){ + public List getGroups() { return myGroups; } public GroupItem[] getToolWindowGroups() { - GroupItem[] groups = new GroupItem[myGroups.size()+1]; - for(int i=0; i groups){ + public void setGroups(@NotNull final ArrayList groups) { myGroups.clear(); myGroups.addAll(groups); @@ -281,9 +274,10 @@ public final class Palette implements Disposable, PersistentStateComponentitem to the palette. + * * @param item item to be added - * @exception java.lang.IllegalArgumentException if an item for the same class - * is already exists in the palette + * @throws IllegalArgumentException if an item for the same class + * is already exists in the palette */ public void addItem(@NotNull final GroupItem group, @NotNull final ComponentItem item) { // class -> item @@ -302,7 +296,7 @@ public final class Palette implements Disposable, PersistentStateComponent propertyName2initialValue = new HashMap(); { final Element initialValues = itemElement.getChild(ELEMENT_INITIAL_VALUES); - if (initialValues != null){ - for(final Object o : initialValues.getChildren(ELEMENT_PROPERTY)) { + if (initialValues != null) { + for (final Object o : initialValues.getChildren(ELEMENT_PROPERTY)) { final Element e = (Element)o; final String name = LwXmlReader.getRequiredString(e, ATTRIBUTE_NAME); // TODO[all] currently all initial values are strings @@ -423,14 +417,11 @@ public final class Palette implements Disposable, PersistentStateComponent groupElements) { + for (Element groupElement : groupElements) { + GroupItem group = new GroupItem(LwXmlReader.getRequiredString(groupElement, ATTRIBUTE_NAME)); myGroups.add(group); - for (final Object o : groupElement.getChildren(ELEMENT_ITEM)) { - final Element itemElement = (Element)o; + for (Element itemElement : groupElement.getChildren(ELEMENT_ITEM)) { try { processItemElement(itemElement, group, false); } @@ -441,8 +432,10 @@ public final class Palette implements Disposable, PersistentStateComponent name2value - ){ + ) { LOG.assertTrue(ELEMENT_ITEM.equals(itemElement.getName())); - if(name2value.size() == 0){ // do not append 'initial-values' subtag + if (name2value.size() == 0) { // do not append 'initial-values' subtag return; } @@ -509,8 +504,10 @@ public final class Palette implements Disposable, PersistentStateComponentDO NOT USE THIS METHOD DIRECTLY. Use {@link com.intellij.uiDesigner.radComponents.RadComponent#getInplaceProperty(int, int) } + * DO NOT USE THIS METHOD DIRECTLY. Use {@link RadComponent#getInplaceProperty(int, int) } * instead. */ @Nullable @@ -767,17 +765,17 @@ public final class Palette implements Disposable, PersistentStateComponent= 0; i--) { final IntrospectedProperty property = properties[i]; - if(property.getName().equals(inplaceProperty)){ + if (property.getName().equals(inplaceProperty)) { return property; } } return null; } - public static boolean isRemovable(@NotNull final GroupItem group){ + public static boolean isRemovable(@NotNull final GroupItem group) { final ComponentItem[] items = group.getItems(); - for(int i = items.length - 1; i >=0; i--){ - if(!items [i].isRemovable()){ + for (int i = items.length - 1; i >= 0; i--) { + if (!items[i].isRemovable()) { return false; } } @@ -787,12 +785,12 @@ public final class Palette implements Disposable, PersistentStateComponent Date: Tue, 29 Sep 2015 15:28:33 +0200 Subject: [PATCH 20/50] Import/Export SettingsAction in kotlin --- .../ide/actions/ExportSettingsAction.java | 507 ++++++++---------- .../ide/actions/ImportSettingsAction.java | 205 +++---- .../src/copyAppSettingsToRepository.kt | 7 +- 3 files changed, 314 insertions(+), 405 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java index f657aa4c95af..33b2de119996 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java @@ -13,320 +13,255 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.intellij.ide.actions -/** - * @author cdr - */ -package com.intellij.ide.actions; +import com.intellij.AbstractBundle +import com.intellij.CommonBundle +import com.intellij.ide.IdeBundle +import com.intellij.ide.plugins.IdeaPluginDescriptor +import com.intellij.ide.plugins.PluginManager +import com.intellij.ide.plugins.PluginManagerCore +import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.PathManager +import com.intellij.openapi.application.impl.ApplicationImpl +import com.intellij.openapi.components.* +import com.intellij.openapi.components.impl.ServiceManagerImpl +import com.intellij.openapi.components.impl.stores.StateStorageManager +import com.intellij.openapi.components.impl.stores.StoreUtil +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.extensions.PluginDescriptor +import com.intellij.openapi.options.OptionsBundle +import com.intellij.openapi.project.DumbAware +import com.intellij.openapi.ui.Messages +import com.intellij.openapi.util.io.FileUtil +import com.intellij.openapi.util.io.FileUtilRt +import com.intellij.openapi.util.text.StringUtil +import com.intellij.openapi.vfs.CharsetToolkit +import com.intellij.util.PairProcessor +import com.intellij.util.PlatformUtils +import com.intellij.util.ReflectionUtil +import com.intellij.util.containers.ContainerUtil +import com.intellij.util.containers.MultiMap +import com.intellij.util.io.ZipUtil +import gnu.trove.THashSet -import com.intellij.AbstractBundle; -import com.intellij.CommonBundle; -import com.intellij.ide.IdeBundle; -import com.intellij.ide.plugins.IdeaPluginDescriptor; -import com.intellij.ide.plugins.PluginManager; -import com.intellij.ide.plugins.PluginManagerCore; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.application.impl.ApplicationImpl; -import com.intellij.openapi.components.*; -import com.intellij.openapi.components.impl.ServiceManagerImpl; -import com.intellij.openapi.components.impl.stores.StateStorageManager; -import com.intellij.openapi.components.impl.stores.StoreUtil; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.extensions.PluginDescriptor; -import com.intellij.openapi.options.OptionsBundle; -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.io.FileUtilRt; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.CharsetToolkit; -import com.intellij.util.PairProcessor; -import com.intellij.util.PlatformUtils; -import com.intellij.util.ReflectionUtil; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.MultiMap; -import com.intellij.util.io.ZipUtil; -import gnu.trove.THashSet; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import java.io.* +import java.util.* +import java.util.zip.ZipEntry +import java.util.zip.ZipOutputStream -import java.io.*; -import java.util.*; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; +private class ExportSettingsAction : AnAction(), DumbAware { + override fun actionPerformed(e: AnActionEvent?) { + ApplicationManager.getApplication().saveSettings() -public class ExportSettingsAction extends AnAction implements DumbAware { - private static final Logger LOG = Logger.getInstance(ExportSettingsAction.class); - - @Override - public void actionPerformed(@Nullable AnActionEvent e) { - ApplicationManager.getApplication().saveSettings(); - - ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(getExportableComponentsMap(true, true), true, - IdeBundle.message("title.select.components.to.export"), - IdeBundle.message( - "prompt.please.check.all.components.to.export")); + val dialog = ChooseComponentsToExportDialog(getExportableComponentsMap(true, true), true, + IdeBundle.message("title.select.components.to.export"), + IdeBundle.message( + "prompt.please.check.all.components.to.export")) if (!dialog.showAndGet()) { - return; + return } - Set markedComponents = dialog.getExportableComponents(); + val markedComponents = dialog.exportableComponents if (markedComponents.isEmpty()) { - return; + return } - Set exportFiles = new THashSet(FileUtil.FILE_HASHING_STRATEGY); - for (ExportableComponent markedComponent : markedComponents) { - ContainerUtil.addAll(exportFiles, markedComponent.getExportFiles()); + val exportFiles = THashSet(FileUtil.FILE_HASHING_STRATEGY) + for (markedComponent in markedComponents) { + ContainerUtil.addAll>(exportFiles, *markedComponent.exportFiles) } - final File saveFile = dialog.getExportFile(); + val saveFile = dialog.exportFile try { if (saveFile.exists() && Messages.showOkCancelDialog( - IdeBundle.message("prompt.overwrite.settings.file", FileUtil.toSystemDependentName(saveFile.getPath())), + IdeBundle.message("prompt.overwrite.settings.file", FileUtil.toSystemDependentName(saveFile.path)), IdeBundle.message("title.file.already.exists"), Messages.getWarningIcon()) != Messages.OK) { - return; + return } - MyZipOutputStream zipOut = new MyZipOutputStream(new BufferedOutputStream(new FileOutputStream(saveFile))); + val zipOut = MyZipOutputStream(BufferedOutputStream(FileOutputStream(saveFile))) try { - Set writtenItemRelativePaths = new THashSet(); - String configRoot = FileUtilRt.toSystemIndependentName(PathManager.getConfigPath()); - for (File file : exportFiles) { + val writtenItemRelativePaths = THashSet() + val configRoot = FileUtilRt.toSystemIndependentName(PathManager.getConfigPath()) + for (file in exportFiles) { if (file.exists()) { - String relativePath = FileUtilRt.getRelativePath(configRoot, FileUtilRt.toSystemIndependentName(file.getAbsolutePath()), '/'); - assert relativePath != null; - ZipUtil.addFileOrDirRecursively(zipOut, null, file, relativePath, null, writtenItemRelativePaths); + val relativePath = FileUtilRt.getRelativePath(configRoot, FileUtilRt.toSystemIndependentName(file.absolutePath), '/')!! + ZipUtil.addFileOrDirRecursively(zipOut, null, file, relativePath, null, writtenItemRelativePaths) } } - exportInstalledPlugins(zipOut); + exportInstalledPlugins(zipOut) - ZipEntry zipEntry = new ZipEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER); - zipOut.putNextEntry(zipEntry); - zipOut.closeEntry(); + val zipEntry = ZipEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER) + zipOut.putNextEntry(zipEntry) + zipOut.closeEntry() } finally { - zipOut.doClose(); + zipOut.doClose() } - ShowFilePathAction.showDialog(getEventProject(e), IdeBundle.message("message.settings.exported.successfully"), - IdeBundle.message("title.export.successful"), saveFile, null); + ShowFilePathAction.showDialog(AnAction.getEventProject(e), IdeBundle.message("message.settings.exported.successfully"), + IdeBundle.message("title.export.successful"), saveFile, null) } - catch (IOException e1) { - Messages.showErrorDialog(IdeBundle.message("error.writing.settings", e1.toString()), IdeBundle.message("title.error.writing.file")); - } - } - - private static void exportInstalledPlugins(@NotNull MyZipOutputStream zipOut) throws IOException { - List plugins = new ArrayList(); - for (IdeaPluginDescriptor descriptor : PluginManagerCore.getPlugins()) { - if (!descriptor.isBundled() && descriptor.isEnabled()) { - plugins.add(descriptor.getPluginId().getIdString()); - } - } - if (plugins.isEmpty()) { - return; - } - - ZipEntry e = new ZipEntry(PluginManager.INSTALLED_TXT); - zipOut.putNextEntry(e); - try { - PluginManagerCore.writePluginsList(plugins, new OutputStreamWriter(zipOut, CharsetToolkit.UTF8_CHARSET)); - } - finally { - zipOut.closeEntry(); - } - } - - private static class MyZipOutputStream extends ZipOutputStream { - private boolean ignoreClose = true; - - public MyZipOutputStream(@NotNull OutputStream out) { - super(out); - } - - @Override - public void close() throws IOException { - if (!ignoreClose) { - doClose(); - } - } - - public void doClose() throws IOException { - super.close(); - } - } - - @NotNull - public static MultiMap getExportableComponentsMap(boolean onlyExisting, boolean computePresentableNames) { - ApplicationImpl application = (ApplicationImpl)ApplicationManager.getApplication(); - StateStorageManager storageManager = ComponentsPackage.getStateStore(application).getStateStorageManager(); - return getExportableComponentsMap(onlyExisting, computePresentableNames, storageManager); - } - - @NotNull - public static MultiMap getExportableComponentsMap(final boolean onlyExisting, final boolean computePresentableNames, final @NotNull StateStorageManager storageManager) { - @SuppressWarnings("deprecation") - List components1 = ComponentsPackage.getComponents(ApplicationManager.getApplication(), ExportableApplicationComponent.class); - List components2 = ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent.class); - final MultiMap result = MultiMap.createLinkedSet(); - for (ExportableComponent component : ContainerUtil.concat(components1, components2)) { - for (File exportFile : component.getExportFiles()) { - result.putValue(exportFile, component); - } - } - - if (onlyExisting) { - for (Iterator it = result.keySet().iterator(); it.hasNext(); ) { - if (!it.next().exists()) { - it.remove(); - } - } - } - - ServiceManagerImpl.processAllImplementationClasses((ApplicationImpl)ApplicationManager.getApplication(), new PairProcessor, PluginDescriptor>() { - @Override - public boolean process(@NotNull Class aClass, @Nullable PluginDescriptor pluginDescriptor) { - State stateAnnotation = StoreUtil.getStateSpec(aClass); - if (stateAnnotation != null && !StringUtil.isEmpty(stateAnnotation.name())) { - if (ExportableComponent.class.isAssignableFrom(aClass)) { - return true; - } - - int storageIndex; - Storage[] storages = stateAnnotation.storages(); - if (storages.length == 1) { - storageIndex = 0; - } - else { - return true; - } - - Storage storage = storages[storageIndex]; - if (storage.roamingType() != RoamingType.DISABLED && - storage.storageClass().equals(StateStorage.class) && - storage.scheme() == StorageScheme.DEFAULT && - !StringUtil.isEmpty(storage.file()) && - storage.file().startsWith(StoragePathMacros.APP_CONFIG)) { - - File additionalExportFile = null; - if (!StringUtil.isEmpty(stateAnnotation.additionalExportFile())) { - String expandedPath = storageManager.expandMacros(stateAnnotation.additionalExportFile()); - additionalExportFile = new File(expandedPath); - if (!additionalExportFile.exists()) { - //noinspection deprecation - additionalExportFile = new File(storageManager.expandMacros(StoragePathMacros.ROOT_CONFIG) + '/' + expandedPath); - } - - if (onlyExisting && !additionalExportFile.exists()) { - additionalExportFile = null; - } - } - - File file = new File(storageManager.expandMacros(storage.file())); - boolean fileExists = !onlyExisting || file.exists(); - if (fileExists || additionalExportFile != null) { - File[] files; - if (additionalExportFile == null) { - files = new File[]{file}; - } - else { - files = fileExists ? new File[]{file, additionalExportFile} : new File[]{additionalExportFile}; - } - ExportableComponentItem item = new ExportableComponentItem(files, - computePresentableNames - ? getComponentPresentableName(stateAnnotation, aClass, pluginDescriptor) - : "", - storage.roamingType()); - result.putValue(file, item); - if (additionalExportFile != null) { - result.putValue(additionalExportFile, item); - } - } - } - } - return true; - } - }); - return result; - } - - @NotNull - private static String getComponentPresentableName(@NotNull State state, @NotNull Class aClass, @Nullable PluginDescriptor pluginDescriptor) { - if (state.presentableName() != State.NameGetter.class) { - try { - return ReflectionUtil.newInstance(state.presentableName()).get(); - } - catch (Exception e) { - LOG.error(e); - } - } - - String defaultName = state.name(); - String resourceBundleName; - if (pluginDescriptor != null && pluginDescriptor instanceof IdeaPluginDescriptor && !"com.intellij".equals(pluginDescriptor.getPluginId().getIdString())) { - resourceBundleName = ((IdeaPluginDescriptor)pluginDescriptor).getResourceBundleBaseName(); - } - else { - resourceBundleName = OptionsBundle.PATH_TO_BUNDLE; - } - - if (resourceBundleName == null) { - return defaultName; - } - - ClassLoader classLoader = pluginDescriptor == null ? null : pluginDescriptor.getPluginClassLoader(); - classLoader = classLoader == null ? aClass.getClassLoader() : classLoader; - if (classLoader != null) { - String message = messageOrDefault(classLoader, resourceBundleName, defaultName); - if (message != defaultName) { - return message; - } - - if (PlatformUtils.isRubyMine()) { - // ruby plugin in RubyMine has id "com.intellij", so, we cannot set "resource-bundle" in plugin.xml - return messageOrDefault(classLoader, "org.jetbrains.plugins.ruby.RBundle", defaultName); - } - } - return defaultName; - } - - @NotNull - private static String messageOrDefault(@NotNull ClassLoader classLoader, @NotNull String bundleName, @NotNull String defaultName) { - ResourceBundle bundle = AbstractBundle.getResourceBundle(bundleName, classLoader); - return bundle == null ? defaultName : CommonBundle.messageOrDefault(bundle, "exportable." + defaultName + ".presentable.name", defaultName); - } - - public static final class ExportableComponentItem implements ExportableComponent { - private final File[] files; - private final String name; - private final RoamingType roamingType; - - public ExportableComponentItem(@NotNull File[] files, @NotNull String name, @NotNull RoamingType roamingType) { - this.files = files; - this.name = name; - this.roamingType = roamingType; - } - - @NotNull - @Override - public File[] getExportFiles() { - return files; - } - - @NotNull - @Override - public String getPresentableName() { - return name; - } - - @NotNull - public RoamingType getRoamingType() { - return roamingType; + catch (e1: IOException) { + Messages.showErrorDialog(IdeBundle.message("error.writing.settings", e1.toString()), IdeBundle.message("title.error.writing.file")) } } } +private class MyZipOutputStream(out: OutputStream) : ZipOutputStream(out) { + override fun close() { + } + + fun doClose() { + super.close() + } +} + +class ExportableComponentItem(private val files: Array, private val name: String, val roamingType: RoamingType) : ExportableComponent { + override fun getExportFiles() = files + + override fun getPresentableName() = name +} + +private val LOG = Logger.getInstance(ExportSettingsAction::class.java) + +private fun exportInstalledPlugins(zipOut: MyZipOutputStream) { + val plugins = ArrayList() + for (descriptor in PluginManagerCore.getPlugins()) { + if (!descriptor.isBundled && descriptor.isEnabled) { + plugins.add(descriptor.pluginId.idString) + } + } + if (plugins.isEmpty()) { + return + } + + val e = ZipEntry(PluginManager.INSTALLED_TXT) + zipOut.putNextEntry(e) + try { + PluginManagerCore.writePluginsList(plugins, OutputStreamWriter(zipOut, CharsetToolkit.UTF8_CHARSET)) + } + finally { + zipOut.closeEntry() + } +} + +fun getExportableComponentsMap(onlyExisting: Boolean, computePresentableNames: Boolean, storageManager: StateStorageManager = ApplicationManager.getApplication().stateStore.stateStorageManager): MultiMap { + val result = MultiMap.createLinkedSet() + val processor = { component: ExportableComponent -> + for (exportFile in component.exportFiles) { + result.putValue(exportFile, component) + } + } + + @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") + ApplicationManager.getApplication().getComponents(ExportableApplicationComponent::class.java).forEach(processor) + ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent::class.java).forEach(processor) + + if (onlyExisting) { + val it = result.keySet().iterator() + while (it.hasNext()) { + if (!it.next().exists()) { + it.remove() + } + } + } + + ServiceManagerImpl.processAllImplementationClasses(ApplicationManager.getApplication() as ApplicationImpl, object : PairProcessor, PluginDescriptor> { + override fun process(aClass: Class<*>, pluginDescriptor: PluginDescriptor?): Boolean { + val stateAnnotation = StoreUtil.getStateSpec(aClass) + if (stateAnnotation != null && !StringUtil.isEmpty(stateAnnotation.name)) { + if (ExportableComponent::class.java.isAssignableFrom(aClass)) { + return true + } + + val storageIndex: Int + val storages = stateAnnotation.storages + if (storages.size() == 1) { + storageIndex = 0 + } + else { + return true + } + + val storage = storages[storageIndex] + if (storage.roamingType != RoamingType.DISABLED && storage.storageClass == StateStorage::class.java && storage.scheme == StorageScheme.DEFAULT && !StringUtil.isEmpty(storage.file) && storage.file.startsWith(StoragePathMacros.APP_CONFIG)) { + var additionalExportFile: File? = null + if (!StringUtil.isEmpty(stateAnnotation.additionalExportFile)) { + val expandedPath = storageManager.expandMacros(stateAnnotation.additionalExportFile) + additionalExportFile = File(expandedPath) + if (!additionalExportFile.exists()) { + //noinspection deprecation + additionalExportFile = File(storageManager.expandMacros(StoragePathMacros.ROOT_CONFIG) + '/' + expandedPath) + } + + if (onlyExisting && !additionalExportFile.exists()) { + additionalExportFile = null + } + } + + val file = File(storageManager.expandMacros(storage.file)) + val fileExists = !onlyExisting || file.exists() + if (fileExists || additionalExportFile != null) { + val files = if (additionalExportFile == null) { + arrayOf(file) + } + else { + if (fileExists) arrayOf(file, additionalExportFile) else arrayOf(additionalExportFile) + } + val item = ExportableComponentItem(files, if (computePresentableNames) getComponentPresentableName(stateAnnotation, aClass, pluginDescriptor) else "", storage.roamingType) + result.putValue(file, item) + if (additionalExportFile != null) { + result.putValue(additionalExportFile, item) + } + } + } + } + return true + } + }) + return result +} + +private fun getComponentPresentableName(state: State, aClass: Class<*>, pluginDescriptor: PluginDescriptor?): String { + val presentableName = state.presentableName.java + if (presentableName != State.NameGetter::class.java) { + try { + return ReflectionUtil.newInstance(presentableName).get() + } + catch (e: Exception) { + LOG.error(e) + } + } + + val defaultName = state.name + val resourceBundleName = (if (pluginDescriptor is IdeaPluginDescriptor && "com.intellij" != pluginDescriptor.pluginId.idString) { + pluginDescriptor.resourceBundleBaseName + } + else { + OptionsBundle.PATH_TO_BUNDLE + }) ?: return defaultName + + var classLoader = pluginDescriptor?.pluginClassLoader ?: aClass.classLoader + if (classLoader != null) { + val message = messageOrDefault(classLoader, resourceBundleName, defaultName) + if (message !== defaultName) { + return message + } + + if (PlatformUtils.isRubyMine()) { + // ruby plugin in RubyMine has id "com.intellij", so, we cannot set "resource-bundle" in plugin.xml + return messageOrDefault(classLoader, "org.jetbrains.plugins.ruby.RBundle", defaultName) + } + } + return defaultName +} + +private fun messageOrDefault(classLoader: ClassLoader, bundleName: String, defaultName: String): String { + val bundle = AbstractBundle.getResourceBundle(bundleName, classLoader) ?: return defaultName + return CommonBundle.messageOrDefault(bundle, "exportable.$defaultName.presentable.name", defaultName) +} + diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java index db61dbc06aaa..e3f5aaf13b8f 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java @@ -13,168 +13,141 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.intellij.ide.actions -/** - * @author cdr - */ -package com.intellij.ide.actions; +import com.intellij.ide.IdeBundle +import com.intellij.ide.plugins.PluginManager +import com.intellij.ide.startup.StartupActionScriptManager +import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.actionSystem.PlatformDataKeys +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.ApplicationNamesInfo +import com.intellij.openapi.application.PathManager +import com.intellij.openapi.application.ex.ApplicationEx +import com.intellij.openapi.components.ExportableComponent +import com.intellij.openapi.project.DumbAware +import com.intellij.openapi.ui.Messages +import com.intellij.openapi.updateSettings.impl.UpdateSettings +import com.intellij.openapi.util.io.FileUtil +import com.intellij.openapi.util.io.FileUtilRt +import com.intellij.util.Consumer +import gnu.trove.THashSet +import java.io.File +import java.io.IOException +import java.util.* +import java.util.zip.ZipException +import java.util.zip.ZipFile -import com.intellij.ide.IdeBundle; -import com.intellij.ide.plugins.PluginManager; -import com.intellij.ide.startup.StartupActionScriptManager; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.application.ex.ApplicationEx; -import com.intellij.openapi.components.ExportableComponent; -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.updateSettings.impl.UpdateSettings; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.io.FileUtilRt; -import com.intellij.util.Consumer; -import com.intellij.util.containers.MultiMap; -import gnu.trove.THashSet; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; -import java.io.File; -import java.io.IOException; -import java.util.*; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipFile; - -public class ImportSettingsAction extends AnAction implements DumbAware { - @Override - public void actionPerformed(@NotNull AnActionEvent e) { - final DataContext dataContext = e.getDataContext(); - final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); - ChooseComponentsToExportDialog.chooseSettingsFile(PathManager.getConfigPath(), component, IdeBundle.message("title.import.file.location"), IdeBundle.message("prompt.choose.import.file.path")).doWhenDone(new Consumer() { - @Override - public void consume(String path) { - File saveFile = new File(path); +private class ImportSettingsAction : AnAction(), DumbAware { + override fun actionPerformed(e: AnActionEvent) { + val dataContext = e.dataContext + val component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext) + ChooseComponentsToExportDialog.chooseSettingsFile(PathManager.getConfigPath(), component, IdeBundle.message("title.import.file.location"), IdeBundle.message("prompt.choose.import.file.path")).doWhenDone(object : Consumer { + override fun consume(path: String) { + val saveFile = File(path) try { - doImport(saveFile); + doImport(saveFile) } - catch (ZipException e1) { + catch (e1: ZipException) { Messages.showErrorDialog( IdeBundle.message("error.reading.settings.file", presentableFileName(saveFile), e1.getMessage(), promptLocationMessage()), - IdeBundle.message("title.invalid.file")); + IdeBundle.message("title.invalid.file")) } - catch (IOException e1) { + catch (e1: IOException) { Messages.showErrorDialog(IdeBundle.message("error.reading.settings.file.2", presentableFileName(saveFile), e1.getMessage()), - IdeBundle.message("title.error.reading.file")); + IdeBundle.message("title.error.reading.file")) } } - }); + }) } - private static void doImport(@NotNull File saveFile) throws IOException { + private fun doImport(saveFile: File) { if (!saveFile.exists()) { Messages.showErrorDialog(IdeBundle.message("error.cannot.find.file", presentableFileName(saveFile)), - IdeBundle.message("title.file.not.found")); - return; + IdeBundle.message("title.file.not.found")) + return } @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") - final ZipEntry magicEntry = new ZipFile(saveFile).getEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER); + val magicEntry = ZipFile(saveFile).getEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER) if (magicEntry == null) { Messages.showErrorDialog( IdeBundle.message("error.file.contains.no.settings.to.import", presentableFileName(saveFile), promptLocationMessage()), - IdeBundle.message("title.invalid.file")); - return; + IdeBundle.message("title.invalid.file")) + return } - MultiMap fileToComponents = ExportSettingsAction.getExportableComponentsMap(false, true); - List components = getComponentsStored(saveFile, fileToComponents.values()); - fileToComponents.values().retainAll(components); - final ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(fileToComponents, false, - IdeBundle.message("title.select.components.to.import"), - IdeBundle.message("prompt.check.components.to.import")); + val fileToComponents = getExportableComponentsMap(false, true) + val components = getComponentsStored(saveFile, fileToComponents.values()) + fileToComponents.values().retainAll(components) + val dialog = ChooseComponentsToExportDialog(fileToComponents, false, + IdeBundle.message("title.select.components.to.import"), + IdeBundle.message("prompt.check.components.to.import")) if (!dialog.showAndGet()) { - return; + return } - final Set chosenComponents = dialog.getExportableComponents(); - Set relativeNamesToExtract = new THashSet(); - for (ExportableComponent chosenComponent : chosenComponents) { - for (File exportFile : chosenComponent.getExportFiles()) { - String rPath = FileUtilRt.getRelativePath(new File(PathManager.getConfigPath()), exportFile); - assert rPath != null; - relativeNamesToExtract.add(FileUtil.toSystemIndependentName(rPath)); + val chosenComponents = dialog.exportableComponents + val relativeNamesToExtract = THashSet() + for (chosenComponent in chosenComponents) { + for (exportFile in chosenComponent.exportFiles) { + relativeNamesToExtract.add(FileUtil.toSystemIndependentName(FileUtilRt.getRelativePath(File(PathManager.getConfigPath()), exportFile)!!)) } } - relativeNamesToExtract.add(PluginManager.INSTALLED_TXT); + relativeNamesToExtract.add(PluginManager.INSTALLED_TXT) - final File tempFile = new File(PathManager.getPluginTempPath() + "/" + saveFile.getName()); - FileUtil.copy(saveFile, tempFile); - File outDir = new File(PathManager.getConfigPath()); - final ImportSettingsFilenameFilter filenameFilter = new ImportSettingsFilenameFilter(relativeNamesToExtract); - StartupActionScriptManager.addActionCommand(new StartupActionScriptManager.UnzipCommand(tempFile, outDir, filenameFilter)); + val tempFile = File(PathManager.getPluginTempPath(), saveFile.name) + FileUtil.copy(saveFile, tempFile) + val outDir = File(PathManager.getConfigPath()) + val filenameFilter = ImportSettingsFilenameFilter(relativeNamesToExtract) + StartupActionScriptManager.addActionCommand(StartupActionScriptManager.UnzipCommand(tempFile, outDir, filenameFilter)) // remove temp file - StartupActionScriptManager.addActionCommand(new StartupActionScriptManager.DeleteCommand(tempFile)); + StartupActionScriptManager.addActionCommand(StartupActionScriptManager.DeleteCommand(tempFile)) - UpdateSettings.getInstance().forceCheckForUpdateAfterRestart(); + UpdateSettings.getInstance().forceCheckForUpdateAfterRestart() - String key = ApplicationManager.getApplication().isRestartCapable() - ? "message.settings.imported.successfully.restart" - : "message.settings.imported.successfully"; + val key = if (ApplicationManager.getApplication().isRestartCapable) + "message.settings.imported.successfully.restart" + else + "message.settings.imported.successfully" if (Messages.showOkCancelDialog(IdeBundle.message(key, - ApplicationNamesInfo.getInstance().getProductName(), - ApplicationNamesInfo.getInstance().getFullProductName()), - IdeBundle.message("title.restart.needed"), Messages.getQuestionIcon()) == Messages.OK) { - ((ApplicationEx)ApplicationManager.getApplication()).restart(true); + ApplicationNamesInfo.getInstance().productName, + ApplicationNamesInfo.getInstance().fullProductName), + IdeBundle.message("title.restart.needed"), Messages.getQuestionIcon()) == Messages.OK) { + (ApplicationManager.getApplication() as ApplicationEx).restart(true) } } - private static String presentableFileName(@NotNull File file) { - return "'" + FileUtil.toSystemDependentName(file.getPath()) + "'"; - } + private fun presentableFileName(file: File) = "'" + FileUtil.toSystemDependentName(file.path) + "'" - private static String promptLocationMessage() { - return IdeBundle.message("message.please.ensure.correct.settings"); - } + private fun promptLocationMessage() = IdeBundle.message("message.please.ensure.correct.settings") - @NotNull - private static List getComponentsStored(@NotNull File settings, - @NotNull Collection registeredComponents) throws IOException { - THashSet zipEntries = new THashSet(); - ZipFile zip = new ZipFile(settings); - try { - Enumeration enumeration = zip.entries(); + private fun getComponentsStored(settings: File, registeredComponents: Collection): List { + val zipEntries = THashSet() + ZipFile(settings).use { + val enumeration = it.entries() while (enumeration.hasMoreElements()) { - ZipEntry zipEntry = (ZipEntry)enumeration.nextElement(); - zipEntries.add(zipEntry.getName()); + zipEntries.add(enumeration.nextElement().name) } } - finally { - zip.close(); - } - File configPath = new File(PathManager.getConfigPath()); - List components = new ArrayList(); - - for (ExportableComponent component : registeredComponents) { - for (File exportFile : component.getExportFiles()) { - String relativePath = FileUtilRt.getRelativePath(configPath, exportFile); - assert relativePath != null; - relativePath = FileUtilRt.toSystemIndependentName(relativePath); - if (exportFile.getName().indexOf('.') == -1 && !exportFile.isFile()) { - relativePath += '/'; + val configPath = File(PathManager.getConfigPath()) + val components = ArrayList() + for (component in registeredComponents) { + for (exportFile in component.exportFiles) { + var relativePath = FileUtilRt.getRelativePath(configPath, exportFile)!! + relativePath = FileUtilRt.toSystemIndependentName(relativePath) + if (exportFile.name.indexOf('.') == -1 && !exportFile.isFile) { + relativePath += '/' } if (zipEntries.contains(relativePath)) { - components.add(component); - break; + components.add(component) + break } } } - return components; + return components } } diff --git a/plugins/settings-repository/src/copyAppSettingsToRepository.kt b/plugins/settings-repository/src/copyAppSettingsToRepository.kt index d638b61f4303..520355b69a1d 100644 --- a/plugins/settings-repository/src/copyAppSettingsToRepository.kt +++ b/plugins/settings-repository/src/copyAppSettingsToRepository.kt @@ -17,7 +17,8 @@ package org.jetbrains.settingsRepository import com.intellij.configurationStore.ROOT_CONFIG import com.intellij.configurationStore.StateStorageManagerImpl -import com.intellij.ide.actions.ExportSettingsAction +import com.intellij.ide.actions.ExportableComponentItem +import com.intellij.ide.actions.getExportableComponentsMap import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.* import com.intellij.openapi.util.io.FileUtil @@ -27,7 +28,7 @@ import java.io.File fun copyLocalConfig(storageManager: StateStorageManagerImpl = ApplicationManager.getApplication()!!.stateStore.stateStorageManager as StateStorageManagerImpl) { val streamProvider = storageManager.streamProvider!! as IcsManager.IcsStreamProvider - val fileToComponents = ExportSettingsAction.getExportableComponentsMap(true, false, storageManager) + val fileToComponents = getExportableComponentsMap(true, false, storageManager) for (file in fileToComponents.keySet()) { val absolutePath = FileUtilRt.toSystemIndependentName(file.absolutePath) var fileSpec = storageManager.collapseMacros(absolutePath) @@ -69,7 +70,7 @@ private fun saveDirectory(parent: File, parentFileSpec: String, roamingType: Roa private fun getRoamingType(components: Collection): RoamingType { for (component in components) { - if (component is ExportSettingsAction.ExportableComponentItem) { + if (component is ExportableComponentItem) { return component.roamingType } else if (component is PersistentStateComponent<*>) { From 95d28bd5beb6cce844ea0bcb29d989c291eb83a6 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 29 Sep 2015 15:29:10 +0200 Subject: [PATCH 21/50] Import/Export SettingsAction in kotlin --- .../{ExportSettingsAction.java => ExportSettingsAction.kt} | 0 .../{ImportSettingsAction.java => ImportSettingsAction.kt} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename platform/platform-impl/src/com/intellij/ide/actions/{ExportSettingsAction.java => ExportSettingsAction.kt} (100%) rename platform/platform-impl/src/com/intellij/ide/actions/{ImportSettingsAction.java => ImportSettingsAction.kt} (100%) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.kt similarity index 100% rename from platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java rename to platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.kt diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.kt similarity index 100% rename from platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java rename to platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.kt From dc4b1d3c8fc83ab783b6ac2fcf698a285551bc38 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 29 Sep 2015 16:53:27 +0200 Subject: [PATCH 22/50] cleanup --- .../configuration-store-impl/testSrc/ModuleStoreTest.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt b/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt index 2082a7ceea56..d48f33c9210f 100644 --- a/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt @@ -39,7 +39,7 @@ class ModuleStoreTest { } } - private fun VirtualFile.loadModule() = runWriteAction { ModuleManager.getInstance(projectRule.project).loadModule(getPath()) } + private fun VirtualFile.loadModule() = runWriteAction { ModuleManager.getInstance(projectRule.project).loadModule(path) } fun Path.createModule() = projectRule.createModule(this) } @@ -51,8 +51,7 @@ class ModuleStoreTest { @Test fun `set option`() { val moduleFile = runWriteAction { - VfsTestUtil.createFile(tempDirManager.newVirtualDirectory("module"), "test.iml", "\n" + - "") + VfsTestUtil.createFile(tempDirManager.newVirtualDirectory("module"), "test.iml", "\n") } moduleFile.loadModule().useAndDispose { @@ -117,7 +116,7 @@ class ModuleStoreTest { assertThat(moduleFile).isRegularFile() val virtualFile = LocalFileSystem.getInstance().findFileByPath(modulePath)!! - val newData = moduleFile.readText().replace("\n", "").toByteArray() + val newData = moduleFile.readText().replace("\n", "").toByteArray() runWriteAction { virtualFile.setBinaryContent(newData) } From 54f41430afc7ac0e7f955e4b6fd1ec834ac6570f Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 29 Sep 2015 16:54:55 +0200 Subject: [PATCH 23/50] test `export settings` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ExportableItem — "files" as list instead of array to be able to compare it (arrays are compated using reference, it is not suitable for us) --- .../testSrc/ApplicationStoreTest.kt | 14 ++++++ .../ChooseComponentsToExportDialog.java | 30 ++++++------- .../ide/actions/ExportSettingsAction.kt | 44 +++++++------------ .../ide/actions/ImportSettingsAction.kt | 9 ++-- .../fileTypes/impl/FileTypeManagerImpl.java | 2 +- .../intellij/openapi/components/State.java | 3 ++ .../src/copyAppSettingsToRepository.kt | 27 ++++++------ 7 files changed, 68 insertions(+), 61 deletions(-) diff --git a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt index 27ac1dbc5e2e..3e8a1fc3e03f 100644 --- a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt @@ -15,6 +15,8 @@ */ package com.intellij.configurationStore +import com.intellij.ide.actions.ExportableItem +import com.intellij.ide.actions.getExportableComponentsMap import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.* import com.intellij.openapi.vfs.CharsetToolkit @@ -33,6 +35,7 @@ import org.junit.ClassRule import org.junit.Rule import org.junit.Test import java.io.ByteArrayInputStream +import java.io.File import java.io.InputStream import java.nio.file.Path import java.nio.file.Paths @@ -109,6 +112,17 @@ internal class ApplicationStoreTest { assertThat(oldFile).doesNotExist() } + @Test fun `export settings`() { + val storageManager = ApplicationManager.getApplication().stateStore.stateStorageManager + val optionsPath = storageManager.expandMacros(StoragePathMacros.APP_CONFIG) + val rootConfigPath = storageManager.expandMacros(ROOT_CONFIG) + val map = getExportableComponentsMap(false, true, storageManager) + assertThat(map.size()).isNotEqualTo(0) + + val key = File(optionsPath, "filetypes.xml") + assertThat(map.get(key)).containsExactly(ExportableItem(listOf(key, File(rootConfigPath, "filetypes")), "File types", RoamingType.DEFAULT)) + } + private fun createComponentData(foo: String) = """""" @Test fun `remove data from deprecated storage if another component data exists`() { diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java b/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java index 686c20b4f0b9..cf83ac0e14ad 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java @@ -19,7 +19,6 @@ import com.intellij.ide.IdeBundle; import com.intellij.ide.util.ElementsChooser; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.components.ExportableComponent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; @@ -32,6 +31,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.FieldPanel; +import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; import com.intellij.util.containers.MultiMap; import gnu.trove.THashSet; @@ -57,14 +57,14 @@ public class ChooseComponentsToExportDialog extends DialogWrapper { private final boolean myShowFilePath; private final String myDescription; - public ChooseComponentsToExportDialog(@NotNull MultiMap fileToComponents, + public ChooseComponentsToExportDialog(@NotNull MultiMap fileToComponents, boolean showFilePath, final String title, String description) { super(false); myDescription = description; myShowFilePath = showFilePath; - Map componentToContainingListElement = new LinkedHashMap(); - for (ExportableComponent component : fileToComponents.values()) { + Map componentToContainingListElement = new LinkedHashMap(); + for (ExportableItem component : fileToComponents.values()) { if (!addToExistingListElement(component, componentToContainingListElement, fileToComponents)) { ComponentElementProperties componentElementProperties = new ComponentElementProperties(); componentElementProperties.addComponent(component); @@ -147,12 +147,12 @@ public class ChooseComponentsToExportDialog extends DialogWrapper { super.doOKAction(); } - private static boolean addToExistingListElement(@NotNull ExportableComponent component, - @NotNull Map componentToContainingListElement, - @NotNull MultiMap fileToComponents) { + private static boolean addToExistingListElement(@NotNull ExportableItem component, + @NotNull Map componentToContainingListElement, + @NotNull MultiMap fileToComponents) { File file = null; - for (File exportFile : component.getExportFiles()) { - for (ExportableComponent tiedComponent : fileToComponents.get(exportFile)) { + for (File exportFile : component.getFiles()) { + for (ExportableItem tiedComponent : fileToComponents.get(exportFile)) { if (tiedComponent == component) { continue; } @@ -234,8 +234,8 @@ public class ChooseComponentsToExportDialog extends DialogWrapper { return panel; } - Set getExportableComponents() { - Set components = new THashSet(); + Set getExportableComponents() { + Set components = new THashSet(); for (ComponentElementProperties elementProperties : myChooser.getMarkedElements()) { components.addAll(elementProperties.myComponents); } @@ -243,9 +243,9 @@ public class ChooseComponentsToExportDialog extends DialogWrapper { } private static class ComponentElementProperties implements ElementsChooser.ElementProperties { - private final Set myComponents = new HashSet(); + private final Set myComponents = new HashSet(); - private boolean addComponent(ExportableComponent component) { + private boolean addComponent(ExportableItem component) { return myComponents.add(component); } @@ -263,10 +263,10 @@ public class ChooseComponentsToExportDialog extends DialogWrapper { public String toString() { Set names = new LinkedHashSet(); - for (ExportableComponent component : myComponents) { + for (ExportableItem component : myComponents) { names.add(component.getPresentableName()); } - return StringUtil.join(names.toArray(new String[names.size()]), ", "); + return StringUtil.join(ArrayUtil.toStringArray(names), ", "); } } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.kt b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.kt index 33b2de119996..d547d67d234e 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.kt +++ b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.kt @@ -42,11 +42,9 @@ import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.util.PairProcessor import com.intellij.util.PlatformUtils import com.intellij.util.ReflectionUtil -import com.intellij.util.containers.ContainerUtil import com.intellij.util.containers.MultiMap import com.intellij.util.io.ZipUtil import gnu.trove.THashSet - import java.io.* import java.util.* import java.util.zip.ZipEntry @@ -71,7 +69,7 @@ private class ExportSettingsAction : AnAction(), DumbAware { val exportFiles = THashSet(FileUtil.FILE_HASHING_STRATEGY) for (markedComponent in markedComponents) { - ContainerUtil.addAll>(exportFiles, *markedComponent.exportFiles) + exportFiles.addAll(markedComponent.files) } val saveFile = dialog.exportFile @@ -120,11 +118,7 @@ private class MyZipOutputStream(out: OutputStream) : ZipOutputStream(out) { } } -class ExportableComponentItem(private val files: Array, private val name: String, val roamingType: RoamingType) : ExportableComponent { - override fun getExportFiles() = files - - override fun getPresentableName() = name -} +data class ExportableItem(val files: List, val presentableName: String, val roamingType: RoamingType) private val LOG = Logger.getInstance(ExportSettingsAction::class.java) @@ -149,11 +143,12 @@ private fun exportInstalledPlugins(zipOut: MyZipOutputStream) { } } -fun getExportableComponentsMap(onlyExisting: Boolean, computePresentableNames: Boolean, storageManager: StateStorageManager = ApplicationManager.getApplication().stateStore.stateStorageManager): MultiMap { - val result = MultiMap.createLinkedSet() +fun getExportableComponentsMap(onlyExisting: Boolean, computePresentableNames: Boolean, storageManager: StateStorageManager = ApplicationManager.getApplication().stateStore.stateStorageManager): MultiMap { + val result = MultiMap.createLinkedSet() val processor = { component: ExportableComponent -> - for (exportFile in component.exportFiles) { - result.putValue(exportFile, component) + val item = ExportableItem(component.exportFiles.toList(), component.presentableName, RoamingType.DEFAULT) + for (exportFile in item.files) { + result.putValue(exportFile, item) } } @@ -188,16 +183,16 @@ fun getExportableComponentsMap(onlyExisting: Boolean, computePresentableNames: B } val storage = storages[storageIndex] - if (storage.roamingType != RoamingType.DISABLED && storage.storageClass == StateStorage::class.java && storage.scheme == StorageScheme.DEFAULT && !StringUtil.isEmpty(storage.file) && storage.file.startsWith(StoragePathMacros.APP_CONFIG)) { + if (storage.roamingType != RoamingType.DISABLED && storage.storageClass == StateStorage::class && storage.scheme == StorageScheme.DEFAULT && !storage.file.isNullOrEmpty()) { var additionalExportFile: File? = null - if (!StringUtil.isEmpty(stateAnnotation.additionalExportFile)) { - val expandedPath = storageManager.expandMacros(stateAnnotation.additionalExportFile) - additionalExportFile = File(expandedPath) - if (!additionalExportFile.exists()) { - //noinspection deprecation - additionalExportFile = File(storageManager.expandMacros(StoragePathMacros.ROOT_CONFIG) + '/' + expandedPath) + var additionalExportPath = stateAnnotation.additionalExportFile + if (additionalExportPath.isNotEmpty()) { + // backward compatibility - path can contain macro + @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") + if (additionalExportPath[0] != '$') { + additionalExportPath = StoragePathMacros.ROOT_CONFIG + "/" + additionalExportPath } - + additionalExportFile = File(storageManager.expandMacros(additionalExportPath)) if (onlyExisting && !additionalExportFile.exists()) { additionalExportFile = null } @@ -206,13 +201,8 @@ fun getExportableComponentsMap(onlyExisting: Boolean, computePresentableNames: B val file = File(storageManager.expandMacros(storage.file)) val fileExists = !onlyExisting || file.exists() if (fileExists || additionalExportFile != null) { - val files = if (additionalExportFile == null) { - arrayOf(file) - } - else { - if (fileExists) arrayOf(file, additionalExportFile) else arrayOf(additionalExportFile) - } - val item = ExportableComponentItem(files, if (computePresentableNames) getComponentPresentableName(stateAnnotation, aClass, pluginDescriptor) else "", storage.roamingType) + val files = if (additionalExportFile == null) listOf(file) else if (fileExists) listOf(file, additionalExportFile) else listOf(additionalExportFile) + val item = ExportableItem(files, if (computePresentableNames) getComponentPresentableName(stateAnnotation, aClass, pluginDescriptor) else "", storage.roamingType) result.putValue(file, item) if (additionalExportFile != null) { result.putValue(additionalExportFile, item) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.kt b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.kt index e3f5aaf13b8f..16a57a782540 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.kt +++ b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.kt @@ -25,7 +25,6 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationNamesInfo import com.intellij.openapi.application.PathManager import com.intellij.openapi.application.ex.ApplicationEx -import com.intellij.openapi.components.ExportableComponent import com.intellij.openapi.project.DumbAware import com.intellij.openapi.ui.Messages import com.intellij.openapi.updateSettings.impl.UpdateSettings @@ -91,7 +90,7 @@ private class ImportSettingsAction : AnAction(), DumbAware { val chosenComponents = dialog.exportableComponents val relativeNamesToExtract = THashSet() for (chosenComponent in chosenComponents) { - for (exportFile in chosenComponent.exportFiles) { + for (exportFile in chosenComponent.files) { relativeNamesToExtract.add(FileUtil.toSystemIndependentName(FileUtilRt.getRelativePath(File(PathManager.getConfigPath()), exportFile)!!)) } } @@ -124,7 +123,7 @@ private class ImportSettingsAction : AnAction(), DumbAware { private fun promptLocationMessage() = IdeBundle.message("message.please.ensure.correct.settings") - private fun getComponentsStored(settings: File, registeredComponents: Collection): List { + private fun getComponentsStored(settings: File, registeredComponents: Collection): List { val zipEntries = THashSet() ZipFile(settings).use { val enumeration = it.entries() @@ -134,9 +133,9 @@ private class ImportSettingsAction : AnAction(), DumbAware { } val configPath = File(PathManager.getConfigPath()) - val components = ArrayList() + val components = ArrayList() for (component in registeredComponents) { - for (exportFile in component.exportFiles) { + for (exportFile in component.files) { var relativePath = FileUtilRt.getRelativePath(configPath, exportFile)!! relativePath = FileUtilRt.toSystemIndependentName(relativePath) if (exportFile.name.indexOf('.') == -1 && !exportFile.isFile) { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java index 04dda45f891d..6bca569c45ac 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java @@ -71,7 +71,7 @@ import java.util.concurrent.atomic.AtomicLong; @State( name = "FileTypeManager", - storages = @Storage(file = StoragePathMacros.APP_CONFIG + "/filetypes.xml"), + storages = @Storage(file = "filetypes.xml"), additionalExportFile = FileTypeManagerImpl.FILE_SPEC ) public class FileTypeManagerImpl extends FileTypeManagerEx implements PersistentStateComponent, ApplicationComponent, Disposable { diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/State.java b/platform/projectModel-api/src/com/intellij/openapi/components/State.java index 1f76209076bb..3dc82b321ec6 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/components/State.java +++ b/platform/projectModel-api/src/com/intellij/openapi/components/State.java @@ -36,6 +36,9 @@ public @interface State { */ boolean defaultStateAsResource() default false; + /** + * Additional export path (relative to application-level configuration root directory). + */ String additionalExportFile() default ""; Class presentableName() default NameGetter.class; diff --git a/plugins/settings-repository/src/copyAppSettingsToRepository.kt b/plugins/settings-repository/src/copyAppSettingsToRepository.kt index 520355b69a1d..435a9116a2dc 100644 --- a/plugins/settings-repository/src/copyAppSettingsToRepository.kt +++ b/plugins/settings-repository/src/copyAppSettingsToRepository.kt @@ -17,10 +17,11 @@ package org.jetbrains.settingsRepository import com.intellij.configurationStore.ROOT_CONFIG import com.intellij.configurationStore.StateStorageManagerImpl -import com.intellij.ide.actions.ExportableComponentItem +import com.intellij.ide.actions.ExportableItem import com.intellij.ide.actions.getExportableComponentsMap import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.components.* +import com.intellij.openapi.components.RoamingType +import com.intellij.openapi.components.stateStore import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtilRt import java.io.File @@ -68,20 +69,20 @@ private fun saveDirectory(parent: File, parentFileSpec: String, roamingType: Roa } } -private fun getRoamingType(components: Collection): RoamingType { +private fun getRoamingType(components: Collection): RoamingType { for (component in components) { - if (component is ExportableComponentItem) { + if (component is ExportableItem) { return component.roamingType } - else if (component is PersistentStateComponent<*>) { - val stateAnnotation = component.javaClass.getAnnotation(State::class.java) - if (stateAnnotation != null) { - val storages = stateAnnotation.storages - if (!storages.isEmpty()) { - return storages[0].roamingType - } - } - } +// else if (component is PersistentStateComponent<*>) { +// val stateAnnotation = component.javaClass.getAnnotation(State::class.java) +// if (stateAnnotation != null) { +// val storages = stateAnnotation.storages +// if (!storages.isEmpty()) { +// return storages[0].roamingType +// } +// } +// } } return RoamingType.DEFAULT } \ No newline at end of file From 38217a3e360ac904edbc6c3fbbc7e348003ac678 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 29 Sep 2015 17:00:54 +0200 Subject: [PATCH 24/50] test basePath --- .../testSrc/DirectoryBasedStorageTest.kt | 2 +- .../testSrc/ProjectStoreTest.kt | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/platform/configuration-store-impl/testSrc/DirectoryBasedStorageTest.kt b/platform/configuration-store-impl/testSrc/DirectoryBasedStorageTest.kt index 27663ecbc040..75d15662fe08 100644 --- a/platform/configuration-store-impl/testSrc/DirectoryBasedStorageTest.kt +++ b/platform/configuration-store-impl/testSrc/DirectoryBasedStorageTest.kt @@ -40,7 +40,7 @@ private fun StateStorage.ExternalizationSession.save() { private fun StateStorageBase<*>.setStateAndSave(componentName: String, state: String?) { var externalizationSession = startExternalization()!! - externalizationSession.setState(null, componentName, if (state == null) Element("state") else JDOMUtil.load(state.reader)) + externalizationSession.setState(null, componentName, if (state == null) Element("state") else JDOMUtil.load(state.reader())) externalizationSession.save() } diff --git a/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt b/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt index 1e66ba93b924..8eab00a7b829 100644 --- a/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt @@ -25,6 +25,7 @@ import com.intellij.openapi.project.impl.ProjectManagerImpl import com.intellij.openapi.util.io.systemIndependentPath import com.intellij.openapi.vfs.VirtualFile import com.intellij.testFramework.* +import com.intellij.util.PathUtil import org.assertj.core.api.Assertions.assertThat import org.intellij.lang.annotations.Language import org.junit.ClassRule @@ -64,7 +65,7 @@ private fun createOrLoadProject(tempDirManager: TemporaryDirectory, task: (Proje } } -class ProjectStoreTest { +internal class ProjectStoreTest { companion object { @ClassRule val projectRule = ProjectRule() } @@ -76,12 +77,7 @@ class ProjectStoreTest { @Language("XML") private val iprFileContent = - "\n" + - "\n" + - " \n" + - " \n" + - "" + "\n\n \n \n" @State(name = "AATestComponent", storages = arrayOf(Storage(file = StoragePathMacros.PROJECT_FILE))) private class TestComponent : PersistentStateComponent { @@ -103,6 +99,8 @@ class ProjectStoreTest { }) { project -> val testComponent = test(project) + assertThat(project.basePath).isEqualTo(PathUtil.getParentPath((PathUtil.getParentPath(project.projectFilePath!!)))) + // test reload on external change val file = File(project.stateStore.stateStorageManager.expandMacros(StoragePathMacros.PROJECT_FILE)) file.writeText(file.readText().replace(""" - - + \ No newline at end of file From c2495cab5dbba11377200175c50b1f41888de5e3 Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 29 Sep 2015 18:31:09 +0300 Subject: [PATCH 27/50] build.xml for IDEA CE: pass system properties without adding extra quotes to fix build on Linux --- build.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/build.xml b/build.xml index ab62c1eb1932..1dc77e703914 100644 --- a/build.xml +++ b/build.xml @@ -42,15 +42,15 @@ - - - - - + + + + + - - - + + + From b74bc547c46f21ea065d93afdf59a3ebba03bc4e Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 29 Sep 2015 18:33:30 +0300 Subject: [PATCH 28/50] ignore empty idea.test.patterns property to simplify build scripts --- platform/testFramework/src/com/intellij/TestCaseLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/testFramework/src/com/intellij/TestCaseLoader.java b/platform/testFramework/src/com/intellij/TestCaseLoader.java index 376a08b8bc63..505f3320b739 100644 --- a/platform/testFramework/src/com/intellij/TestCaseLoader.java +++ b/platform/testFramework/src/com/intellij/TestCaseLoader.java @@ -65,7 +65,7 @@ public class TestCaseLoader { public TestCaseLoader(String classFilterName, boolean forceLoadPerformanceTests) { myForceLoadPerformanceTests = forceLoadPerformanceTests; String patterns = System.getProperty(TARGET_TEST_PATTERNS); - if (patterns != null) { + if (!StringUtil.isEmpty(patterns)) { myTestClassesFilter = new PatternListTestClassFilter(StringUtil.split(patterns, ";")); System.out.println("Using patterns: [" + patterns +"]"); } From b7e190473fd37210c7cc11240367a04258b9f51f Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 29 Sep 2015 18:34:19 +0300 Subject: [PATCH 29/50] corrected default value of idea.test.patterns for IDEA CE build --- build.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.xml b/build.xml index 1dc77e703914..dd8c90d39069 100644 --- a/build.xml +++ b/build.xml @@ -16,8 +16,7 @@ - + From 04c83bb295edf232db5f3a94e4e113fa7711189b Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 29 Sep 2015 17:38:05 +0200 Subject: [PATCH 30/50] kotlin M13 compatibility --- .../src/com/intellij/ide/actions/ImportSettingsAction.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.kt b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.kt index 16a57a782540..44e4d5c57f8e 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.kt +++ b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.kt @@ -125,12 +125,16 @@ private class ImportSettingsAction : AnAction(), DumbAware { private fun getComponentsStored(settings: File, registeredComponents: Collection): List { val zipEntries = THashSet() - ZipFile(settings).use { - val enumeration = it.entries() + val zipFile = ZipFile(settings) + try { + val enumeration = zipFile.entries() while (enumeration.hasMoreElements()) { zipEntries.add(enumeration.nextElement().name) } } + finally { + zipFile.close() + } val configPath = File(PathManager.getConfigPath()) val components = ArrayList() From 9e8d7ed9c8ff892e1c59eee1431d006a98b7cc63 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 29 Sep 2015 17:53:54 +0200 Subject: [PATCH 31/50] [project] inspection profiles tuned --- .idea/inspectionProfiles/idea_default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.idea/inspectionProfiles/idea_default.xml b/.idea/inspectionProfiles/idea_default.xml index 926c4b8e2b99..af758032d20b 100644 --- a/.idea/inspectionProfiles/idea_default.xml +++ b/.idea/inspectionProfiles/idea_default.xml @@ -258,7 +258,7 @@ - From 393bdc0d4e4a570683570f33b08aed995767f0ca Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 29 Sep 2015 12:57:02 +0200 Subject: [PATCH 32/50] catch NoSuchMethodError in case old testng version is used --- .../org/testng/IDEATestNGRemoteListener.java | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java b/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java index 5664908788bf..6232db10a13a 100644 --- a/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java +++ b/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java @@ -31,39 +31,45 @@ public class IDEATestNGRemoteListener implements ISuiteListener, IResultListener public synchronized void onStart(final ISuite suite) { if (suite != null) { - final List allMethods = suite.getAllMethods(); - if (allMethods != null) { - int count = 0; - for (ITestNGMethod method : allMethods) { - if (method.isTest()) count += method.getInvocationCount(); + try { + final List allMethods = suite.getAllMethods(); + if (allMethods != null) { + int count = 0; + for (ITestNGMethod method : allMethods) { + if (method.isTest()) count += method.getInvocationCount(); + } + myPrintStream.println("##teamcity[testCount count = \'" + count + "\']"); } - myPrintStream.println("##teamcity[testCount count = \'" + count + "\']"); } + catch (NoSuchMethodError ignore) {} myPrintStream.println("##teamcity[rootName name = '" + suite.getName() + "' location = 'file://" + suite.getXmlSuite().getFileName() + "']"); } } public synchronized void onFinish(ISuite suite) { - if (suite != null && suite.getAllInvokedMethods().size() < suite.getAllMethods().size()) { - for (ITestNGMethod method : suite.getAllMethods()) { - if (method.isTest()) { - boolean found = false; - for (IInvokedMethod invokedMethod : suite.getAllInvokedMethods()) { - if (invokedMethod.getTestMethod() == method) { - found = true; + try { + if (suite != null && suite.getAllInvokedMethods().size() < suite.getAllMethods().size()) { + for (ITestNGMethod method : suite.getAllMethods()) { + if (method.isTest()) { + boolean found = false; + for (IInvokedMethod invokedMethod : suite.getAllInvokedMethods()) { + if (invokedMethod.getTestMethod() == method) { + found = true; + break; + } + } + if (!found) { + final String fullEscapedMethodName = escapeName(getShortName(method.getTestClass().getName()) + "." + method.getMethodName()); + myPrintStream.println("##teamcity[testStarted name=\'" + fullEscapedMethodName + "\']"); + myPrintStream.println("##teamcity[testIgnored name=\'" + fullEscapedMethodName + "\']"); + myPrintStream.println("##teamcity[testFinished name=\'" + fullEscapedMethodName + "\']"); break; } } - if (!found) { - final String fullEscapedMethodName = escapeName(getShortName(method.getTestClass().getName()) + "." + method.getMethodName()); - myPrintStream.println("##teamcity[testStarted name=\'" + fullEscapedMethodName + "\']"); - myPrintStream.println("##teamcity[testIgnored name=\'" + fullEscapedMethodName + "\']"); - myPrintStream.println("##teamcity[testFinished name=\'" + fullEscapedMethodName + "\']"); - break; - } } } } + catch (NoSuchMethodError ignored) {} for (int i = myCurrentSuites.size() - 1; i >= 0; i--) { onSuiteFinish(myCurrentSuites.remove(i)); } From 4ef09cd872fc6a33561782e5c55fe6dd32dddd8a Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 29 Sep 2015 14:22:34 +0200 Subject: [PATCH 33/50] EA-69541 - assert: TestMethod.addJUnitParameter for configuration with wrong class which is just ignored to proceed with junit error in console --- plugins/junit/src/com/intellij/execution/junit/TestMethod.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/junit/src/com/intellij/execution/junit/TestMethod.java b/plugins/junit/src/com/intellij/execution/junit/TestMethod.java index 013c0e908bf2..3b68c8fb60f8 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestMethod.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestMethod.java @@ -51,8 +51,7 @@ class TestMethod extends TestObject { protected void addJUnit3Parameter(JavaParameters javaParameters, final JUnitConfiguration.Data data, Project project) throws ExecutionException { final PsiClass psiClass = JavaExecutionUtil.findMainClass(project, data.getMainClassName(), GlobalSearchScope.allScope(project)); - LOG.assertTrue(psiClass != null); - if (JUnitUtil.isJUnit4TestClass(psiClass)) { + if (psiClass == null || JUnitUtil.isJUnit4TestClass(psiClass)) { return; } final String methodName = data.getMethodName(); From ef90ef8f630ef40fdc1a3ba2ef8eb1631ec5a7ec Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 29 Sep 2015 15:13:28 +0200 Subject: [PATCH 34/50] ensure logged EA-68436 - NPE: TestFailedEvent. --- .../sm/runner/OutputToGeneralTestEventsConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java index 0d338cea014c..c947d6feb3a4 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/OutputToGeneralTestEventsConverter.java @@ -428,7 +428,7 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer public void visitTestFailed(@NotNull final TestFailed testFailed) { final Map attributes = testFailed.getAttributes(); - assert testFailed.getFailureMessage() != null : "No failure message for: " + myTestFrameworkName; + LOG.assertTrue(testFailed.getFailureMessage() != null, "No failure message for: " + myTestFrameworkName); final boolean testError = attributes.get(ATTR_KEY_TEST_ERROR) != null; TestFailedEvent testFailedEvent = new TestFailedEvent(testFailed, testError, attributes.get(ATTR_KEY_EXPECTED_FILE_PATH), From 090038722ab27356818bcf16b76f77d110684348 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 29 Sep 2015 17:34:29 +0200 Subject: [PATCH 35/50] EA-70589 - IOE: PsiJavaParserFacadeImpl.createExpressionFromText --- .../LambdaCanBeMethodReferenceInspection.java | 12 ++++++++++-- ...eterizedContainerClassToReceiverMethodRef.java | 15 +++++++++++++++ ...eterizedContainerClassToReceiverMethodRef.java | 15 +++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java index ff96f4025ca5..140f672f1a30 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java @@ -26,6 +26,7 @@ import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.util.*; import com.intellij.util.ArrayUtil; +import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -413,8 +414,15 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp } final PsiType qualifierExpressionType = qualifierExpression.getType(); - return qualifierExpressionType != null && !TypeConversionUtil.containsWildcards(qualifierExpressionType) - ? qualifierExpressionType.getCanonicalText() : getClassReferenceName(containingClass); + if (qualifierExpressionType != null && !TypeConversionUtil.containsWildcards(qualifierExpressionType)) { + try { + final String canonicalText = qualifierExpressionType.getCanonicalText(); + JavaPsiFacade.getElementFactory(containingClass.getProject()).createExpressionFromText(canonicalText + "::foo", qualifierExpression); + return canonicalText; + } + catch (IncorrectOperationException ignore){} + } + return getClassReferenceName(containingClass); } private static String getClassReferenceName(PsiClass containingClass) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java new file mode 100644 index 000000000000..d4db9714b032 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java @@ -0,0 +1,15 @@ +// "Replace lambda with method reference" "true" + +import java.util.function.Function; + +class Test { + + + class Bar { + void f( ){ + Function.Bar, String> r = Bar::foo; + } + + private String foo() {} + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java new file mode 100644 index 000000000000..04df9584ad1a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java @@ -0,0 +1,15 @@ +// "Replace lambda with method reference" "true" + +import java.util.function.Function; + +class Test { + + + class Bar { + void f( ){ + Function.Bar, String> r = (Test.Bar t) -> t.foo(); + } + + private String foo() {} + } +} From 6cc077a47bb821086b937e39a82b20403676f83a Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Tue, 29 Sep 2015 19:07:17 +0300 Subject: [PATCH 36/50] better naming as SHELL environment is CONSOLE --- .../execution/configuration/EnvironmentVariablesData.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesData.java b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesData.java index 68be1752b60f..b52e1046487c 100644 --- a/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesData.java +++ b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesData.java @@ -115,10 +115,10 @@ public class EnvironmentVariablesData { parent.addContent(envsElement); } - public void configureCommandLine(@NotNull GeneralCommandLine commandLine, boolean shellParentEnvs) { + public void configureCommandLine(@NotNull GeneralCommandLine commandLine, boolean consoleParentEnvs) { if (myPassParentEnvs) { - commandLine.withParentEnvironmentType(shellParentEnvs ? GeneralCommandLine.ParentEnvironmentType.CONSOLE - : GeneralCommandLine.ParentEnvironmentType.SYSTEM); + commandLine.withParentEnvironmentType(consoleParentEnvs ? GeneralCommandLine.ParentEnvironmentType.CONSOLE + : GeneralCommandLine.ParentEnvironmentType.SYSTEM); } else { commandLine.withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.NONE); From c65b449edf9d04a475ff9ce1c6762e626c39da03 Mon Sep 17 00:00:00 2001 From: Michael Golubev Date: Tue, 29 Sep 2015 16:39:55 +0200 Subject: [PATCH 37/50] IDEA-145685 - Settings do not respect Apply/Cancel button --- .../DeployToServerRunConfiguration.java | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java index 6c133cc28eb1..d5eb4c6e6070 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java @@ -17,10 +17,7 @@ package com.intellij.remoteServer.impl.configuration.deployment; import com.intellij.execution.ExecutionException; import com.intellij.execution.Executor; -import com.intellij.execution.configurations.ConfigurationFactory; -import com.intellij.execution.configurations.RunConfigurationBase; -import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.configurations.RuntimeConfigurationException; +import com.intellij.execution.configurations.*; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.application.Result; @@ -218,6 +215,27 @@ public class DeployToServerRunConfiguration Date: Tue, 29 Sep 2015 19:16:37 +0300 Subject: [PATCH 38/50] enabled graphics objecr renderer for mac jdk --- .../ui/tree/render/GraphicsObjectRenderer.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/GraphicsObjectRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/GraphicsObjectRenderer.java index 1676cf2736c3..b3b257a5824f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/GraphicsObjectRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/GraphicsObjectRenderer.java @@ -45,9 +45,15 @@ public class GraphicsObjectRenderer extends ToStringBasedRenderer implements Ful Field surfaceField = ((ClassType)value.type()).fieldByName("surfaceData"); if (surfaceField == null) return null; ObjectReference surfaceDataValue = (ObjectReference)value.getValue(surfaceField); - final Field bufImgField = ((ClassType)surfaceDataValue.type()).fieldByName("bufImg"); - if (bufImgField == null) return null; - final Value bufImgValue = surfaceDataValue.getValue(bufImgField); + if (surfaceDataValue == null) return null; + + Field imgField = ((ReferenceType)surfaceDataValue.type()).fieldByName("bufImg"); // BufImgSurfaceData + if (imgField == null) { + imgField = ((ReferenceType)surfaceDataValue.type()).fieldByName("offscreenImage"); // CGLSurfaceData + } + if (imgField == null) return null; + + final Value bufImgValue = surfaceDataValue.getValue(imgField); Type type = bufImgValue.type(); if (!(type instanceof ReferenceType) || !DebuggerUtils.instanceOf(type, "java.awt.Image")) { return null; From 5094edd9effeaf4c0bf31fcc4f11e368bf7e3a85 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 29 Sep 2015 18:02:05 +0200 Subject: [PATCH 39/50] Cleanup (test migrated to Java 8) --- .../testSrc/com/intellij/idea/LockSupportTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java b/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java index 134f4ddcf8b4..fa30849fdf37 100644 --- a/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java +++ b/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java @@ -81,7 +81,7 @@ public class LockSupportTest { @Test(timeout = 30000) public void testTwoLocks() { - List toClose = new ArrayList(); + List toClose = new ArrayList<>(); try { assertThat(createLock(toClose, myTempDir, "1", "1-").lock(), equalTo(SocketLock.ActivateStatus.NO_INSTANCE)); assertThat(createLock(toClose, myTempDir, "1.1", "1-1").lock(), equalTo(SocketLock.ActivateStatus.NO_INSTANCE)); @@ -92,9 +92,7 @@ public class LockSupportTest { assertThat(createLock(toClose, myTempDir, "1.1", "1-1").lock(), equalTo(SocketLock.ActivateStatus.ACTIVATED)); } finally { - for (SocketLock lock : toClose) { - lock.dispose(); - } + toClose.forEach(SocketLock::dispose); } } From 8f4bdf0c2a62d999376ea06423f3941f562b64ad Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 29 Sep 2015 18:37:24 +0200 Subject: [PATCH 40/50] Cleanup (saner exceptions; formatting) --- .../src/org/jetbrains/io/BuiltInServer.java | 51 ++++++++++++------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java index b75ea7f93f64..dd650794f018 100644 --- a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java +++ b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java @@ -17,6 +17,8 @@ package org.jetbrains.io; import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.ArrayUtil; +import com.intellij.util.ExceptionUtil; import com.intellij.util.NotNullProducer; import com.intellij.util.net.NetUtils; import io.netty.bootstrap.ServerBootstrap; @@ -52,16 +54,25 @@ public class BuiltInServer implements Disposable { } @NotNull - public static BuiltInServer start(int workerCount, int firstPort, int portsCount, boolean tryAnyPort, @Nullable NotNullProducer channelHandler) throws Throwable { - return start(new NioEventLoopGroup(workerCount, PooledThreadExecutor.INSTANCE), true, firstPort, portsCount, tryAnyPort, channelHandler); + public static BuiltInServer start(int workerCount, + int firstPort, + int portsCount, + boolean tryAnyPort, + @Nullable NotNullProducer handler) throws Exception { + return start(new NioEventLoopGroup(workerCount, PooledThreadExecutor.INSTANCE), true, firstPort, portsCount, tryAnyPort, handler); } @NotNull - public static BuiltInServer start(@NotNull EventLoopGroup eventLoopGroup, boolean isOwnerOfEventLoopGroup, int firstPort, int portsCount, boolean tryAnyPort, @Nullable NotNullProducer channelHandler) throws Throwable { + public static BuiltInServer start(@NotNull EventLoopGroup eventLoopGroup, + boolean isEventLoopGroupOwner, + int firstPort, + int portsCount, + boolean tryAnyPort, + @Nullable NotNullProducer handler) throws Exception { ChannelRegistrar channelRegistrar = new ChannelRegistrar(); ServerBootstrap bootstrap = NettyUtil.nioServerBootstrap(eventLoopGroup); - configureChildHandler(bootstrap, channelRegistrar, channelHandler); - return new BuiltInServer(eventLoopGroup, bind(firstPort, portsCount, tryAnyPort, bootstrap, channelRegistrar), isOwnerOfEventLoopGroup); + configureChildHandler(bootstrap, channelRegistrar, handler); + return new BuiltInServer(eventLoopGroup, bind(firstPort, portsCount, tryAnyPort, bootstrap, channelRegistrar), isEventLoopGroupOwner); } public int getPort() { @@ -73,7 +84,9 @@ public class BuiltInServer implements Disposable { return eventLoopGroup; } - static void configureChildHandler(@NotNull ServerBootstrap bootstrap, @NotNull final ChannelRegistrar channelRegistrar, final @Nullable NotNullProducer channelHandler) { + static void configureChildHandler(@NotNull ServerBootstrap bootstrap, + @NotNull final ChannelRegistrar channelRegistrar, + final @Nullable NotNullProducer channelHandler) { final PortUnificationServerHandler portUnificationServerHandler = channelHandler == null ? new PortUnificationServerHandler() : null; bootstrap.childHandler(new ChannelInitializer() { @Override @@ -83,41 +96,41 @@ public class BuiltInServer implements Disposable { }); } - public static boolean isPortForbidden(int port) { - for (int forbiddenPort : FORBIDDEN_PORTS) { - if (port == forbiddenPort) return true; - } - return false; - } + private static int bind(int firstPort, + int portsCount, + boolean tryAnyPort, + @NotNull ServerBootstrap bootstrap, + @NotNull ChannelRegistrar channelRegistrar) throws Exception { + InetAddress address = NetUtils.getLoopbackAddress(); - private static int bind(int firstPort, int portsCount, boolean tryAnyPort, @NotNull ServerBootstrap bootstrap, @NotNull ChannelRegistrar channelRegistrar) throws Throwable { - InetAddress loopbackAddress = NetUtils.getLoopbackAddress(); for (int i = 0; i < portsCount; i++) { int port = firstPort + i; - if (isPortForbidden(i)) { + if (ArrayUtil.indexOf(FORBIDDEN_PORTS, i) >= 0) { continue; } - ChannelFuture future = bootstrap.bind(loopbackAddress, port).awaitUninterruptibly(); + ChannelFuture future = bootstrap.bind(address, port).awaitUninterruptibly(); if (future.isSuccess()) { channelRegistrar.add(future.channel()); return port; } else if (!tryAnyPort && i == (portsCount - 1)) { - throw future.cause(); + ExceptionUtil.rethrowAll(future.cause()); } } LOG.info("We cannot bind to our default range, so, try to bind to any free port"); - ChannelFuture future = bootstrap.bind(loopbackAddress, 0).awaitUninterruptibly(); + ChannelFuture future = bootstrap.bind(address, 0).awaitUninterruptibly(); if (future.isSuccess()) { channelRegistrar.add(future.channel()); return ((InetSocketAddress)future.channel().localAddress()).getPort(); } else { - throw future.cause(); + ExceptionUtil.rethrowAll(future.cause()); } + + return -1; // unreachable } @Override From 89635c76d40e73cf42f08b92e2063890fa6e1480 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 29 Sep 2015 20:14:37 +0300 Subject: [PATCH 41/50] IDEA-141270 Unexpected JDWP Error --- .../debugger/jdi/StackFrameProxyImpl.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java index c75a41f1f613..81000f4b7eb8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java @@ -306,7 +306,14 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { InvalidStackFrameException error = null; for (int attempt = 0; attempt < 2; attempt++) { try { - return getAllValues().get(localVariable.getVariable()); + Map values = getAllValues(); + LocalVariable variable = localVariable.getVariable(); + if (values.containsKey(variable)) { + return values.get(variable); + } + else { // try direct get + return getStackFrame().getValue(variable); + } } catch (InvalidStackFrameException e) { error = e; @@ -359,6 +366,14 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { catch (AbsentInformationException e) { throw EvaluateExceptionUtil.createEvaluateException(e); } + catch (InternalException e) { + // extra logging for IDEA-141270 + if (e.errorCode() == 35 || e.errorCode() == 101) { + LOG.info(e); + myAllValues = Collections.emptyMap(); + } + else throw e; + } } return myAllValues; } From f68d65bec6d58c7ebdaed2ec0af21216ef108305 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 29 Sep 2015 17:57:54 +0200 Subject: [PATCH 42/50] Cleanup (lock protocol extracted; formatting) --- .../src/com/intellij/idea/SocketLock.java | 249 ++++++++---------- 1 file changed, 111 insertions(+), 138 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/idea/SocketLock.java b/platform/platform-impl/src/com/intellij/idea/SocketLock.java index 9c39bbe7db15..d583592bcb12 100644 --- a/platform/platform-impl/src/com/intellij/idea/SocketLock.java +++ b/platform/platform-impl/src/com/intellij/idea/SocketLock.java @@ -34,7 +34,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufOutputStream; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.io.BuiltInServer; @@ -43,10 +42,10 @@ import org.jetbrains.io.MessageDecoder; import javax.swing.*; import java.io.*; import java.net.Socket; -import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicReference; /** @@ -55,24 +54,24 @@ import java.util.concurrent.atomic.AtomicReference; public final class SocketLock { private static final Logger LOG = Logger.getInstance(SocketLock.class); - @NonNls private static final String ACTIVATE_COMMAND = "activate "; - - private final String configPath; - private final String systemPath; - public enum ActivateStatus {ACTIVATED, NO_INSTANCE, CANNOT_ACTIVATE} - private final AtomicReference>> activateListener = new AtomicReference>>(); + private static final String PORT_FILE = "port"; + private static final String ACTIVATE_COMMAND = "activate "; + private static final String PORT_LOCK_FILE = "port.lock"; - private BuiltInServer server; + private final String myConfigPath; + private final String mySystemPath; + private final AtomicReference>> myActivateListener = new AtomicReference>>(); + private BuiltInServer myServer; public SocketLock(@NotNull String configPath, @NotNull String systemPath) { - this.configPath = canonicalPath(configPath); - this.systemPath = canonicalPath(systemPath); + myConfigPath = canonicalPath(configPath); + mySystemPath = canonicalPath(systemPath); } public void setExternalInstanceListener(@Nullable Consumer> consumer) { - activateListener.set(consumer); + myActivateListener.set(consumer); } public void dispose() { @@ -80,57 +79,32 @@ public final class SocketLock { LOG.debug("enter: destroyProcess()"); } - BuiltInServer server = this.server; - boolean doRemovePortMarker = server != null; + BuiltInServer server = myServer; + if (server == null) return; + try { - if (server != null) { - Disposer.dispose(server); - } + Disposer.dispose(server); } finally { - if (doRemovePortMarker) { - try { - executeAndClose(new Executor() { - @Override - public Void execute(@NotNull List closeables) throws IOException { - File config = new File(configPath); - File system = new File(systemPath); - lockPortMarker(config, closeables); - lockPortMarker(system, closeables); - FileUtil.delete(new File(config, "port")); - FileUtil.delete(new File(system, "port")); - return null; - } - }); - } - catch (Throwable e) { - logError(e); - } + try { + underLocks(new Callable() { + @Override + public Void call() throws Exception { + FileUtil.delete(new File(myConfigPath, PORT_FILE)); + FileUtil.delete(new File(mySystemPath, PORT_FILE)); + return null; + } + }); + } + catch (Throwable e) { + logError(e); } } } @Nullable public BuiltInServer getServer() { - return server; - } - - private static void lockPortMarker(@NotNull File parent, @NotNull List list) throws IOException { - FileUtilRt.createDirectory(parent); - FileOutputStream stream = new FileOutputStream(new File(parent, "port.lock"), true); - list.add(stream); - } - - private static void addExistingPort(@NotNull File portMarker, @NotNull String path, @NotNull MultiMap portToPath) { - if (portMarker.exists()) { - try { - portToPath.putValue(Integer.parseInt(FileUtilRt.loadFile(portMarker)), path); - } - catch (Throwable e) { - LOG.debug(e); - // don't delete - we overwrite it on write in any case - } - } + return myServer; } @Nullable @@ -141,22 +115,19 @@ public final class SocketLock { @Nullable public ActivateStatus lock(@NotNull final String[] args) { if (LOG.isDebugEnabled()) { - LOG.debug("enter: lock(configPath='" + configPath + "', systemPath='" + systemPath + "')"); + LOG.debug("enter: lock(configPath='" + myConfigPath + "', systemPath='" + mySystemPath + "')"); } try { - final File config = new File(configPath); - final File system = new File(systemPath); - final File portMarkerC = new File(config, "port"); - final File portMarkerS = new File(system, "port"); - return executeAndClose(new Executor() { + return underLocks(new Callable() { @Override - public ActivateStatus execute(@NotNull List closeables) throws Throwable { - lockPortMarker(config, closeables); - lockPortMarker(system, closeables); + public ActivateStatus call() throws Exception { + File portMarkerC = new File(myConfigPath, PORT_FILE); + File portMarkerS = new File(mySystemPath, PORT_FILE); + MultiMap portToPath = MultiMap.createSmart(); - addExistingPort(portMarkerC, configPath, portToPath); - addExistingPort(portMarkerS, systemPath, portToPath); + addExistingPort(portMarkerC, myConfigPath, portToPath); + addExistingPort(portMarkerS, mySystemPath, portToPath); if (!portToPath.isEmpty()) { for (Map.Entry> entry : portToPath.entrySet()) { ActivateStatus status = tryActivate(entry.getKey(), entry.getValue(), args); @@ -166,16 +137,16 @@ public final class SocketLock { } } - final String[] lockedPaths = {configPath, systemPath}; - server = BuiltInServer.start(1, 6942, 50, false, new NotNullProducer() { + final String[] lockedPaths = {myConfigPath, mySystemPath}; + myServer = BuiltInServer.start(1, 6942, 50, false, new NotNullProducer() { @NotNull @Override public ChannelHandler produce() { - return new MyChannelInboundHandler(lockedPaths, activateListener); + return new MyChannelInboundHandler(lockedPaths, myActivateListener); } }); - byte[] portBytes = Integer.toString(server.getPort()).getBytes(CharsetToolkit.UTF8_CHARSET); + byte[] portBytes = Integer.toString(myServer.getPort()).getBytes(CharsetToolkit.UTF8_CHARSET); FileUtil.writeToFile(portMarkerC, portBytes); FileUtil.writeToFile(portMarkerS, portBytes); return ActivateStatus.NO_INSTANCE; @@ -198,27 +169,37 @@ public final class SocketLock { JOptionPane.WARNING_MESSAGE ); } + return null; } } - private interface Executor { - T execute(@NotNull List closeables) throws Throwable; - } - - private static T executeAndClose(@NotNull Executor executor) throws Throwable { - List closeables = new ArrayList(); + private V underLocks(@NotNull Callable action) throws Exception { + FileUtilRt.createDirectory(new File(myConfigPath)); + FileOutputStream lock1 = new FileOutputStream(new File(myConfigPath, PORT_LOCK_FILE), true); try { - return executor.execute(closeables); + FileUtilRt.createDirectory(new File(mySystemPath)); + FileOutputStream lock2 = new FileOutputStream(new File(mySystemPath, PORT_LOCK_FILE), true); + try { + return action.call(); + } + finally { + lock2.close(); + } } finally { - for (Closeable closeable : closeables) { - try { - closeable.close(); - } - catch (Throwable e) { - logError(e); - } + lock1.close(); + } + } + + private static void addExistingPort(@NotNull File portMarker, @NotNull String path, @NotNull MultiMap portToPath) { + if (portMarker.exists()) { + try { + portToPath.putValue(Integer.parseInt(FileUtilRt.loadFile(portMarker)), path); + } + catch (Throwable e) { + LOG.debug(e); + // don't delete - we overwrite it on write in any case } } } @@ -233,82 +214,74 @@ public final class SocketLock { } } - @SuppressWarnings({"SocketOpenedButNotSafelyClosed", "IOResourceOpenedButNotSafelyClosed"}) @NotNull private static ActivateStatus tryActivate(int portNumber, @NotNull Collection paths, @NotNull String[] args) { - Socket socket = null; try { - socket = new Socket(NetUtils.getLoopbackAddress(), portNumber); - socket.setSoTimeout(300); + Socket socket = new Socket(NetUtils.getLoopbackAddress(), portNumber); + try { + socket.setSoTimeout(300); - boolean result = false; - DataInputStream in = new DataInputStream(socket.getInputStream()); - while (true) { - try { - String path = in.readUTF(); - if (paths.contains(path)) { - result = true; - // don't break - read all input + boolean result = false; + @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") DataInputStream in = new DataInputStream(socket.getInputStream()); + while (true) { + try { + String path = in.readUTF(); + if (paths.contains(path)) { + result = true; // don't break - read all input + } + } + catch (IOException ignored) { + break; } } - catch (IOException ignored) { - break; + + if (result) { + try { + @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") DataOutputStream out = new DataOutputStream(socket.getOutputStream()); + out.writeUTF(ACTIVATE_COMMAND + new File(".").getAbsolutePath() + "\0" + StringUtil.join(args, "\0")); + out.flush(); + String response = in.readUTF(); + if (response.equals("ok")) { + return ActivateStatus.ACTIVATED; + } + } + catch (IOException e) { + LOG.info(e); + } + + return ActivateStatus.CANNOT_ACTIVATE; } } - - if (result) { - try { - DataOutputStream out = new DataOutputStream(socket.getOutputStream()); - out.writeUTF(ACTIVATE_COMMAND + new File(".").getAbsolutePath() + "\0" + StringUtil.join(args, "\0")); - out.flush(); - String response = in.readUTF(); - if (response.equals("ok")) { - return ActivateStatus.ACTIVATED; - } - } - catch (IOException e) { - LOG.info(e); - } - return ActivateStatus.CANNOT_ACTIVATE; + finally { + socket.close(); } } catch (IOException e) { LOG.debug(e); } - finally { - if (socket != null) { - try { - socket.close(); - } - catch (IOException e) { - LOG.debug(e); - } - } - } return ActivateStatus.NO_INSTANCE; } private static class MyChannelInboundHandler extends MessageDecoder { - private final String[] lockedPaths; - private State state = State.HEADER; - private final AtomicReference>> activateListener; - - public MyChannelInboundHandler(@NotNull String[] lockedPaths, @NotNull AtomicReference>> activateListener) { - this.lockedPaths = lockedPaths; - this.activateListener = activateListener; - } - private enum State {HEADER, CONTENT} - @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") + private final String[] myLockedPaths; + private final AtomicReference>> myActivateListener; + private State myState = State.HEADER; + + public MyChannelInboundHandler(@NotNull String[] lockedPaths, @NotNull AtomicReference>> activateListener) { + myLockedPaths = lockedPaths; + myActivateListener = activateListener; + } + @Override public void channelActive(ChannelHandlerContext context) throws Exception { ByteBuf buffer = context.alloc().ioBuffer(1024); boolean success = false; try { ByteBufOutputStream out = new ByteBufOutputStream(buffer); - for (String path : lockedPaths) { + for (String path : myLockedPaths) { if (path != null) { out.writeUTF(path); } @@ -324,11 +297,10 @@ public final class SocketLock { context.writeAndFlush(buffer); } - @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") @Override protected void messageReceived(@NotNull ChannelHandlerContext context, @NotNull ByteBuf input) throws Exception { while (true) { - switch (state) { + switch (myState) { case HEADER: { ByteBuf buffer = getBufferIfSufficient(input, 2, context); if (buffer == null) { @@ -336,7 +308,7 @@ public final class SocketLock { } contentLength = buffer.readUnsignedShort(); - state = State.CONTENT; + myState = State.CONTENT; } break; @@ -348,7 +320,7 @@ public final class SocketLock { if (StringUtil.startsWith(command, ACTIVATE_COMMAND)) { List args = StringUtil.split(command.subSequence(ACTIVATE_COMMAND.length(), command.length()).toString(), "\0"); - Consumer> listener = activateListener.get(); + Consumer> listener = myActivateListener.get(); if (listener != null) { listener.consume(args); } @@ -371,7 +343,8 @@ public final class SocketLock { private static String canonicalPath(@NotNull String configPath) { try { return new File(configPath).getCanonicalPath(); - } catch (IOException ignore) { + } + catch (IOException ignore) { return configPath; } } From bbabe703e7c258a6358311cba258435c613ebe66 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 29 Sep 2015 21:08:40 +0300 Subject: [PATCH 43/50] fetch icons with low priority --- .../ui/tree/render/IconObjectRenderer.java | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/IconObjectRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/IconObjectRenderer.java index 51cb8b3c0fe7..c5be60cf00a2 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/IconObjectRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/IconObjectRenderer.java @@ -16,10 +16,12 @@ package com.intellij.debugger.ui.tree.render; import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.FullValueEvaluatorProvider; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationContext; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.impl.DebuggerUtilsImpl; import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; @@ -42,15 +44,27 @@ class IconObjectRenderer extends ToStringBasedRenderer implements FullValueEvalu } @Override - public Icon calcValueIcon(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener listener) + public Icon calcValueIcon(final ValueDescriptor descriptor, final EvaluationContext evaluationContext, final DescriptorLabelListener listener) throws EvaluateException { - String getterName = AllIcons.Debugger.Value.getIconHeight() <= 16 ? "iconToBytesPreviewNormal" : "iconToBytesPreviewRetina"; - if (!Registry.is("debugger.auto.fetch.icons") || DebuggerUtilsImpl.isRemote(evaluationContext.getDebugProcess())) { - return null; // do not auto load icon for remote - } - else { - return ImageObjectRenderer.getIcon(evaluationContext, descriptor.getValue(), getterName); - } + EvaluationContextImpl evalContext = ((EvaluationContextImpl)evaluationContext); + DebugProcessImpl debugProcess = evalContext.getDebugProcess(); + + if (!Registry.is("debugger.auto.fetch.icons") || DebuggerUtilsImpl.isRemote(debugProcess)) return null; + + debugProcess.getManagerThread().schedule(new SuspendContextCommandImpl(evalContext.getSuspendContext()) { + @Override + public Priority getPriority() { + return Priority.LOW; + } + + @Override + public void contextAction() throws Exception { + String getterName = AllIcons.Debugger.Value.getIconHeight() <= 16 ? "iconToBytesPreviewNormal" : "iconToBytesPreviewRetina"; + descriptor.setValueIcon(ImageObjectRenderer.getIcon(evaluationContext, descriptor.getValue(), getterName)); + listener.labelChanged(); + } + }); + return null; } @Nullable From 9096279c1541476468945ccc105484fdfe16746c Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 29 Sep 2015 20:21:46 +0200 Subject: [PATCH 44/50] [platform] correct logging in SocketLock (IDEA-CR-5262) --- .../src/com/intellij/idea/SocketLock.java | 67 ++++++------------- .../src/messages/CommonBundle.properties | 3 - 2 files changed, 21 insertions(+), 49 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/idea/SocketLock.java b/platform/platform-impl/src/com/intellij/idea/SocketLock.java index d583592bcb12..c746c7d12ddd 100644 --- a/platform/platform-impl/src/com/intellij/idea/SocketLock.java +++ b/platform/platform-impl/src/com/intellij/idea/SocketLock.java @@ -15,10 +15,6 @@ */ package com.intellij.idea; -import com.intellij.CommonBundle; -import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.diagnostic.DefaultLogger; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; @@ -39,7 +35,6 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.io.BuiltInServer; import org.jetbrains.io.MessageDecoder; -import javax.swing.*; import java.io.*; import java.net.Socket; import java.util.Collection; @@ -52,8 +47,6 @@ import java.util.concurrent.atomic.AtomicReference; * @author mike */ public final class SocketLock { - private static final Logger LOG = Logger.getInstance(SocketLock.class); - public enum ActivateStatus {ACTIVATED, NO_INSTANCE, CANNOT_ACTIVATE} private static final String PORT_FILE = "port"; @@ -75,9 +68,7 @@ public final class SocketLock { } public void dispose() { - if (LOG.isDebugEnabled()) { - LOG.debug("enter: destroyProcess()"); - } + log("enter: dispose()"); BuiltInServer server = myServer; if (server == null) return; @@ -96,8 +87,8 @@ public final class SocketLock { } }); } - catch (Throwable e) { - logError(e); + catch (Exception e) { + Logger.getInstance(SocketLock.class).warn(e); } } } @@ -114,9 +105,7 @@ public final class SocketLock { @Nullable public ActivateStatus lock(@NotNull final String[] args) { - if (LOG.isDebugEnabled()) { - LOG.debug("enter: lock(configPath='" + myConfigPath + "', systemPath='" + mySystemPath + "')"); - } + log("enter: lock(config=%s system=%s)", myConfigPath, mySystemPath); try { return underLocks(new Callable() { @@ -153,23 +142,8 @@ public final class SocketLock { } }); } - catch (Throwable e) { - logError(e); - - if (Main.isHeadless()) { - Main.showMessage("Cannot lock system folders", e); - } - else { - String pathToLogFile = PathManager.getLogPath() + "/idea.log file".replace('/', File.separatorChar); - JOptionPane.showMessageDialog( - JOptionPane.getRootFrame(), - CommonBundle.message("cannot.start.other.instance.is.running.error.message", ApplicationNamesInfo.getInstance().getProductName(), - pathToLogFile), - CommonBundle.message("title.warning"), - JOptionPane.WARNING_MESSAGE - ); - } - + catch (Exception e) { + Main.showMessage("Cannot lock system folders", e); return null; } } @@ -197,23 +171,13 @@ public final class SocketLock { try { portToPath.putValue(Integer.parseInt(FileUtilRt.loadFile(portMarker)), path); } - catch (Throwable e) { - LOG.debug(e); + catch (Exception e) { + log(e); // don't delete - we overwrite it on write in any case } } } - private static void logError(@NotNull Throwable e) { - // default logger throws AssertionError and it leads to startup failure without error message dialog - if (LOG instanceof DefaultLogger) { - LOG.warn(e); - } - else { - LOG.error(e); - } - } - @NotNull private static ActivateStatus tryActivate(int portNumber, @NotNull Collection paths, @NotNull String[] args) { try { @@ -246,7 +210,7 @@ public final class SocketLock { } } catch (IOException e) { - LOG.info(e); + log(e); } return ActivateStatus.CANNOT_ACTIVATE; @@ -257,7 +221,7 @@ public final class SocketLock { } } catch (IOException e) { - LOG.debug(e); + log(e); } return ActivateStatus.NO_INSTANCE; @@ -348,4 +312,15 @@ public final class SocketLock { return configPath; } } + + private static void log(Exception e) { + Logger.getInstance(SocketLock.class).debug(e); + } + + private static void log(String format, Object... args) { + Logger logger = Logger.getInstance(SocketLock.class); + if (logger.isDebugEnabled()) { + logger.debug(String.format(format, args)); + } + } } \ No newline at end of file diff --git a/platform/platform-resources-en/src/messages/CommonBundle.properties b/platform/platform-resources-en/src/messages/CommonBundle.properties index 683703be061e..bf8d5dbabedd 100644 --- a/platform/platform-resources-en/src/messages/CommonBundle.properties +++ b/platform/platform-resources-en/src/messages/CommonBundle.properties @@ -141,10 +141,7 @@ local.vcs.action.name.undo.command=Undo {0} local.vcs.action.name.redo.command=Redo {0} error.reading.color.scheme.from.file.error.message=Error reading color scheme from {0} -corrupted.scheme.file.message.title=Corrupted File button.background=&Background -vcs.configurable.general.tab.title=General -cannot.start.other.instance.is.running.error.message={0} was unable to create a local connection in order to check whether\nother instance of {0} is currently running on the same machine.\nRunning multiple instances of {0} on the same machine may cause unpredictable\nresults because of sharing system folders.\nPlease troubleshoot your TCP/IP configuration and/or local firewall settings.\nand attach the {1} button.load.file=Load File date.frequency=Once {0} name.label.text=Na&me: From 59a87bc4bfd06b94e80583ae64f612c254d5b71c Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 29 Sep 2015 20:55:33 +0200 Subject: [PATCH 45/50] [platform] activation exception handling moved out of SocketLock --- .../src/com/intellij/idea/SocketLock.java | 72 +++++++++---------- .../src/com/intellij/idea/StartupUtil.java | 40 +++++++---- .../com/intellij/idea/LockSupportTest.java | 8 +-- 3 files changed, 63 insertions(+), 57 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/idea/SocketLock.java b/platform/platform-impl/src/com/intellij/idea/SocketLock.java index c746c7d12ddd..58d19c847974 100644 --- a/platform/platform-impl/src/com/intellij/idea/SocketLock.java +++ b/platform/platform-impl/src/com/intellij/idea/SocketLock.java @@ -98,54 +98,48 @@ public final class SocketLock { return myServer; } - @Nullable - public ActivateStatus lock() { + @NotNull + public ActivateStatus lock() throws Exception { return lock(ArrayUtil.EMPTY_STRING_ARRAY); } - @Nullable - public ActivateStatus lock(@NotNull final String[] args) { + @NotNull + public ActivateStatus lock(@NotNull final String[] args) throws Exception { log("enter: lock(config=%s system=%s)", myConfigPath, mySystemPath); - try { - return underLocks(new Callable() { - @Override - public ActivateStatus call() throws Exception { - File portMarkerC = new File(myConfigPath, PORT_FILE); - File portMarkerS = new File(mySystemPath, PORT_FILE); + return underLocks(new Callable() { + @Override + public ActivateStatus call() throws Exception { + File portMarkerC = new File(myConfigPath, PORT_FILE); + File portMarkerS = new File(mySystemPath, PORT_FILE); - MultiMap portToPath = MultiMap.createSmart(); - addExistingPort(portMarkerC, myConfigPath, portToPath); - addExistingPort(portMarkerS, mySystemPath, portToPath); - if (!portToPath.isEmpty()) { - for (Map.Entry> entry : portToPath.entrySet()) { - ActivateStatus status = tryActivate(entry.getKey(), entry.getValue(), args); - if (status != ActivateStatus.NO_INSTANCE) { - return status; - } + MultiMap portToPath = MultiMap.createSmart(); + addExistingPort(portMarkerC, myConfigPath, portToPath); + addExistingPort(portMarkerS, mySystemPath, portToPath); + if (!portToPath.isEmpty()) { + for (Map.Entry> entry : portToPath.entrySet()) { + ActivateStatus status = tryActivate(entry.getKey(), entry.getValue(), args); + if (status != ActivateStatus.NO_INSTANCE) { + return status; } } - - final String[] lockedPaths = {myConfigPath, mySystemPath}; - myServer = BuiltInServer.start(1, 6942, 50, false, new NotNullProducer() { - @NotNull - @Override - public ChannelHandler produce() { - return new MyChannelInboundHandler(lockedPaths, myActivateListener); - } - }); - - byte[] portBytes = Integer.toString(myServer.getPort()).getBytes(CharsetToolkit.UTF8_CHARSET); - FileUtil.writeToFile(portMarkerC, portBytes); - FileUtil.writeToFile(portMarkerS, portBytes); - return ActivateStatus.NO_INSTANCE; } - }); - } - catch (Exception e) { - Main.showMessage("Cannot lock system folders", e); - return null; - } + + final String[] lockedPaths = {myConfigPath, mySystemPath}; + myServer = BuiltInServer.start(1, 6942, 50, false, new NotNullProducer() { + @NotNull + @Override + public ChannelHandler produce() { + return new MyChannelInboundHandler(lockedPaths, myActivateListener); + } + }); + + byte[] portBytes = Integer.toString(myServer.getPort()).getBytes(CharsetToolkit.UTF8_CHARSET); + FileUtil.writeToFile(portMarkerC, portBytes); + FileUtil.writeToFile(portMarkerS, portBytes); + return ActivateStatus.NO_INSTANCE; + } + }); } private V underLocks(@NotNull Callable action) throws Exception { diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java index a87d02672d12..24ead9495020 100644 --- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java +++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java @@ -244,6 +244,7 @@ public class StartupUtil { finally { writer.close(); } } + @SuppressWarnings("SSBasedInspection") private static void delete(File ideTempFile) { if (!FileUtilRt.delete(ideTempFile)) { ideTempFile.deleteOnExit(); @@ -251,25 +252,36 @@ public class StartupUtil { } private synchronized static boolean lockSystemFolders(String[] args) { - assert ourLock == null; + if (ourLock != null) { + throw new AssertionError(); + } + ourLock = new SocketLock(PathManager.getConfigPath(), PathManager.getSystemPath()); - SocketLock.ActivateStatus activateStatus = ourLock.lock(args); - if (activateStatus != SocketLock.ActivateStatus.NO_INSTANCE) { - if (activateStatus != null && (Main.isHeadless() || activateStatus == SocketLock.ActivateStatus.CANNOT_ACTIVATE)) { - String message = "Only one instance of " + ApplicationNamesInfo.getInstance().getFullProductName() + " can be run at a time."; - Main.showMessage("Too Many Instances", message, true); - } + SocketLock.ActivateStatus status; + try { + status = ourLock.lock(args); + } + catch (Exception e) { + Main.showMessage("Cannot Lock System Folders", e); return false; } - ShutDownTracker.getInstance().registerShutdownTask(new Runnable() { - @Override - public void run() { - ourLock.dispose(); - } - }); - return true; + if (status == SocketLock.ActivateStatus.NO_INSTANCE) { + ShutDownTracker.getInstance().registerShutdownTask(new Runnable() { + @Override + public void run() { + ourLock.dispose(); + } + }); + return true; + } + else if (Main.isHeadless() || status == SocketLock.ActivateStatus.CANNOT_ACTIVATE) { + String message = "Only one instance of " + ApplicationNamesInfo.getInstance().getFullProductName() + " can be run at a time."; + Main.showMessage("Too Many Instances", message, true); + } + + return false; } private static void fixProcessEnvironment(Logger log) { diff --git a/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java b/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java index fa30849fdf37..15d6b2d0164f 100644 --- a/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java +++ b/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java @@ -50,7 +50,7 @@ public class LockSupportTest { } @Test(timeout = 30000) - public void testUseCanonicalPathLock() { + public void testUseCanonicalPathLock() throws Exception { assumeThat(SystemInfo.isFileSystemCaseSensitive, is(false)); String path1 = myTempDir.getPath(); @@ -69,7 +69,7 @@ public class LockSupportTest { } @Test(timeout = 30000) - public void testLock() { + public void testLock() throws Exception { SocketLock lock = new SocketLock(myTempDir.getPath() + "/c", myTempDir.getPath() + "/s"); try { assertThat(lock.lock(), equalTo(SocketLock.ActivateStatus.NO_INSTANCE)); @@ -80,7 +80,7 @@ public class LockSupportTest { } @Test(timeout = 30000) - public void testTwoLocks() { + public void testTwoLocks() throws Exception { List toClose = new ArrayList<>(); try { assertThat(createLock(toClose, myTempDir, "1", "1-").lock(), equalTo(SocketLock.ActivateStatus.NO_INSTANCE)); @@ -104,7 +104,7 @@ public class LockSupportTest { } @Test(timeout = 30000) - public void testDispose() { + public void testDispose() throws Exception { SocketLock lock1 = new SocketLock(myTempDir.getPath() + "/1", myTempDir.getPath() + "/1-"); SocketLock lock2 = new SocketLock(myTempDir.getPath() + "/1", myTempDir.getPath() + "/1-"); From cf233de7370f9e9c3e81a08d9239f35ac3837bf7 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 29 Sep 2015 20:30:31 +0200 Subject: [PATCH 46/50] correct misused cached value in GroovyScriptClass --- .../groovy/lang/psi/impl/synthetic/GroovyScriptClass.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java index f7708d4b7a99..e654a83a65ab 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java @@ -194,7 +194,7 @@ public class GroovyScriptClass extends LightElement implements PsiClass, Synthet return RecursionManager.doPreventingRecursion(this, false, new Computable() { @Override public PsiClassType compute() { - return CachedValuesManager.getCachedValue(myFile, new CachedValueProvider() { + return CachedValuesManager.getCachedValue(GroovyScriptClass.this, new CachedValueProvider() { @Nullable @Override public Result compute() { From bbc043dc72332186ec2f16558ebff0d798773573 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 29 Sep 2015 20:31:38 +0200 Subject: [PATCH 47/50] method contract cache shouldn't depend on the annotation which might become invalid --- .../dataFlow/ControlFlowAnalyzer.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index 2559f4e9f3a5..439d23ccaf1b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -1513,12 +1513,12 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { } static List getMethodContracts(@NotNull final PsiMethod method) { - final PsiAnnotation contractAnno = findContractAnnotation(method); - if (contractAnno != null) { - return CachedValuesManager.getCachedValue(contractAnno, new CachedValueProvider>() { - @Nullable - @Override - public Result> compute() { + return CachedValuesManager.getCachedValue(method, new CachedValueProvider>() { + @Nullable + @Override + public Result> compute() { + final PsiAnnotation contractAnno = findContractAnnotation(method); + if (contractAnno != null) { String text = AnnotationUtil.getStringAttributeValue(contractAnno, null); if (text != null) { try { @@ -1534,12 +1534,10 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { catch (Exception ignored) { } } - return Result.create(Collections.emptyList(), contractAnno, method, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); } - }); - } - - return Collections.emptyList(); + return Result.create(Collections.emptyList(), method, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); + } + }); } @Nullable From dbbcad3dee2bebe1b5cd2192f98330af43740243 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Tue, 29 Sep 2015 21:16:34 +0200 Subject: [PATCH 48/50] Bundle EditorConfig plugin --- python/build/plugin-list.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/build/plugin-list.txt b/python/build/plugin-list.txt index 8dfba14b8dae..c034d391e4ce 100644 --- a/python/build/plugin-list.txt +++ b/python/build/plugin-list.txt @@ -19,4 +19,5 @@ IntelliLang-js IntelliLang-python rest python-rest -ipnb \ No newline at end of file +ipnb +editorconfig \ No newline at end of file From 9e683ea1dc72acfd522585dcf305d4c1f4f6b41e Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Tue, 29 Sep 2015 22:29:12 +0300 Subject: [PATCH 49/50] PY-16926 Canonization is not required for Django 1.6 --- python/helpers/python-skeletons/django/db/models/query.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/helpers/python-skeletons/django/db/models/query.py b/python/helpers/python-skeletons/django/db/models/query.py index 8dd04f655159..e65760e76889 100644 --- a/python/helpers/python-skeletons/django/db/models/query.py +++ b/python/helpers/python-skeletons/django/db/models/query.py @@ -4,7 +4,7 @@ QuerySet is parametrized with model object class QuerySet(object): def __init__(self, model=None, query=None, using=None, hints=None): """ - :rtype: django.db.models.QuerySet[T] + :rtype: django.db.models.query.QuerySet[T] """ pass From 1bc9297cc1952a67fc1c510f44a9da34471a4ab2 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 29 Sep 2015 22:38:13 +0200 Subject: [PATCH 50/50] cache class implementation search scope on itself, not just some reference --- .../com/intellij/codeInsight/JavaTargetElementEvaluator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/JavaTargetElementEvaluator.java b/java/java-impl/src/com/intellij/codeInsight/JavaTargetElementEvaluator.java index 015c9efab8bc..e5660c288fa9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/JavaTargetElementEvaluator.java +++ b/java/java-impl/src/com/intellij/codeInsight/JavaTargetElementEvaluator.java @@ -315,7 +315,7 @@ public class JavaTargetElementEvaluator extends TargetElementEvaluatorEx2 implem if (referenceExpression != null && element instanceof PsiMethod) { final PsiClass[] memberClass = getMemberClass(referenceExpression, element); if (memberClass != null && memberClass.length == 1) { - return CachedValuesManager.getCachedValue(referenceExpression, new CachedValueProvider() { + return CachedValuesManager.getCachedValue(memberClass[0], new CachedValueProvider() { @Nullable @Override public Result compute() {