From ee454534c9e308a443bba166c8816e95731fe37f Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 29 Oct 2014 17:17:38 +0300 Subject: [PATCH 01/29] EA-59818 Ensured SvnFileUrlMappingImpl.convertRoots() always returns new list instance (and not possibly internal list from SvnMapping), @NotNull added --- .../src/com/intellij/openapi/vcs/AbstractVcs.java | 4 +++- .../vcs/impl/projectlevelman/NewMappings.java | 1 + .../src/com/intellij/cvsSupport2/CvsVcs2.java | 3 ++- .../hg4idea/src/org/zmlx/hg4idea/HgRootsHandler.java | 4 +++- .../jetbrains/idea/svn/SvnFileUrlMappingImpl.java | 12 +++++------- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcs.java b/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcs.java index c31dddf66aed..63c078802de0 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcs.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcs.java @@ -440,7 +440,9 @@ public abstract class AbstractVcs extends S } public interface RootsConvertor { - List convertRoots(List result); + + @NotNull + List convertRoots(@NotNull List result); } /** diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java index 57754f0190cc..6475fde5a34a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java @@ -273,6 +273,7 @@ public class NewMappings { return FileUtil.startsWith(systemIndependentPath, mapping.systemIndependentPath()); } + @NotNull public List getMappingsAsFilesUnderVcs(@NotNull AbstractVcs vcs) { final List result = new ArrayList(); final String vcsName = vcs.getName(); diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/CvsVcs2.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/CvsVcs2.java index 5adf458b5369..c44bd3857de1 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/CvsVcs2.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/CvsVcs2.java @@ -354,7 +354,8 @@ public class CvsVcs2 extends AbstractVcs implements TransactionPr @Override public RootsConvertor getCustomConvertor() { return new RootsConvertor() { - public List convertRoots(List result) { + @NotNull + public List convertRoots(@NotNull List result) { return FindAllRootsHelper.findVersionedUnder(result); } }; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgRootsHandler.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgRootsHandler.java index 4aef2c466071..a7ccaf8a931e 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgRootsHandler.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgRootsHandler.java @@ -22,6 +22,7 @@ import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.vcsUtil.VcsUtil; import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.util.HgUtil; @@ -44,8 +45,9 @@ public class HgRootsHandler implements AbstractVcs.RootsConvertor { return ServiceManager.getService(project, HgRootsHandler.class); } + @NotNull @Override - public List convertRoots(List original) { + public List convertRoots(@NotNull List original) { final Set result = new THashSet(original.size()); for (VirtualFile vf : original) { final VirtualFile root = convertRoot(vf); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java index 5c660643dc66..cdf7c05a6c45 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java @@ -191,8 +191,9 @@ public class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentState } } - public List convertRoots(final List result) { - if (ThreadLocalDefendedInvoker.isInside()) return result; + @NotNull + public List convertRoots(@NotNull List result) { + if (ThreadLocalDefendedInvoker.isInside()) return ContainerUtil.newArrayList(result); synchronized (myMonitor) { final List cachedRoots = myMoreRealMapping.getUnderVcsRoots(); @@ -200,11 +201,8 @@ public class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentState if (! lonelyRoots.isEmpty()) { myChecker.reportNoRoots(lonelyRoots); } - if (cachedRoots.isEmpty()) { - // todo +- - return result; - } - return cachedRoots; + + return ContainerUtil.newArrayList(cachedRoots.isEmpty() ? result : cachedRoots); } } From 50f7c796e0f669520092bfa67d5a1939d7e84ebb Mon Sep 17 00:00:00 2001 From: Liana Bakradze Date: Wed, 29 Oct 2014 18:16:23 +0300 Subject: [PATCH 02/29] replaced task window with answer placeholder in some string literals --- .../coursecreator/CCEditorFactoryListener.java | 2 +- .../coursecreator/actions/CCAddTaskWindow.java | 2 +- .../coursecreator/actions/CCCreateCourseArchive.java | 2 +- .../coursecreator/actions/CCDeleteTaskWindow.java | 2 +- .../actions/CCShowTaskWindowDetails.java | 2 +- .../coursecreator/ui/CreateTaskWindowDialog.java | 2 +- .../edu/learn-python/resources/META-INF/plugin.xml | 12 ++++++------ .../python/edu/StudyEditorFactoryListener.java | 2 +- .../python/edu/StudyInstructionPainter.java | 6 +++--- .../python/edu/actions/StudyNextWindowAction.java | 2 +- .../python/edu/actions/StudyPrevWindowAction.java | 2 +- .../python/edu/actions/StudyShowHintAction.java | 4 ++-- 12 files changed, 20 insertions(+), 20 deletions(-) diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCEditorFactoryListener.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCEditorFactoryListener.java index 24688c4b2709..c61ab10d7332 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCEditorFactoryListener.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/CCEditorFactoryListener.java @@ -88,7 +88,7 @@ public class CCEditorFactoryListener implements EditorFactoryListener { @Override public void handle(ReadOnlyFragmentModificationException e) { - HintManager.getInstance().showErrorHint(myEditor, "Delete task window before editing its borders"); + HintManager.getInstance().showErrorHint(myEditor, "Delete answer placeholder before editing its borders"); } } } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java index 3df30b7a4608..244de123a33d 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java @@ -24,7 +24,7 @@ public class CCAddTaskWindow extends DumbAwareAction { private static final Logger LOG = Logger.getInstance(CCAddTaskWindow.class); public CCAddTaskWindow() { - super("Add Problem to Solve", "Add problem to solve", null); + super("Add Answer Placeholder", "Add answer placeholder", null); } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateCourseArchive.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateCourseArchive.java index b5a0292db684..de76d5d287de 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateCourseArchive.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCCreateCourseArchive.java @@ -204,7 +204,7 @@ public class CCCreateCourseArchive extends DumbAwareAction { @Override public boolean accept(File pathname) { String name = pathname.getName(); - return !name.contains(".answer") && !name.contains("__pycache__") && !name.contains("_windows"); + return !name.contains(".answer") && !name.contains("__pycache__") && !name.contains("_windows") && !name.contains(".pyc"); } }, null); } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCDeleteTaskWindow.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCDeleteTaskWindow.java index c7d8cd91cf4b..f7245a05fe9f 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCDeleteTaskWindow.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCDeleteTaskWindow.java @@ -18,7 +18,7 @@ public class CCDeleteTaskWindow extends CCTaskWindowAction { private static final Logger LOG = Logger.getInstance(CCDeleteTaskWindow.class); public CCDeleteTaskWindow() { - super("Delete Problem","Delete problem", null); + super("Delete Answer Placeholder","Delete answer placeholder", null); } @Override diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowTaskWindowDetails.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowTaskWindowDetails.java index 30ba802dbedc..62baf7c7399f 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowTaskWindowDetails.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowTaskWindowDetails.java @@ -11,7 +11,7 @@ import org.jetbrains.plugins.coursecreator.ui.CreateTaskWindowDialog; public class CCShowTaskWindowDetails extends CCTaskWindowAction { public CCShowTaskWindowDetails() { - super("Show Problem Details", "Show problem details", null); + super("Edit Answer Placeholder", "Edit answer placeholder", null); } @Override diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java index 213fc55e2cb7..3595e2c28a7b 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/ui/CreateTaskWindowDialog.java @@ -18,7 +18,7 @@ import java.io.*; public class CreateTaskWindowDialog extends DialogWrapper { - public static final String TITLE = "Add Problem to Solve"; + public static final String TITLE = "Add Answer Placeholder"; private static final Logger LOG = Logger.getInstance(CreateTaskWindowDialog.class.getName()); private final TaskWindow myTaskWindow; private final CreateTaskWindowPanel myPanel; diff --git a/python/edu/learn-python/resources/META-INF/plugin.xml b/python/edu/learn-python/resources/META-INF/plugin.xml index 62f5bdc6ef85..f3a52d5ab9d2 100644 --- a/python/edu/learn-python/resources/META-INF/plugin.xml +++ b/python/edu/learn-python/resources/META-INF/plugin.xml @@ -41,11 +41,11 @@ - + - + @@ -55,8 +55,8 @@ description="Refresh current task"/> - + diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyEditorFactoryListener.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyEditorFactoryListener.java index 30a04dd2f136..fb3fc5f3c6f1 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyEditorFactoryListener.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyEditorFactoryListener.java @@ -117,7 +117,7 @@ class StudyEditorFactoryListener implements EditorFactoryListener { @Override public void handle(ReadOnlyFragmentModificationException e) { - HintManager.getInstance().showErrorHint(myEditor, "It's not allowed to delete task windows"); + HintManager.getInstance().showErrorHint(myEditor, "It's not allowed to delete answer placeholders"); } } } diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java index 87f1f7a35454..95ecfb49651f 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java @@ -33,10 +33,10 @@ public class StudyInstructionPainter extends EditorEmptyTextPainter { UIUtil.TextPainter painter = new UIUtil.TextPainter().withLineSpacing(1.5f); painter.appendLine("PyCharm Educational Edition").underlined(new JBColor(Gray._150, Gray._180)); - addAction(painter, "Navigate to the next task window", StudyNextWindowAction.ACTION_ID, StudyNextWindowAction.SHORTCUT2, true); + addAction(painter, "Navigate to the next answer placeholder", StudyNextWindowAction.ACTION_ID, StudyNextWindowAction.SHORTCUT2, true); String shortcut1 = getShortcutText(StudyPrevWindowAction.ACTION_ID, StudyPrevWindowAction.SHORTCUT, false, false); String shortcut2 = getShortcutText(StudyNextWindowAction.ACTION_ID, StudyNextWindowAction.SHORTCUT, false, false); - String text = "Navigate between task windows with " + shortcut1 + + String text = "Navigate between answer placeholders with " + shortcut1 + " and " + shortcut2; painter.appendLine(text).smaller().withBullet(); shortcut1 = getShortcutText(StudyPreviousStudyTaskAction.ACTION_ID, StudyPreviousStudyTaskAction.SHORTCUT, false, false); @@ -44,7 +44,7 @@ public class StudyInstructionPainter extends EditorEmptyTextPainter { painter.appendLine("Navigate between tasks with " + shortcut1 + " and " + shortcut2).smaller().withBullet(); addAction(painter, "Reset current task file", StudyRefreshTaskFileAction.ACTION_ID, StudyRefreshTaskFileAction.SHORTCUT, false); addAction(painter, "Check task", StudyCheckAction.ACTION_ID, StudyCheckAction.SHORTCUT, false); - addAction(painter, "Get hint for the task window", StudyShowHintAction.ACTION_ID, StudyShowHintAction.SHORTCUT, false); + addAction(painter, "Get hint for the answer placeholder", StudyShowHintAction.ACTION_ID, StudyShowHintAction.SHORTCUT, false); painter.appendLine("To see your progress open the 'Course Description' panel").smaller().withBullet(); painter.draw(g, new PairFunction>() { @Override diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextWindowAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextWindowAction.java index 16036a7ba91b..e4d3bb79d7a3 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextWindowAction.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyNextWindowAction.java @@ -16,7 +16,7 @@ public class StudyNextWindowAction extends StudyWindowNavigationAction { public static final String SHORTCUT2 = "ctrl pressed ENTER"; public StudyNextWindowAction() { - super("NextWindowAction", "Select next window", AllIcons.Actions.Forward); + super("Navigate to the Next Answer Placeholder", "Navigate to the next answer placeholder", AllIcons.Actions.Forward); } @Override diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyPrevWindowAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyPrevWindowAction.java index 1e602bd059ff..01f6e1688b02 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyPrevWindowAction.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyPrevWindowAction.java @@ -17,7 +17,7 @@ public class StudyPrevWindowAction extends StudyWindowNavigationAction { public static final String SHORTCUT = "ctrl shift pressed COMMA"; public StudyPrevWindowAction() { - super("PrevWindowAction", "Select previous window", StudyIcons.Prev); + super("Navigate to the Previous Answer Placeholder", "Navigate to the previous answer placeholder", StudyIcons.Prev); } diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyShowHintAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyShowHintAction.java index 7a7c4408f795..c07888519d15 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyShowHintAction.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyShowHintAction.java @@ -28,8 +28,8 @@ import java.io.File; public class StudyShowHintAction extends DumbAwareAction { public static final String ACTION_ID = "ShowHintAction"; public static final String SHORTCUT = "ctrl pressed 7"; - public static final String OUTSIDE_TASK_WINDOW_MESSAGE = "Put caret to the task window to get hint."; - public static final String HINT_NOT_AVAILABLE = "There is no hint for this task window"; + public static final String OUTSIDE_TASK_WINDOW_MESSAGE = "Put caret to answer placeholder to get hint"; + public static final String HINT_NOT_AVAILABLE = "There is no hint for this answer placeholder"; public StudyShowHintAction() { super("Show hint", "Show hint", StudyIcons.ShowHint); From 23956b41be4fd9462c4dddb514c0378d362c8278 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Wed, 29 Oct 2014 18:38:17 +0300 Subject: [PATCH 03/29] renamed task windows to answer placeholders for python code --- .../fileTemplates/internal/test_helper.py.ft | 16 ++++++++-------- .../fileTemplates/internal/tests.py.ft | 12 ++++++------ .../resources/courses/introduction_course.zip | Bin 95611 -> 96022 bytes 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/python/edu/course-creator/resources/fileTemplates/internal/test_helper.py.ft b/python/edu/course-creator/resources/fileTemplates/internal/test_helper.py.ft index 313b9150c467..c08945e0a747 100644 --- a/python/edu/course-creator/resources/fileTemplates/internal/test_helper.py.ft +++ b/python/edu/course-creator/resources/fileTemplates/internal/test_helper.py.ft @@ -46,9 +46,9 @@ def check_importable_path(path): try: import_file(path) except: - failed("File contains syntax errors", test_file_importable.__name__) + failed("File contains syntax errors", test_file_importable.func_name) return - passed(test_file_importable.__name__) + passed(test_file_importable.func_name) def import_file(path): @@ -126,11 +126,11 @@ def test_text_equals(text, error_text): failed(error_text) -def test_window_text_deleted(error_text="Don't just delete task text"): +def test_answer_placeholders_text_deleted(error_text="Don't just delete task text"): """ - Checks that task windows are not empty + Checks that all answer placeholders are not empty """ - windows = get_task_windows() + windows = get_answer_placeholders() for window in windows: if len(window) == 0: @@ -153,9 +153,9 @@ def passed(name=None): print("#educational_plugin " + name + " test OK") -def get_task_windows(file_name=None): +def get_answer_placeholders(file_name=None): """ - Returns all task windows + Returns all answer placeholders text """ prefix = "#educational_plugin_window = " import os @@ -198,4 +198,4 @@ def run_common_tests(error_text="Please, reload file and try again"): test_file_importable() test_is_not_empty() test_is_initial_text(error_text) - test_window_text_deleted(error_text) \ No newline at end of file + test_answer_placeholders_text_deleted(error_text) \ No newline at end of file diff --git a/python/edu/course-creator/resources/fileTemplates/internal/tests.py.ft b/python/edu/course-creator/resources/fileTemplates/internal/tests.py.ft index 788d6f93c49c..c6e2c659a000 100644 --- a/python/edu/course-creator/resources/fileTemplates/internal/tests.py.ft +++ b/python/edu/course-creator/resources/fileTemplates/internal/tests.py.ft @@ -1,10 +1,10 @@ -from test_helper import run_common_tests, failed, passed, get_task_windows +from test_helper import run_common_tests, failed, passed, get_answer_placeholders -def test_task_windows(): - windows = get_task_windows() - window = windows[0] - if window == "": # TODO: your condition here +def test_answer_placeholders(): + placeholders = get_answer_placeholders() + placeholder = placeholders[0] + if placeholder == "": # TODO: your condition here passed() else: failed() @@ -12,6 +12,6 @@ def test_task_windows(): if __name__ == '__main__': run_common_tests() - # test_task_windows() # TODO: uncomment test call + # test_answer_placeholders() # TODO: uncomment test call diff --git a/python/edu/learn-python/resources/courses/introduction_course.zip b/python/edu/learn-python/resources/courses/introduction_course.zip index d6a4303a0a0f8d510156a6e2f9b3d8b676cc4388..d84a8d2a80cb0396e027919077a4586c67239d27 100644 GIT binary patch delta 26717 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 delta 26045 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 df?KM=Lr+# Date: Wed, 29 Oct 2014 17:10:43 +0100 Subject: [PATCH 04/29] recompile classes with potentially ambiguous method calls when vararg method is added --- .../incremental/membersChange/addMethod.log | 2 + .../membersChange/addVarargMethod.log | 14 +++++ .../membersChange/addVarargMethod/src/A.java | 9 +++ .../addVarargMethod/src/A.java.new | 9 +++ .../membersChange/addVarargMethod/src/C.java | 5 ++ .../membersChange/addVarargMethod/src/D.java | 5 ++ .../dependencyView/ClassfileAnalyzer.java | 6 +- .../java/dependencyView/Mappings.java | 60 ++++++++++++------- .../java/dependencyView/MethodRepr.java | 26 ++++---- .../java/dependencyView/UsageRepr.java | 41 +------------ .../incremental/storage/BuildDataManager.java | 2 +- .../org/jetbrains/ether/MemberChangeTest.java | 4 ++ 12 files changed, 105 insertions(+), 78 deletions(-) create mode 100644 java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod.log create mode 100644 java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/A.java create mode 100644 java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/A.java.new create mode 100644 java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/C.java create mode 100644 java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/D.java diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/addMethod.log b/java/java-tests/testData/compileServer/incremental/membersChange/addMethod.log index 316e4be06caa..9e0611c49b3a 100644 --- a/java/java-tests/testData/compileServer/incremental/membersChange/addMethod.log +++ b/java/java-tests/testData/compileServer/incremental/membersChange/addMethod.log @@ -5,8 +5,10 @@ Compiling files: src/A.java End of files Cleaning output files: +out/production/AddMethod/C.class out/production/AddMethod/D.class End of files Compiling files: +src/C.java src/D.java End of files diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod.log b/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod.log new file mode 100644 index 000000000000..424b39bc3bd2 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod.log @@ -0,0 +1,14 @@ +Cleaning output files: +out/production/AddVarargMethod/A.class +End of files +Compiling files: +src/A.java +End of files +Cleaning output files: +out/production/AddVarargMethod/C.class +out/production/AddVarargMethod/D.class +End of files +Compiling files: +src/C.java +src/D.java +End of files diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/A.java b/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/A.java new file mode 100644 index 000000000000..eee8a41d0deb --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/A.java @@ -0,0 +1,9 @@ +public class A { + void f (String x, Integer y) { + + } + + void f (String x, Integer y, Long z, String... v){ + + } +} diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/A.java.new b/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/A.java.new new file mode 100644 index 000000000000..1b7d9e4bdbd8 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/A.java.new @@ -0,0 +1,9 @@ +public class A { + void f (String x, Integer y, String... v) { + + } + + void f (String x, Integer y, Long z, String... v){ + + } +} diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/C.java b/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/C.java new file mode 100644 index 000000000000..4aa7df6d14a0 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/C.java @@ -0,0 +1,5 @@ +public class C { + void f (A a){ + a.f("1", 2); + } +} diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/D.java b/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/D.java new file mode 100644 index 000000000000..8c9dba5c485c --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/membersChange/addVarargMethod/src/D.java @@ -0,0 +1,5 @@ +public class D { + void f(A a){ + a.f("1", 2, null, "comment"); + } +} diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java index 01013e05186a..137f4527b5a8 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java @@ -173,7 +173,7 @@ class ClassfileAnalyzer { } myUsages.add(UsageRepr.createMethodUsage(myContext, methodName, myType.className, methodDescr)); - myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, myType.className, methodDescr)); + myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, myType.className)); myUsedArguments.add(methodName); } @@ -183,7 +183,7 @@ class ClassfileAnalyzer { final String methodDescr = "()" + desc; myUsages.add(UsageRepr.createMethodUsage(myContext, methodName, myType.className, methodDescr)); - myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, myType.className, methodDescr)); + myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, myType.className)); myUsedArguments.add(methodName); } @@ -526,7 +526,7 @@ class ClassfileAnalyzer { final int methodOwner = myContext.get(owner); myUsages.add(UsageRepr.createMethodUsage(myContext, methodName, methodOwner, desc)); - myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, methodOwner, desc)); + myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, methodOwner)); addClassUsage(TypeRepr.getType(myContext, Type.getReturnType(desc))); super.visitMethodInsn(opcode, owner, name, desc, itf); diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java index 3274a7ef896c..612adb06e27d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java @@ -400,16 +400,31 @@ public class Mappings { private boolean hasOverriddenMethods(final ClassRepr fromClass, final MethodRepr.Predicate predicate) { for (int superName : fromClass.getSupers()) { - final ClassRepr superClass = reprByName(superName); - if (superClass == null) { - return true; // assumption + if (superName == myObjectClassName) { + continue; } - for (MethodRepr mm : superClass.findMethods(predicate)) { - if (isVisibleIn(superClass, mm, fromClass)) { + final ClassRepr superClass = reprByName(superName); + if (superClass != null) { + for (MethodRepr mm : superClass.findMethods(predicate)) { + if (isVisibleIn(superClass, mm, fromClass)) { + return true; + } + } + if (hasOverriddenMethods(superClass, predicate)) { return true; } } - if (hasOverriddenMethods(superClass, predicate)) { + } + return false; + } + + private boolean extendsLibraryClass(final ClassRepr fromClass) { + for (int superName : fromClass.getSupers()) { + if (superName != myObjectClassName) { + continue; + } + final ClassRepr superClass = reprByName(superName); + if (superClass == null || extendsLibraryClass(superClass)) { return true; } } @@ -440,6 +455,9 @@ public class Mappings { void addOverriddenFields(final FieldRepr f, final ClassRepr fromClass, final Collection> container) { for (int supername : fromClass.getSupers()) { + if (supername == myObjectClassName) { + continue; + } final ClassRepr superClass = reprByName(supername); if (superClass != null) { final FieldRepr ff = superClass.findField(f.name); @@ -455,6 +473,9 @@ public class Mappings { boolean hasOverriddenFields(final FieldRepr f, final ClassRepr fromClass) { for (int supername : fromClass.getSupers()) { + if (supername == myObjectClassName) { + continue; + } final ClassRepr superClass = reprByName(supername); if (superClass != null) { final FieldRepr ff = superClass.findField(f.name); @@ -534,15 +555,8 @@ public class Mappings { return Boolean.FALSE; } - boolean isMethodVisible(final int className, final MethodRepr m) { - final ClassRepr r = reprByName(className); - if (r != null) { - if (r.findMethods(MethodRepr.equalByJavaRules(m)).size() > 0) { - return true; - } - return hasOverriddenMethods(r, MethodRepr.equalByJavaRules(m)); - } - return false; + boolean isMethodVisible(final ClassRepr classRepr, final MethodRepr m) { + return classRepr.findMethods(MethodRepr.equalByJavaRules(m)).size() > 0 || hasOverriddenMethods(classRepr, MethodRepr.equalByJavaRules(m)); } boolean isFieldVisible(final int className, final FieldRepr field) { @@ -1082,10 +1096,7 @@ public class Mappings { } final ClassRepr oldIt = oldItRef.get(); - if (oldIt != null && myPresent.hasOverriddenMethods(oldIt, MethodRepr.equalByJavaRules(m))) { - - } - else { + if (oldIt == null || !myPresent.hasOverriddenMethods(oldIt, MethodRepr.equalByJavaRules(m))) { if (m.myArgumentTypes.length > 0) { propagated = myFuture.propagateMethodAccess(m, it.name); debug("Conservative case on overriding methods, affecting method usages"); @@ -1170,10 +1181,13 @@ public class Mappings { final Collection sourceFileNames = myClassToSourceFile.get(subClass); if (sourceFileNames != null && !myCompiledFiles.containsAll(sourceFileNames)) { final int outerClass = r.getOuterClassName(); - if (!isEmpty(outerClass) && myFuture.isMethodVisible(outerClass, m)) { - myAffectedFiles.addAll(sourceFileNames); - for (File sourceFileName : sourceFileNames) { - debug("Affecting file due to local overriding: ", sourceFileName); + if (!isEmpty(outerClass)) { + final ClassRepr outerClassRepr = myFuture.reprByName(outerClass); + if (outerClassRepr != null && (myFuture.isMethodVisible(outerClassRepr, m) || myFuture.extendsLibraryClass(outerClassRepr))) { + myAffectedFiles.addAll(sourceFileNames); + for (File sourceFileName : sourceFileNames) { + debug("Affecting file due to local overriding: ", sourceFileName); + } } } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java index fea3d8a3d8d8..1338bca67e08 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java @@ -112,8 +112,8 @@ class MethodRepr extends ProtoMember { public void updateClassUsages(final DependencyContext context, final int owner, final Set s) { myType.updateClassUsages(context, owner, s); - for (int i = 0; i < myArgumentTypes.length; i++) { - myArgumentTypes[i].updateClassUsages(context, owner, s); + for (final TypeRepr.AbstractType argType : myArgumentTypes) { + argType.updateClassUsages(context, owner, s); } if (myExceptions != null) { @@ -124,17 +124,17 @@ class MethodRepr extends ProtoMember { } public MethodRepr(final DependencyContext context, - final int a, - final int n, - final int s, - final String d, - final String[] e, - final Object value) { - super(a, s, n, TypeRepr.getType(context, Type.getReturnType(d)), value); + final int accessFlags, + final int name, + final int signature, + final String descriptor, + final String[] exceptions, + final Object defaultValue) { + super(accessFlags, signature, name, TypeRepr.getType(context, Type.getReturnType(descriptor)), defaultValue); Set typeCollection = - e != null ? new THashSet(e.length) : Collections.emptySet(); - myExceptions = (Set)TypeRepr.createClassType(context, e, typeCollection); - myArgumentTypes = TypeRepr.getType(context, Type.getArgumentTypes(d)); + exceptions != null ? new THashSet(exceptions.length) : Collections.emptySet(); + myExceptions = (Set)TypeRepr.createClassType(context, exceptions, typeCollection); + myArgumentTypes = TypeRepr.getType(context, Type.getArgumentTypes(descriptor)); } public MethodRepr(final DependencyContext context, final DataInput in) { @@ -216,7 +216,7 @@ class MethodRepr extends ProtoMember { } public UsageRepr.Usage createMetaUsage(final DependencyContext context, final int owner) { - return UsageRepr.createMetaMethodUsage(context, name, owner, getDescr(context)); + return UsageRepr.createMetaMethodUsage(context, name, owner); } @Override diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java index e7b376980fae..d6d3ff799a7b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java @@ -278,52 +278,18 @@ class UsageRepr { } public static class MetaMethodUsage extends FMUsage { - private int myArity; - public MetaMethodUsage(final DependencyContext context, final int n, final int o, final String descr) { + public MetaMethodUsage(final int n, final int o) { super(n, o); - myArity = TypeRepr.getType(context, Type.getArgumentTypes(descr)).length; } public MetaMethodUsage(final DataInput in) { super(in); - try { - myArity = DataInputOutputUtil.readINT(in); - } - catch (IOException e) { - throw new BuildDataCorruptedException(e); - } } @Override public void save(final DataOutput out) { save(METAMETHOD_USAGE, out); - try { - DataInputOutputUtil.writeINT(out, myArity); - } - catch (IOException e) { - throw new BuildDataCorruptedException(e); - } - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - - MetaMethodUsage that = (MetaMethodUsage)o; - - if (myArity != that.myArity) return false; - - return super.equals(o); - } - - @Override - public int hashCode() { - int result = super.hashCode(); - result = 31 * result + myArity; - return result; } @Override @@ -334,7 +300,6 @@ class UsageRepr { @Override public void toStream(DependencyContext context, PrintStream stream) { super.toStream(context, stream); - stream.println(" Arity: " + Integer.toString(myArity)); } } @@ -679,8 +644,8 @@ class UsageRepr { return context.getUsage(new MethodUsage(context, name, owner, descr)); } - public static Usage createMetaMethodUsage(final DependencyContext context, final int name, final int owner, final String descr) { - return context.getUsage(new MetaMethodUsage(context, name, owner, descr)); + public static Usage createMetaMethodUsage(final DependencyContext context, final int name, final int owner) { + return context.getUsage(new MetaMethodUsage(name, owner)); } public static Usage createClassUsage(final DependencyContext context, final int name) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java index a6ed636e8d11..9a40498ec619 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java @@ -42,7 +42,7 @@ import java.util.concurrent.ConcurrentMap; * Date: 10/7/11 */ public class BuildDataManager implements StorageOwner { - private static final int VERSION = 25; + private static final int VERSION = 26; private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildDataManager"); private static final String SRC_TO_FORM_STORAGE = "src-form"; private static final String OUT_TARGET_STORAGE = "out-target"; diff --git a/jps/jps-builders/testSrc/org/jetbrains/ether/MemberChangeTest.java b/jps/jps-builders/testSrc/org/jetbrains/ether/MemberChangeTest.java index 90ecb820bbc6..3866756a0929 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/ether/MemberChangeTest.java +++ b/jps/jps-builders/testSrc/org/jetbrains/ether/MemberChangeTest.java @@ -203,4 +203,8 @@ public class MemberChangeTest extends IncrementalTestCase { public void testAddMethod() { doTest(); } + + public void testAddVarargMethod() { + doTest(); + } } From fdf1bbf17d2a26067f2c6709249b78b92dd8df0c Mon Sep 17 00:00:00 2001 From: Liana Bakradze Date: Wed, 29 Oct 2014 19:21:45 +0300 Subject: [PATCH 05/29] fixed bug with empty task files, improved navigation to task --- .../edu/StudyDirectoryProjectGenerator.java | 12 +++++++++-- .../edu/projectView/StudyDirectoryNode.java | 21 +++++++++++++------ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java index a9630f6f730c..90a4b74521de 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyDirectoryProjectGenerator.java @@ -20,6 +20,7 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl; import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter; import com.intellij.openapi.wm.ex.ToolWindowManagerEx; @@ -188,7 +189,6 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple final VirtualFile taskDir = firstTask.getTaskDir(myProject); if (taskDir == null) return; final Map taskFiles = firstTask.getTaskFiles(); - VirtualFile activeVirtualFile = null; for (Map.Entry entry : taskFiles.entrySet()) { final String name = entry.getKey(); @@ -204,8 +204,16 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple if (activeVirtualFile != null) { final PsiFile file = PsiManager.getInstance(myProject).findFile(activeVirtualFile); ProjectView.getInstance(project).select(file, activeVirtualFile, true); - initialized[0] = true; + } else { + String first = StudyUtils.getFirst(taskFiles.keySet()); + if (first != null) { + NewVirtualFile firstFile = ((VirtualDirectoryImpl)taskDir).refreshAndFindChild(first); + if (firstFile != null) { + FileEditorManager.getInstance(project).openFile(firstFile, true); + } + } } + initialized[0] = true; } }, ModalityState.current(), new Condition() { @Override diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java b/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java index bb23f5e918fc..4bd8df9baee7 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/projectView/StudyDirectoryNode.java @@ -19,7 +19,7 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.util.Set; +import java.util.Map; public class StudyDirectoryNode extends PsiDirectoryNode { private final PsiDirectory myValue; @@ -144,15 +144,24 @@ public class StudyDirectoryNode extends PsiDirectoryNode { FileEditorManager.getInstance(myProject).closeFile(openFile); } VirtualFile child = null; - Set fileNames = task.getTaskFiles().keySet(); - for (String name : fileNames) { - child = taskDir.findChild(name); - if (child != null) { - FileEditorManager.getInstance(myProject).openFile(child, true); + Map taskFiles = task.getTaskFiles(); + for (Map.Entry entry: taskFiles.entrySet()) { + VirtualFile file = taskDir.findChild(entry.getKey()); + if (file != null) { + FileEditorManager.getInstance(myProject).openFile(file, true); + } + if (!entry.getValue().getTaskWindows().isEmpty()) { + child = file; } } if (child != null) { ProjectView.getInstance(myProject).select(child, child, false); + FileEditorManager.getInstance(myProject).openFile(child, true); + } else { + VirtualFile[] children = taskDir.getChildren(); + if (children.length > 0) { + ProjectView.getInstance(myProject).select(children[0], children[0], false); + } } } } From 115dd96a27b94260450f1e6bb959b990102b3f18 Mon Sep 17 00:00:00 2001 From: Liana Bakradze Date: Wed, 29 Oct 2014 19:34:39 +0300 Subject: [PATCH 06/29] removed vendor --- python/edu/learn-python/resources/META-INF/plugin.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/python/edu/learn-python/resources/META-INF/plugin.xml b/python/edu/learn-python/resources/META-INF/plugin.xml index f3a52d5ab9d2..81eb2cef801f 100644 --- a/python/edu/learn-python/resources/META-INF/plugin.xml +++ b/python/edu/learn-python/resources/META-INF/plugin.xml @@ -3,7 +3,6 @@ com.jetbrains.python.edu.learn-python Educational plugin for PyCharm 1.1 - YourCompany Date: Wed, 29 Oct 2014 19:38:52 +0300 Subject: [PATCH 07/29] fix matplotlib in console in windows --- python/helpers/pydev/pydev_ipython/matplotlibtools.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/python/helpers/pydev/pydev_ipython/matplotlibtools.py b/python/helpers/pydev/pydev_ipython/matplotlibtools.py index 075c43781ab3..b11cd0c19e99 100644 --- a/python/helpers/pydev/pydev_ipython/matplotlibtools.py +++ b/python/helpers/pydev/pydev_ipython/matplotlibtools.py @@ -57,6 +57,16 @@ def patch_use(interpreter): setattr(matplotlib, "use", patched_use) +def patch_is_interactive(): + """ Patch matplotlib function 'use' """ + matplotlib = sys.modules['matplotlib'] + def patched_is_interactive(): + return matplotlib.rcParams['interactive'] + + setattr(matplotlib, "real_is_interactive", getattr(matplotlib, "is_interactive")) + setattr(matplotlib, "is_interactive", patched_is_interactive) + + def activate_matplotlib(interpreter): """Set interactive to True for interactive backends.""" def activate_matplotlib_inner(): @@ -73,6 +83,7 @@ def activate_matplotlib(interpreter): sys.stdout.write("Backend %s is non-interactive backend. Turning interactive mode off.\n" % backend) matplotlib.interactive(False) patch_use(interpreter) + patch_is_interactive() return activate_matplotlib_inner From 0b57ad257650d1ebec45a66315a62240fb30da36 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Wed, 29 Oct 2014 17:51:23 +0100 Subject: [PATCH 08/29] Memory leak in UndoRedoStacksHolder (IDEA-131506) --- .../intellij/openapi/command/impl/UndoRedoStacksHolder.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoRedoStacksHolder.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoRedoStacksHolder.java index 49bb65608450..529fddd24a5d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoRedoStacksHolder.java +++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoRedoStacksHolder.java @@ -19,6 +19,8 @@ import com.intellij.openapi.command.undo.DocumentReference; import com.intellij.openapi.command.undo.DocumentReferenceManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.testFramework.LightVirtualFile; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.WeakList; import gnu.trove.THashSet; @@ -41,7 +43,8 @@ class UndoRedoStacksHolder { @NotNull LinkedList getStack(@NotNull DocumentReference r) { - return r.getFile() != null ? doGetStackForFile(r) : doGetStackForDocument(r); + VirtualFile file = r.getFile(); + return file != null && !(file instanceof LightVirtualFile) ? doGetStackForFile(r) : doGetStackForDocument(r); } @NotNull From aaf6edac79f55817c058e88de92702e9aacccc2c Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Wed, 29 Oct 2014 17:53:49 +0100 Subject: [PATCH 09/29] don't hold psi in local search scope of SSBasedInspection --- .../com/intellij/structuralsearch/impl/matcher/MatcherImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java index 100abd8650c8..7a166478d3c9 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java @@ -146,6 +146,7 @@ public class MatcherImpl { visitor.matchContext(matchedNodes); } finally { matchedNodes.reset(); + matchContext.getOptions().setScope(null); } } From afe9b5c0562ae5e8ae167389dac8555a2182af07 Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Wed, 29 Oct 2014 20:02:52 +0300 Subject: [PATCH 10/29] refactoring in pydev console --- .../pydev/{import_hook.py => pydev_import_hook.py} | 0 .../helpers/pydev/pydev_ipython/matplotlibtools.py | 13 ------------- python/helpers/pydev/pydevconsole.py | 9 +++++---- 3 files changed, 5 insertions(+), 17 deletions(-) rename python/helpers/pydev/{import_hook.py => pydev_import_hook.py} (100%) diff --git a/python/helpers/pydev/import_hook.py b/python/helpers/pydev/pydev_import_hook.py similarity index 100% rename from python/helpers/pydev/import_hook.py rename to python/helpers/pydev/pydev_import_hook.py diff --git a/python/helpers/pydev/pydev_ipython/matplotlibtools.py b/python/helpers/pydev/pydev_ipython/matplotlibtools.py index b11cd0c19e99..31a7f06fb994 100644 --- a/python/helpers/pydev/pydev_ipython/matplotlibtools.py +++ b/python/helpers/pydev/pydev_ipython/matplotlibtools.py @@ -1,6 +1,5 @@ import sys -from import_hook import import_hook_manager backends = {'tk': 'TkAgg', 'gtk': 'GTKAgg', @@ -87,10 +86,6 @@ def activate_matplotlib(interpreter): return activate_matplotlib_inner -def init_matplotlib(interpreter): - import_hook_manager.add_module_name("matplotlib", activate_matplotlib(interpreter)) - - def flag_calls(func): """Wrap a function to detect and flag when it gets called. @@ -127,17 +122,9 @@ def activate_pylab(): pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive) -def init_pylab(): - import_hook_manager.add_module_name("pylab", activate_pylab) - - def activate_pyplot(): pyplot = sys.modules['matplotlib.pyplot'] pyplot.show._needmain = False # We need to detect at runtime whether show() is called by the user. # For this, we wrap it into a decorator which adds a 'called' flag. pyplot.draw_if_interactive = flag_calls(pyplot.draw_if_interactive) - - -def init_pyplot(): - import_hook_manager.add_module_name("pyplot", activate_pyplot) \ No newline at end of file diff --git a/python/helpers/pydev/pydevconsole.py b/python/helpers/pydev/pydevconsole.py index b38847a82925..f48f975f703f 100644 --- a/python/helpers/pydev/pydevconsole.py +++ b/python/helpers/pydev/pydevconsole.py @@ -171,10 +171,11 @@ def process_exec_queue(interpreter): set_return_control_callback(return_control) - from pydev_ipython.matplotlibtools import init_matplotlib, init_pylab, init_pyplot - init_matplotlib(interpreter) - init_pylab() - init_pyplot() + from pydev_import_hook import import_hook_manager + from pydev_ipython.matplotlibtools import activate_matplotlib, activate_pylab, activate_pyplot + import_hook_manager.add_module_name("matplotlib", activate_matplotlib(interpreter)) + import_hook_manager.add_module_name("pylab", activate_pylab) + import_hook_manager.add_module_name("pyplot", activate_pyplot) while 1: # Running the request may have changed the inputhook in use From 768cdd5d0c4493fdd73b2eb7a8d2139565767915 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Wed, 29 Oct 2014 19:30:53 +0300 Subject: [PATCH 11/29] util: TreeTraverser/FluentIterator from Guava; uiTraverser() and the end of OrphanGuardian --- .../openapi/ui/SimpleToolWindowPanel.java | 27 +- .../ui/components/OrphanGuardian.java | 31 -- .../com/intellij/ui/tabs/impl/JBTabsImpl.java | 29 +- .../openapi/editor/impl/EditorImpl.java | 20 +- .../com/intellij/util/IJSwingUtilities.java | 42 +-- .../com/intellij/openapi/util/Conditions.java | 33 +- .../util/containers/FluentIterable.java | 283 ++++++++++++++++++ .../util/containers/TreeTraverser.java | 215 +++++++++++++ .../intellij/util/ui/JBSwingUtilities.java | 40 +++ .../util/src/com/intellij/util/ui/UIUtil.java | 4 + 10 files changed, 599 insertions(+), 125 deletions(-) delete mode 100644 platform/platform-api/src/com/intellij/ui/components/OrphanGuardian.java create mode 100644 platform/util/src/com/intellij/util/containers/FluentIterable.java create mode 100644 platform/util/src/com/intellij/util/containers/TreeTraverser.java diff --git a/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java b/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java index dfbaa33999fb..7c3e91f78394 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java @@ -19,6 +19,7 @@ import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Conditions; import com.intellij.openapi.util.Ref; import com.intellij.openapi.wm.ToolWindow; import com.intellij.ui.content.Content; @@ -26,9 +27,8 @@ import com.intellij.ui.content.ContentManager; import com.intellij.ui.content.ContentManagerAdapter; import com.intellij.ui.content.ContentManagerEvent; import com.intellij.ui.switcher.QuickActionProvider; -import com.intellij.ui.tabs.JBTabs; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.AwtVisitor; +import com.intellij.util.ui.JBSwingUtilities; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -38,7 +38,6 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ContainerAdapter; import java.awt.event.ContainerEvent; -import java.util.LinkedList; import java.util.List; public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider, DataProvider { @@ -199,14 +198,6 @@ public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider component instanceof DataProvider ? PlatformDataKeys.CONTENT_MANAGER.getData((DataProvider)component) : null; if (contentManager != null) contentManager.addContentManagerListener(this); } - - @Override - public void selectionChanged(ContentManagerEvent event) { - Content content = event.getContent(); - if (content != null) { - setContentToolbarVisible(content.getComponent(), getVisibilityValue()); - } - } }); } @@ -233,18 +224,8 @@ public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider } private static void setContentToolbarVisible(@NotNull JComponent root, boolean state) { - LinkedList deque = ContainerUtil.newLinkedList(root); - while(!deque.isEmpty()) { - JComponent component = deque.pollFirst(); - for (int i = 0, count = component.getComponentCount(); i < count; i++) { - Component c = component.getComponent(i); - if (c instanceof ActionToolbar) { - c.setVisible(state); - } - else if (c instanceof JPanel || c instanceof JLayeredPane || c instanceof JBTabs) { - deque.addLast((JComponent)c); - } - } + for (Component c : JBSwingUtilities.uiTraverser().preOrderTraversal(root).filter(Conditions.instanceOf(ActionToolbar.class))) { + c.setVisible(state); } } } diff --git a/platform/platform-api/src/com/intellij/ui/components/OrphanGuardian.java b/platform/platform-api/src/com/intellij/ui/components/OrphanGuardian.java deleted file mode 100644 index c8a044c16a3c..000000000000 --- a/platform/platform-api/src/com/intellij/ui/components/OrphanGuardian.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2000-2014 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.ui.components; - -import com.intellij.openapi.util.Key; -import com.intellij.util.Consumer; - -import javax.swing.*; - -/** - * @author gregsh - */ -public interface OrphanGuardian { - Key CLIENT_PROPERTY_KEY = Key.create("OrphanGuardian"); - - void iterateOrphans(Consumer processor); -} diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java index 97c158e08d9f..56df43a94eaf 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java @@ -28,7 +28,6 @@ import com.intellij.openapi.wm.*; import com.intellij.ui.*; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.awt.RelativeRectangle; -import com.intellij.ui.components.OrphanGuardian; import com.intellij.ui.switcher.QuickActionProvider; import com.intellij.ui.switcher.SwitchProvider; import com.intellij.ui.switcher.SwitchTarget; @@ -37,13 +36,10 @@ import com.intellij.ui.tabs.impl.singleRow.SingleRowLayout; import com.intellij.ui.tabs.impl.singleRow.SingleRowPassInfo; import com.intellij.ui.tabs.impl.table.TableLayout; import com.intellij.ui.tabs.impl.table.TablePassInfo; -import com.intellij.util.Consumer; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.ui.Animator; -import com.intellij.util.ui.JBInsets; -import com.intellij.util.ui.TimedDeadzone; -import com.intellij.util.ui.UIUtil; +import com.intellij.util.containers.FluentIterable; +import com.intellij.util.ui.*; import com.intellij.util.ui.update.ComparableObject; import com.intellij.util.ui.update.LazyUiDisposable; import org.jetbrains.annotations.NonNls; @@ -316,16 +312,19 @@ public class JBTabsImpl extends JComponent } } }; - putClientProperty(OrphanGuardian.CLIENT_PROPERTY_KEY, new OrphanGuardian() { - - @Override - public void iterateOrphans(Consumer consumer) { - for (TabInfo info : getVisibleInfos()) { - if (info == mySelectedInfo) continue; - consumer.consume(info.getComponent()); + UIUtil.putClientProperty( + this, JBSwingUtilities.NOT_IN_HIERARCHY_COMPONENTS, new Iterable() { + @Override + public Iterator iterator() { + return FluentIterable.from(getVisibleInfos()).filter(Conditions.not(Conditions.is(mySelectedInfo))).transform( + new Function() { + @Override + public JComponent fun(TabInfo info) { + return info.getComponent(); + } + }).iterator(); } - } - }); + }); } protected SingleRowLayout createSingleRowLayout() { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 484191e67b07..504e47abb36a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -74,7 +74,6 @@ import com.intellij.ui.*; import com.intellij.ui.components.JBLayeredPane; import com.intellij.ui.components.JBScrollBar; import com.intellij.ui.components.JBScrollPane; -import com.intellij.ui.components.OrphanGuardian; import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtilRt; @@ -491,16 +490,17 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myVerticalScrollBar = (MyScrollBar)myScrollPane.getVerticalScrollBar(); myPanel = new JPanel(); - myPanel.putClientProperty(OrphanGuardian.CLIENT_PROPERTY_KEY, new OrphanGuardian() { - - @Override - public void iterateOrphans(Consumer consumer) { - JComponent component = getPermanentHeaderComponent(); - if (component != null && !component.isValid()) { - consumer.consume(component); + UIUtil.putClientProperty( + myPanel, JBSwingUtilities.NOT_IN_HIERARCHY_COMPONENTS, new Iterable() { + @Override + public Iterator iterator() { + JComponent component = getPermanentHeaderComponent(); + if (component != null && !component.isValid()) { + return Collections.singleton(component).iterator(); + } + return ContainerUtil.emptyIterator(); } - } - }); + }); myHeaderPanel = new MyHeaderPanel(); myGutterComponent = new EditorGutterComponentImpl(this); diff --git a/platform/platform-impl/src/com/intellij/util/IJSwingUtilities.java b/platform/platform-impl/src/com/intellij/util/IJSwingUtilities.java index 5660f0ca05d6..30e1e5b58d6d 100644 --- a/platform/platform-impl/src/com/intellij/util/IJSwingUtilities.java +++ b/platform/platform-impl/src/com/intellij/util/IJSwingUtilities.java @@ -20,7 +20,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.wm.ex.WindowManagerEx; import com.intellij.ui.EditorTextField; -import com.intellij.ui.components.OrphanGuardian; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.FilteringIterator; import com.intellij.util.ui.JBSwingUtilities; @@ -230,47 +229,16 @@ public class IJSwingUtilities extends JBSwingUtilities { * @param c component * @see javax.swing.SwingUtilities#updateComponentTreeUI */ - public static void updateComponentTreeUI(Component c) { - updateComponentTreeUI0(c); + public static void updateComponentTreeUI(@Nullable Component c) { + if (c == null) return; + for (Component component : uiTraverser().postOrderTraversal(c)) { + if (component instanceof JComponent) ((JComponent)component).updateUI(); + } c.invalidate(); c.validate(); c.repaint(); } - private static final Consumer UI_TREE_UPDATER = new Consumer() { - @Override - public void consume(JComponent component) { - updateComponentTreeUI0(component); - } - }; - - private static void updateComponentTreeUI0(Component c) { - Component[] children = null; - if (c instanceof JMenu) { - children = ((JMenu)c).getMenuComponents(); - } - else if (c instanceof Container) { - children = ((Container)c).getComponents(); - } - if (children != null) { - for (Component aChildren : children) { - updateComponentTreeUI0(aChildren); - } - } - if (c instanceof JComponent) { - JComponent jc = (JComponent)c; - OrphanGuardian orphans = (OrphanGuardian)jc.getClientProperty(OrphanGuardian.CLIENT_PROPERTY_KEY); - if (orphans != null) { - orphans.iterateOrphans(UI_TREE_UPDATER); - } - jc.updateUI(); - JPopupMenu jpm = jc.getComponentPopupMenu(); - if (jpm != null && jpm.isVisible() && jpm.getInvoker() == jc) { - updateComponentTreeUI(jpm); - } - } - } - public static void moveMousePointerOn(Component component) { if (component != null && component.isShowing()) { UISettings settings = ApplicationManager.getApplication() == null ? null : UISettings.getInstance(); diff --git a/platform/util-rt/src/com/intellij/openapi/util/Conditions.java b/platform/util-rt/src/com/intellij/openapi/util/Conditions.java index ef3c0d2acbf6..a837d43487e3 100644 --- a/platform/util-rt/src/com/intellij/openapi/util/Conditions.java +++ b/platform/util-rt/src/com/intellij/openapi/util/Conditions.java @@ -26,12 +26,14 @@ import java.util.HashMap; * @author max */ public class Conditions { - private Conditions() {} + private Conditions() { + } @NotNull public static Condition alwaysTrue() { return (Condition)TRUE; } + @NotNull public static Condition alwaysFalse() { return (Condition)FALSE; @@ -67,12 +69,23 @@ public class Conditions { public static Condition not(Condition c) { return new Not(c); } + public static Condition and(Condition c1, Condition c2) { return new And(c1, c2); } + + public static Condition and2(Condition c1, Condition c2) { + return new And(c1, c2); + } + public static Condition or(Condition c1, Condition c2) { return new Or(c1, c2); } + + public static Condition or2(Condition c1, Condition c2) { + return new Or(c1, c2); + } + public static Condition cached(Condition c) { return new SoftRefCache(c); } @@ -89,11 +102,12 @@ public class Conditions { return !myCondition.value(value); } } - private static class And implements Condition { - private final Condition t1; - private final Condition t2; - public And(final Condition t1, final Condition t2) { + private static class And implements Condition { + private final Condition t1; + private final Condition t2; + + public And(Condition t1, Condition t2) { this.t1 = t1; this.t2 = t2; } @@ -103,11 +117,12 @@ public class Conditions { return t1.value(object) && t2.value(object); } } - private static class Or implements Condition { - private final Condition t1; - private final Condition t2; - public Or(final Condition t1, final Condition t2) { + private static class Or implements Condition { + private final Condition t1; + private final Condition t2; + + public Or(Condition t1, Condition t2) { this.t1 = t1; this.t2 = t2; } diff --git a/platform/util/src/com/intellij/util/containers/FluentIterable.java b/platform/util/src/com/intellij/util/containers/FluentIterable.java new file mode 100644 index 000000000000..44edc2a7ba81 --- /dev/null +++ b/platform/util/src/com/intellij/util/containers/FluentIterable.java @@ -0,0 +1,283 @@ +/* + * Copyright 2000-2014 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.util.containers; + + +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Conditions; +import com.intellij.util.Function; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +/** + * A pruned version of com.google.common.collect.FluentIterable. + *

+ * {@code FluentIterable} provides a rich interface for manipulating {@code Iterable} instances in a + * chained fashion. A {@code FluentIterable} can be created from an {@code Iterable}, or from a set + * of elements. The following types of methods are provided on {@code FluentIterable}: + *

    + *
  • chained methods which return a new {@code FluentIterable} based in some way on the contents + * of the current one (for example {@link #transform}) + *
  • conversion methods which copy the {@code FluentIterable}'s contents into a new collection or + * array (for example {@link #toList}) + *
  • element extraction methods which facilitate the retrieval of certain elements (for example + * {@link #last}) + *
+ *

+ *

Here is an example that merges the lists returned by two separate database calls, transforms + * it by invoking {@code toString()} on each element, and returns the first 10 elements as an + * {@code ImmutableList}:

   {@code
+ *   FluentIterable
+ *       .from(database.getClientList())
+ *       .filter(activeInLastMonth())
+ *       .transform(Functions.toStringFunction())
+ *       .toList();}
+ *

+ *

Anything which can be done using {@code FluentIterable} could be done in a different fashion + * (often with {@link Iterables}), however the use of {@code FluentIterable} makes many sets of + * operations significantly more concise. + * + * @author Marcin Mikosik + */ +public abstract class FluentIterable implements Iterable { + // We store 'iterable' and use it instead of 'this' to allow Iterables to perform instanceof + // checks on the _original_ iterable when FluentIterable.from is used. + private final Iterable myIterable; + + /** + * Constructor for use by subclasses. + */ + protected FluentIterable() { + myIterable = this; + } + + FluentIterable(@NotNull Iterable iterable) { + myIterable = iterable; + } + + /** + * Returns a fluent iterable that wraps {@code iterable}, or {@code iterable} itself if it + * is already a {@code FluentIterable}. + */ + public static FluentIterable from(final Iterable iterable) { + return iterable instanceof FluentIterable ? (FluentIterable)iterable : + new FluentIterable(iterable) { + @Override + public Iterator iterator() { + return iterable.iterator(); + } + }; + } + + /** + * Returns a fluent iterable containing {@code elements} in the specified order. + */ + public static FluentIterable of(E[] elements) { + return from(ContainerUtil.newArrayList(elements)); + } + + /** + * Returns a string representation of this fluent iterable, with the format + * {@code [e1, e2, ..., en]}. + */ + @Override + public String toString() { + return ContainerUtil.toCollection(myIterable).toString(); + } + + /** + * Returns the number of elements in this fluent iterable. + */ + public final int size() { + int count = 0; + for (E ignored : myIterable) { + count++; + } + return count; + } + + /** + * Returns {@code true} if this fluent iterable contains any object for which + * {@code equals(element)} is true. + */ + public final boolean contains(@Nullable Object element) { + if (myIterable instanceof Collection) { + return ((Collection)myIterable).contains(element); + } + for (E e : myIterable) { + if (Comparing.equal(e, element)) return true; + } + return false; + } + + /** + * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, + * followed by those of {@code other}. The iterators are not polled until necessary. + *

+ *

The returned iterable's {@code Iterator} supports {@code remove()} when the corresponding + * {@code Iterator} supports it. + */ + public final FluentIterable append(Iterable other) { + return from(ContainerUtil.concat(myIterable, other)); + } + + /** + * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, + * followed by {@code elements}. + */ + public final FluentIterable append(E... elements) { + return append(Arrays.asList(elements)); + } + + /** + * Returns the elements from this fluent iterable that satisfy a condition. The + * resulting fluent iterable's iterator does not support {@code remove()}. + */ + public final FluentIterable filter(final Condition condition) { + return from(new Iterable() { + @Override + public Iterator iterator() { + return FilteringIterator.create(FluentIterable.this.iterator(), condition); + } + }); + } + + /** + * Returns the elements from this fluent iterable that are instances of class {@code type}. + * @param type the type of elements desired + */ + public final FluentIterable filter(Class type) { + //noinspection unchecked + return (FluentIterable)filter(Conditions.instanceOf(type)); + } + + /** + * Returns a fluent iterable that applies {@code function} to each element of this + * fluent iterable. + *

+ *

The returned fluent iterable's iterator supports {@code remove()} if this iterable's + * iterator does. After a successful {@code remove()} call, this fluent iterable no longer + * contains the corresponding element. + */ + @NotNull + public final FluentIterable transform(@NotNull final Function function) { + return from(new Iterable() { + @Override + public Iterator iterator() { + final Iterator iterator = FluentIterable.this.iterator(); + return new Iterator() { + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public T next() { + return function.fun(iterator.next()); + } + + @Override + public void remove() { + iterator.remove(); + } + }; + } + }); + } + + /** + * Returns an {@link Optional} containing the first element in this fluent iterable. + * If the iterable is empty, {@code Optional.absent()} is returned. + */ + @Nullable + public final E first() { + Iterator iterator = myIterable.iterator(); + return iterator.hasNext() ? iterator.next() : null; + } + + /** + * Returns an {@link Optional} containing the last element in this fluent iterable. + * If the iterable is empty, {@code Optional.absent()} is returned. + */ + @Nullable + public final E last() { + if (myIterable instanceof List) { + return ContainerUtil.getLastItem((List)myIterable); + } + Iterator iterator = myIterable.iterator(); + E prev = null, cur = null; + while (iterator.hasNext()) { + prev = cur; + cur = iterator.next(); + } + return prev; + } + + /** + * Determines whether this fluent iterable is empty. + */ + public final boolean isEmpty() { + return !myIterable.iterator().hasNext(); + } + + /** + * Returns an {@code ImmutableList} containing all of the elements from this fluent iterable in + * proper sequence. + */ + public final List toList() { + return Collections.unmodifiableList(ContainerUtil.newArrayList(myIterable)); + } + + /** + * Returns an {@code ImmutableSet} containing all of the elements from this fluent iterable with + * duplicates removed. + */ + public final Set toSet() { + return Collections.unmodifiableSet(ContainerUtil.newHashSet(myIterable)); + } + + /** + * Returns an immutable map for which the elements of this {@code FluentIterable} are the keys in + * the same order, mapped to values by the given function. If this iterable contains duplicate + * elements, the returned map will contain each distinct element once in the order it first + * appears. + */ + public final Map toMap(Convertor valueFunction) { + return ContainerUtil.newMapFromKeys(iterator(), valueFunction); + } + + /** + * Copies all the elements from this fluent iterable to {@code collection}. This is equivalent to + * calling {@code Iterables.addAll(collection, this)}. + * + * @param collection the collection to copy elements to + * @return {@code collection}, for convenience + */ + public final > C copyInto(@NotNull C collection) { + if (myIterable instanceof Collection) { + collection.addAll((Collection)myIterable); + } + else { + for (E item : myIterable) { + collection.add(item); + } + } + return collection; + } +} diff --git a/platform/util/src/com/intellij/util/containers/TreeTraverser.java b/platform/util/src/com/intellij/util/containers/TreeTraverser.java new file mode 100644 index 000000000000..6b2912137ea0 --- /dev/null +++ b/platform/util/src/com/intellij/util/containers/TreeTraverser.java @@ -0,0 +1,215 @@ +/* + * Copyright 2000-2014 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.util.containers; + +import com.intellij.util.ObjectUtils; +import com.intellij.util.UnmodifiableIterator; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Iterator; + +/** + * A pruned version of com.google.common.collect.TreeTraverser. + * + * Views elements of a type {@code T} as nodes in a tree, and provides methods to traverse the trees + * induced by this traverser. + * + *

For example, the tree + * + *

          {@code
+ *          h
+ *        / | \
+ *       /  e  \
+ *      d       g
+ *     /|\      |
+ *    / | \     f
+ *   a  b  c       }
+ * + *

can be iterated over in preorder (hdabcegf), postorder (abcdefgh), or breadth-first order + * (hdegabcf). + * + *

Null nodes are strictly forbidden. + * + * @author Louis Wasserman + */ +public abstract class TreeTraverser { + /** + * Returns the children of the specified node. Must not contain null. + */ + public abstract Iterable children(T root); + + /** + * Returns an unmodifiable iterable over the nodes in a tree structure, using pre-order + * traversal. That is, each node's subtrees are traversed after the node itself is returned. + * + *

No guarantees are made about the behavior of the traversal when nodes change while + * iteration is in progress or when the iterators generated by {@link #children} are advanced. + */ + public final FluentIterable preOrderTraversal(@NotNull final T root) { + return new FluentIterable() { + @Override + public Iterator iterator() { + return preOrderIterator(root); + } + }; + } + + Iterator preOrderIterator(@NotNull T root) { + return new PreOrderIterator(root); + } + + private final class PreOrderIterator extends UnmodifiableIterator { + private final Deque> stack; + + PreOrderIterator(@NotNull T root) { + super(null); + this.stack = new ArrayDeque>(); + stack.addLast(new SingletonIterator(root)); + } + + @Override + public boolean hasNext() { + return !stack.isEmpty(); + } + + @Override + public T next() { + Iterator itr = stack.getLast(); // throws NSEE if empty + T result = ObjectUtils.assertNotNull(itr.next()); + if (!itr.hasNext()) { + stack.removeLast(); + } + Iterator childItr = children(result).iterator(); + if (childItr.hasNext()) { + stack.addLast(childItr); + } + return result; + } + } + + /** + * Returns an unmodifiable iterable over the nodes in a tree structure, using post-order + * traversal. That is, each node's subtrees are traversed before the node itself is returned. + * + *

No guarantees are made about the behavior of the traversal when nodes change while + * iteration is in progress or when the iterators generated by {@link #children} are advanced. + */ + public final FluentIterable postOrderTraversal(@NotNull final T root) { + return new FluentIterable() { + @Override + public Iterator iterator() { + return postOrderIterator(root); + } + }; + } + + Iterator postOrderIterator(@NotNull T root) { + return new PostOrderIterator(root); + } + + private static final class PostOrderNode { + final T root; + final Iterator childIterator; + + PostOrderNode(@NotNull T root, @NotNull Iterator childIterator) { + this.root = root; + this.childIterator = childIterator; + } + } + + private final class PostOrderIterator extends UnmodifiableIterator { + private final ArrayDeque> stack; + + PostOrderIterator(T root) { + super(null); + this.stack = new ArrayDeque>(); + stack.addLast(expand(root)); + } + + @Override + public boolean hasNext() { + return !stack.isEmpty(); + } + + @Override + public T next() { + return computeNext(); + } + + private T computeNext() { + while (!stack.isEmpty()) { + PostOrderNode top = stack.getLast(); + if (top.childIterator.hasNext()) { + T child = top.childIterator.next(); + stack.addLast(expand(child)); + } else { + stack.removeLast(); + return top.root; + } + } + return null; + } + + private PostOrderNode expand(T t) { + return new PostOrderNode(t, children(t).iterator()); + } + } + + /** + * Returns an unmodifiable iterable over the nodes in a tree structure, using breadth-first + * traversal. That is, all the nodes of depth 0 are returned, then depth 1, then 2, and so on. + * + *

No guarantees are made about the behavior of the traversal when nodes change while + * iteration is in progress or when the iterators generated by {@link #children} are advanced. + */ + public final FluentIterable breadthFirstTraversal(@NotNull final T root) { + return new FluentIterable() { + @Override + public Iterator iterator() { + return new BreadthFirstIterator(root); + } + }; + } + + private final class BreadthFirstIterator extends UnmodifiableIterator { + private final Deque queue; + + BreadthFirstIterator(@NotNull T root) { + super(null); + this.queue = new ArrayDeque(); + queue.add(root); + } + + @Override + public boolean hasNext() { + return !queue.isEmpty(); + } + + //@Override + public T peek() { + return queue.element(); + } + + @Override + public T next() { + T result = queue.remove(); + ContainerUtil.addAll(queue, children(result)); + return result; + } + } +} diff --git a/platform/util/src/com/intellij/util/ui/JBSwingUtilities.java b/platform/util/src/com/intellij/util/ui/JBSwingUtilities.java index d48aa5fc4ad2..bc9fd3efae95 100644 --- a/platform/util/src/com/intellij/util/ui/JBSwingUtilities.java +++ b/platform/util/src/com/intellij/util/ui/JBSwingUtilities.java @@ -15,13 +15,25 @@ */ package com.intellij.util.ui; +import com.intellij.openapi.util.Key; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.TreeTraverser; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; +import java.util.Arrays; +import java.util.Collections; /** * @author gregsh */ public class JBSwingUtilities { + + public static final Key> NOT_IN_HIERARCHY_COMPONENTS = Key.create("NOT_IN_HIERARCHY_COMPONENTS"); + /** * Replaces SwingUtilities#isLeftMouseButton() for consistency with other button-related methods * @@ -50,4 +62,32 @@ public class JBSwingUtilities { public static boolean isRightMouseButton(MouseEvent anEvent) { return (anEvent.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) > 0; } + + @NotNull + public static TreeTraverser uiTraverser() { + return new TreeTraverser() { + @Override + public Iterable children(Component c) { + Iterable result = ContainerUtil.emptyIterable(); + if (c instanceof JMenu) { + result = Arrays.asList(((JMenu)c).getMenuComponents()); + } + else if (c instanceof Container) { + result = Arrays.asList(((Container)c).getComponents()); + } + if (c instanceof JComponent) { + JComponent jc = (JComponent)c; + Iterable orphans = UIUtil.getClientProperty(jc, NOT_IN_HIERARCHY_COMPONENTS); + if (orphans != null) { + result = ContainerUtil.concat(result, orphans); + } + JPopupMenu jpm = jc.getComponentPopupMenu(); + if (jpm != null && jpm.isVisible() && jpm.getInvoker() == jc) { + result = ContainerUtil.concat(result, Collections.singletonList(jpm)); + } + } + return result; + } + }; + } } diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index 1363520875d8..9b3472f2d3ae 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -345,6 +345,10 @@ public class UIUtil { return (T)component.getClientProperty(key); } + public static void putClientProperty(@NotNull JComponent component, @NotNull Key key, T value) { + component.putClientProperty(key, value); + } + public static String getHtmlBody(String text) { int htmlIndex = 6 + text.indexOf(""); if (htmlIndex < 6) { From d137ceeb596764e6749226ae8f70825b130fa144 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Wed, 29 Oct 2014 20:05:46 +0300 Subject: [PATCH 12/29] fixed pycharm edu installer artwork --- python/edu/build/resources/logo.bmp | Bin 154544 -> 154542 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/python/edu/build/resources/logo.bmp b/python/edu/build/resources/logo.bmp index 9ff6698b8e36f9b2aa74d91d272cfbce10c55069..d209849c19afa15984fdc140536373a455fdfa31 100644 GIT binary patch literal 154542 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 literal 154544 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

0|QVfSpXY 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 From fa51c9c53ab50c0c7992134d16a482557a739855 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 29 Oct 2014 15:02:51 +0100 Subject: [PATCH 13/29] guess expected types: limit processed members (IDEA-132072) --- .../daemon/impl/quickfix/CreateFromUsageUtils.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java index c5763cc2691e..1e03e711a72c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java @@ -79,6 +79,7 @@ public class CreateFromUsageUtils { private static final Logger LOG = Logger.getInstance( "#com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils"); private static final int MAX_GUESSED_MEMBERS_COUNT = 10; + private static final int MAX_RAW_GUESSED_MEMBERS_COUNT = 2 * MAX_GUESSED_MEMBERS_COUNT; public static boolean isValidReference(PsiReference reference, boolean unresolvedOnly) { if (!(reference instanceof PsiJavaReference)) return false; @@ -671,12 +672,12 @@ public class CreateFromUsageUtils { final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(expression.getProject()); PsiElementFactory factory = facade.getElementFactory(); for (String fieldName : expectedFieldNames) { - PsiField[] fields = cache.getFieldsByName(fieldName, resolveScope); + PsiField[] fields = cache.getFieldsByNameIfNotMoreThan(fieldName, resolveScope, MAX_RAW_GUESSED_MEMBERS_COUNT); addMemberInfo(fields, expression, typesList, factory); } for (String methodName : expectedMethodNames) { - PsiMethod[] methods = cache.getMethodsByName(methodName, resolveScope); + PsiMethod[] methods = cache.getMethodsByNameIfNotMoreThan(methodName, resolveScope, MAX_RAW_GUESSED_MEMBERS_COUNT); addMemberInfo(methods, expression, typesList, factory); } } @@ -723,12 +724,12 @@ public class CreateFromUsageUtils { final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(expression.getProject()); PsiElementFactory factory = facade.getElementFactory(); for (String fieldName : expectedFieldNames) { - PsiField[] fields = cache.getFieldsByName(fieldName, resolveScope); + PsiField[] fields = cache.getFieldsByNameIfNotMoreThan(fieldName, resolveScope, MAX_RAW_GUESSED_MEMBERS_COUNT); addMemberInfo(fields, expression, typesList, factory); } for (String methodName : expectedMethodNames) { - PsiMethod[] methods = cache.getMethodsByName(methodName, resolveScope); + PsiMethod[] methods = cache.getMethodsByNameIfNotMoreThan(methodName, resolveScope, MAX_RAW_GUESSED_MEMBERS_COUNT); addMemberInfo(methods, expression, typesList, factory); } } From ddbaef946208b68854e4cf8dc56b169872cb5c0a Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 29 Oct 2014 16:04:22 +0100 Subject: [PATCH 14/29] fix message for final locals used inside local/anonym classes in java 8 (IDEA-131949) --- .../daemon/impl/analysis/HighlightControlFlowUtil.java | 5 +++-- java/java-psi-impl/src/messages/JavaErrorMessages.properties | 1 + .../lambda/highlighting/EffectiveFinal.java | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java index d1c5d9bec832..697bf0e0e8a6 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java @@ -651,10 +651,11 @@ public class HighlightControlFlowUtil { return null; } } - if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && isEffectivelyFinal(variable, innerClass, context)) { + final boolean isToBeEffectivelyFinal = languageLevel.isAtLeast(LanguageLevel.JDK_1_8); + if (isToBeEffectivelyFinal && isEffectivelyFinal(variable, innerClass, context)) { return null; } - final String description = JavaErrorMessages.message("variable.must.be.final", context.getText()); + final String description = JavaErrorMessages.message(isToBeEffectivelyFinal ? "variable.must.be.final.or.effectively.final" : "variable.must.be.final", context.getText()); final HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(context).descriptionAndTooltip(description).create(); diff --git a/java/java-psi-impl/src/messages/JavaErrorMessages.properties b/java/java-psi-impl/src/messages/JavaErrorMessages.properties index e4e2303a2be4..f8712565c0ec 100644 --- a/java/java-psi-impl/src/messages/JavaErrorMessages.properties +++ b/java/java-psi-impl/src/messages/JavaErrorMessages.properties @@ -134,6 +134,7 @@ variable.already.assigned=Variable ''{0}'' might already have been assigned to variable.assigned.in.loop=Variable ''{0}'' might be assigned in loop assignment.to.final.variable=Cannot assign a value to final variable ''{0}'' variable.must.be.final=Variable ''{0}'' is accessed from within inner class, needs to be declared final +variable.must.be.final.or.effectively.final=Variable ''{0}'' is accessed from within inner class, needs to be final or effectively final initializer.must.be.able.to.complete.normally=Initializer must be able to complete normally weaker.privileges={0}; attempting to assign weaker access privileges (''{1}''); was ''{2}'' incompatible.return.type=attempting to use incompatible return type diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/EffectiveFinal.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/EffectiveFinal.java index 001b1f39c494..deae737d9853 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/EffectiveFinal.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/EffectiveFinal.java @@ -108,7 +108,7 @@ class ParameterIsEffectivelyFinal { new Runnable() { @Override public void run() { - System.out.println(o); + System.out.println(o); } }.run(); return 0; From c8eaa640bfeeff1668103d9b196a1f398b8accab Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 29 Oct 2014 16:06:26 +0100 Subject: [PATCH 15/29] highlight wrong position in error tooltip (IDEA-131775) --- .../codeInsight/daemon/impl/analysis/HighlightMethodUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index 83af5606d8c8..d00fd30209f1 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -915,7 +915,8 @@ public class HighlightMethodUtil { PsiType paramType = i < parameters.length && parameters[i] != null ? substitutor.substitute(parameters[i].getType()) : null; - return paramType != null && TypeConversionUtil.areTypesAssignmentCompatible(paramType, expression); + PsiType expressionType = expression.getType(); + return paramType != null && expressionType != null && TypeConversionUtil.isAssignable(paramType, expressionType); } From acc4cb4cb2b4a4f80c4e3ac68def007ea769bd8d Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 29 Oct 2014 16:43:50 +0100 Subject: [PATCH 16/29] IDEA-131811 Wrong grammar in a message box text --- .../platform-resources-en/src/messages/IdeBundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index ee5f49e1fb53..96ead9730061 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -514,7 +514,7 @@ message.idea.restart.required=Restart {0} to activate changes in plugins? title.plugins=Plugins title.plugins.changed=Plugins Changed plugin.status.not.specified=(not specified) -error.list.of.plugins.was.not.loaded=List of plugins was not loaded: {0} +error.list.of.plugins.was.not.loaded=Unable to update the list of plugins due to the following error: {0} action.download.and.install.plugin=Download and Install action.update.plugin=Update Plugin error.plugin.download.failed=Plugin download failed From 3e3824fc89c513ffe256d1d22c24d44ef5edbdf0 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 29 Oct 2014 18:01:23 +0100 Subject: [PATCH 17/29] add field to enum: ensure correct position after comment (IDEA-131820) --- .../psi/impl/source/tree/java/ClassElement.java | 4 ++++ .../createFieldFromParameter/afterEnumComments.java | 12 ++++++++++++ .../createFieldFromParameter/beforeEnumComments.java | 9 +++++++++ 3 files changed, 25 insertions(+) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/afterEnumComments.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/beforeEnumComments.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java index 14d72a92da1c..35700b5dab35 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java @@ -26,6 +26,7 @@ import com.intellij.psi.impl.source.tree.*; import com.intellij.psi.tree.ChildRoleBase; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.CharTable; import org.jetbrains.annotations.NotNull; @@ -111,6 +112,9 @@ public class ClassElement extends CompositeElement implements Constants { for (ASTNode run = anchor; run != null; run = run.getTreeNext()) { if (run == semicolonPlace) { anchor = before.booleanValue() ? semicolonPlace.getTreeNext() : semicolonPlace; + if (anchor != null && PsiImplUtil.isWhitespaceOrComment(anchor)) { + anchor = PsiTreeUtil.skipSiblingsForward(anchor.getPsi(), PsiWhiteSpace.class, PsiComment.class).getNode(); + } break; } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/afterEnumComments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/afterEnumComments.java new file mode 100644 index 000000000000..218e3ffcc412 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/afterEnumComments.java @@ -0,0 +1,12 @@ +// "Create Field for Parameter 'p1'" "true" + +enum Test{ + A;//comment + + private int myP1; + + void f(int p1){ + myP1 = p1; + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/beforeEnumComments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/beforeEnumComments.java new file mode 100644 index 000000000000..1de861c06b9b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/beforeEnumComments.java @@ -0,0 +1,9 @@ +// "Create Field for Parameter 'p1'" "true" + +enum Test{ + A;//comment + + void f(int p1){ + } +} + From 5d5fdcbd90a610a27f0e2f759d35330047d68a6a Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Wed, 29 Oct 2014 17:04:15 +0300 Subject: [PATCH 18/29] Fix typo in message shown on Bugzilla connection failure --- .../tasks-core/src/com/intellij/tasks/TaskBundle.properties | 2 +- .../src/com/intellij/tasks/bugzilla/BugzillaRepository.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/TaskBundle.properties b/plugins/tasks/tasks-core/src/com/intellij/tasks/TaskBundle.properties index 0154b2989ff0..ce617cbf01ca 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/TaskBundle.properties +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/TaskBundle.properties @@ -20,6 +20,6 @@ jira.failure.captcha=Login failed. Enter captcha in web-interface. youtrack.default.query=for: me sort by: updated #Unresolved ## Bugzilla -bugzilla.failure.malformed.response=Cannot decode server response. Check that XMLRPC plugin is enabled. +bugzilla.failure.malformed.response=Cannot decode server response. Check that XML-RPC plugin is enabled. bugzilla.failure.no.version=Cannot find Bugzilla version. Check that URL ends with "xmlrpc.cgi". diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepository.java index af3df55b5397..86a511b166c2 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepository.java @@ -346,7 +346,8 @@ public class BugzillaRepository extends BaseRepositoryImpl { return (T)new XmlRpcClient(getUrl()).execute(new XmlRpcRequest(myMethodName, parameters), myTransport); } catch (XmlRpcClientException e) { - if (e.getMessage().contains("Error decoding XML-RPC response")) { + // Unfortunately there is no standard error code to identify this kind of error in portable way + if (e.getMessage().equals("Error decoding XML-RPC response")) { throw new RequestFailedException(TaskBundle.message("bugzilla.failure.malformed.response"), e); } throw e; From 34b675102aa0e6a8727877adc4fa460342bf398e Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Wed, 29 Oct 2014 20:05:34 +0300 Subject: [PATCH 19/29] Fix searching for library directory in mock SDK --- .../jetbrains/python/psi/search/PyProjectScopeBuilder.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python/src/com/jetbrains/python/psi/search/PyProjectScopeBuilder.java b/python/src/com/jetbrains/python/psi/search/PyProjectScopeBuilder.java index a433a9a73315..e3042e0e527a 100644 --- a/python/src/com/jetbrains/python/psi/search/PyProjectScopeBuilder.java +++ b/python/src/com/jetbrains/python/psi/search/PyProjectScopeBuilder.java @@ -16,6 +16,7 @@ package com.jetbrains.python.psi.search; import com.intellij.injected.editor.VirtualFileWindow; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.Project; @@ -186,6 +187,10 @@ public class PyProjectScopeBuilder extends ProjectScopeBuilderImpl { file.findChild("xml") != null && file.findChild("email") != null) { return file; } + // Mock SDK does not have aforementioned modules + if (ApplicationManager.getApplication().isUnitTestMode() && file.getName().equals("Lib")) { + return file; + } } return null; } From 9795eb796bc602aa34535ac12ada697305cfd8a3 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Wed, 29 Oct 2014 20:06:02 +0300 Subject: [PATCH 20/29] PY-13537 Allow to suppress inspection for descendants of standard classes (except builtins) --- .../inspections/PyPep8NamingInspection.java | 71 +++++++++++-------- .../python/testing/pytest/PyTestUtil.java | 11 +-- .../descendantOfStandardClass.py | 7 ++ .../PyPep8NamingInspectionTest.java | 5 ++ 4 files changed, 61 insertions(+), 33 deletions(-) create mode 100644 python/testData/inspections/PyPep8NamingInspection/descendantOfStandardClass.py diff --git a/python/src/com/jetbrains/python/inspections/PyPep8NamingInspection.java b/python/src/com/jetbrains/python/inspections/PyPep8NamingInspection.java index 9cdd4b036aea..17780edb50b6 100644 --- a/python/src/com/jetbrains/python/inspections/PyPep8NamingInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyPep8NamingInspection.java @@ -20,47 +20,50 @@ import com.intellij.codeInspection.ProblemsHolder; import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.lang.ASTNode; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.QualifiedName; -import com.intellij.util.containers.hash.HashMap; +import com.intellij.util.containers.ContainerUtil; import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache; import com.jetbrains.python.codeInsight.dataflow.scope.Scope; import com.jetbrains.python.inspections.quickfix.PyRenameElementQuickFix; import com.jetbrains.python.psi.*; +import com.jetbrains.python.psi.impl.PyBuiltinCache; import com.jetbrains.python.psi.search.PySuperMethodsSearch; +import com.jetbrains.python.sdk.PythonSdkType; import com.jetbrains.python.testing.pytest.PyTestUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.Map; import java.util.regex.Pattern; /** - * * User : ktisha */ public class PyPep8NamingInspection extends PyInspection { + private static final Pattern LOWERCASE_REGEX = Pattern.compile("[_\\p{javaLowerCase}][_\\p{javaLowerCase}0-9]*"); + private static final Pattern UPPERCASE_REGEX = Pattern.compile("[_\\p{javaUpperCase}][_\\p{javaUpperCase}0-9]*"); + private static final Pattern MIXEDCASE_REGEX = Pattern.compile("_?[\\p{javaUpperCase}][\\p{javaLowerCase}\\p{javaUpperCase}0-9]*"); + public boolean ignoreOverriddenFunctions = true; - public boolean ignoreTestFunctions = false; - private static Pattern LOWERCASE_REGEX = Pattern.compile("[_\\p{javaLowerCase}][_\\p{javaLowerCase}0-9]*"); - private static Pattern UPPERCASE_REGEX = Pattern.compile("[_\\p{javaUpperCase}][_\\p{javaUpperCase}0-9]*"); - private static Pattern MIXEDCASE_REGEX = Pattern.compile("_?[\\p{javaUpperCase}][\\p{javaLowerCase}\\p{javaUpperCase}0-9]*"); + public boolean ignoreDescendantsOfStandardClasses = false; @NotNull @Override public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly, @NotNull LocalInspectionToolSession session) { - if (ApplicationManager.getApplication().isUnitTestMode()) - ignoreTestFunctions = true; + if (ApplicationManager.getApplication().isUnitTestMode()) { + ignoreDescendantsOfStandardClasses = true; + } return new Visitor(holder, session); } public class Visitor extends PyInspectionVisitor { - private final Map myHasSupers = new HashMap(); - public Visitor(@NotNull final ProblemsHolder holder, LocalInspectionToolSession session) { super(holder, session); } @@ -95,22 +98,42 @@ public class PyPep8NamingInspection extends PyInspection { } @Override - public void visitPyFunction(PyFunction node) { - final PyClass containingClass = node.getContainingClass(); - if (hasSupers(node) && ignoreOverriddenFunctions) return; - if(containingClass != null && PyTestUtil.isPyTestClass(containingClass) && ignoreTestFunctions) return; - final String name = node.getName(); + public void visitPyFunction(PyFunction function) { + final PyClass containingClass = function.getContainingClass(); + if (ignoreOverriddenFunctions && isOverriddenMethod(function)) return; + final String name = function.getName(); if (name == null) return; - if (containingClass != null && name.startsWith("__") && name.endsWith("__")) { + if (containingClass != null && PyUtil.isSpecialName(name)) { + return; + } + if (containingClass != null && ignoreDescendantsOfStandardClasses && isStandardClassDescendant(containingClass)) { return; } if (!LOWERCASE_REGEX.matcher(name).matches()) { - final ASTNode nameNode = node.getNameNode(); + final ASTNode nameNode = function.getNameNode(); if (nameNode != null) registerProblem(nameNode.getPsi(), "Function name should be lowercase", new PyRenameElementQuickFix()); } } + private boolean isOverriddenMethod(@NotNull PyFunction function) { + return PySuperMethodsSearch.search(function).findFirst() != null; + } + + private boolean isStandardClassDescendant(@NotNull final PyClass cls) { + if (PyTestUtil.isPyTestClass(cls)) { + return true; + } + return ContainerUtil.exists(cls.getAncestorClasses(myTypeEvalContext), new Condition() { + @Override + public boolean value(PyClass ancestor) { + final PsiFile ancestorsModule = ancestor.getContainingFile(); + final Sdk sdk = PyBuiltinCache.findSdkForFile(ancestorsModule); + return PythonSdkType.isStdLib(ancestorsModule.getVirtualFile(), sdk) && !PyBuiltinCache.getInstance(cls).isBuiltin(ancestor); + } + }); + } + @Override public void visitPyClass(PyClass node) { final String name = node.getName(); @@ -147,16 +170,6 @@ public class PyPep8NamingInspection extends PyInspection { registerProblem(node.getAsNameElement(), "CamelCase variable imported as constant", new PyRenameElementQuickFix()); } } - - private boolean hasSupers(@NotNull PyFunction function) { - final Boolean cached = myHasSupers.get(function); - if (cached != null) { - return cached; - } - final boolean result = PySuperMethodsSearch.search(function).findFirst() != null; - myHasSupers.put(function, result); - return result; - } } @Nullable @@ -164,7 +177,7 @@ public class PyPep8NamingInspection extends PyInspection { public JComponent createOptionsPanel() { MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this); panel.addCheckbox("Ignore overridden functions", "ignoreOverriddenFunctions"); - panel.addCheckbox("Ignore test functions", "ignoreTestFunctions"); + panel.addCheckbox("Ignore descendants of standard classes", "ignoreDescendantsOfStandardClasses"); return panel; } } diff --git a/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java b/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java index c2324282546e..4bc36647257c 100644 --- a/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java +++ b/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java @@ -15,23 +15,26 @@ */ package com.jetbrains.python.testing.pytest; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileSystemItem; -import com.jetbrains.python.psi.*; +import com.jetbrains.python.psi.PyClass; +import com.jetbrains.python.psi.PyFile; +import com.jetbrains.python.psi.PyFunction; +import com.jetbrains.python.psi.PyStatement; import com.jetbrains.python.psi.types.PyClassLikeType; import com.jetbrains.python.psi.types.TypeEvalContext; -import java.util.HashSet; import java.util.List; +import java.util.Set; /** * User: catherine */ public class PyTestUtil { - private static final HashSet PYTHON_TEST_QUALIFIED_CLASSES = Sets.newHashSet("unittest.TestCase", "unittest.case.TestCase"); + private static final Set PYTHON_TEST_QUALIFIED_CLASSES = ImmutableSet.of("unittest.TestCase", "unittest.case.TestCase"); public static List getPyTestCasesFromFile(PsiFileSystemItem file) { List result = Lists.newArrayList(); diff --git a/python/testData/inspections/PyPep8NamingInspection/descendantOfStandardClass.py b/python/testData/inspections/PyPep8NamingInspection/descendantOfStandardClass.py new file mode 100644 index 000000000000..a3604d351b7f --- /dev/null +++ b/python/testData/inspections/PyPep8NamingInspection/descendantOfStandardClass.py @@ -0,0 +1,7 @@ +import collections + +class MyDict(collections.OrderedDict): + def getLast(self): + if self: + return list(self.values)[-1] + raise ValueError() \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/inspections/PyPep8NamingInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyPep8NamingInspectionTest.java index e522af7aa9bb..8e2a6bfa2010 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyPep8NamingInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyPep8NamingInspectionTest.java @@ -65,6 +65,11 @@ public class PyPep8NamingInspectionTest extends PyTestCase { doTest(); } + // PY-13537 + public void testDescendantOfStandardClass() { + doTest(); + } + public void testTest() { doTest(); } From a8804a78295ff9ec22d42a91585cce66392eef51 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Wed, 29 Oct 2014 20:15:46 +0300 Subject: [PATCH 21/29] FluentIterator: cleanup & fix last() --- .../intellij/util/containers/FluentIterable.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/platform/util/src/com/intellij/util/containers/FluentIterable.java b/platform/util/src/com/intellij/util/containers/FluentIterable.java index 44edc2a7ba81..d6e9d27d9be6 100644 --- a/platform/util/src/com/intellij/util/containers/FluentIterable.java +++ b/platform/util/src/com/intellij/util/containers/FluentIterable.java @@ -42,7 +42,7 @@ import java.util.*; *

*

Here is an example that merges the lists returned by two separate database calls, transforms * it by invoking {@code toString()} on each element, and returns the first 10 elements as an - * {@code ImmutableList}:

   {@code
+ * {@code List}: 
   {@code
  *   FluentIterable
  *       .from(database.getClientList())
  *       .filter(activeInLastMonth())
@@ -221,12 +221,11 @@ public abstract class FluentIterable implements Iterable {
       return ContainerUtil.getLastItem((List)myIterable);
     }
     Iterator iterator = myIterable.iterator();
-    E prev = null, cur = null;
+    E cur = null;
     while (iterator.hasNext()) {
-      prev = cur;
       cur = iterator.next();
     }
-    return prev;
+    return cur;
   }
 
   /**
@@ -237,7 +236,7 @@ public abstract class FluentIterable implements Iterable {
   }
 
   /**
-   * Returns an {@code ImmutableList} containing all of the elements from this fluent iterable in
+   * Returns an {@code List} containing all of the elements from this fluent iterable in
    * proper sequence.
    */
   public final List toList() {
@@ -245,7 +244,7 @@ public abstract class FluentIterable implements Iterable {
   }
 
   /**
-   * Returns an {@code ImmutableSet} containing all of the elements from this fluent iterable with
+   * Returns an {@code Set} containing all of the elements from this fluent iterable with
    * duplicates removed.
    */
   public final Set toSet() {
@@ -253,13 +252,13 @@ public abstract class FluentIterable implements Iterable {
   }
 
   /**
-   * Returns an immutable map for which the elements of this {@code FluentIterable} are the keys in
+   * Returns an {@code Map} for which the elements of this {@code FluentIterable} are the keys in
    * the same order, mapped to values by the given function. If this iterable contains duplicate
    * elements, the returned map will contain each distinct element once in the order it first
    * appears.
    */
   public final  Map toMap(Convertor valueFunction) {
-    return ContainerUtil.newMapFromKeys(iterator(), valueFunction);
+    return Collections.unmodifiableMap(ContainerUtil.newMapFromKeys(iterator(), valueFunction));
   }
 
   /**

From e455c6c065281ebd02e4cc0ca56c712a08401cf5 Mon Sep 17 00:00:00 2001
From: Eugene Zhuravlev 
Date: Wed, 29 Oct 2014 20:37:02 +0100
Subject: [PATCH 22/29] refreshing generated roots in one refresh session to
 avoid multiple 'roots changed' events (IDEA-131634)

---
 .../intellij/compiler/impl/CompilerUtil.java  |  3 +-
 .../compiler/server/BuildManager.java         | 50 ++++++++++++-------
 2 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java
index 67bdb5209f39..1881d088c61f 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java
@@ -37,7 +37,6 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
-import java.util.Set;
 
 public class CompilerUtil {
   private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompilerUtil");
@@ -74,7 +73,7 @@ public class CompilerUtil {
     }
   }
 
-  public static void refreshOutputDirectories(Set outputs, boolean async) {
+  public static void refreshOutputDirectories(Collection outputs, boolean async) {
     LocalFileSystem fileSystem = LocalFileSystem.getInstance();
     List toRefresh = new ArrayList();
 
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
index efaf9e2b4346..d516d5b2f74e 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
@@ -17,6 +17,7 @@ package com.intellij.compiler.server;
 
 import com.intellij.ProjectTopics;
 import com.intellij.compiler.CompilerWorkspaceConfiguration;
+import com.intellij.compiler.impl.CompilerUtil;
 import com.intellij.compiler.impl.javaCompiler.javac.JavacConfiguration;
 import com.intellij.compiler.server.impl.BuildProcessClasspathManager;
 import com.intellij.execution.ExecutionAdapter;
@@ -1266,26 +1267,39 @@ public class BuildManager implements ApplicationComponent{
             roots = ArrayUtil.toStringArray(myRootsToRefresh);
             myRootsToRefresh.clear();
           }
-          ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
-            @Override
-            public void run() {
-              if (project.isDisposed()) {
-                return;
-              }
-              final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
-              final LocalFileSystem lfs = LocalFileSystem.getInstance();
-              final Set filesToRefresh = new HashSet();
-              for (String root : roots) {
-                final VirtualFile rootFile = lfs.refreshAndFindFileByPath(root);
-                if (rootFile != null && fileIndex.isInSourceContent(rootFile)) {
-                  filesToRefresh.add(rootFile);
+          if (roots.length != 0) {
+            ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+              @Override
+              public void run() {
+                if (project.isDisposed()) {
+                  return;
                 }
+                final List rootFiles = new ArrayList(roots.length);
+                for (String root : roots) {
+                  rootFiles.add(new File(root));
+                }
+                // this will ensure that we'll be able to obtain VirtualFile for existing roots
+                CompilerUtil.refreshOutputDirectories(rootFiles, false);
+
+                final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+                final LocalFileSystem lfs = LocalFileSystem.getInstance();
+                final Set filesToRefresh = new HashSet();
+                ApplicationManager.getApplication().runReadAction(new Runnable() {
+                  public void run() {
+                    for (File root : rootFiles) {
+                      final VirtualFile rootFile = lfs.findFileByIoFile(root);
+                      if (rootFile != null && fileIndex.isInSourceContent(rootFile)) {
+                        filesToRefresh.add(rootFile);
+                      }
+                    }
+                    if (!filesToRefresh.isEmpty()) {
+                      lfs.refreshFiles(filesToRefresh, true, true, null);
+                    }
+                  }
+                });
               }
-              if (!filesToRefresh.isEmpty()) {
-                lfs.refreshFiles(filesToRefresh, true, true, null);
-              }
-            }
-          });
+            });
+          }
         }
 
         @Override

From 0f93915c6cade084011e23a934c42f52b3e5fdf0 Mon Sep 17 00:00:00 2001
From: Anna Kozlova 
Date: Wed, 29 Oct 2014 20:03:00 +0100
Subject: [PATCH 23/29] bombed

---
 .../codeInsight/daemon/lambda/NewLambdaHighlightingTest.java | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java
index d7b123839b3a..5f606082970e 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java
@@ -75,12 +75,13 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
   public void testNestedCallsInsideLambdaReturnExpression() { doTest(); }
   public void testIDEA123731() { doTest(); }
   public void testIDEA123869() { doTest(); }
+  @Bombed(day = 30, month = Calendar.NOVEMBER)
   public void testIDEA123848() { doTest(); }
   public void testOnlyLambdaAtTypeParameterPlace() { doTest(); }
   public void testLiftedIntersectionType() { doTest(); }
   public void testInferenceFromReturnStatements() { doTest(); }
   public void testDownUpThroughLambdaReturnStatements() { doTest(); }
-  @Bombed(day = 30, month = Calendar.OCTOBER)
+  @Bombed(day = 30, month = Calendar.NOVEMBER)
   public void testIDEA124547() { doTest(); }
   public void testIDEA118362() { doTest(); }
   public void testIDEA126056() { doTest(); }
@@ -134,7 +135,7 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
     doTest();
   }
 
-  @Bombed(month = Calendar.OCTOBER, day = 30)
+  @Bombed(month = Calendar.NOVEMBER, day = 30)
   public void testCheckedExceptionsConstraintsSubstitutions() throws Exception {
     doTest();
   }

From e71fc0b1726f0ea8004634440f4ee829242faf49 Mon Sep 17 00:00:00 2001
From: "Maxim.Mossienko" 
Date: Wed, 29 Oct 2014 20:56:07 +0100
Subject: [PATCH 24/29] don't hold psi in local search scope in tests

---
 .../com/intellij/structuralsearch/impl/matcher/MatcherImpl.java | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java
index 7a166478d3c9..06a61b1da4fc 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java
@@ -441,6 +441,8 @@ public class MatcherImpl {
       MalformedPatternException exception = new MalformedPatternException();
       exception.initCause(e);
       throw exception;
+    } finally {
+      options.setScope(null);
     }
 
     return sink.getMatches();

From 37687b57eb8b9b3c8b9cb40de450e49583db3b5b Mon Sep 17 00:00:00 2001
From: Konstantin Bulenkov 
Date: Wed, 29 Oct 2014 12:30:43 +0100
Subject: [PATCH 25/29] add onDone handler to ActionLink

(cherry picked from commit 063425f6b1d660f9bf3ec5ada6cc42722e96208f)
---
 .../com/intellij/ui/components/labels/ActionLink.java | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/platform/platform-api/src/com/intellij/ui/components/labels/ActionLink.java b/platform/platform-api/src/com/intellij/ui/components/labels/ActionLink.java
index a4f278539dd4..4a790facf2ee 100644
--- a/platform/platform-api/src/com/intellij/ui/components/labels/ActionLink.java
+++ b/platform/platform-api/src/com/intellij/ui/components/labels/ActionLink.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -21,6 +21,7 @@ import com.intellij.util.ui.EmptyIcon;
 import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.awt.*;
@@ -41,7 +42,12 @@ public class ActionLink extends LinkLabel implements DataProvider {
   public ActionLink(String text, @NotNull AnAction action) {
     this(text, ICON, action);
   }
+
   public ActionLink(String text, Icon icon, @NotNull AnAction action) {
+    this(text, icon, action, null);
+  }
+
+  public ActionLink(String text, Icon icon, @NotNull AnAction action, @Nullable final Runnable onDone) {
     super(text, icon);
     setListener(new LinkListener() {
       @Override
@@ -56,6 +62,9 @@ public class ActionLink extends LinkLabel implements DataProvider {
         myAction.update(event);
         if (event.getPresentation().isEnabled() && event.getPresentation().isVisible()) {
           myAction.actionPerformed(event);
+          if (onDone != null) {
+            onDone.run();
+          }
         }
       }
     }, null);

From 4e8756970c6d944c9df1cdd59e8fc87ba8bdac6d Mon Sep 17 00:00:00 2001
From: Dennis Ushakov 
Date: Wed, 29 Oct 2014 19:33:15 +0300
Subject: [PATCH 26/29] highlight element on breadcrumb hover #WEB-427 fixed

---
 .../breadcrumbs/BreadcrumbsXmlWrapper.java    | 33 ++++++++++++++++---
 .../xml/breadcrumbs/BreadcrumbsComponent.java |  3 ++
 .../breadcrumbs/BreadcrumbsItemListener.java  |  4 +--
 .../XmlTagTreeHighlightingUtil.java           |  4 +--
 4 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java b/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java
index bbee880bfde1..0ae4b53b8694 100644
--- a/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java
+++ b/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java
@@ -16,6 +16,8 @@
 package com.intellij.xml.breadcrumbs;
 
 import com.intellij.application.options.editor.WebEditorOptions;
+import com.intellij.codeInsight.daemon.impl.tagTreeHighlighting.XmlTagTreeHighlightingUtil;
+import com.intellij.codeInsight.highlighting.HighlightManager;
 import com.intellij.ide.ui.UISettings;
 import com.intellij.ide.ui.UISettingsListener;
 import com.intellij.lang.Language;
@@ -25,10 +27,14 @@ import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.LogicalPosition;
 import com.intellij.openapi.editor.ScrollType;
+import com.intellij.openapi.editor.colors.EditorColors;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
 import com.intellij.openapi.editor.colors.EditorFontType;
 import com.intellij.openapi.editor.event.CaretAdapter;
 import com.intellij.openapi.editor.event.CaretEvent;
 import com.intellij.openapi.editor.event.CaretListener;
+import com.intellij.openapi.editor.markup.RangeHighlighter;
+import com.intellij.openapi.editor.markup.TextAttributes;
 import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.project.Project;
@@ -52,10 +58,7 @@ import javax.swing.*;
 import java.awt.*;
 import java.awt.event.ComponentAdapter;
 import java.awt.event.ComponentEvent;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.LinkedList;
-import java.util.PriorityQueue;
+import java.util.*;
 
 /**
  * @author spleaner
@@ -64,6 +67,7 @@ public class BreadcrumbsXmlWrapper implements BreadcrumbsItemListener myComponent;
   private final Project myProject;
   private Editor myEditor;
+  private Collection myHighlighed;
   private final VirtualFile myFile;
   private boolean myUserCaretChange;
   private final MergingUpdateQueue myQueue;
@@ -383,6 +387,27 @@ public class BreadcrumbsXmlWrapper implements BreadcrumbsItemListener(1);
+      HighlightManager.getInstance(myProject).addRangeHighlight(myEditor, range.getStartOffset(), range.getEndOffset(),
+                                                                attributes, true, true, myHighlighed);
+    }
+  }
+
   @Nullable
   public static BreadcrumbsXmlWrapper getBreadcrumbsComponent(@NotNull Editor editor) {
     return editor.getUserData(BREADCRUMBS_COMPONENT_KEY);
diff --git a/xml/openapi/src/com/intellij/xml/breadcrumbs/BreadcrumbsComponent.java b/xml/openapi/src/com/intellij/xml/breadcrumbs/BreadcrumbsComponent.java
index 9cb570842442..a70254639ba7 100644
--- a/xml/openapi/src/com/intellij/xml/breadcrumbs/BreadcrumbsComponent.java
+++ b/xml/openapi/src/com/intellij/xml/breadcrumbs/BreadcrumbsComponent.java
@@ -121,6 +121,9 @@ public class BreadcrumbsComponent extends JComponent
     }
 
     myHovered = crumb;
+    for (BreadcrumbsItemListener listener : myListeners) {
+      listener.itemHovered(myHovered != null ? myHovered.myItem : null);
+    }
     repaint();
   }
 
diff --git a/xml/openapi/src/com/intellij/xml/breadcrumbs/BreadcrumbsItemListener.java b/xml/openapi/src/com/intellij/xml/breadcrumbs/BreadcrumbsItemListener.java
index 0b74d342de56..e85b4d876113 100644
--- a/xml/openapi/src/com/intellij/xml/breadcrumbs/BreadcrumbsItemListener.java
+++ b/xml/openapi/src/com/intellij/xml/breadcrumbs/BreadcrumbsItemListener.java
@@ -16,12 +16,12 @@
 package com.intellij.xml.breadcrumbs;
 
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * @author spleaner
  */
 public interface BreadcrumbsItemListener {
-
   void itemSelected(@NotNull final T item, final int modifiers);
-
+  void itemHovered(@Nullable final T item);
 }
diff --git a/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/tagTreeHighlighting/XmlTagTreeHighlightingUtil.java b/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/tagTreeHighlighting/XmlTagTreeHighlightingUtil.java
index bddbcd7bc4ef..289ae5e58507 100644
--- a/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/tagTreeHighlighting/XmlTagTreeHighlightingUtil.java
+++ b/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/tagTreeHighlighting/XmlTagTreeHighlightingUtil.java
@@ -33,7 +33,7 @@ import java.util.Set;
 /**
  * @author Eugene.Kudelevsky
  */
-class XmlTagTreeHighlightingUtil {
+public class XmlTagTreeHighlightingUtil {
   private XmlTagTreeHighlightingUtil() {
   }
 
@@ -76,7 +76,7 @@ class XmlTagTreeHighlightingUtil {
     return false;
   }
 
-  static Color makeTransparent(@NotNull Color color, @NotNull Color backgroundColor, double transparency) {
+  public static Color makeTransparent(@NotNull Color color, @NotNull Color backgroundColor, double transparency) {
     int r = makeTransparent(transparency, color.getRed(), backgroundColor.getRed());
     int g = makeTransparent(transparency, color.getGreen(), backgroundColor.getGreen());
     int b = makeTransparent(transparency, color.getBlue(), backgroundColor.getBlue());

From 9a99320058a77533294ad5bc89c9c878688ef9f5 Mon Sep 17 00:00:00 2001
From: Konstantin Bulenkov 
Date: Wed, 29 Oct 2014 13:43:21 +0100
Subject: [PATCH 27/29] new flat welcome screen icon for idea

(cherry picked from commit e11e7850863ca367a6a46b8b2ae04564014a5438)
---
 platform/icons/src/Logo_welcomeScreen.png    | Bin 7918 -> 2475 bytes
 platform/icons/src/Logo_welcomeScreen@2x.png | Bin 18137 -> 5145 bytes
 2 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/platform/icons/src/Logo_welcomeScreen.png b/platform/icons/src/Logo_welcomeScreen.png
index 211668560d0f78024bc26b2c6394504736ce862f..9023c4285eba6c94f8b12cd20ecfea7f39451e60 100644
GIT binary patch
delta 2428
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ⅆC
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�Of%3T8lz!a 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 Date: Wed, 29 Oct 2014 22:52:06 +0100 Subject: [PATCH 28/29] IDEA-132030 (OS X file watcher recompiled) --- bin/mac/fsnotifier | Bin 13984 -> 34624 bytes native/fsNotifier/mac/make.sh | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/mac/fsnotifier b/bin/mac/fsnotifier index 9bbf3898bb5dff531c425325803098472bba23d8..02040b8cbf39cef1c7e4c95432b199ee7ab4ebb1 100755 GIT binary patch delta 6152 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 delta 298 zcmX@m$Fv}KkpL6dI(-HP4+aK?b@CGpr8cVwu`y203Xx-7V!*&)IN4WNak7@M9On%n zPXMUs#^gX@*~z;?q#hG2YnR>m Date: Wed, 29 Oct 2014 23:17:53 +0100 Subject: [PATCH 29/29] add statistics to new welcome screen --- .../impl/welcomeScreen/FlatWelcomeFrame.java | 65 +++++++++++-------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java index 72f9fbf05459..916c9e796518 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java @@ -17,7 +17,8 @@ package com.intellij.openapi.wm.impl.welcomeScreen; import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; -import com.intellij.ide.RecentProjectsManager; +import com.intellij.ide.RecentProjectsManagerBase; +import com.intellij.internal.statistic.UsageTrigger; import com.intellij.openapi.Disposable; import com.intellij.openapi.MnemonicHelper; import com.intellij.openapi.actionSystem.*; @@ -88,7 +89,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { setTitle("Welcome to " + ApplicationNamesInfo.getInstance().getFullProductName()); AppUIUtil.updateWindowIcon(this); //Rectangle bounds = ScreenUtil.getMainScreenBounds(); - if (RecentProjectsManager.getInstance().getRecentProjectsActions(false).length > 0) { + if (RecentProjectsManagerBase.getInstance().getRecentProjectsActions(false).length > 0) { setSize(666, 460); } else { setSize(555, 460); @@ -166,23 +167,23 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { public StatusBar getStatusBar() { return null; } - + public static Color getMainBackground() { return new JBColor(0xf7f7f7, 0x45474a); } - + public static Color getProjectsBackground() { return new JBColor(Gray.xFF, Gray.x39); } - + public static Color getLinkNormalColor() { return new JBColor(Gray._0, Gray.xBB); } - + public static Color getListSelectionColor(boolean hasFocus) { return hasFocus ? new JBColor(0x3875d6, 0x4b6eaf) : new JBColor(Gray.xDD, Gray.x45); } - + public static Color getActionLinkSelectionColor() { return new JBColor(0xdbe5f5, 0x485875); } @@ -195,14 +196,14 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { public FlatWelcomeScreen() { super(new BorderLayout()); setBackground(getMainBackground()); - if (RecentProjectsManager.getInstance().getRecentProjectsActions(false).length > 0) { + if (RecentProjectsManagerBase.getInstance().getRecentProjectsActions(false).length > 0) { final JComponent recentProjects = createRecentProjects(); add(recentProjects, BorderLayout.WEST); final JList projectsList = UIUtil.findComponentOfType(recentProjects, JList.class); if (projectsList != null) { projectsList.getModel().addListDataListener(new ListDataListener() { @Override - public void intervalAdded(ListDataEvent e) { + public void intervalAdded(ListDataEvent e) { } @Override @@ -211,7 +212,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { } private void removeIfNeeded() { - if (RecentProjectsManager.getInstance().getRecentProjectsActions(false).length == 0) { + if (RecentProjectsManagerBase.getInstance().getRecentProjectsActions(false).length == 0) { FlatWelcomeScreen.this.remove(recentProjects); FlatWelcomeScreen.this.revalidate(); FlatWelcomeScreen.this.repaint(); @@ -260,7 +261,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { if (register != null) { Presentation presentation = register.getTemplatePresentation(); register.update(new AnActionEvent(null, DataManager.getInstance().getDataContext(this), - ActionPlaces.WELCOME_SCREEN, presentation, ActionManager.getInstance(), 0)); + ActionPlaces.WELCOME_SCREEN, presentation, ActionManager.getInstance(), 0)); if (presentation.isEnabled()) { ActionLink registerLink = new ActionLink("Register", register); registerLink.setNormalColor(getLinkNormalColor()); @@ -279,14 +280,14 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.X_AXIS)); toolbar.add(createActionLink("Configure", IdeActions.GROUP_WELCOME_SCREEN_CONFIGURE, AllIcons.General.GearPlain, !registeredVisible)); toolbar.add(createActionLink("Get Help", IdeActions.GROUP_WELCOME_SCREEN_DOC, null, false)); - + panel.add(toolbar, BorderLayout.EAST); - + panel.setBorder(new EmptyBorder(0,0,8,11)); return panel; } - + private JComponent createActionLink(final String text, final String groupId, Icon icon, boolean focusListOnLeft) { final Ref ref = new Ref(null); AnAction action = new AnAction() { @@ -294,8 +295,10 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { public void actionPerformed(@NotNull AnActionEvent e) { ActionGroup configureGroup = (ActionGroup)ActionManager.getInstance().getAction(groupId); final PopupFactoryImpl.ActionGroupPopup popup = (PopupFactoryImpl.ActionGroupPopup)JBPopupFactory.getInstance() - .createActionGroupPopup(null, new IconsFreeActionGroup(configureGroup), e.getDataContext(), JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false, ActionPlaces.WELCOME_SCREEN); + .createActionGroupPopup(null, new IconsFreeActionGroup(configureGroup), e.getDataContext(), JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false, + ActionPlaces.WELCOME_SCREEN); popup.showUnderneathOfLabel(ref.get()); + UsageTrigger.trigger("welcome.screen." + groupId); } }; ref.set(new ActionLink(text, icon, action)); @@ -334,7 +337,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { if (icon.getIconHeight() != 16 || icon.getIconWidth() != 16) { icon = EmptyIcon.ICON_16; } - ActionLink link = new ActionLink(text, icon, action); + ActionLink link = new ActionLink(text, icon, action, createUsageTracker(action)); link.setPaintUnderline(false); link.setNormalColor(getLinkNormalColor()); button.add(link); @@ -374,16 +377,16 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { appName.setFont(font.deriveFont(36f).deriveFont(Font.PLAIN)); appName.setHorizontalAlignment(SwingConstants.CENTER); String appVersion = "Version " + app.getFullVersion(); - + if (app.isEAP() && app.getBuild().getBuildNumber() < Integer.MAX_VALUE) { appVersion += " (" + app.getBuild().asString() + ")"; } - + JLabel version = new JLabel(appVersion); version.setFont(getProductFont().deriveFont(16f)); version.setHorizontalAlignment(SwingConstants.CENTER); version.setForeground(Gray._128); - + panel.add(appName); panel.add(version, BorderLayout.SOUTH); panel.setBorder(new EmptyBorder(0, 0, 20, 0)); @@ -393,9 +396,9 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { private Font getProductFont() { String name = "/fonts/Roboto-Light.ttf"; URL url = AppUIUtil.class.getResource(name); - if (url == null) { - Logger.getInstance(AppUIUtil.class).warn("Resource missing: " + name); - } else { + if (url == null) { + Logger.getInstance(AppUIUtil.class).warn("Resource missing: " + name); + } else { try { InputStream is = url.openStream(); @@ -450,7 +453,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { if (focusListOnLeft) { if (list != null) { list.requestFocus(); - } + } } else { focusPrev(comp); } @@ -533,14 +536,15 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { if (child instanceof ActionGroup) { return new IconsFreeActionGroup((ActionGroup)child); } - - Presentation presentation = child.getTemplatePresentation(); + + Presentation presentation = child.getTemplatePresentation(); return new AnAction(presentation.getText(), presentation.getDescription(), null) { @Override public void actionPerformed(@NotNull AnActionEvent e) { child.actionPerformed(e); + UsageTrigger.trigger("welcome.screen." + e.getActionManager().getId(child)); } @Override @@ -558,6 +562,15 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { } } + private static Runnable createUsageTracker(final AnAction action) { + return new Runnable() { + @Override + public void run() { + UsageTrigger.trigger("welcome.screen." + ActionManager.getInstance().getId(action)); + } + }; + } + private static JLabel createArrow(final ActionLink link) { JLabel arrow = new JLabel(AllIcons.General.Combo3); arrow.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); @@ -613,7 +626,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { public static void notifyFrameClosed(JFrame frame) { saveLocation(frame.getBounds()); } - + public static class WelcomeScreenActionsPanel { private JPanel root; private JPanel actions;