From 1e71e1130314911b023a6757fffc5a51cd607a60 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Sun, 17 Aug 2014 19:47:05 +0200 Subject: [PATCH 01/25] move 'show registry' up as the most popular in the maintenance group --- platform/platform-resources/src/idea/PlatformActions.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index ea65788a2554..7773a2b00e49 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -581,8 +581,8 @@ - + From 5ffdd2b01557a21137f590ebb9e58d0412e911da Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Mon, 18 Aug 2014 12:13:03 +0400 Subject: [PATCH 02/25] inspections ui: SeverityEditorDialog AssertionError fixed while pressing "Colors&Fonts" button --- .../com/intellij/codeInspection/ex/SeverityEditorDialog.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java index 527235b5166c..a7bcd970660d 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java @@ -37,6 +37,7 @@ import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.options.ex.ConfigurableWrapper; import com.intellij.openapi.options.newEditor.OptionsEditor; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.InputValidator; @@ -231,7 +232,8 @@ public class SeverityEditorDialog extends DialogWrapper { final DataContext dataContext = DataManager.getInstance().getDataContext(myPanel); final OptionsEditor optionsEditor = OptionsEditor.KEY.getData(dataContext); if (optionsEditor != null) { - final ColorAndFontOptions colorAndFontOptions = optionsEditor.findConfigurable(ColorAndFontOptions.class); + final ColorAndFontOptions colorAndFontOptions = + (ColorAndFontOptions)((ConfigurableWrapper)optionsEditor.findConfigurableById("reference.settingsdialog.IDE.editor.colors")).getConfigurable(); assert colorAndFontOptions != null; final SearchableConfigurable javaPage = colorAndFontOptions.findSubConfigurable(InspectionColorSettingsPage.class); LOG.assertTrue(javaPage != null); From a26c89af4169e0030bb2e5fe1e79e846226f763a Mon Sep 17 00:00:00 2001 From: medvector Date: Mon, 18 Aug 2014 12:22:07 +0400 Subject: [PATCH 03/25] EDIDE-88 loop task windows --- .../edu/actions/StudyNextWindowAction.java | 54 ++++----------- .../edu/actions/StudyPrevWindowAction.java | 54 ++++----------- .../actions/StudyWindowNavigationAction.java | 65 +++++++++++++++++++ .../jetbrains/python/edu/course/TaskFile.java | 2 + 4 files changed, 92 insertions(+), 83 deletions(-) create mode 100644 python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyWindowNavigationAction.java 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 a4ecfda8baba..595aeeff42e3 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 @@ -1,23 +1,16 @@ package com.jetbrains.python.edu.actions; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.project.DumbAwareAction; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.jetbrains.python.edu.StudyTaskManager; import com.jetbrains.python.edu.StudyUtils; -import com.jetbrains.python.edu.course.StudyStatus; -import com.jetbrains.python.edu.course.TaskFile; import com.jetbrains.python.edu.course.TaskWindow; -import com.jetbrains.python.edu.editor.StudyEditor; import icons.StudyIcons; +import org.jetbrains.annotations.NotNull; + +import java.util.List; /** * move caret to next task window */ -public class StudyNextWindowAction extends DumbAwareAction { +public class StudyNextWindowAction extends StudyWindowNavigationAction { public static final String ACTION_ID = "NextWindow"; public static final String SHORTCUT = "ctrl pressed PERIOD"; public static final String SHORTCUT2 = "ctrl pressed ENTER"; @@ -26,37 +19,14 @@ public class StudyNextWindowAction extends DumbAwareAction { super("NextWindowAction", "Select next window", StudyIcons.Next); } - public void actionPerformed(AnActionEvent e) { - Project project = e.getProject(); - if (project != null) { - Editor selectedEditor = StudyEditor.getSelectedEditor(project); - if (selectedEditor != null) { - FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance(); - VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument()); - if (openedFile != null) { - StudyTaskManager taskManager = StudyTaskManager.getInstance(project); - TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile); - if (selectedTaskFile != null) { - TaskWindow selectedTaskWindow = selectedTaskFile.getSelectedTaskWindow(); - boolean ifDraw = false; - for (TaskWindow taskWindow : selectedTaskFile.getTaskWindows()) { - if (ifDraw) { - selectedTaskFile.setSelectedTaskWindow(taskWindow); - taskWindow.draw(selectedEditor, taskWindow.getStatus() != StudyStatus.Solved, true); - return; - } - if (taskWindow == selectedTaskWindow) { - ifDraw = true; - } - } - } - } - } - } - } - @Override - public void update(AnActionEvent e) { - StudyUtils.updateAction(e); + protected TaskWindow getNextTaskWindow(@NotNull final TaskWindow window) { + int index = window.getIndex(); + List windows = window.getTaskFile().getTaskWindows(); + if (StudyUtils.indexIsValid(index, windows)) { + int newIndex = index + 1; + return newIndex == windows.size() ? windows.get(0) : windows.get(newIndex); + } + return null; } } 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 3cc41511c069..347456189a00 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 @@ -1,24 +1,18 @@ package com.jetbrains.python.edu.actions; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.project.DumbAwareAction; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.jetbrains.python.edu.StudyTaskManager; import com.jetbrains.python.edu.StudyUtils; -import com.jetbrains.python.edu.course.StudyStatus; -import com.jetbrains.python.edu.course.TaskFile; import com.jetbrains.python.edu.course.TaskWindow; -import com.jetbrains.python.edu.editor.StudyEditor; import icons.StudyIcons; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; /** * author: liana * data: 6/30/14. */ -public class StudyPrevWindowAction extends DumbAwareAction { +public class StudyPrevWindowAction extends StudyWindowNavigationAction { public static final String ACTION_ID = "PrevWindowAction"; public static final String SHORTCUT = "ctrl pressed COMMA"; @@ -26,37 +20,15 @@ public class StudyPrevWindowAction extends DumbAwareAction { super("PrevWindowAction", "Select previous window", StudyIcons.Prev); } - public void actionPerformed(AnActionEvent e) { - Project project = e.getProject(); - assert project != null; - Editor selectedEditor = StudyEditor.getSelectedEditor(project); - if (selectedEditor != null) { - FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance(); - VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument()); - if (openedFile != null) { - StudyTaskManager taskManager = StudyTaskManager.getInstance(project); - TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile); - if (selectedTaskFile != null) { - TaskWindow selectedTaskWindow = selectedTaskFile.getSelectedTaskWindow(); - TaskWindow prev = null; - for (TaskWindow taskWindow : selectedTaskFile.getTaskWindows()) { - if (taskWindow == selectedTaskWindow) { - break; - } - prev = taskWindow; - } - - if (prev != null) { - selectedTaskFile.setSelectedTaskWindow(prev); - prev.draw(selectedEditor, prev.getStatus() != StudyStatus.Solved, true); - } - } - } - } - } + @Nullable @Override - public void update(AnActionEvent e) { - StudyUtils.updateAction(e); + protected TaskWindow getNextTaskWindow(@NotNull final TaskWindow window) { + int prevIndex = window.getIndex() - 1; + List windows = window.getTaskFile().getTaskWindows(); + if (StudyUtils.indexIsValid(prevIndex, windows)) { + return windows.get(prevIndex); + } + return null; } } diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyWindowNavigationAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyWindowNavigationAction.java new file mode 100644 index 000000000000..8c6b90221555 --- /dev/null +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyWindowNavigationAction.java @@ -0,0 +1,65 @@ +package com.jetbrains.python.edu.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.jetbrains.python.edu.StudyTaskManager; +import com.jetbrains.python.edu.StudyUtils; +import com.jetbrains.python.edu.course.TaskFile; +import com.jetbrains.python.edu.course.TaskWindow; +import com.jetbrains.python.edu.editor.StudyEditor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +abstract public class StudyWindowNavigationAction extends DumbAwareAction { + + public StudyWindowNavigationAction(String actionId, String description, Icon icon) { + super(actionId, description, icon); + } + + public void navigateWindow(@NotNull final Project project) { + Editor selectedEditor = StudyEditor.getSelectedEditor(project); + if (selectedEditor != null) { + FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance(); + VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument()); + if (openedFile != null) { + StudyTaskManager taskManager = StudyTaskManager.getInstance(project); + TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile); + if (selectedTaskFile != null) { + TaskWindow selectedTaskWindow = selectedTaskFile.getSelectedTaskWindow(); + if (selectedTaskWindow == null) { + return; + } + TaskWindow nextTaskWindow = getNextTaskWindow(selectedTaskWindow); + if (nextTaskWindow == null) { + return; + } + nextTaskWindow.draw(selectedEditor, true, true); + selectedTaskFile.setSelectedTaskWindow(nextTaskWindow); + } + } + } + } + + @Nullable + protected abstract TaskWindow getNextTaskWindow(@NotNull final TaskWindow window); + + @Override + public void actionPerformed(AnActionEvent e) { + Project project = e.getProject(); + if (project == null) { + return; + } + navigateWindow(project); + } + + @Override + public void update(AnActionEvent e) { + StudyUtils.updateAction(e); + } +} diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java b/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java index ed4f2bfe80da..9b53dabbf3ec 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/course/TaskFile.java @@ -50,6 +50,7 @@ public class TaskFile implements Stateful{ return myTask; } + @Nullable @Transient public TaskWindow getSelectedTaskWindow() { return mySelectedTaskWindow; @@ -215,6 +216,7 @@ public class TaskFile implements Stateful{ public void navigateToFirstTaskWindow(@NotNull final Editor editor) { if (!taskWindows.isEmpty()) { TaskWindow firstTaskWindow = StudyUtils.getFirst(taskWindows); + mySelectedTaskWindow = firstTaskWindow; LogicalPosition taskWindowStart = new LogicalPosition(firstTaskWindow.getLine(), firstTaskWindow.getStart()); editor.getCaretModel().moveToLogicalPosition(taskWindowStart); int startOffset = firstTaskWindow.getRealStartOffset(editor.getDocument()); From 22e84f149ca930921c4ce0dba8e84a9ad03a293e Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Mon, 18 Aug 2014 12:21:31 +0400 Subject: [PATCH 04/25] another attempt to fix blinking InjectedLanguageFoldingTest --- .../src/com/intellij/psi/impl/DocumentCommitThread.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java index 5176c95c812b..32a2e38384d9 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java @@ -563,7 +563,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run int attempts = 0; int delay = 100; synchronized (documentsToCommit) { - while(!documentsToCommit.isEmpty()) { + while(!documentsToCommit.isEmpty() || currentTask != null) { documentsToCommit.wait(delay); if (delay * attempts > timeout) { throw new RuntimeException("timeout"); From cfb2d39c7868263d11d4903d10e918a2e6d3c5e5 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Fri, 15 Aug 2014 19:41:06 +0400 Subject: [PATCH 05/25] EA-57803 - correcting previous fix for injected folding pass (EA-54811) --- .../com/intellij/codeInsight/folding/impl/FoldingUpdate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java index 7d0b4453c517..4c137f8d2a37 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java @@ -174,7 +174,7 @@ public class FoldingUpdate { injectedFiles.add(injectedFile); final FoldingMap map = new FoldingMap(); maps.add(map); - getFoldingsFor(injectedFile, injectedDocument, map, false); + getFoldingsFor(injectedFile, injectedEditor.getDocument(), map, false); } }); } From 87624b560bebfe308e55d84b5571c4c0f1ae6ea6 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Mon, 18 Aug 2014 12:57:56 +0400 Subject: [PATCH 06/25] extracted constant for ColorAndFontOptions ID --- .../application/options/colors/ColorAndFontOptions.java | 4 +++- .../com/intellij/codeInspection/ex/SeverityEditorDialog.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java index 5e3017206132..ce2a00d3d671 100644 --- a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java +++ b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java @@ -81,6 +81,8 @@ import java.util.*; import java.util.List; public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract implements EditorOptionsProvider { + public static final String ID = "reference.settingsdialog.IDE.editor.colors"; + private HashMap mySchemes; private MyColorScheme mySelectedScheme; public static final String DIFF_GROUP = ApplicationBundle.message("title.diff"); @@ -999,7 +1001,7 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract @Override @NotNull public String getHelpTopic() { - return "reference.settingsdialog.IDE.editor.colors"; + return ID; } private static class MyColorScheme extends EditorColorsSchemeImpl { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java index a7bcd970660d..e239678af0ad 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java @@ -233,7 +233,7 @@ public class SeverityEditorDialog extends DialogWrapper { final OptionsEditor optionsEditor = OptionsEditor.KEY.getData(dataContext); if (optionsEditor != null) { final ColorAndFontOptions colorAndFontOptions = - (ColorAndFontOptions)((ConfigurableWrapper)optionsEditor.findConfigurableById("reference.settingsdialog.IDE.editor.colors")).getConfigurable(); + (ColorAndFontOptions)((ConfigurableWrapper)optionsEditor.findConfigurableById(ColorAndFontOptions.ID)).getConfigurable(); assert colorAndFontOptions != null; final SearchableConfigurable javaPage = colorAndFontOptions.findSubConfigurable(InspectionColorSettingsPage.class); LOG.assertTrue(javaPage != null); From a45dc879b1d8fd6e07db6ee76d733a749640d3ca Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Mon, 18 Aug 2014 12:59:34 +0400 Subject: [PATCH 07/25] inspections ui: severities table cell not changes foreground on selection while editing fixed --- .../src/com/intellij/openapi/ui/ComboBoxTableRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java b/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java index c02f27af5d4b..f35d76fff51c 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java @@ -117,7 +117,7 @@ public class ComboBoxTableRenderer extends JLabel implements TableCellRendere public Component getTableCellEditorComponent(JTable table, final Object value, boolean isSelected, final int row, final int column) { @SuppressWarnings("unchecked") final T t = (T)value; myValue = t; - customizeComponent(t, table, isSelected); + customizeComponent(t, table, true); //noinspection SSBasedInspection SwingUtilities.invokeLater(new Runnable() { From 0bc48c87e2198ba47884881c173a75f5a03930d7 Mon Sep 17 00:00:00 2001 From: medvector Date: Mon, 18 Aug 2014 13:02:10 +0400 Subject: [PATCH 08/25] EDIDE-113 fixed --- .../jetbrains/python/edu/StudyDirectoryProjectGenerator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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 363c4d64691f..d4831d93e367 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 @@ -257,8 +257,8 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple courseInfo = new CourseInfo(courseName, courseAuthor, courseDescription); } } - catch (FileNotFoundException e) { - LOG.error(e); + catch (Exception e) { + //error will be shown in UI } finally { StudyUtils.closeSilently(reader); From a135c365446fcc55508ef480294e464e9764b14d Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Mon, 18 Aug 2014 13:05:28 +0400 Subject: [PATCH 09/25] IDEA-128661 NPE during inplace renaming variable --- .../template/impl/actions/NextVariableAction.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/actions/NextVariableAction.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/actions/NextVariableAction.java index c63a758385fe..102626785a24 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/actions/NextVariableAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/actions/NextVariableAction.java @@ -28,12 +28,12 @@ import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorAction; import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class NextVariableAction extends EditorAction { @@ -46,14 +46,15 @@ public class NextVariableAction extends EditorAction { @Override public void executeWriteAction(Editor editor, @Nullable Caret caret, DataContext dataContext) { TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); + assert templateState != null; CommandProcessor.getInstance().setCurrentCommandName(CodeInsightBundle.message("template.next.variable.command")); templateState.nextTab(); } - } - @Override - public void update(Editor editor, Presentation presentation, DataContext dataContext) { - TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); - presentation.setEnabled(templateState != null && !templateState.isFinished() && templateState.isToProcessTab()); + @Override + protected boolean isEnabledForCaret(@NotNull Editor editor, @NotNull Caret caret, DataContext dataContext) { + TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); + return templateState != null && !templateState.isFinished() && templateState.isToProcessTab(); + } } } From a1ae56b0f9a723aef1d4e85385ff57f89b18159f Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Thu, 14 Aug 2014 18:27:28 +0400 Subject: [PATCH 10/25] PY-9342 Distinguish between function and method types --- .../module_redeclarator.py | 2 + .../pycharm_generator_utils/util_methods.py | 19 ++++ .../src/com/jetbrains/python/PyNames.java | 30 ++++++ .../python/psi/types/PyFunctionType.java | 63 +++++++++++-- .../MockSdk2.7/python_stubs/__builtin__.py | 13 +++ .../MockSdk3.2/python_stubs/builtins.py | 14 ++- .../boundMethodSpecialAttributes.py | 5 + .../completion/lambdaSpecialAttributes.py | 1 + .../staticMethodSpecialAttributes.py | 6 ++ .../unboundMethodSpecialAttributes.py | 5 + .../weakQualifierBoundMethodAttributes.py | 10 ++ .../python/PythonCompletionTest.java | 91 +++++++++++++++---- 12 files changed, 234 insertions(+), 25 deletions(-) create mode 100644 python/testData/completion/boundMethodSpecialAttributes.py create mode 100644 python/testData/completion/lambdaSpecialAttributes.py create mode 100644 python/testData/completion/staticMethodSpecialAttributes.py create mode 100644 python/testData/completion/unboundMethodSpecialAttributes.py create mode 100644 python/testData/completion/weakQualifierBoundMethodAttributes.py diff --git a/python/helpers/pycharm_generator_utils/module_redeclarator.py b/python/helpers/pycharm_generator_utils/module_redeclarator.py index 0dbdbb58ac6b..bdffe3ec8e97 100644 --- a/python/helpers/pycharm_generator_utils/module_redeclarator.py +++ b/python/helpers/pycharm_generator_utils/module_redeclarator.py @@ -1009,6 +1009,8 @@ class ModuleRedeclarator(object): self.classes_buf.out(0, txt) txt = create_function() self.classes_buf.out(0, txt) + txt = create_method() + self.classes_buf.out(0, txt) # Fake if version[0] >= 3 or (version[0] == 2 and version[1] >= 6): diff --git a/python/helpers/pycharm_generator_utils/util_methods.py b/python/helpers/pycharm_generator_utils/util_methods.py index b6805c4a5942..273b0a20b715 100644 --- a/python/helpers/pycharm_generator_utils/util_methods.py +++ b/python/helpers/pycharm_generator_utils/util_methods.py @@ -115,6 +115,25 @@ class __function(object): """ return txt +def create_method(): + txt = """ +class __method(object): + '''A mock class representing method type.''' + + def __init__(self): +""" + if version[0] == 2: + txt += """ + self.im_class = None + self.im_self = None + self.im_func = None +""" + if version[0] >= 3 or (version[0] == 2 and version[1] >= 6): + txt += """ + self.__func__ = None + self.__self__ = None +""" + return txt def _searchbases(cls, accum): # logic copied from inspect.py diff --git a/python/psi-api/src/com/jetbrains/python/PyNames.java b/python/psi-api/src/com/jetbrains/python/PyNames.java index 94e35f711c29..bd927c5d49bf 100644 --- a/python/psi-api/src/com/jetbrains/python/PyNames.java +++ b/python/psi-api/src/com/jetbrains/python/PyNames.java @@ -60,6 +60,7 @@ public class PyNames { public static final String FAKE_OLD_BASE = "___Classobj"; public static final String FAKE_GENERATOR = "__generator"; public static final String FAKE_FUNCTION = "__function"; + public static final String FAKE_METHOD = "__method"; public static final String FAKE_NAMEDTUPLE = "__namedtuple"; public static final String FUTURE_MODULE = "__future__"; @@ -471,4 +472,33 @@ public class PyNames { public static boolean isRightOperatorName(@Nullable String name) { return name != null && name.matches("__r[a-z]+__"); } + + /** + * Available in Python 3 and Python 2 starting from 2.6. + *

+ * Attributes {@code __doc__}, {@code __dict__} and {@code __module__} should be inherited from object. + */ + public static final ImmutableSet FUNCTION_SPECIAL_ATTRIBUTES = ImmutableSet.of( + "__defaults__", + "__globals__", + "__closure__", + "__code__", + "__name__" + ); + + public static final ImmutableSet LEGACY_FUNCTION_SPECIAL_ATTRIBUTES = ImmutableSet.of( + "func_defaults", + "func_globals", + "func_closure", + "func_code", + "func_name", + "func_doc", + "func_dict" + ); + + public static final ImmutableSet PY3_ONLY_FUNCTION_SPECIAL_ATTRIBUTES = ImmutableSet.of("__annotations__", "__kwdefaults__"); + + public static final ImmutableSet METHOD_SPECIAL_ATTRIBUTES = ImmutableSet.of("__func__", "__self__"); + + public static final ImmutableSet LEGACY_METHOD_SPECIAL_ATTRIBUTES = ImmutableSet.of("im_func", "im_self", "im_class"); } diff --git a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java index 4b3adfd112f8..2c804260c704 100644 --- a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java +++ b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java @@ -30,6 +30,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static com.jetbrains.python.psi.PyFunction.Modifier.STATICMETHOD; +import static com.jetbrains.python.psi.PyUtil.as; + /** * Type of a particular function that is represented as a {@link Callable} in the PSI tree. * @@ -74,20 +77,68 @@ public class PyFunctionType implements PyCallableType { @Nullable PyExpression location, @NotNull AccessDirection direction, @NotNull PyResolveContext resolveContext) { - final PyClassTypeImpl functionType = PyBuiltinCache.getInstance(getCallable()).getObjectType(PyNames.FAKE_FUNCTION); - if (functionType == null) { + final PyClassType delegate = selectFakeType(location, resolveContext.getTypeEvalContext()); + if (delegate == null) { return Collections.emptyList(); } - return functionType.resolveMember(name, location, direction, resolveContext); + return delegate.resolveMember(name, location, direction, resolveContext); } @Override public Object[] getCompletionVariants(String completionPrefix, PsiElement location, ProcessingContext context) { - final PyClassTypeImpl functionType = PyBuiltinCache.getInstance(getCallable()).getObjectType(PyNames.FAKE_FUNCTION); - if (functionType == null) { + final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(location.getContainingFile()); + final PyClassType delegate; + if (location instanceof PyReferenceExpression) { + delegate = selectFakeType(((PyReferenceExpression)location).getQualifier(), typeEvalContext); + } + else { + delegate = PyBuiltinCache.getInstance(getCallable()).getObjectType(PyNames.FAKE_FUNCTION); + } + if (delegate == null) { return ArrayUtil.EMPTY_OBJECT_ARRAY; } - return functionType.getCompletionVariants(completionPrefix, location, context); + return delegate.getCompletionVariants(completionPrefix, location, context); + } + + /** + * Select either {@link PyNames#FAKE_FUNCTION} or {@link PyNames#FAKE_METHOD} fake class depending on concrete reference used and + * language level. Will fallback to fake function type. + */ + @Nullable + private PyClassTypeImpl selectFakeType(@Nullable PyExpression location, @NotNull TypeEvalContext context) { + if (location instanceof PyReferenceExpression && isBoundMethodReference(((PyReferenceExpression)location), context)) { + return PyBuiltinCache.getInstance(getCallable()).getObjectType(PyNames.FAKE_METHOD); + } + return PyBuiltinCache.getInstance(getCallable()).getObjectType(PyNames.FAKE_FUNCTION); + } + + private boolean isBoundMethodReference(@NotNull PyReferenceExpression location, @NotNull TypeEvalContext context) { + final PyFunction function = as(getCallable(), PyFunction.class); + final boolean isNonStaticMethod = function != null && function.getContainingClass() != null && function.getModifier() != STATICMETHOD; + if (isNonStaticMethod) { + if (LanguageLevel.forElement(location).isOlderThan(LanguageLevel.PYTHON30)) { + return true; + } + if (location.isQualified()) { + //noinspection ConstantConditions + final PyType qualifierType = PyTypeChecker.toNonWeakType(context.getType(location.getQualifier()), context); + if (isInstanceType(qualifierType)) { + return true; + } + else if (qualifierType instanceof PyUnionType) { + for (PyType type : ((PyUnionType)qualifierType).getMembers()) { + if (isInstanceType(type)) { + return true; + } + } + } + } + } + return false; + } + + private static boolean isInstanceType(@Nullable PyType type) { + return type instanceof PyClassType && !((PyClassType)type).isDefinition(); } @Override diff --git a/python/testData/MockSdk2.7/python_stubs/__builtin__.py b/python/testData/MockSdk2.7/python_stubs/__builtin__.py index ca174bbf6716..5ef056b2a62c 100644 --- a/python/testData/MockSdk2.7/python_stubs/__builtin__.py +++ b/python/testData/MockSdk2.7/python_stubs/__builtin__.py @@ -652,6 +652,19 @@ class __function(object): self.__name__ = '' +class __method(object): + '''A mock class representing method type.''' + + def __init__(self): + + self.im_class = None + self.im_self = None + self.im_func = None + + self.__func__ = None + self.__self__ = None + + class __namedtuple(tuple): '''A mock base class for named tuples.''' diff --git a/python/testData/MockSdk3.2/python_stubs/builtins.py b/python/testData/MockSdk3.2/python_stubs/builtins.py index 88b74ab951ac..58fcaac8b763 100644 --- a/python/testData/MockSdk3.2/python_stubs/builtins.py +++ b/python/testData/MockSdk3.2/python_stubs/builtins.py @@ -613,14 +613,24 @@ class __function(object): self.__dict__ = '' self.__module__ = '' - self.__annotations__ = {} self.__defaults__ = {} self.__globals__ = {} - self.__kwdefaults__ = {} self.__closure__ = None self.__code__ = None self.__name__ = '' + self.__annotations__ = {} + self.__kwdefaults__ = {} + + +class __method(object): + '''A mock class representing method type.''' + + def __init__(self): + + self.__func__ = None + self.__self__ = None + class __namedtuple(tuple): '''A mock base class for named tuples.''' diff --git a/python/testData/completion/boundMethodSpecialAttributes.py b/python/testData/completion/boundMethodSpecialAttributes.py new file mode 100644 index 000000000000..02afa569bfbe --- /dev/null +++ b/python/testData/completion/boundMethodSpecialAttributes.py @@ -0,0 +1,5 @@ +class MyClass(object): + def method(self): + pass + +MyClass().method.__ \ No newline at end of file diff --git a/python/testData/completion/lambdaSpecialAttributes.py b/python/testData/completion/lambdaSpecialAttributes.py new file mode 100644 index 000000000000..0b0465eb2aa6 --- /dev/null +++ b/python/testData/completion/lambdaSpecialAttributes.py @@ -0,0 +1 @@ +(lambda: 42).__ \ No newline at end of file diff --git a/python/testData/completion/staticMethodSpecialAttributes.py b/python/testData/completion/staticMethodSpecialAttributes.py new file mode 100644 index 000000000000..84b0e751af43 --- /dev/null +++ b/python/testData/completion/staticMethodSpecialAttributes.py @@ -0,0 +1,6 @@ +class MyClass(object): + @staticmethod + def method(self): + pass + +MyClass().method.__ \ No newline at end of file diff --git a/python/testData/completion/unboundMethodSpecialAttributes.py b/python/testData/completion/unboundMethodSpecialAttributes.py new file mode 100644 index 000000000000..b7e9b520de42 --- /dev/null +++ b/python/testData/completion/unboundMethodSpecialAttributes.py @@ -0,0 +1,5 @@ +class MyClass(object): + def method(self): + pass + +MyClass.method.__ \ No newline at end of file diff --git a/python/testData/completion/weakQualifierBoundMethodAttributes.py b/python/testData/completion/weakQualifierBoundMethodAttributes.py new file mode 100644 index 000000000000..2433cfbfa054 --- /dev/null +++ b/python/testData/completion/weakQualifierBoundMethodAttributes.py @@ -0,0 +1,10 @@ +class MyClass(object): + def method(self): + pass + +if True: + inst = MyClass() +else: + inst = unresolved + +inst.method.__ \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java index f365eea4da34..e47171c856b8 100644 --- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java @@ -626,23 +626,80 @@ public class PythonCompletionTest extends PyTestCase { } // PY-4073 - public void testSpecialFunctionAttributes() throws Exception { - setLanguageLevel(LanguageLevel.PYTHON27); - try { - List suggested = doTestByText("def func(): pass; func.func_"); - assertNotNull(suggested); - assertContainsElements(suggested, - "func_defaults", "func_globals", "func_closure", - "func_code", "func_name", "func_doc", "func_dict"); + public void testFunctionSpecialAttributes() { + runWithLanguageLevel(LanguageLevel.PYTHON27, new Runnable() { + @Override + public void run() { + List suggested = doTestByText("def func(): pass; func.func_"); + assertNotNull(suggested); + assertContainsElements(suggested, PyNames.LEGACY_FUNCTION_SPECIAL_ATTRIBUTES); - suggested = doTestByText("def func(): pass; func.__"); - assertNotNull(suggested); - assertContainsElements(suggested, "__defaults__", "__globals__", "__closure__", - "__code__", "__name__", "__doc__", "__dict__", "__module__"); - assertDoesntContain(suggested, "__annotations__", "__kwdefaults__"); - } - finally { - setLanguageLevel(null); - } + suggested = doTestByText("def func(): pass; func.__"); + assertNotNull(suggested); + assertContainsElements(suggested, PyNames.FUNCTION_SPECIAL_ATTRIBUTES); + assertDoesntContain(suggested, PyNames.PY3_ONLY_FUNCTION_SPECIAL_ATTRIBUTES); + } + }); + } + + // PY-9342 + public void testBoundMethodSpecialAttributes() { + List suggested = doTestByText("{}.update.im_"); + assertNotNull(suggested); + assertContainsElements(suggested, PyNames.LEGACY_METHOD_SPECIAL_ATTRIBUTES); + + suggested = doTestByText("{}.update.__"); + assertNotNull(suggested); + assertContainsElements(suggested, PyNames.METHOD_SPECIAL_ATTRIBUTES); + assertDoesntContain(suggested, PyNames.FUNCTION_SPECIAL_ATTRIBUTES); + } + + // PY-9342 + public void testWeakQualifierBoundMethodAttributes() { + assertUnderscoredMethodSpecialAttributesSuggested(); + } + + private void assertUnderscoredMethodSpecialAttributesSuggested() { + myFixture.configureByFile("completion/" + getTestName(true) + ".py"); + myFixture.completeBasic(); + final List suggested = myFixture.getLookupElementStrings(); + assertNotNull(suggested); + assertContainsElements(suggested, PyNames.METHOD_SPECIAL_ATTRIBUTES); + assertDoesntContain(suggested, PyNames.FUNCTION_SPECIAL_ATTRIBUTES); + } + + // PY-9342 + public void testUnboundMethodSpecialAttributes() { + runWithLanguageLevel(LanguageLevel.PYTHON27, new Runnable() { + @Override + public void run() { + assertUnderscoredMethodSpecialAttributesSuggested(); + } + }); + runWithLanguageLevel(LanguageLevel.PYTHON32, new Runnable() { + @Override + public void run() { + assertUnderscoredFunctionAttributesSuggested(); + } + }); + } + + // PY-9342 + public void testStaticMethodSpecialAttributes() { + assertUnderscoredFunctionAttributesSuggested(); + } + + // PY-9342 + public void testLambdaSpecialAttributes() { + assertUnderscoredFunctionAttributesSuggested(); + } + + private void assertUnderscoredFunctionAttributesSuggested() { + myFixture.configureByFile("completion/" + getTestName(true) + ".py"); + myFixture.completeBasic(); + final List suggested = myFixture.getLookupElementStrings(); + assertNotNull(suggested); + assertContainsElements(suggested, PyNames.FUNCTION_SPECIAL_ATTRIBUTES); + assertDoesntContain(suggested, PyNames.METHOD_SPECIAL_ATTRIBUTES); } } From d75f031428609d052e18f56ee3bba2c6afc6fd95 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Fri, 15 Aug 2014 19:44:39 +0400 Subject: [PATCH 11/25] PY-9342 Follow assignments chain to determine that method is bound --- .../python/psi/types/PyFunctionType.java | 15 ++++++++++- .../reassignedMethodSpecialAttributes.py | 6 +++++ .../methodSpecialAttributes.py | 25 +++++++++++++++++++ .../python/PythonCompletionTest.java | 5 ++++ .../PyUnresolvedReferencesInspectionTest.java | 5 ++++ 5 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 python/testData/completion/reassignedMethodSpecialAttributes.py create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection/methodSpecialAttributes.py diff --git a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java index 2c804260c704..4bdbae69d83d 100644 --- a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java +++ b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java @@ -18,10 +18,12 @@ package com.jetbrains.python.psi.types; import com.intellij.psi.PsiElement; import com.intellij.util.ArrayUtil; import com.intellij.util.ProcessingContext; +import com.intellij.util.containers.ContainerUtil; import com.jetbrains.python.PyNames; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyBuiltinCache; import com.jetbrains.python.psi.resolve.PyResolveContext; +import com.jetbrains.python.psi.resolve.QualifiedResolveResult; import com.jetbrains.python.psi.resolve.RatedResolveResult; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -116,12 +118,23 @@ public class PyFunctionType implements PyCallableType { final PyFunction function = as(getCallable(), PyFunction.class); final boolean isNonStaticMethod = function != null && function.getContainingClass() != null && function.getModifier() != STATICMETHOD; if (isNonStaticMethod) { + // In Python 2 unbound methods have __method fake type if (LanguageLevel.forElement(location).isOlderThan(LanguageLevel.PYTHON30)) { return true; } + final PyExpression qualifier; if (location.isQualified()) { + qualifier = location.getQualifier(); + } + else { + final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context); + final QualifiedResolveResult resolveResult = location.followAssignmentsChain(resolveContext); + final List qualifiers = resolveResult.getQualifiers(); + qualifier = ContainerUtil.isEmpty(qualifiers) ? null : qualifiers.get(qualifiers.size() - 1); + } + if (qualifier != null) { //noinspection ConstantConditions - final PyType qualifierType = PyTypeChecker.toNonWeakType(context.getType(location.getQualifier()), context); + final PyType qualifierType = PyTypeChecker.toNonWeakType(context.getType(qualifier), context); if (isInstanceType(qualifierType)) { return true; } diff --git a/python/testData/completion/reassignedMethodSpecialAttributes.py b/python/testData/completion/reassignedMethodSpecialAttributes.py new file mode 100644 index 000000000000..faf25e0022c7 --- /dev/null +++ b/python/testData/completion/reassignedMethodSpecialAttributes.py @@ -0,0 +1,6 @@ +class MyClass(object): + def method(self): + pass + +m = MyClass().method +m.__ \ No newline at end of file diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/methodSpecialAttributes.py b/python/testData/inspections/PyUnresolvedReferencesInspection/methodSpecialAttributes.py new file mode 100644 index 000000000000..7a60e533a15d --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/methodSpecialAttributes.py @@ -0,0 +1,25 @@ +class MyClass(object): + def method(self): + pass + + @staticmethod + def static_method(): + pass + + +# Unbound method still treated as __method in Python 2 +MyClass.method.__func__ +MyClass.method.__defaults__ + +# Bound method with qualifier +inst = MyClass() +inst.method.__func__ +inst.method.__defaults__ + +# Reassigned bound method without qualifier +m = inst.method + +# Static method +# This reference should be marked as unresolved, but such warnings are suppressed for methods with decorators +inst.static_method.__func__ +inst.static_method.__defaults__ diff --git a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java index e47171c856b8..a1366ac2e17a 100644 --- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java @@ -694,6 +694,11 @@ public class PythonCompletionTest extends PyTestCase { assertUnderscoredFunctionAttributesSuggested(); } + // PY-9342 + public void testReassignedMethodSpecialAttributes() { + assertUnderscoredMethodSpecialAttributesSuggested(); + } + private void assertUnderscoredFunctionAttributesSuggested() { myFixture.configureByFile("completion/" + getTestName(true) + ".py"); myFixture.completeBasic(); diff --git a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java index a0a2a1232b2e..3451712f6bcd 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java @@ -371,6 +371,11 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase { doMultiFileTest(); } + // PY-9342 + public void testMethodSpecialAttributes() { + doTest(); + } + // PY-11472 public void testUnusedImportBeforeStarImport() { doMultiFileTest(); From 2465f0df5b0cdb8bad16eb6206e56f9183de19aa Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Mon, 18 Aug 2014 13:19:48 +0400 Subject: [PATCH 12/25] inspections ui: in scopes table used getScopeName() instead getScope().getName() + unused fields deleted --- .../ui/SingleInspectionProfilePanel.java | 6 +---- .../ui/table/ScopesAndSeveritiesTable.java | 22 ++++++------------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java index 2da5c80a758b..81d0bf651688 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java @@ -16,7 +16,6 @@ package com.intellij.profile.codeInspection.ui; -import com.intellij.CommonBundle; import com.intellij.codeHighlighting.HighlightDisplayLevel; import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInsight.daemon.impl.HighlightInfoType; @@ -62,7 +61,6 @@ import com.intellij.profile.codeInspection.ui.table.ScopesAndSeveritiesTable; import com.intellij.psi.search.scope.packageSet.NamedScope; import com.intellij.ui.*; import com.intellij.ui.components.JBLabel; -import com.intellij.ui.treeStructure.Tree; import com.intellij.util.Alarm; import com.intellij.util.Function; import com.intellij.util.config.StorageAccessors; @@ -85,8 +83,6 @@ import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.awt.*; -import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; import java.io.IOException; import java.io.StringReader; import java.util.*; @@ -811,7 +807,7 @@ public class SingleInspectionProfilePanel extends JPanel { } } final JTable scopesAndScopesAndSeveritiesTable = - new ScopesAndSeveritiesTable(new ScopesAndSeveritiesTable.TableSettings(nodes, mySelectedProfile, myTreeTable, project) { + new ScopesAndSeveritiesTable(new ScopesAndSeveritiesTable.TableSettings(nodes, mySelectedProfile, project) { @Override protected void onScopeChosen(@NotNull final ScopeToolState state) { setConfigPanel(configPanelAnchor, state); diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java index a0e2bc1472f2..3733415fb530 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java @@ -114,12 +114,10 @@ public class ScopesAndSeveritiesTable extends JBTable { private final List myKeyNames; private final List myKeys; private final InspectionProfileImpl myInspectionProfile; - private final TreeTable myTreeTable; private final Project myProject; protected TableSettings(final List nodes, final InspectionProfileImpl inspectionProfile, - final TreeTable treeTable, final Project project) { myNodes = nodes; myKeys = new ArrayList(myNodes.size()); @@ -131,7 +129,6 @@ public class ScopesAndSeveritiesTable extends JBTable { } myInspectionProfile = inspectionProfile; - myTreeTable = treeTable; myProject = project; } @@ -151,10 +148,6 @@ public class ScopesAndSeveritiesTable extends JBTable { return myInspectionProfile; } - public TreeTable getTreeTable() { - return myTreeTable; - } - public Project getProject() { return myProject; } @@ -187,8 +180,6 @@ public class ScopesAndSeveritiesTable extends JBTable { private static class MyTableModel extends AbstractTableModel implements EditableModel { private final InspectionProfileImpl myInspectionProfile; private final List myKeyNames; - private final List myNodes; - private final TreeTable myTreeTable; private final Project myProject; private final TableSettings myTableSettings; private final List myKeys; @@ -203,8 +194,6 @@ public class ScopesAndSeveritiesTable extends JBTable { myInspectionProfile = tableSettings.getInspectionProfile(); myKeys = tableSettings.getKeys(); myKeyNames = tableSettings.getKeyNames(); - myNodes = tableSettings.getNodes(); - myTreeTable = tableSettings.getTreeTable(); myScopeComparator = new ScopeOrderComparator(myInspectionProfile); refreshAggregatedScopes(); } @@ -264,7 +253,7 @@ public class ScopesAndSeveritiesTable extends JBTable { case SCOPE_ENABLED_COLUMN: return isEnabled(rowIndex); case SCOPE_NAME_COLUMN: - return rowIndex == lastRowIndex() ? "Everywhere else" : getScope(rowIndex).getName(); + return rowIndex == lastRowIndex() ? "Everywhere else" : getScopeName(rowIndex); case SEVERITY_COLUMN: return getSeverityState(rowIndex); default: @@ -276,13 +265,17 @@ public class ScopesAndSeveritiesTable extends JBTable { return getScopeToolState(rowIndex).getExistedStates().get(0).getScope(myProject); } + private String getScopeName(final int rowIndex) { + return getScopeToolState(rowIndex).getExistedStates().get(0).getScopeName(); + } + @NotNull private SeverityState getSeverityState(final int rowIndex) { final ExistedScopesStatesAndNonExistNames existedScopesStatesAndNonExistNames = getScopeToolState(rowIndex); if (!existedScopesStatesAndNonExistNames.getNonExistNames().isEmpty()) { return new SeverityState(MIXED_FAKE_SEVERITY, false); } - return new SeverityState(ScopesAndSeveritiesTable.getSeverity(existedScopesStatesAndNonExistNames.getExistedStates()), true); + return new SeverityState(getSeverity(existedScopesStatesAndNonExistNames.getExistedStates()), true); } @Nullable @@ -362,7 +355,7 @@ public class ScopesAndSeveritiesTable extends JBTable { LOG.error("no display level found for name " + severityState.getSeverity().getName()); return; } - final String scopeName = rowIndex == lastRowIndex() ? null : getScope(rowIndex).getName(); + final String scopeName = rowIndex == lastRowIndex() ? null : getScopeName(rowIndex); myInspectionProfile.setErrorLevel(myKeys, level, scopeName, myProject); } else if (columnIndex == SCOPE_ENABLED_COLUMN) { @@ -418,7 +411,6 @@ public class ScopesAndSeveritiesTable extends JBTable { } }; DataContext dataContext = DataManager.getInstance().getDataContext(myTable); - final JComponent component = (JComponent)PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); final ListPopup popup = JBPopupFactory.getInstance() .createActionGroupPopup(ScopesChooser.TITLE, scopesChooser.createPopupActionGroup(myTable), dataContext, JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false); From 7ceb4becdaf46339f3ea33ccf76d1b2715fc567a Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Mon, 18 Aug 2014 13:25:11 +0400 Subject: [PATCH 13/25] inspections ui: added missing whitespace between 2 words to description --- .../intellij/profile/codeInspection/ui/ScopesOrderDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopesOrderDialog.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopesOrderDialog.java index c69a3e5566a2..602de3c8dba5 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopesOrderDialog.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopesOrderDialog.java @@ -64,7 +64,7 @@ public class ScopesOrderDialog extends DialogWrapper { ListUtil.moveSelectedItemsUp(myOptionsList); } }).disableRemoveAction().disableAddAction().createPanel(); - final JLabel descr = new JLabel("

If file appears in two or more scopes, it will be" + + final JLabel descr = new JLabel("

If file appears in two or more scopes, it will be " + "inspected with settings of the topmost scope in list above.

" + "

Scope order is set globally for all inspections in the profile.

"); descr.setPreferredSize(new Dimension(300, 100)); From 0b71111ef02acdd6d8cdc36733c4397e43b619b6 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 18 Aug 2014 13:38:02 +0400 Subject: [PATCH 14/25] Show referring objects - initial commit, only internal for now --- .../actions/ShowReferringObjectsAction.java | 124 ++++++++++++++++++ .../intellij/debugger/engine/JavaValue.java | 2 +- .../src/messages/ActionsBundle.properties | 1 + resources/src/idea/JavaActions.xml | 3 + 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 java/debugger/impl/src/com/intellij/debugger/actions/ShowReferringObjectsAction.java diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ShowReferringObjectsAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ShowReferringObjectsAction.java new file mode 100644 index 000000000000..2df05b6b7fe0 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ShowReferringObjectsAction.java @@ -0,0 +1,124 @@ +/* + * 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.debugger.actions; + +import com.intellij.debugger.DebuggerContext; +import com.intellij.debugger.engine.JavaValue; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.psi.PsiExpression; +import com.intellij.xdebugger.frame.*; +import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; +import com.intellij.xdebugger.impl.ui.tree.XInspectDialog; +import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase; +import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.Value; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author egor + */ +public class ShowReferringObjectsAction extends XDebuggerTreeActionBase { + private static final long MAX_REFERRING = 100; + + @Override + public void update(AnActionEvent e) { + super.update(e); + } + + @Override + protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) { + if (node.getValueContainer() instanceof JavaValue) { + JavaValue javaValue = ((JavaValue)node.getValueContainer()); + XDebuggerTree tree = XDebuggerTree.getTree(e.getDataContext()); + XInspectDialog dialog = new XInspectDialog(tree.getProject(), + tree.getEditorsProvider(), + tree.getSourcePosition(), + nodeName, + new ReferringObjectsValue(javaValue), + tree.getValueMarkers()); + dialog.setTitle("Referring objects for " + nodeName); + dialog.show(); + } + } + + private static class ReferringObjectsValue extends XValue { + private final JavaValue myJavaValue; + + public ReferringObjectsValue(JavaValue javaValue) { + myJavaValue = javaValue; + } + + @Override + public void computePresentation(@NotNull XValueNode node, @NotNull XValuePlace place) { + myJavaValue.computePresentation(node, place); + } + + @Override + public void computeChildren(@NotNull final XCompositeNode node) { + myJavaValue.getEvaluationContext().getDebugProcess().getManagerThread().schedule( + new SuspendContextCommandImpl(myJavaValue.getEvaluationContext().getSuspendContext()) { + @Override + public Priority getPriority() { + return Priority.NORMAL; + } + + @Override + public void contextAction() throws Exception { + final XValueChildrenList children = new XValueChildrenList(); + + Value value = myJavaValue.getDescriptor().getValue(); + List references = ((ObjectReference)value).referringObjects(MAX_REFERRING); + int i = 1; + for (final ObjectReference reference : references) { + ValueDescriptorImpl descriptor = new ValueDescriptorImpl(myJavaValue.getProject(), reference) { + @Override + public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException { + return reference; + } + + @Override + public String getName() { + return "Ref"; + } + + @Override + public String calcValueName() { + return "Ref"; + } + + @Override + public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException { + return null; + } + }; + JavaValue jValue = JavaValue.create(descriptor, myJavaValue.getEvaluationContext(), null); + children.add("Referrer " + i++ ,new ReferringObjectsValue(jValue)); + } + + node.addChildren(children, true); + } + } + ); + } + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java index 728af065721d..1603ed928ded 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java @@ -83,7 +83,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV return new JavaValue(parent, valueDescriptor, evaluationContext, nodeManager); } - static JavaValue create(@NotNull ValueDescriptorImpl valueDescriptor, + public static JavaValue create(@NotNull ValueDescriptorImpl valueDescriptor, EvaluationContextImpl evaluationContext, NodeManagerImpl nodeManager) { return create(null, valueDescriptor, evaluationContext, nodeManager, true); diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 47c4cef92207..50500e895c48 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -939,6 +939,7 @@ action.Debugger.Inspect.text=Inspect action.Debugger.CopyValue.text=Copy Value action.Debugger.ViewText.text=View Text action.Debugger.ViewText.description=View text value of selected node in a separate pane +action.Debugger.ShowReferring.text=Show Referring Objects action.Debugger.CompareValueWithClipboard.text=Compare Value with Clipboard action.Debugger.CompareValueWithClipboard.description=Compare value of selected node with clipboard text action.Debugger.CustomizeContextView.text=Customize Data Views... diff --git a/resources/src/idea/JavaActions.xml b/resources/src/idea/JavaActions.xml index 81a791f42208..bcfa7f37dda1 100644 --- a/resources/src/idea/JavaActions.xml +++ b/resources/src/idea/JavaActions.xml @@ -162,6 +162,9 @@ + + + From 7e53b8eabfd3771880949f4e4c305b4550f7d14a Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 18 Aug 2014 11:50:27 +0200 Subject: [PATCH 15/25] suppress exception while evaluating line number --- .../impl/ui/tree/nodes/XValueNodeImpl.java | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java index c154c486224d..1f3d4c77e84f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java @@ -120,22 +120,26 @@ public class XValueNodeImpl extends XValueContainerNode implements XValu myValuePresentation = valuePresentation; myRawValue = XValuePresentationUtil.computeValueText(valuePresentation); if (Registry.is("ide.debugger.inline")) { - getValueContainer().computeSourcePosition(new XNavigatable() { - @Override - public void setSourcePosition(@Nullable XSourcePosition sourcePosition) { - Map, Set> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES); - if (map == null || sourcePosition == null) return; - VirtualFile file = sourcePosition.getFile(); - int line = sourcePosition.getLine(); - Pair key = Pair.create(file, line); - Set presentations = map.get(key); - if (presentations == null) { - presentations = new LinkedHashSet(); - map.put(key, presentations); + try { + getValueContainer().computeSourcePosition(new XNavigatable() { + @Override + public void setSourcePosition(@Nullable XSourcePosition sourcePosition) { + Map, Set> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES); + if (map == null || sourcePosition == null) return; + VirtualFile file = sourcePosition.getFile(); + int line = sourcePosition.getLine(); + Pair key = Pair.create(file, line); + Set presentations = map.get(key); + if (presentations == null) { + presentations = new LinkedHashSet(); + map.put(key, presentations); + } + presentations.add(XValueNodeImpl.this); } - presentations.add(XValueNodeImpl.this); - } - }); + }); + } + catch (Exception ignore) { + } } updateText(); setLeaf(!hasChildren); From b35c04475bd45b3b28591d666e3a3be32de160a0 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Mon, 18 Aug 2014 14:11:27 +0400 Subject: [PATCH 16/25] inspections ui: CME fixed in ThreeStateCheckBoxRenderer --- .../ui/inspectionsTree/InspectionsConfigTreeTable.java | 4 ++-- .../codeInspection/ui/table/ScopesAndSeveritiesTable.java | 7 ++----- .../ui/table/ThreeStateCheckBoxRenderer.java | 7 ++++--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java index 92cb62f0f800..5607816ad13c 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java @@ -64,8 +64,8 @@ public class InspectionsConfigTreeTable extends TreeTable { final TableColumn isEnabledColumn = getColumnModel().getColumn(IS_ENABLED_COLUMN); isEnabledColumn.setMaxWidth(20); - isEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer(false)); - isEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer(true)); + isEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer()); + isEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer()); addMouseMotionListener(new MouseAdapter() { @Override diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java index 3733415fb530..385b764af027 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java @@ -20,11 +20,9 @@ import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInspection.ex.Descriptor; import com.intellij.codeInspection.ex.InspectionProfileImpl; import com.intellij.codeInspection.ex.ScopeToolState; -import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopupFactory; @@ -36,7 +34,6 @@ import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionConfigTr import com.intellij.psi.search.scope.packageSet.NamedScope; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.table.JBTable; -import com.intellij.ui.treeStructure.treetable.TreeTable; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import com.intellij.util.SmartList; @@ -77,8 +74,8 @@ public class ScopesAndSeveritiesTable extends JBTable { final TableColumn scopeEnabledColumn = columnModel.getColumn(SCOPE_ENABLED_COLUMN); scopeEnabledColumn.setMaxWidth(30); - scopeEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer(false)); - scopeEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer(true)); + scopeEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer()); + scopeEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer()); final TableColumn severityColumn = columnModel.getColumn(SEVERITY_COLUMN); severityColumn.setCellRenderer(SeverityRenderer.create(tableSettings.getInspectionProfile())); diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ThreeStateCheckBoxRenderer.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ThreeStateCheckBoxRenderer.java index 455e2a60cd19..9e2a4ead10f1 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ThreeStateCheckBoxRenderer.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ThreeStateCheckBoxRenderer.java @@ -27,6 +27,7 @@ import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import java.awt.*; import java.awt.event.*; +import java.util.ArrayList; import java.util.EventObject; import java.util.List; @@ -37,7 +38,7 @@ public class ThreeStateCheckBoxRenderer extends ThreeStateCheckBox implements Ta private final List myListeners = new SmartList(); - public ThreeStateCheckBoxRenderer(final boolean isEditor) { + public ThreeStateCheckBoxRenderer() { setThirdStateEnabled(false); setHorizontalAlignment(CENTER); setVerticalAlignment(CENTER); @@ -95,7 +96,7 @@ public class ThreeStateCheckBoxRenderer extends ThreeStateCheckBox implements Ta @Override public boolean stopCellEditing() { final ChangeEvent e = new ChangeEvent(this); - for (final CellEditorListener listener : myListeners) { + for (final CellEditorListener listener : new ArrayList(myListeners)) { listener.editingStopped(e); } return true; @@ -104,7 +105,7 @@ public class ThreeStateCheckBoxRenderer extends ThreeStateCheckBox implements Ta @Override public void cancelCellEditing() { final ChangeEvent e = new ChangeEvent(this); - for (final CellEditorListener listener : myListeners) { + for (final CellEditorListener listener : new ArrayList(myListeners)) { listener.editingCanceled(e); } } From a0e69b8c7c2609b868ddca9739506eb6b0774eaa Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Mon, 18 Aug 2014 14:25:55 +0400 Subject: [PATCH 17/25] progress icon shows in multiple places when scrolling --- .../src/com/intellij/util/ui/AsyncProcessIcon.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/platform/platform-api/src/com/intellij/util/ui/AsyncProcessIcon.java b/platform/platform-api/src/com/intellij/util/ui/AsyncProcessIcon.java index 3c3b42721b58..3d467232b3e3 100644 --- a/platform/platform-api/src/com/intellij/util/ui/AsyncProcessIcon.java +++ b/platform/platform-api/src/com/intellij/util/ui/AsyncProcessIcon.java @@ -71,7 +71,7 @@ public class AsyncProcessIcon extends AnimatedIcon { return icons; } - public void updateLocation(JComponent container) { + public void updateLocation(final JComponent container) { final Rectangle rec = container.getVisibleRect(); final Dimension iconSize = getPreferredSize(); @@ -79,7 +79,14 @@ public class AsyncProcessIcon extends AnimatedIcon { final Rectangle newBounds = new Rectangle(rec.x + rec.width - iconSize.width, rec.y, iconSize.width, iconSize.height); if (!newBounds.equals(getBounds())) { setBounds(newBounds); - container.repaint(); + // painting problems with scrollpane + // repaint shouldn't be called from paint method + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + container.repaint(); + } + }); } } From 87a984538a431963bffa6c347c74a4f0acaecad7 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Mon, 18 Aug 2014 14:28:32 +0400 Subject: [PATCH 18/25] IDEA-128661 NPE during inplace renaming variable --- .../impl/actions/PreviousVariableAction.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/actions/PreviousVariableAction.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/actions/PreviousVariableAction.java index bbb1f6a2bdf7..04a19bdd9b65 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/actions/PreviousVariableAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/actions/PreviousVariableAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 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. @@ -28,11 +28,12 @@ import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorAction; import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import org.jetbrains.annotations.NotNull; public class PreviousVariableAction extends EditorAction { public PreviousVariableAction() { @@ -42,16 +43,17 @@ public class PreviousVariableAction extends EditorAction { private static class Handler extends EditorWriteActionHandler { @Override - public void executeWriteAction(Editor editor, DataContext dataContext) { + public void executeWriteAction(Editor editor, Caret caret, DataContext dataContext) { final TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); + assert templateState != null; CommandProcessor.getInstance().setCurrentCommandName(CodeInsightBundle.message("template.previous.variable.command")); templateState.previousTab(); } - } - @Override - public void update(Editor editor, Presentation presentation, DataContext dataContext) { - final TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); - presentation.setEnabled(templateState != null && !templateState.isFinished()); + @Override + protected boolean isEnabledForCaret(@NotNull Editor editor, @NotNull Caret caret, DataContext dataContext) { + final TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); + return templateState != null && !templateState.isFinished(); + } } } From 81fc7616bfa0bcb0ffa3deb4af42483006ad4907 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 18 Aug 2014 13:15:15 +0400 Subject: [PATCH 19/25] forbid 'static'/'default' in annotation types --- .../codeInsight/daemon/impl/analysis/HighlightUtil.java | 5 +++++ .../AnnotationTypeExtensionsNotSupported.java | 9 +++++++++ .../daemon/lambda/Interface8MethodsHighlightingTest.java | 3 +++ 3 files changed, 17 insertions(+) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/AnnotationTypeExtensionsNotSupported.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 7404d1fbfae3..b85fb167f6e3 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -889,6 +889,11 @@ public class HighlightUtil extends HighlightUtilBase { PsiModifier.STRICTFP.equals(modifier) || PsiModifier.SYNCHRONIZED.equals(modifier)) { isAllowed &= modifierOwnerParent instanceof PsiClass && !((PsiClass)modifierOwnerParent).isInterface(); } + + if (containingClass != null && containingClass.isAnnotationType()) { + isAllowed &= !PsiModifier.STATIC.equals(modifier); + isAllowed &= !PsiModifier.DEFAULT.equals(modifier); + } } else if (modifierOwner instanceof PsiField) { if (PsiModifier.PRIVATE.equals(modifier) || PsiModifier.PROTECTED.equals(modifier) || PsiModifier.TRANSIENT.equals(modifier) || diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/AnnotationTypeExtensionsNotSupported.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/AnnotationTypeExtensionsNotSupported.java new file mode 100644 index 000000000000..258bf1132d5b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/AnnotationTypeExtensionsNotSupported.java @@ -0,0 +1,9 @@ +@interface Example { + + public static String myMethod() { + return ""; + } + public default String myMethod1() { + return ""; + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java index 95b3bfb7395d..2162b96db138 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java @@ -43,6 +43,9 @@ public class Interface8MethodsHighlightingTest extends LightCodeInsightFixtureTe public void testDefaultSupersInStaticContext() { doTest(false, false); } + public void testAnnotationTypeExtensionsNotSupported() { + doTest(false, false); + } public void testSuperProtectedCalls() throws Exception { myFixture.addClass("package p; public class Foo {" + From 2a41b7a9c30655bd2708218eb634ebb9d6a781de Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 18 Aug 2014 13:20:48 +0400 Subject: [PATCH 20/25] annotation type: error for duplicated methods (IDEA-128675) --- .../daemon/impl/analysis/HighlightVisitorImpl.java | 7 ++++++- .../daemonCodeAnalyzer/annotations/dupMethods.java | 4 ++++ .../codeInsight/daemon/AnnotationsHighlightingTest.java | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/dupMethods.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index df94270b16b8..095912a20094 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -257,8 +257,13 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } myHolder.add(AnnotationsHighlightUtil.checkValidAnnotationType(method.getReturnTypeElement())); - myHolder.add(AnnotationsHighlightUtil.checkCyclicMemberType(method.getReturnTypeElement(), method.getContainingClass())); + final PsiClass aClass = method.getContainingClass(); + myHolder.add(AnnotationsHighlightUtil.checkCyclicMemberType(method.getReturnTypeElement(), aClass)); myHolder.add(AnnotationsHighlightUtil.checkClashesWithSuperMethods(method)); + + if (!myHolder.hasErrorResults() && aClass != null) { + myHolder.add(HighlightMethodUtil.checkDuplicateMethod(aClass, method, getDuplicateMethods(aClass))); + } } @Override diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/dupMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/dupMethods.java new file mode 100644 index 000000000000..94744fa9be03 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/dupMethods.java @@ -0,0 +1,4 @@ +@interface Example { + public String myMethod(); + public int myMethod(); +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java index 964566fcf5ff..4421896b67c5 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java @@ -41,6 +41,7 @@ public class AnnotationsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testDuplicateTarget() { doTest(false); } public void testPingPongAnnotationTypesDependencies() { doTest(false);} public void testClashMethods() { doTest(false);} + public void testDupMethods() { doTest(false);} public void testInvalidPackageAnnotationTarget() { doTest(BASE_PATH + "/" + getTestName(true) + "/package-info.java", false, false); } public void testPackageAnnotationNotInPackageInfo() { doTest(BASE_PATH + "/" + getTestName(true) + "/notPackageInfo.java", false, false); } From 469ee0e4d5c2c64e83d32270976d0cf756c6cd32 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 18 Aug 2014 13:46:40 +0400 Subject: [PATCH 21/25] generate getter/setter via providers (IDEA-128662) --- .../JavaGenerateMemberCompletionContributor.java | 10 ++++------ .../daemon/impl/quickfix/CreateGetterOrSetterFix.java | 6 ++++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java index 7015004b7340..0deafb45cad9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java @@ -15,10 +15,7 @@ */ package com.intellij.codeInsight.completion; -import com.intellij.codeInsight.generation.GenerateMembersUtil; -import com.intellij.codeInsight.generation.OverrideImplementExploreUtil; -import com.intellij.codeInsight.generation.OverrideImplementUtil; -import com.intellij.codeInsight.generation.PsiGenerationInfo; +import com.intellij.codeInsight.generation.*; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.icons.AllIcons; @@ -35,6 +32,7 @@ import com.intellij.util.containers.ContainerUtil; import javax.swing.*; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -70,8 +68,8 @@ public class JavaGenerateMemberCompletionContributor { List prototypes = ContainerUtil.newArrayList(); for (PsiField field : parent.getFields()) { if (!(field instanceof PsiEnumConstant)) { - prototypes.add(GenerateMembersUtil.generateGetterPrototype(field)); - prototypes.add(GenerateMembersUtil.generateSetterPrototype(field)); + Collections.addAll(prototypes, GetterSetterPrototypeProvider.generateGetterSetters(field, true)); + Collections.addAll(prototypes, GetterSetterPrototypeProvider.generateGetterSetters(field, true)); } } for (final PsiMethod prototype : prototypes) { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterFix.java index 209dde6cf4ea..897c6f80a571 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterFix.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.codeInsight.generation.GenerateMembersUtil; +import com.intellij.codeInsight.generation.GetterSetterPrototypeProvider; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.intention.LowPriorityAction; import com.intellij.openapi.editor.Editor; @@ -29,6 +30,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -115,10 +117,10 @@ public class CreateGetterOrSetterFix implements IntentionAction, LowPriorityActi PsiClass aClass = myField.getContainingClass(); final List methods = new ArrayList(); if (myCreateGetter) { - methods.add(GenerateMembersUtil.generateGetterPrototype(myField)); + Collections.addAll(methods, GetterSetterPrototypeProvider.generateGetterSetters(myField, true)); } if (myCreateSetter) { - methods.add(GenerateMembersUtil.generateSetterPrototype(myField)); + Collections.addAll(methods, GetterSetterPrototypeProvider.generateGetterSetters(myField, false)); } for (PsiMethod method : methods) { aClass.add(method); From b5e4457cc9056323160ecde5ae1786299e2c480c Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Mon, 18 Aug 2014 14:49:56 +0400 Subject: [PATCH 22/25] ResourceBundlePropertyStructureViewElement#getValue() returns Property (instanceof PsiElement) => proper tree updating after property key renamed fixed --- ...rceBundlePropertyStructureViewElement.java | 5 +++-- .../structureView/GroupByWordPrefixes.java | 13 ++++++------ .../structureView/PropertiesPrefixGroup.java | 20 ++++++++----------- .../editor/ResourceBundleEditor.java | 4 ++-- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java index ed660536d052..724a794ca3bb 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java @@ -24,6 +24,7 @@ import com.intellij.lang.properties.IProperty; import com.intellij.lang.properties.PropertiesHighlighter; import com.intellij.lang.properties.PropertiesUtil; import com.intellij.lang.properties.ResourceBundle; +import com.intellij.lang.properties.psi.Property; import com.intellij.navigation.ColoredItemPresentation; import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.editor.colors.EditorColorsManager; @@ -69,8 +70,8 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView } @Override - public String getValue() { - return myProperty.getName(); + public Property getValue() { + return (Property)myProperty.getPsiElement(); } @Override diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/GroupByWordPrefixes.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/GroupByWordPrefixes.java index b67f6bfbea3f..efdbeaf3e863 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/GroupByWordPrefixes.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/GroupByWordPrefixes.java @@ -16,6 +16,7 @@ package com.intellij.lang.properties.structureView; import com.intellij.icons.AllIcons; +import com.intellij.ide.structureView.StructureViewTreeElement; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.ide.util.treeView.smartTree.*; import com.intellij.lang.properties.IProperty; @@ -65,14 +66,14 @@ public class GroupByWordPrefixes implements Grouper, Sorter { parentPrefixLength = 0; } for (TreeElement element : children) { - String text = null; - if (element instanceof PropertiesStructureViewElement) { - IProperty property = ((PropertiesStructureViewElement)element).getValue(); - text = property.getUnescapedKey(); + if (!(element instanceof StructureViewTreeElement)) { + continue; } - else if (element instanceof ResourceBundlePropertyStructureViewElement) { - text = ((ResourceBundlePropertyStructureViewElement)element).getValue(); + final Object value = ((StructureViewTreeElement)element).getValue(); + if (!(value instanceof IProperty)) { + continue; } + final String text = ((IProperty) value).getUnescapedKey(); if (text == null) continue; LOG.assertTrue(text.startsWith(parentPrefix) || text.startsWith(mySeparator)); List words = StringUtil.split(text, mySeparator); diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesPrefixGroup.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesPrefixGroup.java index 61b3c0202619..c4958502c25a 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesPrefixGroup.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesPrefixGroup.java @@ -16,11 +16,13 @@ package com.intellij.lang.properties.structureView; import com.intellij.icons.AllIcons; +import com.intellij.ide.structureView.StructureViewTreeElement; import com.intellij.ide.util.treeView.smartTree.Group; import com.intellij.ide.util.treeView.smartTree.TreeElement; import com.intellij.lang.properties.IProperty; import com.intellij.lang.properties.editor.ResourceBundleEditorViewElement; import com.intellij.lang.properties.editor.ResourceBundlePropertyStructureViewElement; +import com.intellij.lang.properties.psi.Property; import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; @@ -90,20 +92,14 @@ public class PropertiesPrefixGroup implements Group, ResourceBundleEditorViewEle Collection result = new ArrayList(); List prefixWords = StringUtil.split(myPrefix, mySeparator); for (TreeElement treeElement : myProperties) { - String key; - if (treeElement instanceof PropertiesStructureViewElement) { - PropertiesStructureViewElement propertiesElement = (PropertiesStructureViewElement)treeElement; - IProperty property = propertiesElement.getValue(); - - key = property.getUnescapedKey(); - } - else if (treeElement instanceof ResourceBundlePropertyStructureViewElement) { - key = ((ResourceBundlePropertyStructureViewElement)treeElement).getValue(); - } - else { + if (!(treeElement instanceof StructureViewTreeElement)) { continue; } - + final Object value = ((StructureViewTreeElement)treeElement).getValue(); + if (!(value instanceof IProperty)) { + continue; + } + final String key = ((IProperty) value).getUnescapedKey(); if (key == null || key.equals(myPrefix)) { continue; } diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java index 0339b09b8c88..39e9ed67e7b2 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java @@ -170,7 +170,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit TreeElement[] children = myStructureViewComponent.getTreeModel().getRoot().getChildren(); if (children.length != 0) { TreeElement child = children[0]; - String propName = ((ResourceBundlePropertyStructureViewElement)child).getValue(); + String propName = ((ResourceBundlePropertyStructureViewElement)child).getValue().getUnescapedKey(); setState(new ResourceBundleEditorState(propName)); } myDataProviderPanel = new DataProviderPanel(splitPanel); @@ -248,7 +248,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit DefaultMutableTreeNode node = toCheck.pop(); final ResourceBundleEditorViewElement element = getSelectedElement(node); String value = element instanceof ResourceBundlePropertyStructureViewElement - ? ((ResourceBundlePropertyStructureViewElement)element).getValue() + ? ((ResourceBundlePropertyStructureViewElement)element).getValue().getUnescapedKey() : null; if (propertyName.equals(value)) { nodeToSelect = node; From 8369db787853d0320cebdb9cb9b4596a0f163eef Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 18 Aug 2014 15:21:11 +0400 Subject: [PATCH 23/25] create from new: fix type parameters setup (IDEA-128679; IDEA-128682) --- .../daemon/impl/quickfix/CreateFromUsageBaseFix.java | 2 +- .../impl/quickfix/CreateInnerClassFromNewFix.java | 3 +-- .../createInnerClassFromNew/afterTypeParamSetup.java | 11 +++++++++++ .../createInnerClassFromNew/afterTypeParamSetup1.java | 11 +++++++++++ .../createInnerClassFromNew/beforeTypeParamSetup.java | 6 ++++++ .../beforeTypeParamSetup1.java | 6 ++++++ 6 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/afterTypeParamSetup.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/afterTypeParamSetup1.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeTypeParamSetup.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeTypeParamSetup1.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java index abe9368374e8..9e8684899939 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java @@ -475,7 +475,7 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction { } else { while (true) { final String paramName = idx > 0 ? "T" + idx : "T"; - if (!typeParamNames.contains(paramName)) { + if (typeParamNames.add(paramName)) { targetClass.getTypeParameterList().add(factory.createTypeParameterFromText(paramName, null)); break; } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateInnerClassFromNewFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateInnerClassFromNewFix.java index 55fe7664d0b0..333ca47b014c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateInnerClassFromNewFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateInnerClassFromNewFix.java @@ -67,9 +67,8 @@ public class CreateInnerClassFromNewFix extends CreateClassFromNewFix { } created = (PsiClass)targetClass.add(created); - setupClassFromNewExpression(created, newExpression); - setupGenericParameters(created, ref); + setupClassFromNewExpression(created, newExpression); } private static boolean isInThisOrSuperCall(PsiNewExpression newExpression) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/afterTypeParamSetup.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/afterTypeParamSetup.java new file mode 100644 index 000000000000..9d516996894c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/afterTypeParamSetup.java @@ -0,0 +1,11 @@ +// "Create Inner Class 'AInner'" "true" +class Test { + { + AInner aInner = new AInner(42); + } + + private class AInner { + public AInner(int i) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/afterTypeParamSetup1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/afterTypeParamSetup1.java new file mode 100644 index 000000000000..aac015e28360 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/afterTypeParamSetup1.java @@ -0,0 +1,11 @@ +// "Create Inner Class 'AInner'" "true" +class Test { + { + AInner aInner = new AInner(42); + } + + private class AInner { + public AInner(int i) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeTypeParamSetup.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeTypeParamSetup.java new file mode 100644 index 000000000000..1d26d9d55357 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeTypeParamSetup.java @@ -0,0 +1,6 @@ +// "Create Inner Class 'AInner'" "true" +class Test { + { + AInner aInner = new AInner(42); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeTypeParamSetup1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeTypeParamSetup1.java new file mode 100644 index 000000000000..bf0997aed99e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeTypeParamSetup1.java @@ -0,0 +1,6 @@ +// "Create Inner Class 'AInner'" "true" +class Test { + { + AInner aInner = new AInner(42); + } +} \ No newline at end of file From 900b80451e5757ba308c56c0e2e5a470ba068a1e Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Mon, 18 Aug 2014 15:28:03 +0400 Subject: [PATCH 24/25] ability to show busy icon if needed --- .../src/com/intellij/ui/treeStructure/Tree.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java index 3551f9db3dc7..c8c50bc94680 100644 --- a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java +++ b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java @@ -283,7 +283,7 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith if (myBusyIcon != null) { if (myBusy) { - if (hasFocus()) { + if (shouldShowBusyIconIfNeeded()) { myBusyIcon.resume(); myBusyIcon.setToolTipText("Update is in progress. Click to cancel"); } @@ -305,6 +305,11 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith } } + protected boolean shouldShowBusyIconIfNeeded() { + // http://youtrack.jetbrains.com/issue/IDEA-101422 "Rotating wait symbol in Project list whenever typing" + return hasFocus(); + } + protected boolean paintNodes() { return false; } From 0a5c8d741b8ac37d209eb74523dd65f0e623a31b Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 18 Aug 2014 15:25:24 +0400 Subject: [PATCH 25/25] IDEA-128539 web.xml: highlight usages in file should highlight all occurrences of servlet-name re-fixed --- .../com/intellij/util/xml/ClassMappingNameConverter.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/java/openapi/src/com/intellij/util/xml/ClassMappingNameConverter.java b/java/openapi/src/com/intellij/util/xml/ClassMappingNameConverter.java index 609605b32a25..1e296e4d3523 100644 --- a/java/openapi/src/com/intellij/util/xml/ClassMappingNameConverter.java +++ b/java/openapi/src/com/intellij/util/xml/ClassMappingNameConverter.java @@ -26,6 +26,7 @@ import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.util.PsiTypesUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.Collection; @@ -77,4 +78,12 @@ public class ClassMappingNameConverter extends ResolvingConverter.StringConverte assert parent != null; return parent.getXmlElement(); } + + @Override + public boolean isReferenceTo(@NotNull PsiElement element, + String stringValue, + @Nullable String resolveResult, + ConvertContext context) { + return element.getManager().areElementsEquivalent(element, resolve(stringValue, context)); + } }