From ad2de9feca73ee35d60502228c4e99f3a396c133 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 20 Feb 2017 08:20:43 +0100 Subject: [PATCH 01/38] no stubs in deleted files (EA-96420 - IVFAE: PersistentFSImpl.getFileId) --- .../core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index a044a58b4309..1c3e2ecf2674 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -682,7 +682,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF if (getElementTypeForStubBuilder() == null) return null; final VirtualFile vFile = getVirtualFile(); - if (!(vFile instanceof VirtualFileWithId)) return null; + if (!(vFile instanceof VirtualFileWithId) || !vFile.isValid()) return null; ObjectStubTree tree = StubTreeLoader.getInstance().readOrBuild(getProject(), vFile, this); if (!(tree instanceof StubTree)) return null; From b72443262bddef7b2b7bb6653439f93c8ac1cd0d Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 20 Feb 2017 08:23:20 +0100 Subject: [PATCH 02/38] really disable usage view buttons in dumb mode (EA-97020 - INRE: FileBasedIndexImpl.handleDumbMode) --- .../com/intellij/usages/impl/UsageViewImpl.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java index 4f0f6b663bfd..4f3f67796613 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java @@ -1724,8 +1724,18 @@ public class UsageViewImpl implements UsageView { final JButton button = new JButton(UIUtil.replaceMnemonicAmpersand(text)); DialogUtil.registerMnemonic(button); - DumbService.getInstance(myProject).makeDumbAware(button, UsageViewImpl.this); - + getProject().getMessageBus().connect(UsageViewImpl.this).subscribe(DumbService.DUMB_MODE, new DumbService.DumbModeListener() { + @Override + public void enteredDumbMode() { + update(); + } + + @Override + public void exitDumbMode() { + update(); + } + }); + button.setFocusable(false); button.addActionListener(e -> runnable.run()); @@ -1742,7 +1752,7 @@ public class UsageViewImpl implements UsageView { Component component = getComponent(i); if (component instanceof JButton) { final JButton button = (JButton)component; - button.setEnabled(!isSearchInProgress()); + button.setEnabled(!isSearchInProgress() && !DumbService.isDumb(myProject)); } } } From 1180ce8a663152bbf2c0225397d02f5cc48a2188 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 20 Feb 2017 08:25:36 +0100 Subject: [PATCH 03/38] SpecifyTypeInDocstringIntention: show dialog outside write action (EA-97214 - assert: NoSwingUnderWriteAction.lambda$watchForEvents$) --- .../SpecifyTypeInDocstringIntention.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInDocstringIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInDocstringIntention.java index 9ca526ef072e..fe40968f767b 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInDocstringIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInDocstringIntention.java @@ -15,6 +15,7 @@ */ package com.jetbrains.python.codeInsight.intentions; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; @@ -77,6 +78,17 @@ public class SpecifyTypeInDocstringIntention extends TypeIntention { } } + @Override + public boolean startInWriteAction() { + return false; + } + + @Nullable + @Override + public PsiElement getElementToMakeWritable(@NotNull PsiFile currentFile) { + return currentFile; + } + private static void generateDocstring(@Nullable PyNamedParameter param, @NotNull PyFunction pyFunction) { if (!DocStringUtil.ensureNotPlainDocstringFormat(pyFunction)) { return; @@ -100,8 +112,10 @@ public class SpecifyTypeInDocstringIntention extends TypeIntention { docstringGenerator.withReturnValue(type); } - docstringGenerator.addFirstEmptyLine().buildAndInsert(); - docstringGenerator.startTemplate(); + WriteAction.run(() -> { + docstringGenerator.addFirstEmptyLine().buildAndInsert(); + docstringGenerator.startTemplate(); + }); } @Override From 31c7b7a54fef0fb742676ccf9c3413320267e581 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 20 Feb 2017 08:41:31 +0100 Subject: [PATCH 04/38] py fragment validity shouldn't depend on contxet validity (EA-89617 - PIEAE: PsiUtilCore.ensureValid) --- .../python/psi/impl/PyExpressionCodeFragmentImpl.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/impl/PyExpressionCodeFragmentImpl.java b/python/src/com/jetbrains/python/psi/impl/PyExpressionCodeFragmentImpl.java index 324fde700ddc..e0464cab6926 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyExpressionCodeFragmentImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyExpressionCodeFragmentImpl.java @@ -25,7 +25,6 @@ import com.intellij.psi.impl.file.impl.FileManager; import com.intellij.psi.impl.source.tree.FileElement; import com.intellij.testFramework.LightVirtualFile; import com.jetbrains.python.psi.PyExpressionCodeFragment; -import com.jetbrains.python.psi.PyUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -66,12 +65,6 @@ public class PyExpressionCodeFragmentImpl extends PyFileImpl implements PyExpres return super.getViewProvider(); } - public boolean isValid() { - if (!super.isValid()) return false; - if (myContext != null && !myContext.isValid()) return false; - return true; - } - public boolean isPhysical() { return myPhysical; } From 12d9a2e6c71083524a7ff9bef0fea186badc567e Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Mon, 20 Feb 2017 11:07:10 +0300 Subject: [PATCH 05/38] IDEA-168452 Backspace does not change cursor position --- .../openapi/wm/impl/status/PositionPanel.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java index 9a1f17715770..70cca110ea70 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -17,10 +17,7 @@ package com.intellij.openapi.wm.impl.status; import com.intellij.ide.util.GotoLineNumberDialog; import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.EditorFactory; -import com.intellij.openapi.editor.LogicalPosition; -import com.intellij.openapi.editor.SelectionModel; +import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.event.*; import com.intellij.openapi.fileEditor.FileEditorManagerEvent; import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; @@ -36,7 +33,8 @@ import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; -public class PositionPanel extends EditorBasedWidget implements StatusBarWidget.Multiframe, StatusBarWidget.TextPresentation, CaretListener, SelectionListener { +public class PositionPanel extends EditorBasedWidget + implements StatusBarWidget.Multiframe, StatusBarWidget.TextPresentation, CaretListener, SelectionListener, DocumentListener { private static final int CHAR_COUNT_SYNC_LIMIT = 500_000; private static final String CHAR_COUNT_UNKNOWN = "..."; @@ -112,6 +110,7 @@ public class PositionPanel extends EditorBasedWidget implements StatusBarWidget. final EditorEventMulticaster multicaster = EditorFactory.getInstance().getEventMulticaster(); multicaster.addCaretListener(this, this); multicaster.addSelectionListener(this, this); + multicaster.addDocumentListener(this, this); } @Override @@ -135,6 +134,22 @@ public class PositionPanel extends EditorBasedWidget implements StatusBarWidget. updatePosition(e.getEditor()); } + @Override + public void beforeDocumentChange(DocumentEvent event) {} + + @Override + public void documentChanged(DocumentEvent event) { + Document document = event.getDocument(); + Editor[] editors = EditorFactory.getInstance().getEditors(document); + Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + for (Editor editor : editors) { + if (editor.getContentComponent() == focusOwner) { + updatePosition(editor); + break; + } + } + } + private void updatePosition(final Editor editor) { if (editor == null) { myText = ""; From cd5abb4339597ffe805f5c90fa5c178ba53da49d Mon Sep 17 00:00:00 2001 From: Valentina Kiryushkina Date: Sun, 22 Jan 2017 21:46:54 +0300 Subject: [PATCH 06/38] EDU-834 Support theory tasks from adaptive course --- .../jetbrains/edu/learning/StudyUtils.java | 6 +-- .../edu/learning/checker/StudyCheckTask.java | 20 ++++++++- ...eters.java => AdaptiveTaskParameters.java} | 11 ++++- .../edu/learning/courseFormat/Task.java | 43 ++++++++++++------- .../stepic/EduAdaptiveStepicConnector.java | 36 +++++++++++----- .../stepic/StepicAdaptiveReactionsPanel.java | 9 ++-- .../edu/learning/ui/StudyToolWindow.java | 2 - 7 files changed, 91 insertions(+), 36 deletions(-) rename python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/{ChoiceParameters.java => AdaptiveTaskParameters.java} (79%) diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java index 043bef13905e..b9e3debed96c 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java @@ -501,7 +501,7 @@ public class StudyUtils { if (text == null) return null; text = convertToHtml(text); - if (course.isAdaptive() && !task.isChoiceTask()) text = wrapAdaptiveCourseText(text); + if (course.isAdaptive() && !task.isChoiceTask() && !task.isTheoryTask()) text = wrapAdaptiveCourseText(text); return wrapTextToDisplayLatex(text); } @@ -780,9 +780,9 @@ public class StudyUtils { return FileDocumentManager.getInstance().getDocument(taskFile); } - public static void showErrorPopupOnToolbar(@NotNull Project project) { + public static void showErrorPopupOnToolbar(@NotNull Project project, String content) { final Balloon balloon = - JBPopupFactory.getInstance().createHtmlTextBalloonBuilder("Couldn't post your reaction", MessageType.ERROR, null).createBalloon(); + JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(content, MessageType.ERROR, null).createBalloon(); showCheckPopUp(project, balloon); } diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java b/python/educational-core/student/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java index b2ee1e17b4b3..e74bfdd19cd7 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java @@ -24,6 +24,7 @@ import com.jetbrains.edu.learning.courseFormat.*; import com.jetbrains.edu.learning.stepic.EduAdaptiveStepicConnector; import com.jetbrains.edu.learning.stepic.EduStepicConnector; import com.jetbrains.edu.learning.stepic.StepicUpdateSettings; +import com.jetbrains.edu.learning.stepic.StepicUser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -148,6 +149,23 @@ public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroun final Pair result = EduAdaptiveStepicConnector.checkChoiceTask(myProject, myTask); processStepicCheckOutput(indicator, result); } + else if (myTask.isTheoryTask()) { + final int lessonId = myTask.getLesson().getId(); + final StepicUser user = StepicUpdateSettings.getInstance().getUser(); + final boolean reactionPosted = EduAdaptiveStepicConnector.postRecommendationReaction(String.valueOf(lessonId), + String.valueOf(user.getId()), + EduAdaptiveStepicConnector.NEXT_RECOMMENDATION_REACTION); + if (reactionPosted) { + if (myStatusBeforeCheck != StudyStatus.Solved) { + myTask.setStatus(StudyStatus.Solved); + EduAdaptiveStepicConnector.addNextRecommendedTask(myProject, indicator, EduAdaptiveStepicConnector.NEXT_RECOMMENDATION_REACTION); + } + } + else { + ApplicationManager.getApplication().invokeLater(() -> + StudyUtils.showErrorPopupOnToolbar(myProject, "Unable to get next recommendation")); + } + } else { final StudyTestsOutputParser.TestsOutput testOutput = getTestOutput(indicator); if (testOutput != null) { @@ -169,7 +187,7 @@ public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroun if (pair.getFirst()) { onTaskSolved("Congratulations! Remote tests passed."); if (myStatusBeforeCheck != StudyStatus.Solved) { - EduAdaptiveStepicConnector.addNextRecommendedTask(myProject, indicator, 2); + EduAdaptiveStepicConnector.addNextRecommendedTask(myProject, indicator, EduAdaptiveStepicConnector.NEXT_RECOMMENDATION_REACTION); } } else { diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/ChoiceParameters.java b/python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/AdaptiveTaskParameters.java similarity index 79% rename from python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/ChoiceParameters.java rename to python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/AdaptiveTaskParameters.java index 6f833e511278..cefcb18b1df9 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/ChoiceParameters.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/AdaptiveTaskParameters.java @@ -6,10 +6,11 @@ import com.google.gson.annotations.SerializedName; import java.util.ArrayList; import java.util.List; -public class ChoiceParameters { +public class AdaptiveTaskParameters { @Expose @SerializedName("choice_variants") private List myChoiceVariants = new ArrayList<>(); @Expose @SerializedName("is_multichoice") private boolean myIsMultipleChoice; @SerializedName("selected_variants") private List mySelectedVariants = new ArrayList<>(); + @Expose @SerializedName("is_theory_task") private boolean isTheoryTask = false; public List getSelectedVariants() { return mySelectedVariants; @@ -34,4 +35,12 @@ public class ChoiceParameters { public void setChoiceVariants(List choiceVariants) { myChoiceVariants = choiceVariants; } + + public boolean isTheoryTask() { + return isTheoryTask; + } + + public void setTheoryTask(boolean theoryTask) { + isTheoryTask = theoryTask; + } } diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/Task.java b/python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/Task.java index 6645209de07a..d2b794d743f0 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/Task.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/Task.java @@ -44,7 +44,7 @@ public class Task implements StudyItem { @Transient private Lesson myLesson; @Expose @SerializedName("update_date") private Date myUpdateDate; - @Expose @SerializedName("choice_parameters") private ChoiceParameters myChoiceParameters; + @Expose @SerializedName("choice_parameters") private AdaptiveTaskParameters myAdaptiveTaskParameters; private int myActiveSubtaskIndex = 0; @SerializedName("last_subtask_index") @Expose private int myLastSubtaskIndex = 0; @@ -57,7 +57,7 @@ public class Task implements StudyItem { public static Task createChoiceTask(@NotNull String name) { final Task task = new Task(name); - task.setChoiceParameters(new ChoiceParameters()); + task.setAdaptiveTaskParameters(new AdaptiveTaskParameters()); return task; } @@ -307,48 +307,59 @@ public class Task implements StudyItem { @Transient @NotNull public List getChoiceVariants() { - return myChoiceParameters.getChoiceVariants(); + return myAdaptiveTaskParameters.getChoiceVariants(); } @Transient public void setChoiceVariants(List choiceVariants) { - myChoiceParameters.setChoiceVariants(choiceVariants); + myAdaptiveTaskParameters.setChoiceVariants(choiceVariants); } @Transient public boolean isMultipleChoice() { - return myChoiceParameters.isMultipleChoice(); + return myAdaptiveTaskParameters.isMultipleChoice(); } @Transient public void setMultipleChoice(boolean multipleChoice) { - myChoiceParameters.setMultipleChoice(multipleChoice); + myAdaptiveTaskParameters.setMultipleChoice(multipleChoice); } @Transient public List getSelectedVariants() { - return myChoiceParameters.getSelectedVariants(); + return myAdaptiveTaskParameters.getSelectedVariants(); } @Transient public void setSelectedVariants(List selectedVariants) { - myChoiceParameters.setSelectedVariants(selectedVariants); + myAdaptiveTaskParameters.setSelectedVariants(selectedVariants); } public boolean isChoiceTask() { - return myChoiceParameters != null; + return myAdaptiveTaskParameters != null && !myAdaptiveTaskParameters.getChoiceVariants().isEmpty(); + } + + public boolean isTheoryTask() { + return myAdaptiveTaskParameters != null && myAdaptiveTaskParameters.isTheoryTask(); + } + + public void setTheoryTask(boolean isTheoryTask) { + if (myAdaptiveTaskParameters == null) { + myAdaptiveTaskParameters = new AdaptiveTaskParameters(); + } + myAdaptiveTaskParameters.setTheoryTask(isTheoryTask); } // used for serialization @SuppressWarnings("unused") - public ChoiceParameters getChoiceParameters() { - return myChoiceParameters; + public AdaptiveTaskParameters getAdaptiveTaskParameters() { + return myAdaptiveTaskParameters; } // used for serialization @SuppressWarnings("unused") - public void setChoiceParameters(ChoiceParameters choiceParameters) { - myChoiceParameters = choiceParameters; + public void setAdaptiveTaskParameters(AdaptiveTaskParameters adaptiveTaskParameters) { + myAdaptiveTaskParameters = adaptiveTaskParameters; } public void copyParametersOf(@NotNull Task task) { @@ -357,12 +368,14 @@ public class Task implements StudyItem { setText(task.getText()); getTestsText().clear(); setStatus(StudyStatus.Unchecked); - if (task.isChoiceTask()) { + setTheoryTask(task.isTheoryTask()); + if (task.isChoiceTask() || task.isTheoryTask()) { setChoiceVariants(task.getChoiceVariants()); setMultipleChoice(task.isMultipleChoice()); + setTheoryTask(task.isTheoryTask()); } else { - setChoiceParameters(null); + setAdaptiveTaskParameters(null); } final Map testsText = task.getTestsText(); for (String testName : testsText.keySet()) { diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduAdaptiveStepicConnector.java b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduAdaptiveStepicConnector.java index 0191176175be..649b5c7585ba 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduAdaptiveStepicConnector.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduAdaptiveStepicConnector.java @@ -59,10 +59,14 @@ public class EduAdaptiveStepicConnector { public static final String PYTHON2 = "python2"; public static final String PYTHON3 = "python3"; public static final String PYCHARM_COMMENT = "# Posted from PyCharm Edu\n"; + public static final int NEXT_RECOMMENDATION_REACTION = 2; + public static final int TOO_HARD_RECOMMENDATION_REACTION = 0; + public static final int TOO_BORING_RECOMMENDATION_REACTION = -1; private static final Logger LOG = Logger.getInstance(EduAdaptiveStepicConnector.class); private static final int CONNECTION_TIMEOUT = 60 * 1000; private static final String CODE_TASK_TYPE = "code"; private static final String CHOICE_TYPE_TEXT = "choice"; + private static final String TEXT_STEP_TYPE = "text"; @Nullable public static Task getNextRecommendation(@NotNull Project project, @NotNull Course course) { @@ -104,7 +108,7 @@ public class EduAdaptiveStepicConnector { final StepicUser user = StepicUpdateSettings.getInstance().getUser(); postRecommendationReaction(lessonId, - String.valueOf(user.getId()), -1); + String.valueOf(user.getId()), TOO_BORING_RECOMMENDATION_REACTION); return getNextRecommendation(project, course); } else { @@ -151,9 +155,22 @@ public class EduAdaptiveStepicConnector { else if (stepType.startsWith(EduStepicConnector.PYCHARM_PREFIX)) { return EduStepicConnector.createTask(stepId); } + else if (stepType.equals(TEXT_STEP_TYPE)) { + return getTheoryTaskFromStep(name, step.block, stepId); + } return null; } + + private static Task getTheoryTaskFromStep(@NotNull String lessonName, @NotNull StepicWrappers.Step block, int stepId) { + final Task task = new Task(lessonName); + task.setStepId(stepId); + task.setText(block.text); + task.setTheoryTask(true); + + createMockTaskFile(task); + return task; + } private static Task getChoiceTaskFromStep(@NotNull String lessonName, @NotNull StepicWrappers.Step block, @@ -174,11 +191,11 @@ public class EduAdaptiveStepicConnector { } } - createMockTaskFileForChoiceProblem(task); + createMockTaskFile(task); return task; } - private static void createMockTaskFileForChoiceProblem(@NotNull Task task) { + private static void createMockTaskFile(@NotNull Task task) { final TaskFile taskFile = new TaskFile(); taskFile.text = "# you can experiment here, it won't be checked"; taskFile.name = "code"; @@ -289,7 +306,7 @@ public class EduAdaptiveStepicConnector { final Lesson adaptive = course.getLessons().get(0); final Task unsolvedTask = adaptive.getTaskList().get(adaptive.getTaskList().size() - 1); final String lessonName = EduNames.LESSON + String.valueOf(adaptive.getIndex()); - if (reaction == 0 || reaction == -1) { + if (reaction == TOO_HARD_RECOMMENDATION_REACTION || reaction == TOO_BORING_RECOMMENDATION_REACTION) { unsolvedTask.copyParametersOf(task); final Map taskFiles = task.getTaskFiles(); @@ -299,8 +316,7 @@ public class EduAdaptiveStepicConnector { ApplicationManager.getApplication().invokeLater(() -> ApplicationManager.getApplication().runWriteAction(() -> { final Document document = editor.getEditor().getDocument(); - final String taskFileText = taskFiles.get(EduStepicNames.DEFAULT_TASKFILE_NAME).text; - document.setText(taskFileText); + document.setText(taskFile.text); })); } else { @@ -315,7 +331,7 @@ public class EduAdaptiveStepicConnector { final VirtualFile lessonDir = project.getBaseDir().findChild(lessonName); if (lessonDir != null) { - createTestFiles(course, task, unsolvedTask, lessonDir); + createTestFiles(course, project, unsolvedTask, lessonDir); } final StudyToolWindow window = StudyUtils.getStudyToolWindow(project); if (window != null) { @@ -361,12 +377,12 @@ public class EduAdaptiveStepicConnector { } else { LOG.warn("Recommendation reactions weren't posted"); - ApplicationManager.getApplication().invokeLater(() -> StudyUtils.showErrorPopupOnToolbar(project)); + ApplicationManager.getApplication().invokeLater(() -> StudyUtils.showErrorPopupOnToolbar(project, "Couldn't post your reaction")); } } } - private static void createTestFiles(@NotNull Course course, @NotNull Task task, + private static void createTestFiles(@NotNull Course course, @NotNull Project project, @NotNull Task unsolvedTask, @NotNull VirtualFile lessonDir) { ApplicationManager.getApplication().invokeLater(() -> ApplicationManager.getApplication().runWriteAction(() -> { try { @@ -380,7 +396,7 @@ public class EduAdaptiveStepicConnector { if (filesInTask != null) { for (File file : filesInTask) { final String taskRelativePath = FileUtil.getRelativePath(taskDir.getPath(), file.getPath(), '/'); - if (taskRelativePath != null && !task.isTaskFile(taskRelativePath)) { + if (taskRelativePath != null && StudyUtils.isTestsFile(project, taskDir.getName())) { final File resourceFile = new File(newResourceRoot, taskRelativePath); final File fileInProject = new File(taskDir.getCanonicalPath(), taskRelativePath); FileUtil.copy(resourceFile, fileInProject); diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicAdaptiveReactionsPanel.java b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicAdaptiveReactionsPanel.java index f76bc589434b..ec6fde47a403 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicAdaptiveReactionsPanel.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicAdaptiveReactionsPanel.java @@ -19,13 +19,14 @@ import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import static com.jetbrains.edu.learning.stepic.EduAdaptiveStepicConnector.TOO_BORING_RECOMMENDATION_REACTION; +import static com.jetbrains.edu.learning.stepic.EduAdaptiveStepicConnector.TOO_HARD_RECOMMENDATION_REACTION; + public class StepicAdaptiveReactionsPanel extends JPanel { private final ReactionButtonPanel myHardPanel; private final ReactionButtonPanel myBoringPanel; @NotNull private final Project myProject; - private static final int TOO_HARD_REACTION = 0; - private static final int TOO_BORING_REACTION = -1; private static final String HARD_REACTION = "Too Hard"; private static final String BORING_REACTION = "Too Boring"; private static final String SOLVED_TASK_TOOLTIP = "Reaction Disabled Due To Task Is Solved"; @@ -37,8 +38,8 @@ public class StepicAdaptiveReactionsPanel extends JPanel { setLayout(new GridBagLayout()); setBackground(UIUtil.getTextFieldBackground()); - myHardPanel = new ReactionButtonPanel(HARD_REACTION, HARD_LABEL_TOOLTIP, TOO_HARD_REACTION); - myBoringPanel = new ReactionButtonPanel(BORING_REACTION, BORING_LABEL_TOOLTIP, TOO_BORING_REACTION); + myHardPanel = new ReactionButtonPanel(HARD_REACTION, HARD_LABEL_TOOLTIP, TOO_HARD_RECOMMENDATION_REACTION); + myBoringPanel = new ReactionButtonPanel(BORING_REACTION, BORING_LABEL_TOOLTIP, TOO_BORING_RECOMMENDATION_REACTION); addFileListener(); final GridBagConstraints c = new GridBagConstraints(); diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java b/python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java index 3cbc26a11b9b..dede22335891 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java @@ -149,8 +149,6 @@ public abstract class StudyToolWindow extends SimpleToolWindowPanel implements D myCardLayout.swipe(myContentPanel, panelId, JBCardLayout.SwipeDirection.AUTO); } - //used in checkiO plugin. - @SuppressWarnings("unused") public void setBottomComponent(JComponent component) { mySplitPane.setSecondComponent(component); } From 6eb59a3e30312b845e5f65aa2a9747e98fdaa349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20C=C3=A9bron?= Date: Mon, 20 Feb 2017 09:48:30 +0100 Subject: [PATCH 07/38] EA-97241 - assert: FileManagerImpl.findFile --- .../com/intellij/xml/config/ConfigFilesTreeBuilder.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/xml/impl/src/com/intellij/xml/config/ConfigFilesTreeBuilder.java b/xml/impl/src/com/intellij/xml/config/ConfigFilesTreeBuilder.java index 01c6b653b0b3..82d07432841f 100644 --- a/xml/impl/src/com/intellij/xml/config/ConfigFilesTreeBuilder.java +++ b/xml/impl/src/com/intellij/xml/config/ConfigFilesTreeBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -108,7 +108,8 @@ public class ConfigFilesTreeBuilder { moduleNode.add(fileTypeNode); addChildrenFiles(psiFiles, fileTypeNode, new ArrayList<>(entry.getValue())); } - } else { + } + else { addChildrenFiles(psiFiles, moduleNode, moduleFiles); } } @@ -117,6 +118,7 @@ public class ConfigFilesTreeBuilder { List sortedJars = new ArrayList<>(jars.keySet()); Collections.sort(sortedJars, (o1, o2) -> StringUtil.naturalCompare(o1.getName(), o2.getName())); for (VirtualFile file : sortedJars) { + if (!file.isValid()) continue; final List list = new ArrayList<>(jars.get(file)); final PsiFile jar = list.get(0).getManager().findFile(file); if (jar != null) { @@ -133,7 +135,7 @@ public class ConfigFilesTreeBuilder { } private static String getFileTypeNodeName(FileType fileType) { - return fileType.getName() + " context files" ; + return fileType.getName() + " context files"; } private static boolean hasNonEmptyGroups(MultiMap filesByType) { From fb6f8e1d7e059d3ae18066d625b9fe2500451577 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Mon, 20 Feb 2017 12:14:04 +0300 Subject: [PATCH 08/38] schemes ui: fix for focus request on scheme name edit --- .../application/options/schemes/EditableSchemesCombo.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/schemes/EditableSchemesCombo.java b/platform/lang-impl/src/com/intellij/application/options/schemes/EditableSchemesCombo.java index e96582e51f4d..4b8c882cb663 100644 --- a/platform/lang-impl/src/com/intellij/application/options/schemes/EditableSchemesCombo.java +++ b/platform/lang-impl/src/com/intellij/application/options/schemes/EditableSchemesCombo.java @@ -17,6 +17,7 @@ package com.intellij.application.options.schemes; import com.intellij.openapi.options.Scheme; import com.intellij.openapi.ui.MessageType; +import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.DocumentAdapter; import com.intellij.ui.JBColor; import com.intellij.ui.SimpleTextAttributes; @@ -144,7 +145,8 @@ public class EditableSchemesCombo { public void cancelEdit() { mySchemesPanel.clearInfo(); myLayout.first(myRootPanel); - myRootPanel.requestFocus(); + final IdeFocusManager focusManager = IdeFocusManager.getGlobalInstance(); + focusManager.doWhenFocusSettlesDown(() -> IdeFocusManager.getGlobalInstance().requestFocus(myRootPanel, true)); } private void createCombo() { @@ -186,7 +188,8 @@ public class EditableSchemesCombo { showHint(); myNameEditorField.setText(scheme.getName()); myLayout.last(myRootPanel); - myNameEditorField.requestFocus(); + final IdeFocusManager focusManager = IdeFocusManager.getGlobalInstance(); + focusManager.doWhenFocusSettlesDown(() -> focusManager.requestFocus(myNameEditorField, true)); } } From 81f33d803513c74294738ddda2daadf584bc19a8 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 20 Feb 2017 12:10:51 +0300 Subject: [PATCH 09/38] ui: remove accidential changes this commit partially reverts 1ca47c961936721b7845a151e81a095d5a5b7519 --- platform/platform-resources/src/idea/PlatformActions.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index b609625ace03..329ae7f28f01 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -574,6 +574,12 @@ + + + + + + @@ -700,7 +706,7 @@ - + From 57e185e4813d7dc0a98e4ece9190e210bd806957 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Mon, 20 Feb 2017 12:20:35 +0300 Subject: [PATCH 10/38] obligate SyntheticLibrary inheritors to implement equals/hashCode (IDEA-CR-18386) --- .../openapi/roots/SyntheticLibrary.java | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/SyntheticLibrary.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/SyntheticLibrary.java index 0a3a34b373f9..2c1bb57899fc 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/SyntheticLibrary.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/SyntheticLibrary.java @@ -65,20 +65,13 @@ public abstract class SyntheticLibrary { * changed (use some caching in {@link AdditionalLibraryRootsProvider#getAdditionalProjectLibraries(Project)}). */ @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - SyntheticLibrary library = (SyntheticLibrary)o; - return getSourceRoots().equals(library.getSourceRoots()); - } + public abstract boolean equals(Object o); /** * @see #equals(Object) javadoc */ @Override - public int hashCode() { - return getSourceRoots().hashCode(); - } + public abstract int hashCode(); @NotNull public static SyntheticLibrary newImmutableLibrary(@NotNull Collection sourceRoots) { @@ -88,6 +81,19 @@ public abstract class SyntheticLibrary { public Collection getSourceRoots() { return sourceRoots; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SyntheticLibrary library = (SyntheticLibrary)o; + return getSourceRoots().equals(library.getSourceRoots()); + } + + @Override + public int hashCode() { + return sourceRoots.hashCode(); + } }; } } From 9b4896ae0cdde1e47fffc946bf57d33827e86515 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 20 Feb 2017 10:40:16 +0100 Subject: [PATCH 11/38] Cleanup (simpler annotation tests) --- .../daemon/AnnotationsHighlightingTest.java | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) 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 6cf7c1c6d20a..87a29afac391 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -23,7 +23,7 @@ import com.intellij.pom.java.LanguageLevel; public class AnnotationsHighlightingTest extends LightDaemonAnalyzerTestCase { private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/annotations"; - public void testWrongPlace() { doTest(); } + public void testWrongPlace() { setLanguageLevel(LanguageLevel.JDK_1_7); doTest(); } public void testNotValueNameOmitted() { doTest(); } public void testCannotFindMethod() { doTest(); } public void testIncompatibleType1() { doTest(); } @@ -32,7 +32,7 @@ public class AnnotationsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIncompatibleType4() { doTest(); } public void testIncompatibleType5() { doTest(); } public void testMissingAttribute() { doTest(); } - public void testDuplicateAnnotation() { doTest(); } + public void testDuplicateAnnotation() { setLanguageLevel(LanguageLevel.JDK_1_7); doTest(); } public void testNonConstantInitializer() { doTest(); } public void testInvalidType() { doTest(); } public void testInapplicable() { doTest(); } @@ -44,20 +44,13 @@ public class AnnotationsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testPrivateInaccessibleConstant() { doTest(); } public void testInvalidPackageAnnotationTarget() { doTest(BASE_PATH + "/package-info.java", false, false); } public void testPackageAnnotationNotInPackageInfo() { doTest(); } - - public void testTypeAnnotations() { doTest8(); } - public void testRepeatable() { doTest8(); } - public void testEnumValues() { doTest8(); } - public void testReceiverParameters() { doTest8(); } + public void testTypeAnnotations() { doTest(); } + public void testRepeatable() { doTest(); } + public void testEnumValues() { doTest(); } + public void testReceiverParameters() { doTest(); } public void testAnnotationOverIncompleteCode() { doTest(); } private void doTest() { - setLanguageLevel(LanguageLevel.JDK_1_7); doTest(BASE_PATH + "/" + getTestName(true) + ".java", false, false); } - - private void doTest8() { - setLanguageLevel(LanguageLevel.JDK_1_8); - doTest(BASE_PATH + "/" + getTestName(true) + ".java", false, false); - } -} +} \ No newline at end of file From 2c86a18a54c6b7014d16967700841ecf53468c7b Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 20 Feb 2017 11:14:47 +0100 Subject: [PATCH 12/38] [platform] avoids 'null' file chooser root (EA-97093) --- .../roots/ui/configuration/ContentEntryTreeEditor.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java index 90171e905bd1..e2547cdd3b17 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -148,9 +148,11 @@ public class ContentEntryTreeEditor { final ContentEntry entry = contentEntryEditor.getContentEntry(); assert entry != null : contentEntryEditor; final VirtualFile file = entry.getFile(); - myDescriptor.setRoots(file); - if (file == null) { - final String path = VfsUtilCore.urlToPath(entry.getUrl()); + if (file != null) { + myDescriptor.setRoots(file); + } + else { + String path = VfsUtilCore.urlToPath(entry.getUrl()); myDescriptor.setTitle(FileUtil.toSystemDependentName(path)); } From 83361e061efd1e7619db345cb1fa8075b499cb51 Mon Sep 17 00:00:00 2001 From: Kirill Kirichenko Date: Mon, 20 Feb 2017 13:16:08 +0300 Subject: [PATCH 13/38] IDEA-168385 Widen Balloon API for new error selection feature --- .../intellij/openapi/ui/DialogWrapper.java | 67 ++++++++----------- .../intellij/ide/ui/laf/LafManagerImpl.java | 2 + .../ide/ui/laf/darcula/DarculaLaf.java | 17 ++--- .../ide/ui/laf/darcula/DarculaUIUtil.java | 19 +++++- .../ide/ui/laf/darcula/darcula.properties | 5 -- .../laf/intellij/MacIntelliJTextBorder.java | 1 + .../ide/ui/laf/intellijlaf.properties | 5 -- .../util/src/com/intellij/util/ui/UIUtil.java | 8 --- 8 files changed, 55 insertions(+), 69 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java index 21e34be655dc..01e57bc5cf5e 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java @@ -31,7 +31,7 @@ import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.popup.Balloon; +import com.intellij.openapi.ui.popup.BalloonBuilder; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.util.PopupUtil; import com.intellij.openapi.util.*; @@ -52,7 +52,10 @@ import com.intellij.util.Alarm; import com.intellij.util.IconUtil; import com.intellij.util.TimeoutUtil; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.ui.*; +import com.intellij.util.ui.DialogUtil; +import com.intellij.util.ui.GridBag; +import com.intellij.util.ui.JBUI; +import com.intellij.util.ui.UIUtil; import org.intellij.lang.annotations.MagicConstant; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; @@ -345,16 +348,8 @@ public abstract class DialogWrapper { private void reportProblem(@NotNull final ValidationInfo info) { installErrorPainter(); - myErrorPainter.setValidationInfo(info); - if (needRefresh(info.message)) { - SwingUtilities.invokeLater(() -> { - if (myDisposed) return; - setErrorText(info.message, info.component); - myPeer.getRootPane().getGlassPane().repaint(); - getOKAction().setEnabled(false); - }); - } + updateErrorMessage(info); } private void installErrorPainter() { @@ -365,21 +360,22 @@ public abstract class DialogWrapper { private void clearProblems() { myErrorPainter.setValidationInfo(null); - if (needRefresh(null)) { - SwingUtilities.invokeLater(() -> { - if (myDisposed) return; - setErrorText(null, null); - myPeer.getRootPane().getGlassPane().repaint(); - getOKAction().setEnabled(true); - }); - } + updateErrorMessage(null); } - private boolean needRefresh(String expectedText) { - if (Registry.is("ide.inplace.errors.balloon")) { - return !StringUtil.equals(expectedText, myLastErrorText); - } else { - return !myErrorText.isTextSet(expectedText); + protected void updateErrorMessage(@Nullable ValidationInfo info) { + String msg = (info == null) ? null : info.message; + JComponent errorComponent = (info == null) ? null : info.component; + boolean updateNeeded = Registry.is("ide.inplace.errors.balloon") ? + !StringUtil.equals(msg, myLastErrorText) : !myErrorText.isTextSet(msg); + + if (updateNeeded) { + SwingUtilities.invokeLater(() -> { + if (myDisposed) return; + setErrorText(msg, errorComponent); + myPeer.getRootPane().getGlassPane().repaint(); + getOKAction().setEnabled(msg == null); + }); } } @@ -1963,32 +1959,23 @@ public abstract class DialogWrapper { component.putClientProperty("JComponent.error.outline", outline); } - if (Registry.is("ide.inplace.errors.balloon") && outline) { + if (Registry.is("ide.inplace.errors.balloon") && component != null && outline) { JLabel label = new JLabel(); - Insets insets = UIUtil.getUIResource("Balloon.textInsets", Insets.class); + Insets insets = UIManager.getInsets("Balloon.error.textInsets"); int oneLineWidth = SwingUtilities2.stringWidth(label, label.getFontMetrics(label.getFont()), text); - int textWidth = component.getWidth() - JBUI.scale(30) - insets.right - insets.left; + int textWidth = component.getWidth() - JBUI.scale(30) - insets.left - insets.right; if (textWidth > oneLineWidth) textWidth = oneLineWidth; String htmlText = String.format("
%s
", textWidth, text); label.setText(htmlText); - label.setHorizontalAlignment(JLabel.LEADING); + label.setHorizontalAlignment(SwingConstants.LEADING); - Balloon balloon = JBPopupFactory.getInstance().createBalloonBuilder(label) + BalloonBuilder bb = JBPopupFactory.getInstance().createBalloonBuilder(label) .setDisposable(getDisposable()) - .setBorderColor(UIUtil.getUIResource("Balloon.border.color", Color.class)) - .setFillColor(UIUtil.getUIResource("Balloon.background.color", Color.class)) - .setPointerSize(UIUtil.getUIResource("Balloon.pointerSize", Dimension.class)) - .setCornerToPointerDistance(JBUI.scale(30)) - .setBorderInsets(insets) - .setHideOnFrameResize(false) - .setRequestFocus(false) - .setAnimationCycle(300) - .setShadow(false) - .createBalloon(); + .setBorderInsets(insets); - component.putClientProperty("JComponent.error.balloon", balloon); + component.putClientProperty("JComponent.error.balloonBuilder", bb); } else { myErrorTextAlarm.addRequest(() -> { myErrorText.setError(myLastErrorText); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java index 507877de3d5d..8228bd1b3d45 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java @@ -55,6 +55,7 @@ import com.intellij.util.IconUtil; import com.intellij.util.ObjectUtils; import com.intellij.util.ReflectionUtil; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.JBInsets; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; import org.jdom.Element; @@ -503,6 +504,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo initInputMapDefaults(uiDefaults); uiDefaults.put("Button.defaultButtonFollowsFocus", Boolean.FALSE); + uiDefaults.put("Balloon.error.textInsets", new JBInsets(3, 8, 3, 8).asUIResource()); patchFileChooserStrings(uiDefaults); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java index 5d7490f17ed0..0ecd0336b314 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java @@ -40,7 +40,10 @@ import org.jetbrains.annotations.NotNull; import sun.awt.AppContext; import javax.swing.*; -import javax.swing.plaf.*; +import javax.swing.plaf.BorderUIResource; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.FontUIResource; +import javax.swing.plaf.IconUIResource; import javax.swing.plaf.basic.BasicLookAndFeel; import javax.swing.plaf.metal.DefaultMetalTheme; import javax.swing.plaf.metal.MetalLookAndFeel; @@ -422,11 +425,10 @@ public class DarculaLaf extends BasicLookAndFeel { private static Insets parseInsets(String value) { final List numbers = StringUtil.split(value, ","); - JBInsets insets = new JBInsets(Integer.parseInt(numbers.get(0)), - Integer.parseInt(numbers.get(1)), - Integer.parseInt(numbers.get(2)), - Integer.parseInt(numbers.get(3))); - return insets.asUIResource(); + return new JBInsets(Integer.parseInt(numbers.get(0)), + Integer.parseInt(numbers.get(1)), + Integer.parseInt(numbers.get(2)), + Integer.parseInt(numbers.get(3))).asUIResource(); } @SuppressWarnings("UseJBColor") @@ -455,8 +457,7 @@ public class DarculaLaf extends BasicLookAndFeel { private static Dimension parseSize(String value) { final List numbers = StringUtil.split(value, ","); - JBDimension dimension = new JBDimension(Integer.parseInt(numbers.get(0)), Integer.parseInt(numbers.get(1))); - return dimension.asUIResource(); + return new JBDimension(Integer.parseInt(numbers.get(0)), Integer.parseInt(numbers.get(1))).asUIResource(); } @Override diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaUIUtil.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaUIUtil.java index a099a4cc3cd4..cdd50485a703 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaUIUtil.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaUIUtil.java @@ -41,6 +41,9 @@ import static javax.swing.SwingConstants.WEST; public class DarculaUIUtil { private static final Color GLOW_COLOR = new JBColor(new Color(31, 121, 212), new Color(96, 175, 255)); + private static final Color BALLOON_BORDER = new JBColor(new Color(0xe0a8a9), new Color(0x73454b)); + private static final Color BALLOON_BACKGROUND = new JBColor(new Color(0xf5e6e7), new Color(0x593d41)); + public static void paintFocusRing(Graphics g, Rectangle bounds) { MacUIUtil.paintFocusRing((Graphics2D)g, GLOW_COLOR, bounds); } @@ -121,9 +124,19 @@ public class DarculaUIUtil { } public static void showErrorTip(JComponent component) { - Balloon balloon = (Balloon)component.getClientProperty("JComponent.error.balloon"); - if (balloon != null) { - component.putClientProperty("JComponent.error.balloon", null); + BalloonBuilder bb = (BalloonBuilder)component.getClientProperty("JComponent.error.balloonBuilder"); + if (bb != null) { + component.putClientProperty("JComponent.error.balloonBuilder", null); + + Balloon balloon = bb.setPointerSize(new JBDimension(17, 6)) + .setCornerToPointerDistance(JBUI.scale(30)) + .setBorderColor(BALLOON_BORDER) + .setFillColor(BALLOON_BACKGROUND) + .setHideOnFrameResize(false) + .setRequestFocus(false) + .setAnimationCycle(300) + .setShadow(false) + .createBalloon(); JComponent root = component.getRootPane(); Point componentPos = SwingUtilities.convertPoint(component, 0, 0, root); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties index ae57de6b6217..ccd2a96ccd42 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties @@ -171,8 +171,3 @@ Tree.collapsedIcon=AllIcons.Mac.Tree_white_right_arrow Tree.expandedIcon=AllIcons.Mac.Tree_white_down_arrow FileView.fileIcon=AllIcons.FileTypes.Unknown - -Balloon.border.color=73454b -Balloon.background.color=593d41 -Balloon.textInsets=3,8,3,8 -Balloon.pointerSize=17,6 \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJTextBorder.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJTextBorder.java index 059db41115e0..7495c6ee4d99 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJTextBorder.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJTextBorder.java @@ -55,6 +55,7 @@ public class MacIntelliJTextBorder extends DarculaTextBorder { try { g2.translate(x, y); DarculaUIUtil.paintErrorRing(g2, width, height, c.hasFocus()); + g2.translate(-x, -y); } finally { g2.dispose(); } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties index 3975c2a149ec..6b298b0b9079 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties @@ -175,8 +175,3 @@ Tree.collapsedIcon=AllIcons.Nodes.TreeRightArrow Tree.expandedIcon=AllIcons.Nodes.TreeDownArrow FileView.fileIcon=AllIcons.FileTypes.Unknown - -Balloon.border.color=e0a8a9 -Balloon.background.color=f5e6e7 -Balloon.textInsets=3,3,3,3 -Balloon.pointerSize=17,6 \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index fdec1029255a..dc2c3b25e0c8 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -3959,12 +3959,4 @@ public class UIUtil { } }); } - - /** - * @param key a key in UIDefaults table - * @return the property value from the specified component or {@code null} - */ - public static T getUIResource(@NotNull Object key, @NotNull Class type) { - return ObjectUtils.tryCast(UIManager.get(key), type); - } } From 423be1677d2e4979cb686d52217dcd0000a0ee9e Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 20 Feb 2017 11:22:23 +0100 Subject: [PATCH 14/38] more diagnostics for EA-96901 - assert: FileTrees.withGreenStub --- .../src/com/intellij/psi/impl/source/FileTrees.java | 10 ++++------ .../src/com/intellij/psi/impl/source/PsiFileImpl.java | 1 + 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/FileTrees.java b/platform/core-impl/src/com/intellij/psi/impl/source/FileTrees.java index 1bebf4bf94a1..6c9c1cf68d97 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/FileTrees.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/FileTrees.java @@ -68,14 +68,12 @@ final class FileTrees { } FileTrees withExclusiveStub(@NotNull StubTree stub) { - assert derefTreeElement() == null; - assert !useStrongRefs; + assert derefTreeElement() == null && !useStrongRefs : this; return new FileTrees(new SoftReference<>(stub), null, false, false); } FileTrees withGreenStub(@NotNull StubTree stub) { - assert derefTreeElement() != null; - assert astLoaded; + assert derefTreeElement() != null && astLoaded : this; return new FileTrees(new SoftReference<>(stub), myTreeElementPointer, true, useStrongRefs); } @@ -86,8 +84,8 @@ final class FileTrees { @Override public String toString() { return "FileTrees{" + - "stub=" + derefStub() + - ", AST=" + derefTreeElement() + + "stub=" + (myStub == null ? "noRef" : derefStub()) + + ", AST=" + (myTreeElementPointer == null ? "noRef" : derefTreeElement()) + ", astLoaded=" + astLoaded + ", useStrongRefs=" + useStrongRefs + '}' ; diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index 1c3e2ecf2674..d3527709c708 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -1059,6 +1059,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF if (tree != null) { return tree; } + assert myFileElementBeingLoaded.get() == null : "non-empty thread-local"; FileElement fileElement = calcTreeElement(); synchronized (myStubFromTreeLock) { tree = derefStub(); From 6fc3caf5a26b1a59d455f5d13c4f07276c3e3f1d Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Mon, 20 Feb 2017 13:35:33 +0300 Subject: [PATCH 15/38] gradle: get all known modules for linked project settings --- .../settings/GradleProjectSettings.java | 40 ++----------------- 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleProjectSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleProjectSettings.java index be59c6679fed..1c3b4680bf77 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleProjectSettings.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleProjectSettings.java @@ -19,15 +19,15 @@ import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUt import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.xmlb.annotations.*; +import com.intellij.util.xmlb.annotations.AbstractCollection; +import com.intellij.util.xmlb.annotations.Attribute; +import com.intellij.util.xmlb.annotations.OptionTag; +import com.intellij.util.xmlb.annotations.Tag; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.model.data.BuildParticipant; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; /** * @author Denis Zhdanov @@ -41,38 +41,6 @@ public class GradleProjectSettings extends ExternalProjectSettings { private boolean disableWrapperSourceDistributionNotification; private boolean resolveModulePerSourceSet = true; @Nullable private CompositeBuild myCompositeBuild; - @Nullable private Set myNonCompositeModules = new HashSet<>(); - - @OptionTag("modules") - @Nullable - public Set getNonCompositeModules() { - Set modules = getModules(); - if (myCompositeBuild != null && !modules.isEmpty()) { - Set compositePaths = myCompositeBuild.getCompositeParticipants().stream() - .flatMap(participant -> participant.getProjects().stream()).collect(Collectors.toSet()); - return modules.stream().filter(m -> !compositePaths.contains(m)).collect(Collectors.toSet()); - } - else { - return myNonCompositeModules; - } - } - - public void setNonCompositeModules(@Nullable Set modules) { - myNonCompositeModules = modules; - } - - @Transient - @NotNull - @Override - public Set getModules() { - return super.getModules(); - } - - @Override - public void setModules(@Nullable Set modules) { - super.setModules(modules); - setNonCompositeModules(modules); - } @Nullable public String getGradleHome() { From 13d20c38594d32bd01385622e8d7aeb9a177295d Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 20 Feb 2017 11:51:37 +0100 Subject: [PATCH 16/38] [java] accepts annotations on modules --- .../codeInsight/AnnotationTargetUtil.java | 6 +++++- .../annotations/module-info.java | 1 + .../daemon/AnnotationsHighlightingTest.java | 6 +++--- java/mockJDK-1.8/jre/lib/rt.jar | Bin 5411376 -> 5410773 bytes 4 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/module-info.java diff --git a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java index 6f48206a0c79..05b946491f42 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -45,6 +45,7 @@ public class AnnotationTargetUtil { private static final TargetType[] FIELD_TARGETS = {TargetType.FIELD, TargetType.TYPE_USE}; private static final TargetType[] PARAMETER_TARGETS = {TargetType.PARAMETER, TargetType.TYPE_USE}; private static final TargetType[] LOCAL_VARIABLE_TARGETS = {TargetType.LOCAL_VARIABLE, TargetType.TYPE_USE}; + private static final TargetType[] MODULE_TARGETS = {TargetType.MODULE}; @NotNull public static TargetType[] getTargetsForLocation(@Nullable PsiAnnotationOwner owner) { @@ -107,6 +108,9 @@ public class AnnotationTargetUtil { if (element instanceof PsiReceiverParameter) { return TYPE_USE_TARGETS; } + if (element instanceof PsiJavaModule) { + return MODULE_TARGETS; + } } return TargetType.EMPTY_ARRAY; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/module-info.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/module-info.java new file mode 100644 index 000000000000..9da527c4bab6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/module-info.java @@ -0,0 +1 @@ +@Deprecated module M.M.M { } \ 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 87a29afac391..1af8334b0408 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java @@ -49,8 +49,8 @@ public class AnnotationsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testEnumValues() { doTest(); } public void testReceiverParameters() { doTest(); } public void testAnnotationOverIncompleteCode() { doTest(); } + public void testModuleAnnotation() { setLanguageLevel(LanguageLevel.JDK_1_9); doTest("module-info.java"); } - private void doTest() { - doTest(BASE_PATH + "/" + getTestName(true) + ".java", false, false); - } + private void doTest() { doTest(getTestName(true) + ".java"); } + private void doTest(String name) { doTest(BASE_PATH + "/" + name, false, false); } } \ No newline at end of file diff --git a/java/mockJDK-1.8/jre/lib/rt.jar b/java/mockJDK-1.8/jre/lib/rt.jar index 405e80298239a956bb3fc6d6a9b69b1f93e963c4..13a2d8bd9b93f174bc81d2a55dc743396b4113b4 100644 GIT binary patch delta 36844 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 From 008dea7c9aa5807031e0f010012931a3df3ea2ee Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Mon, 20 Feb 2017 13:52:13 +0300 Subject: [PATCH 17/38] scheme ui: fix importer/exporter name when single exporter/importer exists --- .../options/schemes/AbstractSchemeActions.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/schemes/AbstractSchemeActions.java b/platform/lang-impl/src/com/intellij/application/options/schemes/AbstractSchemeActions.java index 74baf1ed3c0a..bb4905596537 100644 --- a/platform/lang-impl/src/com/intellij/application/options/schemes/AbstractSchemeActions.java +++ b/platform/lang-impl/src/com/intellij/application/options/schemes/AbstractSchemeActions.java @@ -22,13 +22,14 @@ import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.ListPopup; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.function.Function; +import java.util.function.BiFunction; /** *

@@ -254,15 +255,15 @@ public abstract class AbstractSchemeActions { private AnAction createImportExportAction(@NotNull String groupName, @NotNull Collection actionNames, - @NotNull Function createActionByName) { + @NotNull BiFunction createActionByName) { if (actionNames.size() == 1) { - return createActionByName.apply(groupName); + return createActionByName.apply(ContainerUtil.getFirstItem(actionNames), groupName); } else { return new ActionGroupPopupAction(groupName, actionNames) { @NotNull @Override protected AnAction createAction(@NotNull String actionName) { - return createActionByName.apply(actionName); + return createActionByName.apply(actionName, actionName); } }; } @@ -300,8 +301,8 @@ public abstract class AbstractSchemeActions { private String myImporterName; - public ImportAction(@NotNull String importerName) { - super(importerName); + public ImportAction(@NotNull String importerName, @NotNull String importerText) { + super(importerText); myImporterName = importerName; } @@ -315,8 +316,8 @@ public abstract class AbstractSchemeActions { private class ExportAction extends DumbAwareAction { private String myExporterName; - public ExportAction(@NotNull String exporterName) { - super(exporterName); + public ExportAction(@NotNull String exporterName, @NotNull String exporterText) { + super(exporterText); myExporterName = exporterName; } From 1b5600e2c4aa6c328ada2faa17b9f2e1816cae60 Mon Sep 17 00:00:00 2001 From: Pavel Dolgov Date: Mon, 20 Feb 2017 14:36:31 +0300 Subject: [PATCH 18/38] Java: Fixed the intention "Invert 'if' condition" in the case of nested 'if' without braces (IDEA-167957) --- .../impl/InvertIfConditionAction.java | 66 +++++++++++++------ .../invertIfCondition/afterNestedIf1.java | 12 ++++ .../invertIfCondition/afterNestedIf2.java | 13 ++++ .../invertIfCondition/afterNestedIf3.java | 14 ++++ .../invertIfCondition/afterNestedIf4.java | 13 ++++ .../invertIfCondition/beforeNestedIf1.java | 9 +++ .../invertIfCondition/beforeNestedIf2.java | 10 +++ .../invertIfCondition/beforeNestedIf3.java | 10 +++ .../invertIfCondition/beforeNestedIf4.java | 9 +++ 9 files changed, 137 insertions(+), 19 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf1.java create mode 100644 java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf2.java create mode 100644 java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf3.java create mode 100644 java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf4.java create mode 100644 java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf1.java create mode 100644 java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf2.java create mode 100644 java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf3.java create mode 100644 java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf4.java diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/InvertIfConditionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/InvertIfConditionAction.java index 97335908d2d9..d37fbf3d8c74 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/InvertIfConditionAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/InvertIfConditionAction.java @@ -84,7 +84,7 @@ public class InvertIfConditionAction extends PsiElementBaseIntentionAction { PsiExpression condition = (PsiExpression) ifStatement.getCondition().copy(); - setupBranches(ifStatement, controlFlow); + ifStatement = setupBranches(ifStatement, controlFlow); if (condition != null) { ifStatement.getCondition().replace(CodeInsightServicesUtil.invertCondition(condition)); } @@ -156,10 +156,6 @@ public class InvertIfConditionAction extends PsiElementBaseIntentionAction { return null; } - private static PsiElement findNearestCodeBlock(PsiIfStatement ifStatement) { - return PsiTreeUtil.getParentOfType(ifStatement, PsiCodeBlock.class); - } - private static ControlFlow buildControlFlow(PsiElement element) { try { return ControlFlowFactory.getInstance(element.getProject()).getControlFlow(element, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance(), false); @@ -169,7 +165,7 @@ public class InvertIfConditionAction extends PsiElementBaseIntentionAction { } } - private static void setupBranches(PsiIfStatement ifStatement, ControlFlow flow) throws IncorrectOperationException { + private static PsiIfStatement setupBranches(PsiIfStatement ifStatement, ControlFlow flow) throws IncorrectOperationException { PsiElementFactory factory = JavaPsiFacade.getInstance(ifStatement.getProject()).getElementFactory(); Project project = ifStatement.getProject(); @@ -180,7 +176,7 @@ public class InvertIfConditionAction extends PsiElementBaseIntentionAction { elseBranch = (PsiStatement) elseBranch.copy(); setElseBranch(ifStatement, thenBranch, flow); ifStatement.getThenBranch().replace(elseBranch); - return; + return ifStatement; } final CodeStyleManager codeStyle = CodeStyleManager.getInstance(project); @@ -190,7 +186,7 @@ public class InvertIfConditionAction extends PsiElementBaseIntentionAction { statement = (PsiStatement) codeStyle.reformat(statement); statement = (PsiStatement) ifStatement.getThenBranch().replace(statement); codeStyle.reformat(statement); - return; + return ifStatement; } int endOffset = calcEndOffset(flow, ifStatement); @@ -211,11 +207,11 @@ public class InvertIfConditionAction extends PsiElementBaseIntentionAction { } } else { if (!(thenBranch instanceof PsiReturnStatement)) { - addAfter(ifStatement, thenBranch); + ifStatement = addAfterWithinCodeBlock(ifStatement, thenBranch); } } ifStatement.getThenBranch().replace(statement); - return; + return ifStatement; } PsiElement element = flow.getElement(endOffset); while (element != null && !(element instanceof PsiStatement)) element = element.getParent(); @@ -225,27 +221,38 @@ public class InvertIfConditionAction extends PsiElementBaseIntentionAction { element instanceof PsiForeachStatement && flow.getStartOffset(element) + 1 == endOffset) { PsiStatement statement = factory.createStatementFromText("continue;", null); statement = (PsiStatement)codeStyle.reformat(statement); - addAfter(ifStatement, thenBranch); + ifStatement = addAfterWithinCodeBlock(ifStatement, thenBranch); ifStatement.getThenBranch().replace(statement); - return; + return ifStatement; } if (element instanceof PsiReturnStatement) { PsiReturnStatement returnStatement = (PsiReturnStatement) element; - addAfter(ifStatement, thenBranch); + ifStatement = addAfterWithinCodeBlock(ifStatement, thenBranch); ifStatement.getThenBranch().replace(returnStatement.copy()); ControlFlow flow2 = buildControlFlow(findCodeBlock(ifStatement)); if (!ControlFlowUtil.isInstructionReachable(flow2, flow2.getStartOffset(returnStatement), 0)) returnStatement.delete(); - return; + return ifStatement; } boolean nextUnreachable = flow.getEndOffset(ifStatement) == flow.getSize(); if (!nextUnreachable) { - PsiElement nearestCodeBlock = findNearestCodeBlock(ifStatement); - if (nearestCodeBlock != null) { - ControlFlow flow2 = buildControlFlow(nearestCodeBlock); - nextUnreachable = !ControlFlowUtil.isInstructionReachable(flow2, flow2.getEndOffset(ifStatement), getThenOffset(flow2, ifStatement)); + PsiElement parent = ifStatement.getParent(); + if (parent != null) { + if (!(parent instanceof PsiCodeBlock)) { + PsiCodeBlock codeBlock = factory.createCodeBlockFromText("{}", ifStatement); + codeBlock = (PsiCodeBlock)codeStyle.reformat(codeBlock); + codeBlock.add(ifStatement); + codeBlock = (PsiCodeBlock)ifStatement.replace(codeBlock); + ifStatement = (PsiIfStatement)codeBlock.getStatements()[0]; + parent = ifStatement.getParent(); + thenBranch = ifStatement.getThenBranch(); + } + ControlFlow localFlow = buildControlFlow(parent); + int startThenOffset = getThenOffset(localFlow, ifStatement); + int afterIfOffset = localFlow.getEndOffset(ifStatement); + nextUnreachable = !ControlFlowUtil.isInstructionReachable(localFlow, afterIfOffset, startThenOffset); } } if (nextUnreachable) { @@ -270,7 +277,7 @@ public class InvertIfConditionAction extends PsiElementBaseIntentionAction { ifStatement.getThenBranch().replace(codeBlock); } codeStyle.reformat(ifStatement); - return; + return ifStatement; } setElseBranch(ifStatement, thenBranch, flow); @@ -278,6 +285,7 @@ public class InvertIfConditionAction extends PsiElementBaseIntentionAction { statement = (PsiStatement) codeStyle.reformat(statement); statement = (PsiStatement) ifStatement.getThenBranch().replace(statement); codeStyle.reformat(statement); + return ifStatement; } private static void setElseBranch(PsiIfStatement ifStatement, PsiStatement thenBranch, ControlFlow flow) @@ -312,6 +320,26 @@ public class InvertIfConditionAction extends PsiElementBaseIntentionAction { ifStatement.setElseBranch(thenBranch); } + private static PsiIfStatement addAfterWithinCodeBlock(PsiIfStatement ifStatement, PsiStatement branch) { + final PsiElement parent = ifStatement.getParent(); + if (parent != null && !(parent instanceof PsiCodeBlock)) { + final Project project = ifStatement.getProject(); + final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); + final CodeStyleManager codeStyle = CodeStyleManager.getInstance(project); + PsiCodeBlock codeBlock = factory.createCodeBlockFromText("{}", ifStatement); + codeBlock = (PsiCodeBlock)codeStyle.reformat(codeBlock); + final PsiIfStatement wrappedIfStatement = (PsiIfStatement)codeBlock.add(ifStatement); + + addAfter(wrappedIfStatement, branch); + codeBlock = (PsiCodeBlock)ifStatement.replace(codeBlock); + return (PsiIfStatement)codeBlock.getStatements()[0]; + } + else { + addAfter(ifStatement, branch); + return ifStatement; + } + } + static void addAfter(PsiIfStatement ifStatement, PsiStatement branch) throws IncorrectOperationException { if (branch instanceof PsiBlockStatement) { PsiBlockStatement blockStatement = (PsiBlockStatement) branch; diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf1.java b/java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf1.java new file mode 100644 index 000000000000..c8bf8d0089d2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf1.java @@ -0,0 +1,12 @@ +// "Invert 'if' condition" "true" +class Main { + boolean method(boolean a, boolean b) { + if (a) { + if (b) { + return false; + } + return true; + } + return false; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf2.java b/java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf2.java new file mode 100644 index 000000000000..045cc9dc04a6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf2.java @@ -0,0 +1,13 @@ +// "Invert 'if' condition" "true" +class Main { + boolean method(boolean a, boolean b) { + for (int i = 1; i < 10; i++) + if (a) { + if (b) /* comment 1 */ { + continue; + } + return true; /* comment 2 */ + } + return false; /* comment 3 */ + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf3.java b/java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf3.java new file mode 100644 index 000000000000..4f7632c20a21 --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf3.java @@ -0,0 +1,14 @@ +// "Invert 'if' condition" "true" +class Main { + boolean method(boolean a, boolean b) { + if (a) { + if (b) { + } + else { + return true; // comment + } + } + int x = 1; + return false; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf4.java b/java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf4.java new file mode 100644 index 000000000000..66f3bcd0613f --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/afterNestedIf4.java @@ -0,0 +1,13 @@ +// "Invert 'if' condition" "true" +class Main { + boolean method(boolean a, boolean b) { + for (int i = 1; i < 10; i++) + { + if (b) { + continue; + } + return true; + } + return false; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf1.java b/java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf1.java new file mode 100644 index 000000000000..1a224826a483 --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf1.java @@ -0,0 +1,9 @@ +// "Invert 'if' condition" "true" +class Main { + boolean method(boolean a, boolean b) { + if (a) + if (!b) + return true; + return false; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf2.java b/java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf2.java new file mode 100644 index 000000000000..ec41dd060885 --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf2.java @@ -0,0 +1,10 @@ +// "Invert 'if' condition" "true" +class Main { + boolean method(boolean a, boolean b) { + for (int i = 1; i < 10; i++) + if (a) + if (!b) /* comment 1 */ + return true; /* comment 2 */ + return false; /* comment 3 */ + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf3.java b/java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf3.java new file mode 100644 index 000000000000..24e2682371f6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf3.java @@ -0,0 +1,10 @@ +// "Invert 'if' condition" "true" +class Main { + boolean method(boolean a, boolean b) { + if (a) + if (!b) + return true; // comment + int x = 1; + return false; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf4.java b/java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf4.java new file mode 100644 index 000000000000..56ee3f0bfdfd --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/beforeNestedIf4.java @@ -0,0 +1,9 @@ +// "Invert 'if' condition" "true" +class Main { + boolean method(boolean a, boolean b) { + for (int i = 1; i < 10; i++) + if (!b) + return true; + return false; + } +} \ No newline at end of file From 79d1ae7ce45497103263956c8b9dc1222672e3be Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Mon, 20 Feb 2017 14:51:28 +0300 Subject: [PATCH 19/38] Extract Notification.id calculation --- .../src/com/intellij/notification/Notification.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/platform-api/src/com/intellij/notification/Notification.java b/platform/platform-api/src/com/intellij/notification/Notification.java index d7b1b6e0e32f..3ddbda756dad 100644 --- a/platform/platform-api/src/com/intellij/notification/Notification.java +++ b/platform/platform-api/src/com/intellij/notification/Notification.java @@ -104,7 +104,7 @@ public class Notification { LOG.assertTrue(hasTitle() || hasContent(), "Notification should have title: " + title + " and/or subtitle and/or content groupId: " + myGroupId); - id = calcId(this); + id = calculateId(this); } public Notification(@NotNull String groupDisplayId, @NotNull String title, @NotNull String content, @NotNull NotificationType type) { @@ -132,7 +132,7 @@ public class Notification { myTimestamp = System.currentTimeMillis(); LOG.assertTrue(hasContent(), "Notification should have content, title: " + title + ", groupId: " + myGroupId); - id = calcId(this); + id = calculateId(this); } /** @@ -348,7 +348,7 @@ public class Notification { } @NotNull - private static String calcId(@NotNull Notification notification) { + private static String calculateId(@NotNull Object notification) { return String.valueOf(System.currentTimeMillis()) + "." + String.valueOf(System.identityHashCode(notification)); } } From dac1cb21a0d10d7179f0af8729e7bcdf5847858d Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Mon, 20 Feb 2017 11:49:24 +0100 Subject: [PATCH 20/38] separate lines with tests (IDEA-168017) --- .../com/intellij/coverage/actions/ShowCoveringTestsAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/coverage-common/src/com/intellij/coverage/actions/ShowCoveringTestsAction.java b/plugins/coverage-common/src/com/intellij/coverage/actions/ShowCoveringTestsAction.java index b26e8fae2209..88c4eefbb73a 100644 --- a/plugins/coverage-common/src/com/intellij/coverage/actions/ShowCoveringTestsAction.java +++ b/plugins/coverage-common/src/com/intellij/coverage/actions/ShowCoveringTestsAction.java @@ -122,7 +122,7 @@ public class ShowCoveringTestsAction extends AnAction { }); } else { component = null; - final JPanel panel = new PanelWithText("Following test" + (testNames.length > 1 ? "s" : "") + " could not be found: " + StringUtil.join(testNames, ",").replace("_", ".")); + final JPanel panel = new PanelWithText("Following test" + (testNames.length > 1 ? "s" : "") + " could not be found: " + StringUtil.join(testNames, "
").replace("_", ".")); popupBuilder = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, null); } final JBPopup popup = popupBuilder.setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE) From 053da43a2e35f05d1077b0e0348df0abf1658423 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Mon, 20 Feb 2017 12:34:14 +0100 Subject: [PATCH 21/38] ensure target directory is searched when dirs refs are found EA-97221 - IAE: PsiMultiReference.bindToElement --- .../MoveDirectoryWithClassesProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java index caa2ecb8e391..18cdd6d2c077 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java @@ -189,7 +189,7 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping); for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { - helper.postProcessUsages(usages, dir -> getResultDirectory(dir).getTargetDirectory()); + helper.postProcessUsages(usages, dir -> getResultDirectory(dir).findOrCreateTargetDirectory()); } for (PsiDirectory directory : myDirectories) { final TargetDirectoryWrapper wrapper = myNestedDirsToMove.get(directory); From 9fd48a9995173a3d0d7b55599133a4810f58fc9f Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Mon, 20 Feb 2017 12:53:17 +0100 Subject: [PATCH 22/38] explicitly include all nodes from configuration into coverage view (IDEA-167971) --- .../com/intellij/coverage/view/JavaCoverageViewExtension.java | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java b/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java index 90afeef0b6c1..95ad637585cf 100644 --- a/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java +++ b/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java @@ -179,7 +179,6 @@ public class JavaCoverageViewExtension extends CoverageViewExtension { } for (PsiClass aClass : classes) { - if (getClassCoverageInfo(aClass) == null) continue; topLevelNodes.add(new CoverageListNode(myProject, aClass, mySuitesBundle, myStateBean)); } return topLevelNodes; From c94a21fd7a073b81f1b24335e6bcc48e1dff9a34 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 17 Feb 2017 16:16:57 +0300 Subject: [PATCH 23/38] external annotations moved to the code --- .../com/intellij/patterns/annotations.xml | 6 --- java/java-psi-api/java-psi-api.iml | 3 -- .../intellij/patterns/PsiJavaPatterns.java | 8 +++- .../anno/com/intellij/ide/annotations.xml | 15 ------- .../anno/com/intellij/lang/annotations.xml | 6 --- .../intellij/openapi/progress/annotations.xml | 9 ---- .../intellij/openapi/project/annotations.xml | 6 --- .../intellij/openapi/roots/annotations.xml | 6 --- .../com/intellij/patterns/annotations.xml | 18 -------- .../com/intellij/psi/search/annotations.xml | 6 --- .../com/intellij/psi/util/annotations.xml | 45 ------------------- platform/core-api/core-api.iml | 3 -- .../com/intellij/lang/ITokenTypeRemapper.java | 1 + .../progress/NonCancelableSection.java | 1 + .../openapi/progress/Progressive.java | 1 + .../openapi/project/DumbAwareRunnable.java | 1 + .../openapi/roots/ContentIterator.java | 1 + .../intellij/patterns/StandardPatterns.java | 10 +++-- .../intellij/patterns/TreeElementPattern.java | 9 ++-- .../PsiNonJavaFileReferenceProcessor.java | 1 + .../psi/util/CachedValueProvider.java | 1 + .../com/intellij/psi/util/PsiTreeUtil.java | 29 +++++++----- 22 files changed, 44 insertions(+), 142 deletions(-) delete mode 100644 java/java-psi-api/anno/com/intellij/patterns/annotations.xml delete mode 100644 platform/core-api/anno/com/intellij/ide/annotations.xml delete mode 100644 platform/core-api/anno/com/intellij/lang/annotations.xml delete mode 100644 platform/core-api/anno/com/intellij/openapi/progress/annotations.xml delete mode 100644 platform/core-api/anno/com/intellij/openapi/project/annotations.xml delete mode 100644 platform/core-api/anno/com/intellij/openapi/roots/annotations.xml delete mode 100644 platform/core-api/anno/com/intellij/patterns/annotations.xml delete mode 100644 platform/core-api/anno/com/intellij/psi/search/annotations.xml delete mode 100644 platform/core-api/anno/com/intellij/psi/util/annotations.xml diff --git a/java/java-psi-api/anno/com/intellij/patterns/annotations.xml b/java/java-psi-api/anno/com/intellij/patterns/annotations.xml deleted file mode 100644 index 32e2972fcf37..000000000000 --- a/java/java-psi-api/anno/com/intellij/patterns/annotations.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/java/java-psi-api/java-psi-api.iml b/java/java-psi-api/java-psi-api.iml index 2e92efedd035..9e771bf16372 100644 --- a/java/java-psi-api/java-psi-api.iml +++ b/java/java-psi-api/java-psi-api.iml @@ -2,9 +2,6 @@ - - - diff --git a/java/java-psi-api/src/com/intellij/patterns/PsiJavaPatterns.java b/java/java-psi-api/src/com/intellij/patterns/PsiJavaPatterns.java index 0f521a5a91da..39d39e348af2 100644 --- a/java/java-psi-api/src/com/intellij/patterns/PsiJavaPatterns.java +++ b/java/java-psi-api/src/com/intellij/patterns/PsiJavaPatterns.java @@ -49,6 +49,7 @@ public class PsiJavaPatterns extends StandardPatterns{ return new PsiJavaElementPattern.Capture<>(aClass); } + @SafeVarargs public static PsiJavaElementPattern.Capture psiElement(final Class... classAlternatives) { return new PsiJavaElementPattern.Capture<>(new InitialPatternCondition(PsiElement.class) { @Override @@ -73,19 +74,21 @@ public class PsiJavaPatterns extends StandardPatterns{ public static PsiJavaElementPattern.Capture psiLiteral(@Nullable final ElementPattern value) { return new PsiJavaElementPattern.Capture<>(new InitialPatternConditionPlus(PsiLiteral.class) { + @Override public boolean accepts(@Nullable final Object o, final ProcessingContext context) { return o instanceof PsiLiteral && (value == null || value.accepts(((PsiLiteral)o).getValue(), context)); } @Override public List> getPatterns() { - return Collections.>singletonList(value); + return Collections.singletonList(value); } }); } public static PsiJavaElementPattern.Capture psiNewExpression(@NotNull final String... fqns) { return new PsiJavaElementPattern.Capture<>(new InitialPatternCondition(PsiNewExpression.class) { + @Override public boolean accepts(@Nullable final Object o, final ProcessingContext context) { if (o instanceof PsiNewExpression) { PsiJavaCodeReferenceElement reference = ((PsiNewExpression)o).getClassOrAnonymousClassReference(); @@ -102,13 +105,14 @@ public class PsiJavaPatterns extends StandardPatterns{ public static PsiJavaElementPattern.Capture literalExpression(@Nullable final ElementPattern value) { return new PsiJavaElementPattern.Capture<>(new InitialPatternConditionPlus(PsiLiteralExpression.class) { + @Override public boolean accepts(@Nullable final Object o, final ProcessingContext context) { return o instanceof PsiLiteralExpression && (value == null || value.accepts(((PsiLiteralExpression)o).getValue(), context)); } @Override public List> getPatterns() { - return Collections.>singletonList(value); + return Collections.singletonList(value); } }); } diff --git a/platform/core-api/anno/com/intellij/ide/annotations.xml b/platform/core-api/anno/com/intellij/ide/annotations.xml deleted file mode 100644 index 18250848f857..000000000000 --- a/platform/core-api/anno/com/intellij/ide/annotations.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/platform/core-api/anno/com/intellij/lang/annotations.xml b/platform/core-api/anno/com/intellij/lang/annotations.xml deleted file mode 100644 index b34f4ea410f7..000000000000 --- a/platform/core-api/anno/com/intellij/lang/annotations.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/platform/core-api/anno/com/intellij/openapi/progress/annotations.xml b/platform/core-api/anno/com/intellij/openapi/progress/annotations.xml deleted file mode 100644 index 67cd14dba2f9..000000000000 --- a/platform/core-api/anno/com/intellij/openapi/progress/annotations.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/platform/core-api/anno/com/intellij/openapi/project/annotations.xml b/platform/core-api/anno/com/intellij/openapi/project/annotations.xml deleted file mode 100644 index 95cfbb0d891c..000000000000 --- a/platform/core-api/anno/com/intellij/openapi/project/annotations.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/platform/core-api/anno/com/intellij/openapi/roots/annotations.xml b/platform/core-api/anno/com/intellij/openapi/roots/annotations.xml deleted file mode 100644 index d679dd1a9e6c..000000000000 --- a/platform/core-api/anno/com/intellij/openapi/roots/annotations.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/platform/core-api/anno/com/intellij/patterns/annotations.xml b/platform/core-api/anno/com/intellij/patterns/annotations.xml deleted file mode 100644 index d8c1fb0df7d7..000000000000 --- a/platform/core-api/anno/com/intellij/patterns/annotations.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/platform/core-api/anno/com/intellij/psi/search/annotations.xml b/platform/core-api/anno/com/intellij/psi/search/annotations.xml deleted file mode 100644 index 8dd390064e23..000000000000 --- a/platform/core-api/anno/com/intellij/psi/search/annotations.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/platform/core-api/anno/com/intellij/psi/util/annotations.xml b/platform/core-api/anno/com/intellij/psi/util/annotations.xml deleted file mode 100644 index f34c69802be4..000000000000 --- a/platform/core-api/anno/com/intellij/psi/util/annotations.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/platform/core-api/core-api.iml b/platform/core-api/core-api.iml index 9d5cfe79a52a..fedaceca9ba6 100644 --- a/platform/core-api/core-api.iml +++ b/platform/core-api/core-api.iml @@ -2,9 +2,6 @@ - - - diff --git a/platform/core-api/src/com/intellij/lang/ITokenTypeRemapper.java b/platform/core-api/src/com/intellij/lang/ITokenTypeRemapper.java index c5eca6676e08..b41795db91af 100644 --- a/platform/core-api/src/com/intellij/lang/ITokenTypeRemapper.java +++ b/platform/core-api/src/com/intellij/lang/ITokenTypeRemapper.java @@ -24,6 +24,7 @@ import com.intellij.psi.tree.IElementType; * Date: 06.04.2008 * Time: 23:41:56 */ +@FunctionalInterface public interface ITokenTypeRemapper { /** * An external hook to see and alter token types reported by lexer. diff --git a/platform/core-api/src/com/intellij/openapi/progress/NonCancelableSection.java b/platform/core-api/src/com/intellij/openapi/progress/NonCancelableSection.java index 7cc84c75d20d..6e9955e26d64 100644 --- a/platform/core-api/src/com/intellij/openapi/progress/NonCancelableSection.java +++ b/platform/core-api/src/com/intellij/openapi/progress/NonCancelableSection.java @@ -21,6 +21,7 @@ package com.intellij.openapi.progress; import org.jetbrains.annotations.NotNull; +@FunctionalInterface public interface NonCancelableSection { void done(); diff --git a/platform/core-api/src/com/intellij/openapi/progress/Progressive.java b/platform/core-api/src/com/intellij/openapi/progress/Progressive.java index 710dc06daa77..9a0e185824c8 100644 --- a/platform/core-api/src/com/intellij/openapi/progress/Progressive.java +++ b/platform/core-api/src/com/intellij/openapi/progress/Progressive.java @@ -17,6 +17,7 @@ package com.intellij.openapi.progress; import org.jetbrains.annotations.NotNull; +@FunctionalInterface public interface Progressive { void run(@NotNull ProgressIndicator indicator); diff --git a/platform/core-api/src/com/intellij/openapi/project/DumbAwareRunnable.java b/platform/core-api/src/com/intellij/openapi/project/DumbAwareRunnable.java index 8c8b03de447f..685d37c601a8 100644 --- a/platform/core-api/src/com/intellij/openapi/project/DumbAwareRunnable.java +++ b/platform/core-api/src/com/intellij/openapi/project/DumbAwareRunnable.java @@ -18,5 +18,6 @@ package com.intellij.openapi.project; /** * @author peter */ +@FunctionalInterface public interface DumbAwareRunnable extends Runnable, DumbAware { } diff --git a/platform/core-api/src/com/intellij/openapi/roots/ContentIterator.java b/platform/core-api/src/com/intellij/openapi/roots/ContentIterator.java index 78b781c4c2a4..91ceadc057aa 100644 --- a/platform/core-api/src/com/intellij/openapi/roots/ContentIterator.java +++ b/platform/core-api/src/com/intellij/openapi/roots/ContentIterator.java @@ -22,6 +22,7 @@ import com.intellij.openapi.vfs.VirtualFile; * * @see FileIndex#iterateContent(ContentIterator) */ +@FunctionalInterface public interface ContentIterator { /** * Processes the specified file or directory. diff --git a/platform/core-api/src/com/intellij/patterns/StandardPatterns.java b/platform/core-api/src/com/intellij/patterns/StandardPatterns.java index b3a818cd3e07..b6807a054185 100644 --- a/platform/core-api/src/com/intellij/patterns/StandardPatterns.java +++ b/platform/core-api/src/com/intellij/patterns/StandardPatterns.java @@ -17,7 +17,6 @@ package com.intellij.patterns; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; -import com.intellij.util.Function; import com.intellij.util.ProcessingContext; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; @@ -52,8 +51,9 @@ public class StandardPatterns { } @NotNull + @SafeVarargs public static ElementPattern instanceOf(@NotNull Class... classes) { - ElementPattern[] patterns = ContainerUtil.map(classes, aClass -> instanceOf(aClass), new ElementPattern[0]); + ElementPattern[] patterns = ContainerUtil.map(classes, StandardPatterns::instanceOf, new ElementPattern[0]); return or(patterns); } @@ -109,6 +109,7 @@ public class StandardPatterns { } @NotNull + @SafeVarargs public static ElementPattern or(@NotNull final ElementPattern... patterns) { return new ObjectPattern.Capture<>(new InitialPatternConditionPlus(Object.class) { @Override @@ -133,12 +134,13 @@ public class StandardPatterns { @Override public List> getPatterns() { - return Arrays.>asList(patterns); + return Arrays.asList(patterns); } }); } @NotNull + @SafeVarargs public static ElementPattern and(final ElementPattern... patterns) { final List initial = ContainerUtil.newSmartList(); for (ElementPattern pattern : patterns) { @@ -194,7 +196,7 @@ public class StandardPatterns { @Override public List> getPatterns() { - return Collections.>singletonList(pattern); + return Collections.singletonList(pattern); } }); } diff --git a/platform/core-api/src/com/intellij/patterns/TreeElementPattern.java b/platform/core-api/src/com/intellij/patterns/TreeElementPattern.java index 4c29e06abf97..8a3c18fd2914 100644 --- a/platform/core-api/src/com/intellij/patterns/TreeElementPattern.java +++ b/platform/core-api/src/com/intellij/patterns/TreeElementPattern.java @@ -42,7 +42,8 @@ public abstract class TreeElementPattern... types) { + @SafeVarargs + public final Self withParents(@NotNull final Class... types) { return with(new PatternCondition("withParents") { @Override public boolean accepts(@NotNull T t, ProcessingContext context) { @@ -91,6 +92,7 @@ public abstract class TreeElementPattern pattern) { return with(new PatternCondition("isFirstAcceptedChild") { + @Override public boolean accepts(@NotNull final T t, final ProcessingContext context) { final ParentType parent = getParent(t); if (parent != null) { @@ -183,11 +185,12 @@ public abstract class TreeElementPattern... patterns) { + @SafeVarargs + public final Self insideSequence(final boolean strict, @NotNull final ElementPattern... patterns) { return with(new PatternCondition("insideSequence") { + @Override public boolean accepts(@NotNull final T t, final ProcessingContext context) { int i = 0; ParentType element = strict ? getParent(t) : t; diff --git a/platform/core-api/src/com/intellij/psi/search/PsiNonJavaFileReferenceProcessor.java b/platform/core-api/src/com/intellij/psi/search/PsiNonJavaFileReferenceProcessor.java index 406e95b74f8c..ccb662541491 100644 --- a/platform/core-api/src/com/intellij/psi/search/PsiNonJavaFileReferenceProcessor.java +++ b/platform/core-api/src/com/intellij/psi/search/PsiNonJavaFileReferenceProcessor.java @@ -17,6 +17,7 @@ package com.intellij.psi.search; import com.intellij.psi.PsiFile; +@FunctionalInterface public interface PsiNonJavaFileReferenceProcessor { boolean process(PsiFile file, int startOffset, int endOffset); } diff --git a/platform/core-api/src/com/intellij/psi/util/CachedValueProvider.java b/platform/core-api/src/com/intellij/psi/util/CachedValueProvider.java index 2fb23b95b953..e5bf7633f413 100644 --- a/platform/core-api/src/com/intellij/psi/util/CachedValueProvider.java +++ b/platform/core-api/src/com/intellij/psi/util/CachedValueProvider.java @@ -26,6 +26,7 @@ import java.util.Collection; * A computation (typically an anonymous class) to used in {@link CachedValue} to cache some computation result. * @param the type of the cached value */ +@FunctionalInterface public interface CachedValueProvider { /** diff --git a/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java b/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java index a2ac93f96532..ed907a2b696d 100644 --- a/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java +++ b/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java @@ -235,6 +235,7 @@ public class PsiTreeUtil { */ @Nullable @Contract("null, _ -> null") + @SafeVarargs public static T findChildOfAnyType(@Nullable final PsiElement element, @NotNull final Class... classes) { return findChildOfAnyType(element, true, classes); } @@ -248,6 +249,7 @@ public class PsiTreeUtil { * @param type to cast found element to. * @return first found element, or null if nothing found. */ + @SafeVarargs @Nullable @Contract("null, _, _ -> null") public static T findChildOfAnyType(@Nullable final PsiElement element, @@ -274,6 +276,7 @@ public class PsiTreeUtil { return findChildrenOfAnyType(element, aClass); } + @SafeVarargs @NotNull public static Collection findChildrenOfAnyType(@Nullable final PsiElement element, @NotNull final Class... classes) { @@ -372,6 +375,7 @@ public class PsiTreeUtil { return result == null ? null : ArrayUtil.toObjectArray(result, aClass); } + @SafeVarargs @NotNull public static List getChildrenOfAnyType(@Nullable PsiElement element, @NotNull Class... classes) { if (element == null) return ContainerUtil.emptyList(); @@ -457,6 +461,7 @@ public class PsiTreeUtil { * @return the element, or null if none was found. * @since 5.1 */ + @SafeVarargs @Nullable @Contract("null, _ -> null") public static T getChildOfAnyType(@Nullable PsiElement element, @NotNull Class... classes) { @@ -546,6 +551,7 @@ public class PsiTreeUtil { return getParentOfType(element, parentClass); } + @SafeVarargs @Nullable @Contract("null, _, _, _ -> null") public static T getContextOfType(@Nullable PsiElement element, @@ -574,11 +580,13 @@ public class PsiTreeUtil { return getContextOfType(element, strict, aClass); } + @SafeVarargs @Nullable public static T getContextOfType(@Nullable PsiElement element, @NotNull Class... classes) { return getContextOfType(element, true, classes); } + @SafeVarargs @Nullable @Contract("null, _, _ -> null") public static T getContextOfType(@Nullable PsiElement element, @@ -630,6 +638,7 @@ public class PsiTreeUtil { return null; } + @SafeVarargs @Nullable @Contract("null, _, _, _ -> null") public static T getParentOfType(@Nullable PsiElement element, @@ -688,6 +697,7 @@ public class PsiTreeUtil { return null; } + @SafeVarargs @Nullable @Contract("null, _ -> null") public static T getParentOfType(@Nullable final PsiElement element, @@ -698,6 +708,7 @@ public class PsiTreeUtil { return getNonStrictParentOfType(parent, classes); } + @SafeVarargs @Nullable @Contract("null, _ -> null") public static T getNonStrictParentOfType(@Nullable final PsiElement element, @@ -722,21 +733,18 @@ public class PsiTreeUtil { return processor.toArray(); } + @SafeVarargs @NotNull public static Collection collectElementsOfType(@Nullable final PsiElement element, @NotNull final Class... classes) { - CollectFilteredElements processor = new CollectFilteredElements<>(new PsiElementFilter() { - - @Override - public boolean isAccepted(PsiElement element) { - for (Class clazz : classes) { - if (clazz.isInstance(element)) { - return true; - } + CollectFilteredElements processor = new CollectFilteredElements<>(element1 -> { + for (Class clazz : classes) { + if (clazz.isInstance(element1)) { + return true; } - - return false; } + + return false; }); processElements(element, processor); return processor.getCollection(); @@ -873,6 +881,7 @@ public class PsiTreeUtil { return result; } + @SafeVarargs @Nullable public static T findElementOfClassAtOffsetWithStopSet(@NotNull PsiFile file, int offset, From 4b0a7e6bd313da19ecd7db217dd86ab359fa38cb Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 20 Feb 2017 13:55:42 +0300 Subject: [PATCH 24/38] marked create* methods pure to avoid abandoning the result --- .../codeInspection/InspectionManager.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/platform/analysis-api/src/com/intellij/codeInspection/InspectionManager.java b/platform/analysis-api/src/com/intellij/codeInspection/InspectionManager.java index dbdce739369a..81deb2dc9dc8 100644 --- a/platform/analysis-api/src/com/intellij/codeInspection/InspectionManager.java +++ b/platform/analysis-api/src/com/intellij/codeInspection/InspectionManager.java @@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,6 +40,7 @@ public abstract class InspectionManager { public abstract Project getProject(); @NotNull + @Contract(pure = true) public abstract CommonProblemDescriptor createProblemDescriptor(@NotNull @Nls(capitalization = Nls.Capitalization.Sentence) String descriptionTemplate, QuickFix... fixes); /** @@ -49,6 +51,7 @@ public abstract class InspectionManager { * @param onTheFly for local tools on batch run */ @NotNull + @Contract(pure = true) public abstract ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement, @NotNull @Nls(capitalization = Nls.Capitalization.Sentence) String descriptionTemplate, LocalQuickFix fix, @@ -56,6 +59,7 @@ public abstract class InspectionManager { boolean onTheFly); @NotNull + @Contract(pure = true) public abstract ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement, @NotNull @Nls(capitalization = Nls.Capitalization.Sentence) String descriptionTemplate, boolean onTheFly, @@ -63,6 +67,7 @@ public abstract class InspectionManager { @NotNull ProblemHighlightType highlightType); @NotNull + @Contract(pure = true) public abstract ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement, @NotNull @Nls(capitalization = Nls.Capitalization.Sentence) String descriptionTemplate, LocalQuickFix[] fixes, @@ -71,6 +76,7 @@ public abstract class InspectionManager { boolean isAfterEndOfLine); @NotNull + @Contract(pure = true) public abstract ProblemDescriptor createProblemDescriptor(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull @Nls(capitalization = Nls.Capitalization.Sentence) String descriptionTemplate, @@ -79,6 +85,7 @@ public abstract class InspectionManager { LocalQuickFix... fixes); @NotNull + @Contract(pure = true) public abstract ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement, @Nullable("null means the text range of the element") TextRange rangeInElement, @NotNull @Nls(capitalization = Nls.Capitalization.Sentence) String descriptionTemplate, @@ -87,6 +94,7 @@ public abstract class InspectionManager { LocalQuickFix... fixes); @NotNull + @Contract(pure = true) public abstract ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement, @NotNull @Nls(capitalization = Nls.Capitalization.Sentence) String descriptionTemplate, final boolean showTooltip, @@ -98,6 +106,7 @@ public abstract class InspectionManager { */ @Deprecated @NotNull + @Contract(pure = true) public abstract ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement, @NotNull String descriptionTemplate, LocalQuickFix fix, @@ -108,6 +117,7 @@ public abstract class InspectionManager { */ @Deprecated @NotNull + @Contract(pure = true) public abstract ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement, @NotNull String descriptionTemplate, LocalQuickFix[] fixes, @@ -118,6 +128,7 @@ public abstract class InspectionManager { */ @Deprecated @NotNull + @Contract(pure = true) public abstract ProblemDescriptor createProblemDescriptor(@NotNull PsiElement psiElement, @NotNull String descriptionTemplate, LocalQuickFix[] fixes, @@ -129,6 +140,7 @@ public abstract class InspectionManager { */ @Deprecated @NotNull + @Contract(pure = true) public abstract ProblemDescriptor createProblemDescriptor(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String descriptionTemplate, @@ -141,6 +153,7 @@ public abstract class InspectionManager { */ @Deprecated @NotNull + @Contract(pure = true) public abstract ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement, final TextRange rangeInElement, @NotNull final String descriptionTemplate, @@ -152,6 +165,7 @@ public abstract class InspectionManager { */ @Deprecated @NotNull + @Contract(pure = true) public abstract ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement, @NotNull final String descriptionTemplate, final boolean showTooltip, @@ -159,5 +173,6 @@ public abstract class InspectionManager { final LocalQuickFix... fixes); @NotNull + @Contract(pure = true) public abstract GlobalInspectionContext createNewGlobalContext(boolean reuse); } From 78e091ebcaddba355958267d6b1b19454f230239 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 20 Feb 2017 13:56:34 +0300 Subject: [PATCH 25/38] get rid of "result is ignored" --- .../jetbrains/plugins/groovy/dsl/CustomMembersGenerator.java | 5 ++--- .../lang/completion/closureParameters/ClosureDescriptor.java | 5 ++--- .../lang/psi/impl/signatures/GrClosureSignatureUtil.java | 3 +-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dsl/CustomMembersGenerator.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dsl/CustomMembersGenerator.java index a9c06d017103..407ca581f356 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dsl/CustomMembersGenerator.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dsl/CustomMembersGenerator.java @@ -21,7 +21,6 @@ import com.intellij.psi.*; import com.intellij.psi.impl.FakePsiElement; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.FList; import groovy.lang.Closure; @@ -196,8 +195,8 @@ public class CustomMembersGenerator extends GroovyObjectSupport implements GdslM PsiType[] argTypes = PsiUtil.getArgumentTypes(ref, false); if (argTypes == null) return; - String[] types = new String[argTypes.length]; - ContainerUtil.map(argTypes, (Function)type -> type.getCanonicalText(), types); + String[] types = + ContainerUtil.map(argTypes, PsiType::getCanonicalText, new String[argTypes.length]); generator.setDelegate(this); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/completion/closureParameters/ClosureDescriptor.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/completion/closureParameters/ClosureDescriptor.java index 00dba6d4dbba..fe0ad8a746f9 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/completion/closureParameters/ClosureDescriptor.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/completion/closureParameters/ClosureDescriptor.java @@ -20,7 +20,6 @@ import com.intellij.psi.impl.compiled.ClsMethodImpl; import com.intellij.psi.impl.light.LightElement; import com.intellij.psi.util.MethodSignature; import com.intellij.psi.util.MethodSignatureUtil; -import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -92,8 +91,8 @@ public class ClosureDescriptor extends LightElement implements PsiElement { if (method instanceof ClsMethodImpl) method = ((ClsMethodImpl)method).getSourceMirrorMethod(); final PsiParameter[] parameters = method.getParameterList().getParameters(); - final PsiType[] typeArray = PsiType.createArray(parameters.length); - ContainerUtil.map(parameters, parameter -> parameter.getType(), typeArray); + final PsiType[] typeArray = + ContainerUtil.map(parameters, parameter -> parameter.getType(), PsiType.createArray(parameters.length)); return GrClosureSignatureUtil.isSignatureApplicable(closureSignature, typeArray, place); } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrClosureSignatureUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrClosureSignatureUtil.java index 4c9bd920bfad..e421bf714c5d 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrClosureSignatureUtil.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/signatures/GrClosureSignatureUtil.java @@ -97,8 +97,7 @@ public class GrClosureSignatureUtil { public static GrClosureSignature createSignature(MethodSignature signature) { final PsiType[] types = signature.getParameterTypes(); - GrClosureParameter[] parameters = new GrClosureParameter[types.length]; - ContainerUtil.map(types, type -> new GrImmediateClosureParameterImpl(type, null, false, null), parameters); + GrClosureParameter[] parameters = ContainerUtil.map(types, type -> new GrImmediateClosureParameterImpl(type, null, false, null), new GrClosureParameter[types.length]); return new GrImmediateClosureSignatureImpl(parameters, null, false, false); } From 1d321865dcc889f2419f2c49babf6f82b5119ab4 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 16 Feb 2017 16:36:14 +0300 Subject: [PATCH 26/38] ui: restore QuickActionProvider it was removed by mistake along with SwitchManager in 66273cebf33ea9cfcd266c39cefcf4dd06403643 --- .../ui/switcher/QuickActionProvider.java | 14 ++- .../switcher/ShowQuickActionPopupAction.java | 94 +++++++++++++++++++ .../src/idea/PlatformActions.xml | 2 + .../src/keymaps/$default.xml | 4 + .../com/intellij/keymap/KeymapsTestCase.java | 1 + 5 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 platform/platform-api/src/com/intellij/ui/switcher/ShowQuickActionPopupAction.java diff --git a/platform/editor-ui-api/src/com/intellij/ui/switcher/QuickActionProvider.java b/platform/editor-ui-api/src/com/intellij/ui/switcher/QuickActionProvider.java index 40a57a2f013a..1dc3946e7e9e 100644 --- a/platform/editor-ui-api/src/com/intellij/ui/switcher/QuickActionProvider.java +++ b/platform/editor-ui-api/src/com/intellij/ui/switcher/QuickActionProvider.java @@ -17,15 +17,23 @@ package com.intellij.ui.switcher; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DataKey; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.util.List; -@Deprecated public interface QuickActionProvider { - DataKey KEY = DataKey.create("QuickActionProvider"); - String getName(); + @Nullable List getActions(boolean originalProvider); + boolean isCycleRoot(); + + @Nullable + JComponent getComponent(); + + @Nullable + String getName(); } diff --git a/platform/platform-api/src/com/intellij/ui/switcher/ShowQuickActionPopupAction.java b/platform/platform-api/src/com/intellij/ui/switcher/ShowQuickActionPopupAction.java new file mode 100644 index 000000000000..48359779ef4d --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/switcher/ShowQuickActionPopupAction.java @@ -0,0 +1,94 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ui.switcher; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.ui.popup.JBPopupFactory; + +import java.awt.*; +import java.util.List; + +import static com.intellij.openapi.ui.popup.JBPopupFactory.ActionSelectionAid.ALPHA_NUMBERING; + +public class ShowQuickActionPopupAction extends AnAction { + @Override + public void update(AnActionEvent e) { + QuickActionProvider quickActionProvider = QuickActionProvider.KEY.getData(e.getDataContext()); + if (quickActionProvider == null) { + e.getPresentation().setEnabled(false); + } + else { + List actions = quickActionProvider.getActions(true); + e.getPresentation().setEnabled(actions != null && !actions.isEmpty()); + } + } + + @Override + public void actionPerformed(AnActionEvent e) { + DataContext context = e.getDataContext(); + QuickActionProvider provider = QuickActionProvider.KEY.getData(context); + if (provider == null) return; + + List actions = provider.getActions(true); + if (actions != null && actions.size() > 0) { + DefaultActionGroup group = new DefaultActionGroup(); + for (AnAction each : actions) { + group.add(each); + } + + boolean firstParent = true; + Component eachParent = provider.getComponent().getParent(); + while (eachParent != null) { + if (eachParent instanceof QuickActionProvider) { + QuickActionProvider eachProvider = (QuickActionProvider)eachParent; + if (firstParent) { + group.addSeparator(); + firstParent = false; + } + List eachActionList = eachProvider.getActions(false); + if (eachActionList.size() > 0) { + group.add(new Group(eachActionList, eachProvider.getName())); + } + if (eachProvider.isCycleRoot()) break; + } + eachParent = eachParent.getParent(); + } + + JBPopupFactory.getInstance().createActionGroupPopup(null, group, context, ALPHA_NUMBERING, true).showInBestPositionFor(context); + } + } + + private static class Group extends DefaultActionGroup implements DumbAware { + private String myTitle; + + private Group(List actions, String title) { + setPopup(true); + for (AnAction each : actions) { + add(each); + } + myTitle = title; + } + + @Override + public void update(AnActionEvent e) { + e.getPresentation().setText(myTitle); + } + } +} \ No newline at end of file diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 329ae7f28f01..d8022a713e01 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -15,6 +15,8 @@ --> + + diff --git a/platform/platform-resources/src/keymaps/$default.xml b/platform/platform-resources/src/keymaps/$default.xml index d3079c49d7e7..ca88b59a9742 100644 --- a/platform/platform-resources/src/keymaps/$default.xml +++ b/platform/platform-resources/src/keymaps/$default.xml @@ -1041,4 +1041,8 @@ + + + + \ No newline at end of file diff --git a/platform/testFramework/extensions/src/com/intellij/keymap/KeymapsTestCase.java b/platform/testFramework/extensions/src/com/intellij/keymap/KeymapsTestCase.java index 5080c1ccae8f..a00dd7842a21 100644 --- a/platform/testFramework/extensions/src/com/intellij/keymap/KeymapsTestCase.java +++ b/platform/testFramework/extensions/src/com/intellij/keymap/KeymapsTestCase.java @@ -143,6 +143,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase { { "control alt Z", "Vcs.RollbackChangedLines", "ChangesView.Revert"}, { "control TAB", "Switcher", "Diff.FocusOppositePane"}, { "shift control TAB", "Switcher", "Diff.FocusOppositePaneAndScroll"}, + { "ctrl alt ENTER", "EditorStartNewLineBefore", "QuickActionPopup"}, }); put("Mac OS X 10.5+", new String[][] { { "F5", "CopyElement", "Console.TableResult.Reload", "UML.ApplyCurrentLayout"}, From e834a468fa2859f2727ce4b504e267959e76971a Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 20 Feb 2017 12:39:21 +0300 Subject: [PATCH 27/38] ui: restore QuickActionProvider implementations this commit partially reverts 054bb2ae01cafd44cd70e109db18a1c95732e568 2b58d760c32e860e18a3e7714d1aae869c29859d b4b84a480707c6543bacbe336a07608c53a30c88 --- .../ui/layout/impl/RunnerContentUi.java | 53 ++++++++++- .../ui/layout/impl/RunnerLayoutUiImpl.java | 3 +- .../ide/projectView/impl/ProjectViewImpl.java | 93 ++++++++++++++++++- .../openapi/ui/SimpleToolWindowPanel.java | 15 ++- .../com/intellij/ui/tabs/impl/JBTabsImpl.java | 28 +++++- .../actionSystem/impl/ActionToolbarImpl.java | 13 ++- .../edu/learning/StudyProjectComponent.java | 2 +- 7 files changed, 192 insertions(+), 15 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java index a958238a676c..0f24b58ae39b 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java @@ -47,11 +47,13 @@ import com.intellij.ui.docking.DockManager; import com.intellij.ui.docking.DockableContent; import com.intellij.ui.docking.DragSession; import com.intellij.ui.docking.impl.DockManagerImpl; +import com.intellij.ui.switcher.QuickActionProvider; import com.intellij.ui.tabs.JBTabs; import com.intellij.ui.tabs.TabInfo; import com.intellij.ui.tabs.TabsListener; import com.intellij.ui.tabs.impl.JBTabsImpl; import com.intellij.util.NotNullFunction; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.AbstractLayoutManager; import com.intellij.util.ui.GraphicsUtil; import com.intellij.util.ui.JBUI; @@ -75,7 +77,7 @@ import java.util.concurrent.CopyOnWriteArraySet; import java.util.stream.Collectors; public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Facade, ViewContextEx, PropertyChangeListener, - DockContainer.Dialog { + QuickActionProvider, DockContainer.Dialog { public static final DataKey KEY = DataKey.create("DebuggerContentUI"); public static final Key LIGHTWEIGHT_CONTENT_MARKER = Key.create("LightweightContent"); @@ -618,6 +620,11 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac return myOriginal != null; } + @Override + public boolean isCycleRoot() { + return false; + } + @Override public void setManager(@NotNull final ContentManager manager) { assert myManager == null; @@ -1351,7 +1358,7 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac } } - private class MyComponent extends NonOpaquePanel implements DataProvider { + private class MyComponent extends NonOpaquePanel implements DataProvider, QuickActionProvider { private boolean myWasEverAdded; public MyComponent(LayoutManager layout) { @@ -1364,7 +1371,10 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac @Override @Nullable public Object getData(@NonNls final String dataId) { - if (CloseAction.CloseTarget.KEY.is(dataId)) { + if (QuickActionProvider.KEY.is(dataId)) { + return RunnerContentUi.this; + } + else if (CloseAction.CloseTarget.KEY.is(dataId)) { Content content = getContentManager().getSelectedContent(); if (content != null && content.getManager().canCloseContents() && content.isCloseable()) { return new CloseAction.CloseTarget() { @@ -1384,6 +1394,27 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac return null; } + @NotNull + @Override + public String getName() { + return RunnerContentUi.this.getName(); + } + + @Override + public List getActions(boolean originalProvider) { + return RunnerContentUi.this.getActions(originalProvider); + } + + @Override + public JComponent getComponent() { + return RunnerContentUi.this.getComponent(); + } + + @Override + public boolean isCycleRoot() { + return RunnerContentUi.this.isCycleRoot(); + } + @Override public void addNotify() { super.addNotify(); @@ -1671,6 +1702,22 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac return myRunnerUi; } + @NotNull + @Override + public String getName() { + return mySessionName; + } + + @Override + public List getActions(boolean originalProvider) { + ArrayList result = new ArrayList<>(); + if (myLeftToolbarActions != null) { + AnAction[] kids = myLeftToolbarActions.getChildren(null); + ContainerUtil.addAll(result, kids); + } + return result; + } + private int findFreeWindow() { int i; for (i = 1; i < Integer.MAX_VALUE; i++) { diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiImpl.java index 707ad5344f60..c5f40a5bd1df 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiImpl.java @@ -36,6 +36,7 @@ import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; import com.intellij.ui.content.ContentManager; import com.intellij.ui.content.ContentManagerListener; +import com.intellij.ui.switcher.QuickActionProvider; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -376,7 +377,7 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La @Nullable @Override public Object getData(@NonNls String dataId) { - if (RunnerContentUi.KEY.is(dataId)) { + if (QuickActionProvider.KEY.is(dataId) || RunnerContentUi.KEY.is(dataId)) { return myContentUI; } return null; diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java index 2151736b31c5..e113a545b39e 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -82,6 +82,7 @@ import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentManager; import com.intellij.ui.content.ContentManagerAdapter; import com.intellij.ui.content.ContentManagerEvent; +import com.intellij.ui.switcher.QuickActionProvider; import com.intellij.util.ArrayUtil; import com.intellij.util.IJSwingUtilities; import com.intellij.util.PlatformIcons; @@ -106,7 +107,7 @@ import java.util.*; import java.util.List; @State(name = "ProjectView", storages = @Storage(StoragePathMacros.WORKSPACE_FILE)) -public class ProjectViewImpl extends ProjectView implements PersistentStateComponent, Disposable, BusyObject { +public class ProjectViewImpl extends ProjectView implements PersistentStateComponent, Disposable, QuickActionProvider, BusyObject { private static final Logger LOG = Logger.getInstance("#com.intellij.ide.projectView.impl.ProjectViewImpl"); private static final Key ID_KEY = Key.create("pane-id"); private static final Key SUB_ID_KEY = Key.create("pane-sub-id"); @@ -253,14 +254,93 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo private void constructUi() { myViewContentPanel = new JPanel(); - myPanel = new SimpleToolWindowPanel(true); + myPanel = new SimpleToolWindowPanel(true).setProvideQuickActions(false); myPanel.setContent(myViewContentPanel); } @NotNull - @Deprecated + @Override + public String getName() { + return "Project"; + } + + @Override + @NotNull public List getActions(boolean originalProvider) { - return Collections.emptyList(); + ArrayList result = new ArrayList<>(); + + DefaultActionGroup views = new DefaultActionGroup("Change View", true); + boolean lastHeaderHadKids = false; + for (int i = 0; i < myContentManager.getContentCount(); i++) { + Content each = myContentManager.getContent(i); + if (each != null) { + if (each.getUserData(SUB_ID_KEY) == null) { + if (lastHeaderHadKids) { + views.add(new Separator()); + } else { + if (i + 1 < myContentManager.getContentCount()) { + Content next = myContentManager.getContent(i + 1); + if (next != null) { + if (next.getUserData(SUB_ID_KEY) != null) { + views.add(new Separator()); + } + } + } + } + } + else { + lastHeaderHadKids = true; + } + + views.add(new ChangeViewAction(each.getUserData(ID_KEY), each.getUserData(SUB_ID_KEY))); + } + } + result.add(views); + result.add(new Separator()); + + + List secondary = new ArrayList<>(); + if (myActionGroup != null) { + AnAction[] kids = myActionGroup.getChildren(null); + for (AnAction each : kids) { + if (myActionGroup.isPrimary(each)) { + result.add(each); + } + else { + secondary.add(each); + } + } + } + result.add(new Separator()); + result.addAll(secondary); + + return result; + } + + private class ChangeViewAction extends AnAction { + private final String myId; + private final String mySubId; + + private ChangeViewAction(@NotNull String id, String subId) { + myId = id; + mySubId = subId; + } + + @Override + public void update(AnActionEvent e) { + AbstractProjectViewPane pane = getProjectViewPaneById(myId); + e.getPresentation().setText(pane.getTitle() + (mySubId != null ? (" - " + pane.getPresentableSubIdName(mySubId)) : "")); + } + + @Override + public void actionPerformed(AnActionEvent e) { + changeView(myId, mySubId); + } + } + + @Override + public boolean isCycleRoot() { + return false; } @Override @@ -729,6 +809,7 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo myConnection.disconnect(); } + @Override public JComponent getComponent() { return myDataProvider; } @@ -1060,6 +1141,10 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo return selectedElements.isEmpty() ? null : selectedElements.toArray(new NamedLibraryElement[selectedElements.size()]); } + if (QuickActionProvider.KEY.is(dataId)) { + return ProjectViewImpl.this; + } + return null; } diff --git a/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java b/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java index 90b3b6bb347f..9e5e428cc3d1 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java @@ -18,6 +18,7 @@ package com.intellij.openapi.ui; import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.ui.switcher.QuickActionProvider; import com.intellij.util.containers.JBIterable; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; @@ -29,13 +30,14 @@ import java.awt.event.ContainerAdapter; import java.awt.event.ContainerEvent; import java.util.List; -public class SimpleToolWindowPanel extends JPanel implements DataProvider { +public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider, DataProvider { private JComponent myToolbar; private JComponent myContent; private boolean myBorderless; protected boolean myVertical; + private boolean myProvideQuickActions; public SimpleToolWindowPanel(boolean vertical) { this(vertical, false); @@ -45,6 +47,7 @@ public class SimpleToolWindowPanel extends JPanel implements DataProvider { setLayout(new BorderLayout(vertical ? 0 : 1, vertical ? 1 : 0)); myBorderless = borderless; myVertical = vertical; + setProvideQuickActions(true); addContainerListener(new ContainerAdapter() { @Override @@ -94,15 +97,15 @@ public class SimpleToolWindowPanel extends JPanel implements DataProvider { @Nullable public Object getData(@NonNls String dataId) { - return null; + return QuickActionProvider.KEY.is(dataId) && myProvideQuickActions ? this : null; } - @Deprecated public SimpleToolWindowPanel setProvideQuickActions(boolean provide) { + myProvideQuickActions = provide; return this; } - public List getActions() { + public List getActions(boolean originalProvider) { JBIterable toolbars = UIUtil.uiTraverser(myToolbar).traverse().filter(ActionToolbar.class); if (toolbars.size() == 0) return null; @@ -113,6 +116,10 @@ public class SimpleToolWindowPanel extends JPanel implements DataProvider { return this; } + public boolean isCycleRoot() { + return false; + } + public void setContent(JComponent c) { myContent = c; add(c, BorderLayout.CENTER); diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java index 1d38e07d226c..aefe23f361c9 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java @@ -28,6 +28,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.*; import com.intellij.ui.*; import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.switcher.QuickActionProvider; import com.intellij.ui.tabs.*; import com.intellij.ui.tabs.impl.singleRow.ScrollableSingleRowLayout; import com.intellij.ui.tabs.impl.singleRow.SingleRowLayout; @@ -60,7 +61,7 @@ import java.util.List; public class JBTabsImpl extends JComponent implements JBTabs, PropertyChangeListener, TimerListener, DataProvider, PopupMenuListener, Disposable, JBTabsPresentation, Queryable, - UISettingsListener, Accessible { + UISettingsListener, QuickActionProvider, Accessible { public static final DataKey NAVIGATION_ACTIONS_KEY = DataKey.create("JBTabs"); @NonNls public static final Key SIDE_TABS_SIZE_LIMIT_KEY = Key.create("SIDE_TABS_SIZE_LIMIT_KEY"); @@ -2686,6 +2687,11 @@ public class JBTabsImpl extends JComponent return this; } + @Override + public boolean isCycleRoot() { + return false; + } + private void addListeners() { for (TabInfo eachInfo : myVisibleInfos) { final TabLabel label = myInfo2Label.get(eachInfo); @@ -3115,9 +3121,29 @@ public class JBTabsImpl extends JComponent if (value != null) return value; } + if (QuickActionProvider.KEY.getName().equals(dataId)) { + return this; + } + return NAVIGATION_ACTIONS_KEY.is(dataId) ? this : null; } + @Override + public List getActions(boolean originalProvider) { + ArrayList result = new ArrayList<>(); + + TabInfo selection = getSelectedInfo(); + if (selection != null) { + ActionGroup group = selection.getGroup(); + if (group != null) { + AnAction[] children = group.getChildren(null); + Collections.addAll(result, children); + } + } + + return result; + } + @Override public DataProvider getDataProvider() { return myDataProvider; diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java index fc3c1ac16ecd..8396476759c3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java @@ -38,6 +38,7 @@ import com.intellij.ui.Gray; import com.intellij.ui.JBColor; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.awt.RelativeRectangle; +import com.intellij.ui.switcher.QuickActionProvider; import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.*; @@ -59,7 +60,7 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; -public class ActionToolbarImpl extends JPanel implements ActionToolbar { +public class ActionToolbarImpl extends JPanel implements ActionToolbar, QuickActionProvider { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.actionSystem.impl.ActionToolbarImpl"); private static final List ourToolbars = new LinkedList<>(); @@ -1237,6 +1238,16 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar { mySecondaryActions.getTemplatePresentation().setDescription(secondaryActionsTooltip); } + @Override + public boolean isCycleRoot() { + return false; + } + + @Override + public List getActions(boolean originalProvider) { + return getActions(); + } + @NotNull @Override public List getActions() { diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java index 09cf96aca171..4cd698fc28c4 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java @@ -130,7 +130,7 @@ public class StudyProjectComponent implements ProjectComponent { private void registerShortcuts() { StudyToolWindow window = StudyUtils.getStudyToolWindow(myProject); if (window != null) { - List actionsOnToolbar = window.getActions(); + List actionsOnToolbar = window.getActions(true); if (actionsOnToolbar != null) { for (AnAction action : actionsOnToolbar) { if (action instanceof StudyActionWithShortcut) { From 470a462e57b1844ffaed9e378beb0637e9db1e69 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 20 Feb 2017 12:51:34 +0300 Subject: [PATCH 28/38] ui: QuickActionProvider - add default method implementation --- .../src/com/intellij/ui/switcher/QuickActionProvider.java | 2 +- .../intellij/execution/ui/layout/impl/RunnerContentUi.java | 5 ----- .../com/intellij/ide/projectView/impl/ProjectViewImpl.java | 5 ----- .../src/com/intellij/openapi/ui/SimpleToolWindowPanel.java | 4 ---- .../src/com/intellij/ui/tabs/impl/JBTabsImpl.java | 5 ----- .../openapi/actionSystem/impl/ActionToolbarImpl.java | 5 ----- 6 files changed, 1 insertion(+), 25 deletions(-) diff --git a/platform/editor-ui-api/src/com/intellij/ui/switcher/QuickActionProvider.java b/platform/editor-ui-api/src/com/intellij/ui/switcher/QuickActionProvider.java index 1dc3946e7e9e..3c880db543ce 100644 --- a/platform/editor-ui-api/src/com/intellij/ui/switcher/QuickActionProvider.java +++ b/platform/editor-ui-api/src/com/intellij/ui/switcher/QuickActionProvider.java @@ -29,7 +29,7 @@ public interface QuickActionProvider { @Nullable List getActions(boolean originalProvider); - boolean isCycleRoot(); + default boolean isCycleRoot() { return false; } @Nullable JComponent getComponent(); diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java index 0f24b58ae39b..32d4b0fe4c32 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java @@ -620,11 +620,6 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac return myOriginal != null; } - @Override - public boolean isCycleRoot() { - return false; - } - @Override public void setManager(@NotNull final ContentManager manager) { assert myManager == null; diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java index e113a545b39e..b0f8c97336f8 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -338,11 +338,6 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo } } - @Override - public boolean isCycleRoot() { - return false; - } - @Override public synchronized void addProjectPane(@NotNull final AbstractProjectViewPane pane) { myUninitializedPanes.add(pane); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java b/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java index 9e5e428cc3d1..b8de0f651047 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java @@ -116,10 +116,6 @@ public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider return this; } - public boolean isCycleRoot() { - return false; - } - public void setContent(JComponent c) { myContent = c; add(c, BorderLayout.CENTER); diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java index aefe23f361c9..d5e25f76b64f 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java @@ -2687,11 +2687,6 @@ public class JBTabsImpl extends JComponent return this; } - @Override - public boolean isCycleRoot() { - return false; - } - private void addListeners() { for (TabInfo eachInfo : myVisibleInfos) { final TabLabel label = myInfo2Label.get(eachInfo); diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java index 8396476759c3..93516628fe0b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java @@ -1238,11 +1238,6 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar, QuickAct mySecondaryActions.getTemplatePresentation().setDescription(secondaryActionsTooltip); } - @Override - public boolean isCycleRoot() { - return false; - } - @Override public List getActions(boolean originalProvider) { return getActions(); From 56772a1bbdf118e6b4444b63d9150b8d23da7834 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 20 Feb 2017 12:55:16 +0300 Subject: [PATCH 29/38] ui: QuickActionProvider - mark method as @NotNull it might've throw NPE for enclosed providers anyway --- .../ui/switcher/QuickActionProvider.java | 2 +- .../ui/layout/impl/RunnerContentUi.java | 2 ++ .../openapi/ui/SimpleToolWindowPanel.java | 6 ++++-- .../switcher/ShowQuickActionPopupAction.java | 4 ++-- .../com/intellij/ui/tabs/impl/JBTabsImpl.java | 1 + .../actionSystem/impl/ActionToolbarImpl.java | 1 + .../edu/learning/StudyProjectComponent.java | 21 +++++++------------ 7 files changed, 19 insertions(+), 18 deletions(-) diff --git a/platform/editor-ui-api/src/com/intellij/ui/switcher/QuickActionProvider.java b/platform/editor-ui-api/src/com/intellij/ui/switcher/QuickActionProvider.java index 3c880db543ce..bbad28c414cd 100644 --- a/platform/editor-ui-api/src/com/intellij/ui/switcher/QuickActionProvider.java +++ b/platform/editor-ui-api/src/com/intellij/ui/switcher/QuickActionProvider.java @@ -26,7 +26,7 @@ import java.util.List; public interface QuickActionProvider { DataKey KEY = DataKey.create("QuickActionProvider"); - @Nullable + @NotNull List getActions(boolean originalProvider); default boolean isCycleRoot() { return false; } diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java index 32d4b0fe4c32..5dd012866127 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java @@ -1395,6 +1395,7 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac return RunnerContentUi.this.getName(); } + @NotNull @Override public List getActions(boolean originalProvider) { return RunnerContentUi.this.getActions(originalProvider); @@ -1703,6 +1704,7 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac return mySessionName; } + @NotNull @Override public List getActions(boolean originalProvider) { ArrayList result = new ArrayList<>(); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java b/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java index b8de0f651047..bed652b0fe01 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java @@ -22,12 +22,14 @@ import com.intellij.ui.switcher.QuickActionProvider; import com.intellij.util.containers.JBIterable; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.event.ContainerAdapter; import java.awt.event.ContainerEvent; +import java.util.Collections; import java.util.List; public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider, DataProvider { @@ -105,10 +107,10 @@ public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider return this; } + @NotNull public List getActions(boolean originalProvider) { JBIterable toolbars = UIUtil.uiTraverser(myToolbar).traverse().filter(ActionToolbar.class); - if (toolbars.size() == 0) - return null; + if (toolbars.size() == 0) return Collections.emptyList(); return toolbars.flatten(toolbar -> toolbar.getActions()).toList(); } diff --git a/platform/platform-api/src/com/intellij/ui/switcher/ShowQuickActionPopupAction.java b/platform/platform-api/src/com/intellij/ui/switcher/ShowQuickActionPopupAction.java index 48359779ef4d..9bd61c715d2b 100644 --- a/platform/platform-api/src/com/intellij/ui/switcher/ShowQuickActionPopupAction.java +++ b/platform/platform-api/src/com/intellij/ui/switcher/ShowQuickActionPopupAction.java @@ -36,7 +36,7 @@ public class ShowQuickActionPopupAction extends AnAction { } else { List actions = quickActionProvider.getActions(true); - e.getPresentation().setEnabled(actions != null && !actions.isEmpty()); + e.getPresentation().setEnabled(!actions.isEmpty()); } } @@ -47,7 +47,7 @@ public class ShowQuickActionPopupAction extends AnAction { if (provider == null) return; List actions = provider.getActions(true); - if (actions != null && actions.size() > 0) { + if (actions.size() > 0) { DefaultActionGroup group = new DefaultActionGroup(); for (AnAction each : actions) { group.add(each); diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java index d5e25f76b64f..f3ac1110488a 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java @@ -3123,6 +3123,7 @@ public class JBTabsImpl extends JComponent return NAVIGATION_ACTIONS_KEY.is(dataId) ? this : null; } + @NotNull @Override public List getActions(boolean originalProvider) { ArrayList result = new ArrayList<>(); diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java index 93516628fe0b..b2103ce43c42 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java @@ -1238,6 +1238,7 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar, QuickAct mySecondaryActions.getTemplatePresentation().setDescription(secondaryActionsTooltip); } + @NotNull @Override public List getActions(boolean originalProvider) { return getActions(); diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java index 4cd698fc28c4..a3024f0d79ee 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java @@ -131,22 +131,17 @@ public class StudyProjectComponent implements ProjectComponent { StudyToolWindow window = StudyUtils.getStudyToolWindow(myProject); if (window != null) { List actionsOnToolbar = window.getActions(true); - if (actionsOnToolbar != null) { - for (AnAction action : actionsOnToolbar) { - if (action instanceof StudyActionWithShortcut) { - String id = ((StudyActionWithShortcut)action).getActionId(); - String[] shortcuts = ((StudyActionWithShortcut)action).getShortcuts(); - if (shortcuts != null) { - addShortcut(id, shortcuts); - } + for (AnAction action : actionsOnToolbar) { + if (action instanceof StudyActionWithShortcut) { + String id = ((StudyActionWithShortcut)action).getActionId(); + String[] shortcuts = ((StudyActionWithShortcut)action).getShortcuts(); + if (shortcuts != null) { + addShortcut(id, shortcuts); } } - addShortcut(StudyNextWindowAction.ACTION_ID, new String[]{StudyNextWindowAction.SHORTCUT, StudyNextWindowAction.SHORTCUT2}); - addShortcut(StudyPrevWindowAction.ACTION_ID, new String[]{StudyPrevWindowAction.SHORTCUT}); - } - else { - LOG.warn("Actions on toolbar are nulls"); } + addShortcut(StudyNextWindowAction.ACTION_ID, new String[]{StudyNextWindowAction.SHORTCUT, StudyNextWindowAction.SHORTCUT2}); + addShortcut(StudyPrevWindowAction.ACTION_ID, new String[]{StudyPrevWindowAction.SHORTCUT}); } } From e09a03c4a13679839d992846f363e2884a5f440f Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 20 Feb 2017 12:59:24 +0300 Subject: [PATCH 30/38] ui: simplify ShowQuickActionPopupAction --- .../switcher/ShowQuickActionPopupAction.java | 84 ++++++++----------- 1 file changed, 36 insertions(+), 48 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/switcher/ShowQuickActionPopupAction.java b/platform/platform-api/src/com/intellij/ui/switcher/ShowQuickActionPopupAction.java index 9bd61c715d2b..ab1c529d7949 100644 --- a/platform/platform-api/src/com/intellij/ui/switcher/ShowQuickActionPopupAction.java +++ b/platform/platform-api/src/com/intellij/ui/switcher/ShowQuickActionPopupAction.java @@ -17,11 +17,13 @@ package com.intellij.ui.switcher; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.DefaultActionGroup; -import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.actionSystem.Separator; import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.ObjectUtils; +import javax.swing.*; import java.awt.*; import java.util.List; @@ -30,65 +32,51 @@ import static com.intellij.openapi.ui.popup.JBPopupFactory.ActionSelectionAid.AL public class ShowQuickActionPopupAction extends AnAction { @Override public void update(AnActionEvent e) { - QuickActionProvider quickActionProvider = QuickActionProvider.KEY.getData(e.getDataContext()); + QuickActionProvider quickActionProvider = e.getData(QuickActionProvider.KEY); if (quickActionProvider == null) { e.getPresentation().setEnabled(false); + return; } - else { - List actions = quickActionProvider.getActions(true); - e.getPresentation().setEnabled(!actions.isEmpty()); - } + + List actions = quickActionProvider.getActions(true); + e.getPresentation().setEnabled(!actions.isEmpty()); } + @Override public void actionPerformed(AnActionEvent e) { - DataContext context = e.getDataContext(); - QuickActionProvider provider = QuickActionProvider.KEY.getData(context); - if (provider == null) return; - + QuickActionProvider provider = e.getRequiredData(QuickActionProvider.KEY); List actions = provider.getActions(true); - if (actions.size() > 0) { - DefaultActionGroup group = new DefaultActionGroup(); - for (AnAction each : actions) { - group.add(each); - } - boolean firstParent = true; - Component eachParent = provider.getComponent().getParent(); + DefaultActionGroup group = new DefaultActionGroup(actions); + group.addSeparator(); + + JComponent component = provider.getComponent(); + if (component != null && !provider.isCycleRoot()) { + Component eachParent = component.getParent(); while (eachParent != null) { - if (eachParent instanceof QuickActionProvider) { - QuickActionProvider eachProvider = (QuickActionProvider)eachParent; - if (firstParent) { - group.addSeparator(); - firstParent = false; + QuickActionProvider parentProvider = ObjectUtils.tryCast(eachParent, QuickActionProvider.class); + if (parentProvider != null) { + List parentActions = parentProvider.getActions(false); + if (!parentActions.isEmpty()) { + String name = StringUtil.notNullize(parentProvider.getName(), ""); + DefaultActionGroup parentGroup = new DefaultActionGroup(name, parentActions); + if (!StringUtil.isEmpty(name)) { + parentGroup.setPopup(true); + } + else { + group.add(Separator.getInstance()); + } + group.add(parentGroup); } - List eachActionList = eachProvider.getActions(false); - if (eachActionList.size() > 0) { - group.add(new Group(eachActionList, eachProvider.getName())); - } - if (eachProvider.isCycleRoot()) break; + if (parentProvider.isCycleRoot()) break; } eachParent = eachParent.getParent(); } - - JBPopupFactory.getInstance().createActionGroupPopup(null, group, context, ALPHA_NUMBERING, true).showInBestPositionFor(context); } + + JBPopupFactory.getInstance() + .createActionGroupPopup(null, group, e.getDataContext(), ALPHA_NUMBERING, true) + .showInBestPositionFor(e.getDataContext()); } - - private static class Group extends DefaultActionGroup implements DumbAware { - private String myTitle; - - private Group(List actions, String title) { - setPopup(true); - for (AnAction each : actions) { - add(each); - } - myTitle = title; - } - - @Override - public void update(AnActionEvent e) { - e.getPresentation().setText(myTitle); - } - } -} \ No newline at end of file +} From 4269ba3ea4dbbae169b29c6710ccc55055d074f6 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 20 Feb 2017 13:08:45 +0300 Subject: [PATCH 31/38] ui: QuickActionProvider - fix separators in project view --- .../ide/projectView/impl/ProjectViewImpl.java | 60 +++++++++---------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java index b0f8c97336f8..493d9d2482fe 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -264,45 +264,40 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo return "Project"; } - @Override @NotNull + @Override public List getActions(boolean originalProvider) { - ArrayList result = new ArrayList<>(); + List result = new ArrayList<>(); DefaultActionGroup views = new DefaultActionGroup("Change View", true); - boolean lastHeaderHadKids = false; + + ChangeViewAction lastHeader = null; for (int i = 0; i < myContentManager.getContentCount(); i++) { Content each = myContentManager.getContent(i); - if (each != null) { - if (each.getUserData(SUB_ID_KEY) == null) { - if (lastHeaderHadKids) { - views.add(new Separator()); - } else { - if (i + 1 < myContentManager.getContentCount()) { - Content next = myContentManager.getContent(i + 1); - if (next != null) { - if (next.getUserData(SUB_ID_KEY) != null) { - views.add(new Separator()); - } - } - } - } - } - else { - lastHeaderHadKids = true; - } + if (each == null) continue; - views.add(new ChangeViewAction(each.getUserData(ID_KEY), each.getUserData(SUB_ID_KEY))); + String id = each.getUserData(ID_KEY); + String subId = each.getUserData(SUB_ID_KEY); + ChangeViewAction newHeader = new ChangeViewAction(id, subId); + + if (lastHeader != null) { + boolean lastHasKids = lastHeader.mySubId != null; + boolean newHasKids = newHeader.mySubId != null; + if (lastHasKids != newHasKids || + lastHasKids && lastHeader.myId != newHeader.myId) { + views.add(Separator.getInstance()); + } } + + views.add(newHeader); + lastHeader = newHeader; } result.add(views); - result.add(new Separator()); + result.add(Separator.getInstance()); - - List secondary = new ArrayList<>(); if (myActionGroup != null) { - AnAction[] kids = myActionGroup.getChildren(null); - for (AnAction each : kids) { + List secondary = new ArrayList<>(); + for (AnAction each : myActionGroup.getChildren(null)) { if (myActionGroup.isPrimary(each)) { result.add(each); } @@ -310,18 +305,19 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo secondary.add(each); } } + + result.add(Separator.getInstance()); + result.addAll(secondary); } - result.add(new Separator()); - result.addAll(secondary); return result; } private class ChangeViewAction extends AnAction { - private final String myId; - private final String mySubId; + @NotNull private final String myId; + @Nullable private final String mySubId; - private ChangeViewAction(@NotNull String id, String subId) { + private ChangeViewAction(@NotNull String id, @Nullable String subId) { myId = id; mySubId = subId; } From a673a5c82c290ea64a9f4f3870c2a1826110a5f7 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 20 Feb 2017 14:24:31 +0300 Subject: [PATCH 32/38] git: do not log traces for info messages --- plugins/git4idea/src/git4idea/merge/GitMergeProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java b/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java index 79d846ed3902..fc82b74c29ee 100644 --- a/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java +++ b/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java @@ -303,14 +303,14 @@ public class GitMergeProvider implements MergeProvider2 { return GitRevisionNumber.resolve(myProject, root, MERGE_HEAD); } catch (VcsException e) { - LOG.info("Couldn't resolve the MERGE_HEAD in " + root, e); // this may be not a bug, just cherry-pick + LOG.info("Couldn't resolve the MERGE_HEAD in " + root + ": " + e.getMessage()); // this may be not a bug, just cherry-pick } try { return GitRevisionNumber.resolve(myProject, root, CHERRY_PICK_HEAD); } catch (VcsException e) { - LOG.info("Couldn't resolve the CHERRY_PICK_HEAD in " + root, e); + LOG.info("Couldn't resolve the CHERRY_PICK_HEAD in " + root + ": " + e.getMessage()); } GitRepository repository = GitUtil.getRepositoryManager(myProject).getRepositoryForRoot(root); From a28498e2d4539f5c23dff025cbfd6a7f2bebff30 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 20 Feb 2017 15:39:38 +0300 Subject: [PATCH 33/38] ui: fix action title capitalisation --- 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 d8022a713e01..32f974feeb4e 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -15,7 +15,7 @@ --> - + From 1344f56dcbf449bd153acd379c47c9b20de4ceb5 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 20 Feb 2017 12:30:32 +0100 Subject: [PATCH 34/38] Cleanup (warnings; formatting) --- .../deprecation/DeprecationInspection.java | 130 +++++++++--------- .../impl/analysis/HighlightMessageUtil.java | 47 ++++--- .../impl/source/resolve/ResolveClassUtil.java | 66 ++++----- 3 files changed, 116 insertions(+), 127 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java index 6c3a1a4600f1..813cc819b320 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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,7 +28,6 @@ import com.intellij.psi.*; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; import com.intellij.psi.util.PsiTreeUtil; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,8 +38,8 @@ import java.util.List; * @author max */ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool { - @NonNls public static final String SHORT_NAME = DeprecationUtil.DEPRECATION_SHORT_NAME; - @NonNls public static final String ID = DeprecationUtil.DEPRECATION_ID; + public static final String SHORT_NAME = DeprecationUtil.DEPRECATION_SHORT_NAME; + public static final String ID = DeprecationUtil.DEPRECATION_ID; public static final String DISPLAY_NAME = DeprecationUtil.DEPRECATION_DISPLAY_NAME; public static final String IGNORE_METHODS_OF_DEPRECATED_NAME = "IGNORE_METHODS_OF_DEPRECATED"; @@ -51,8 +50,8 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool { @Override @NotNull - public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { - return new DeprecationElementVisitor(holder, IGNORE_INSIDE_DEPRECATED, IGNORE_ABSTRACT_DEPRECATED_OVERRIDES, + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + return new DeprecationElementVisitor(holder, IGNORE_INSIDE_DEPRECATED, IGNORE_ABSTRACT_DEPRECATED_OVERRIDES, IGNORE_IMPORT_STATEMENTS, IGNORE_METHODS_OF_DEPRECATED); } @@ -76,7 +75,7 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool { @Override @NotNull - @NonNls + @SuppressWarnings("PatternOverriddenByNonAnnotatedMethod") public String getID() { return ID; } @@ -94,7 +93,6 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool { panel.addCheckbox("Ignore overrides of deprecated abstract methods from non-deprecated supers", "IGNORE_ABSTRACT_DEPRECATED_OVERRIDES"); panel.addCheckbox("Ignore members of deprecated classes", IGNORE_METHODS_OF_DEPRECATED_NAME); return panel; - } private static class DeprecationElementVisitor extends JavaElementVisitor { @@ -104,11 +102,11 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool { private final boolean myIgnoreImportStatements; private final boolean myIgnoreMethodsOfDeprecated; - DeprecationElementVisitor(@NotNull ProblemsHolder holder, - boolean ignoreInsideDeprecated, - boolean ignoreAbstractDeprecatedOverrides, - boolean ignoreImportStatements, - boolean ignoreMethodsOfDeprecated) { + private DeprecationElementVisitor(ProblemsHolder holder, + boolean ignoreInsideDeprecated, + boolean ignoreAbstractDeprecatedOverrides, + boolean ignoreImportStatements, + boolean ignoreMethodsOfDeprecated) { myHolder = holder; myIgnoreInsideDeprecated = ignoreInsideDeprecated; myIgnoreAbstractDeprecatedOverrides = ignoreAbstractDeprecatedOverrides; @@ -118,59 +116,63 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool { @Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { - JavaResolveResult result = reference.advancedResolve(true); - PsiElement resolved = result.getElement(); - checkDeprecated(resolved, reference.getReferenceNameElement(), null, myIgnoreInsideDeprecated, myIgnoreImportStatements, myIgnoreMethodsOfDeprecated, myHolder); + PsiElement resolved = reference.advancedResolve(true).getElement(); + PsiElement refName = reference.getReferenceNameElement(); + checkDeprecated(resolved, refName, null, myIgnoreInsideDeprecated, myIgnoreImportStatements, myIgnoreMethodsOfDeprecated, myHolder); } @Override public void visitImportStaticStatement(PsiImportStaticStatement statement) { - final PsiJavaCodeReferenceElement importReference = statement.getImportReference(); + PsiJavaCodeReferenceElement importReference = statement.getImportReference(); if (importReference != null) { - checkDeprecated(importReference.resolve(), importReference.getReferenceNameElement(), null, myIgnoreInsideDeprecated, false, true, myHolder); + PsiElement refName = importReference.getReferenceNameElement(); + checkDeprecated(importReference.resolve(), refName, null, myIgnoreInsideDeprecated, false, true, myHolder); } } - @Override public void visitReferenceExpression(PsiReferenceExpression expression) { + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { visitReferenceElement(expression); } - @Override public void visitNewExpression(PsiNewExpression expression) { + @Override + public void visitNewExpression(PsiNewExpression expression) { + PsiClass aClass = null; PsiType type = expression.getType(); - PsiExpressionList list = expression.getArgumentList(); - if (!(type instanceof PsiClassType)) return; - PsiClassType.ClassResolveResult typeResult = ((PsiClassType)type).resolveGenerics(); - PsiClass aClass = typeResult.getElement(); - if (aClass == null) return; - if (aClass instanceof PsiAnonymousClass) { - type = ((PsiAnonymousClass)aClass).getBaseClassType(); - typeResult = ((PsiClassType)type).resolveGenerics(); - aClass = typeResult.getElement(); - if (aClass == null) return; + if (type instanceof PsiClassType) { + aClass = ((PsiClassType)type).resolveGenerics().getElement(); + if (aClass instanceof PsiAnonymousClass) { + type = ((PsiAnonymousClass)aClass).getBaseClassType(); + aClass = ((PsiClassType)type).resolveGenerics().getElement(); + } } - final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(expression.getProject()).getResolveHelper(); - final PsiMethod[] constructors = aClass.getConstructors(); - if (constructors.length > 0 && list != null) { + if (aClass == null) return; + PsiExpressionList list = expression.getArgumentList(); + PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(expression.getProject()).getResolveHelper(); + if (list != null && aClass.getConstructors().length > 0) { JavaResolveResult[] results = resolveHelper.multiResolveConstructor((PsiClassType)type, list, list); MethodCandidateInfo result = null; if (results.length == 1) result = (MethodCandidateInfo)results[0]; PsiMethod constructor = result == null ? null : result.getElement(); - if (constructor != null && expression.getClassOrAnonymousClassReference() != null) { + PsiJavaCodeReferenceElement ref; + if (constructor != null && (ref = expression.getClassOrAnonymousClassReference()) != null) { if (expression.getClassReference() == null && constructor.getParameterList().getParametersCount() == 0) return; - checkDeprecated(constructor, expression.getClassOrAnonymousClassReference(), null, myIgnoreInsideDeprecated, myIgnoreImportStatements, true, myHolder); + checkDeprecated(constructor, ref, null, myIgnoreInsideDeprecated, myIgnoreImportStatements, true, myHolder); } } } - @Override public void visitMethod(PsiMethod method){ - MethodSignatureBackedByPsiMethod methodSignature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY); - if (!method.isConstructor()) { - List superMethodSignatures = method.findSuperMethodSignaturesIncludingStatic(true); - checkMethodOverridesDeprecated(methodSignature, superMethodSignatures, myIgnoreAbstractDeprecatedOverrides, myHolder); - } else { - checkImplicitCallToSuper(method); - } + @Override + public void visitMethod(PsiMethod method) { + MethodSignatureBackedByPsiMethod methodSignature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY); + if (!method.isConstructor()) { + List superMethodSignatures = method.findSuperMethodSignaturesIncludingStatic(true); + checkMethodOverridesDeprecated(methodSignature, superMethodSignatures, myIgnoreAbstractDeprecatedOverrides, myHolder); + } + else { + checkImplicitCallToSuper(method); + } } private void checkImplicitCallToSuper(PsiMethod method) { @@ -193,8 +195,8 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool { } private void registerDefaultConstructorProblem(PsiClass superClass, PsiElement nameIdentifier, boolean asDeprecated) { - myHolder.registerProblem(nameIdentifier, "Default constructor in " + superClass.getQualifiedName() + " is deprecated", - asDeprecated ? ProblemHighlightType.LIKE_DEPRECATED : ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + ProblemHighlightType type = asDeprecated ? ProblemHighlightType.LIKE_DEPRECATED : ProblemHighlightType.GENERIC_ERROR_OR_WARNING; + myHolder.registerProblem(nameIdentifier, "Default constructor in " + superClass.getQualifiedName() + " is deprecated", type); } @Override @@ -209,7 +211,8 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool { final PsiExpressionList argumentList = ((PsiAnonymousClass)aClass).getArgumentList(); if (argumentList != null && argumentList.getExpressions().length > 0) return; } - registerDefaultConstructorProblem(superClass, isAnonymous ? ((PsiAnonymousClass)aClass).getBaseClassReference() : aClass.getNameIdentifier(), isAnonymous); + PsiElement identifier = isAnonymous ? ((PsiAnonymousClass)aClass).getBaseClassReference() : aClass.getNameIdentifier(); + registerDefaultConstructorProblem(superClass, identifier, isAnonymous); } } } @@ -227,12 +230,13 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool { return false; } - //@top - static void checkMethodOverridesDeprecated(MethodSignatureBackedByPsiMethod methodSignature, - List superMethodSignatures, - boolean ignoreAbstractDeprecatedOverrides, ProblemsHolder holder) { + private static void checkMethodOverridesDeprecated(MethodSignatureBackedByPsiMethod methodSignature, + List superMethodSignatures, + boolean ignoreAbstractDeprecatedOverrides, + ProblemsHolder holder) { PsiMethod method = methodSignature.getMethod(); PsiElement methodName = method.getNameIdentifier(); + if (methodName == null) return; for (MethodSignatureBackedByPsiMethod superMethodSignature : superMethodSignatures) { PsiMethod superMethod = superMethodSignature.getMethod(); PsiClass aClass = superMethod.getContainingClass(); @@ -240,8 +244,7 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool { // do not show deprecated warning for class implementing deprecated methods if (ignoreAbstractDeprecatedOverrides && !aClass.isDeprecated() && superMethod.hasModifierProperty(PsiModifier.ABSTRACT)) continue; if (superMethod.isDeprecated()) { - String description = JavaErrorMessages.message("overrides.deprecated.method", - HighlightMessageUtil.getSymbolName(aClass, PsiSubstitutor.EMPTY)); + String description = JavaErrorMessages.message("overrides.deprecated.method", HighlightMessageUtil.getSymbolName(aClass)); holder.registerProblem(methodName, description, ProblemHighlightType.LIKE_DEPRECATED); } } @@ -254,17 +257,18 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool { checkDeprecated(refElement, elementToHighlight, rangeInElement, false, false, true, holder); } - static void checkDeprecated(PsiElement refElement, - PsiElement elementToHighlight, - @Nullable TextRange rangeInElement, - boolean ignoreInsideDeprecated, - boolean ignoreImportStatements, - boolean ignoreMethodsOfDeprecated, - ProblemsHolder holder) { + private static void checkDeprecated(PsiElement refElement, + PsiElement elementToHighlight, + @Nullable TextRange rangeInElement, + boolean ignoreInsideDeprecated, + boolean ignoreImportStatements, + boolean ignoreMethodsOfDeprecated, + ProblemsHolder holder) { if (!(refElement instanceof PsiDocCommentOwner)) return; + if (!((PsiDocCommentOwner)refElement).isDeprecated()) { if (!ignoreMethodsOfDeprecated) { - checkDeprecated(((PsiDocCommentOwner)refElement).getContainingClass(), elementToHighlight, rangeInElement, + checkDeprecated(((PsiDocCommentOwner)refElement).getContainingClass(), elementToHighlight, rangeInElement, ignoreInsideDeprecated, ignoreImportStatements, false, holder); } return; @@ -281,9 +285,7 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool { return; } - String description = JavaErrorMessages.message("deprecated.symbol", - HighlightMessageUtil.getSymbolName(refElement, PsiSubstitutor.EMPTY)); - + String description = JavaErrorMessages.message("deprecated.symbol", HighlightMessageUtil.getSymbolName(refElement)); holder.registerProblem(elementToHighlight, description, ProblemHighlightType.LIKE_DEPRECATED, rangeInElement); } -} +} \ No newline at end of file diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java index 078a49974ca5..42ee7bc215db 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java @@ -1,18 +1,18 @@ /* -* Copyright 2000-2009 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. -*/ + * Copyright 2000-2017 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.codeInsight.daemon.impl.analysis; import com.intellij.lang.LangBundle; @@ -26,12 +26,18 @@ public class HighlightMessageUtil { private HighlightMessageUtil() { } @Nullable - public static String getSymbolName(@NotNull PsiElement symbol, PsiSubstitutor substitutor) { - return getSymbolName(symbol, substitutor, PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.SHOW_FQ_CLASS_NAMES | PsiFormatUtilBase.USE_INTERNAL_CANONICAL_TEXT); + public static String getSymbolName(@NotNull PsiElement symbol) { + return getSymbolName(symbol, PsiSubstitutor.EMPTY); } @Nullable - public static String getSymbolName(@NotNull PsiElement symbol, PsiSubstitutor substitutor, final int parameterOptions) { + public static String getSymbolName(@NotNull PsiElement symbol, PsiSubstitutor substitutor) { + int options = PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.SHOW_FQ_CLASS_NAMES | PsiFormatUtilBase.USE_INTERNAL_CANONICAL_TEXT; + return getSymbolName(symbol, substitutor, options); + } + + @Nullable + public static String getSymbolName(@NotNull PsiElement symbol, PsiSubstitutor substitutor, int parameterOptions) { String symbolName = null; if (symbol instanceof PsiClass) { @@ -46,9 +52,8 @@ public class HighlightMessageUtil { } } else if (symbol instanceof PsiMethod) { - symbolName = PsiFormatUtil.formatMethod((PsiMethod)symbol, - substitutor, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS, - parameterOptions); + int options = PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS; + symbolName = PsiFormatUtil.formatMethod((PsiMethod)symbol, substitutor, options, parameterOptions); } else if (symbol instanceof PsiVariable) { symbolName = ((PsiVariable)symbol).getName(); @@ -67,4 +72,4 @@ public class HighlightMessageUtil { return symbolName; } -} +} \ No newline at end of file diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ResolveClassUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ResolveClassUtil.java index 2bedff69ed04..45665654b324 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ResolveClassUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ResolveClassUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ */ package com.intellij.psi.impl.source.resolve; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl; import com.intellij.psi.scope.util.PsiScopesUtil; @@ -24,56 +23,39 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class ResolveClassUtil { - private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.resolve.ResolveClassUtil"); - @Nullable public static PsiClass resolveClass(@NotNull PsiJavaCodeReferenceElement ref, @NotNull PsiFile containingFile) { if (ref instanceof PsiJavaCodeReferenceElementImpl && ((PsiJavaCodeReferenceElementImpl)ref).getKind(containingFile) == PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND) { PsiElement parent = ref.getParent(); - if (parent instanceof PsiAnonymousClass){ + if (parent instanceof PsiAnonymousClass) { parent = parent.getParent(); } - PsiExpression qualifier; - if (parent instanceof PsiNewExpression){ - qualifier = ((PsiNewExpression)parent).getQualifier(); - LOG.assertTrue(qualifier != null); + if (parent instanceof PsiNewExpression) { + PsiExpression qualifier = ((PsiNewExpression)parent).getQualifier(); + if (qualifier != null) { + PsiType qualifierType = qualifier.getType(); + if (qualifierType instanceof PsiClassType) { + PsiClass qualifierClass = PsiUtil.resolveClassInType(qualifierType); + if (qualifierClass != null) { + return qualifierClass.findInnerClassByName(ref.getText(), true); + } + } + } } - else if (parent instanceof PsiJavaCodeReferenceElement){ - return null; + } + else { + PsiElement classNameElement = ref.getReferenceNameElement(); + if (classNameElement instanceof PsiIdentifier) { + String className = classNameElement.getText(); + ClassResolverProcessor processor = new ClassResolverProcessor(className, ref, containingFile); + PsiScopesUtil.resolveAndWalk(processor, ref, null); + if (processor.getResult().length == 1) { + return (PsiClass)processor.getResult()[0].getElement(); + } } - else{ - LOG.assertTrue(false); - return null; - } - - PsiType qualifierType = qualifier.getType(); - if (qualifierType == null) return null; - if (!(qualifierType instanceof PsiClassType)) return null; - PsiClass qualifierClass = PsiUtil.resolveClassInType(qualifierType); - if (qualifierClass == null) return null; - String name = ref.getText(); - return qualifierClass.findInnerClassByName(name, true); } - final PsiElement classNameElement = ref.getReferenceNameElement(); - if (!(classNameElement instanceof PsiIdentifier)) return null; - String className = classNameElement.getText(); - - /* - long time1 = System.currentTimeMillis(); - */ - - ClassResolverProcessor processor = new ClassResolverProcessor(className, ref, containingFile); - PsiScopesUtil.resolveAndWalk(processor, ref, null); - - - /* - long time2 = System.currentTimeMillis(); - Statistics.resolveClassTime += (time2 - time1); - Statistics.resolveClassCount++; - */ - - return processor.getResult().length == 1 ? (PsiClass)processor.getResult()[0].getElement() : null; + return null; } } \ No newline at end of file From 68a6a503da01e073a083f5da904648401ae6ea8b Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 20 Feb 2017 13:47:09 +0100 Subject: [PATCH 35/38] [java] highlighting for deprecated module usages --- .../deprecation/DeprecationInspection.java | 14 ++++++++++++++ .../daemon/impl/analysis/HighlightMessageUtil.java | 3 +++ .../codeInsight/daemon/ModuleHighlightingTest.kt | 7 +++++++ 3 files changed, 24 insertions(+) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java index 813cc819b320..5c14b72ded54 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java @@ -25,6 +25,7 @@ import com.intellij.codeInspection.ProblemsHolder; import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; +import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; import com.intellij.psi.util.PsiTreeUtil; @@ -216,6 +217,19 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool { } } } + + @Override + public void visitRequiresStatement(PsiRequiresStatement statement) { + PsiJavaModuleReferenceElement refElement = statement.getReferenceElement(); + if (refElement != null) { + PsiPolyVariantReference ref = refElement.getReference(); + PsiElement target = ref != null ? ref.resolve() : null; + if (target instanceof PsiJavaModule && PsiImplUtil.isDeprecatedByAnnotation((PsiJavaModule)target)) { + String message = JavaErrorMessages.message("deprecated.symbol", HighlightMessageUtil.getSymbolName(target)); + myHolder.registerProblem(refElement, message, ProblemHighlightType.LIKE_DEPRECATED); + } + } + } } private static boolean hasDefaultDeprecatedConstructor(PsiClass superClass) { diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java index 42ee7bc215db..5d2aec204db9 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java @@ -69,6 +69,9 @@ public class HighlightMessageUtil { else if (symbol instanceof PsiDirectory) { symbolName = ((PsiDirectory)symbol).getName(); } + else if (symbol instanceof PsiJavaModule) { + symbolName = ((PsiJavaModule)symbol).getName(); + } return symbolName; } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt index a49e65b8e69e..e309cf036003 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt @@ -16,6 +16,7 @@ package com.intellij.codeInsight.daemon import com.intellij.codeInsight.daemon.impl.JavaHighlightInfoTypes +import com.intellij.codeInspection.deprecation.DeprecationInspection import com.intellij.openapi.util.TextRange import com.intellij.testFramework.fixtures.LightJava9ModulesCodeInsightFixtureTestCase import com.intellij.testFramework.fixtures.MultiModuleJava9ProjectDescriptor.ModuleDescriptor.* @@ -215,6 +216,12 @@ class ModuleHighlightingTest : LightJava9ModulesCodeInsightFixtureTestCase() { highlight("module M { requires M6; }") } + fun testDeprecations() { + myFixture.enableInspections(DeprecationInspection()) + addFile("module-info.java", "@Deprecated module M2 { }", M2) + highlight("""module M { requires M2; }""") + } + // private fun highlight(text: String) = highlight("module-info.java", text) From 0b3a66fc4b0adcdfb3e8868bd58191f2a6c91f9c Mon Sep 17 00:00:00 2001 From: Leonid Shalupov Date: Mon, 20 Feb 2017 15:50:26 +0300 Subject: [PATCH 36/38] add old versions of com.intellij.resharper.unity to brokenPlugins.txt --- platform/platform-resources/src/brokenPlugins.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-resources/src/brokenPlugins.txt b/platform/platform-resources/src/brokenPlugins.txt index 4c5b7664c7e0..6e02f908a4b7 100644 --- a/platform/platform-resources/src/brokenPlugins.txt +++ b/platform/platform-resources/src/brokenPlugins.txt @@ -66,4 +66,5 @@ org.jetbrains.memory.view 0.0.2 0.0.3 0.0.4 0.0.5 0.0.6 0.0.7 0.0.8 0.0.9 0.0.10 com.jetbrains.intellij.api.watcher 5.0.0 5.1.0 5.2.0 5.3.0 5.4.0 com.jetbrains.performancePlugin 1.1 1.3 1.3.1 1.3.2 org.vuejs 1.1.0 1.0.1 1.0.0 -Vue.js 1.1.0 1.0.1 1.0.0 \ No newline at end of file +Vue.js 1.1.0 1.0.1 1.0.0 +com.intellij.resharper.unity 1.5.0.0 1.5.0.1 From 18547af62e8c8f1d94ac4bfeb2bfee9ab83988cb Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 20 Feb 2017 15:47:10 +0300 Subject: [PATCH 37/38] do not show tooltips for INFORMATION infos for some inspections --- .../AnonymousCanBeLambdaInspection.java | 21 +++++++++++++++---- ...HasFrequentlyUsedInheritorsInspection.java | 7 +++---- ...onymousCanBeMethodReferenceInspection.java | 11 ++++++---- .../OptionalIsPresentInspection.java | 9 +++++--- .../java18api/Java8MapForEachInspection.java | 7 ++++--- .../LambdaCanBeMethodReferenceInspection.java | 15 +++++++------ 6 files changed, 46 insertions(+), 24 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java index fac35822aa13..e6af19f806c1 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java @@ -100,21 +100,34 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection final PsiElement lBrace = aClass.getLBrace(); LOG.assertTrue(lBrace != null); final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent()); - ProblemHighlightType problemHighlightType = ProblemHighlightType.LIKE_UNUSED_SYMBOL; + ProblemHighlightType type = ProblemHighlightType.LIKE_UNUSED_SYMBOL; if (isOnTheFly && !reportNotAnnotatedInterfaces) { final PsiClass baseClass = aClass.getBaseClassType().resolve(); LOG.assertTrue(baseClass != null); if (!AnnotationUtil.isAnnotated(baseClass, CommonClassNames.JAVA_LANG_FUNCTIONAL_INTERFACE, false, false)) { - problemHighlightType = ProblemHighlightType.INFORMATION; + type = ProblemHighlightType.INFORMATION; } } - holder.registerProblem(parent, "Anonymous #ref #loc can be replaced with lambda", - problemHighlightType, rangeInElement, new ReplaceWithLambdaFix()); + ProblemDescriptorBase descriptor = new ProblemDescriptorBase(parent, parent, "Anonymous #ref #loc can be replaced with lambda", + new LocalQuickFix[]{new ReplaceWithLambdaFix()}, + type, false, rangeInElement, + type != ProblemHighlightType.INFORMATION, true); + holder.registerProblem(descriptor); } } }; } + interface R { void run(); } + void f(R r) { + f(new R() { + @Override + public void run() { + System.out.println(); + } + }); + } + static boolean hasRuntimeAnnotations(PsiMethod method, @NotNull Set runtimeAnnotationsToIgnore) { PsiAnnotation[] annotations = method.getModifierList().getAnnotations(); for (PsiAnnotation annotation : annotations) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java index e7b9e3e353a4..d7c8e0aa4675 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java @@ -75,10 +75,9 @@ public class SuperClassHasFrequentlyUsedInheritorsInspection extends BaseJavaBat break; } } - return new ProblemDescriptor[]{manager - .createProblemDescriptor(aClass, getDisplayName(), false, - topInheritorsQuickFix.toArray(new LocalQuickFix[topInheritorsQuickFix.size()]), - ProblemHighlightType.INFORMATION)}; + return new ProblemDescriptor[]{ + manager.createProblemDescriptor(aClass, getDisplayName(), false, ProblemHighlightType.INFORMATION, false, + topInheritorsQuickFix.toArray(new LocalQuickFix[topInheritorsQuickFix.size()]))}; } @Nullable diff --git a/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java b/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java index 473770741a3e..896a6b7fe4d9 100644 --- a/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java @@ -98,11 +98,14 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI final PsiElement lBrace = aClass.getLBrace(); LOG.assertTrue(lBrace != null); final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent()); - ProblemHighlightType highlightType = LambdaCanBeMethodReferenceInspection.checkQualifier(lambdaBodyCandidate) ? ProblemHighlightType.LIKE_UNUSED_SYMBOL + ProblemHighlightType type = LambdaCanBeMethodReferenceInspection.checkQualifier(lambdaBodyCandidate) ? ProblemHighlightType.LIKE_UNUSED_SYMBOL : ProblemHighlightType.INFORMATION; - holder.registerProblem(parent, - "Anonymous #ref #loc can be replaced with method reference", - highlightType, rangeInElement, new ReplaceWithMethodRefFix()); + ProblemDescriptorBase descriptor = new ProblemDescriptorBase(parent, parent, + "Anonymous #ref #loc can be replaced with method reference", + new LocalQuickFix[]{new ReplaceWithMethodRefFix()}, + type, false, rangeInElement, + type != ProblemHighlightType.INFORMATION, true); + holder.registerProblem(descriptor); } } } diff --git a/java/java-impl/src/com/intellij/codeInspection/OptionalIsPresentInspection.java b/java/java-impl/src/com/intellij/codeInspection/OptionalIsPresentInspection.java index 6fb31afa813d..6f6a69c6c9b8 100644 --- a/java/java-impl/src/com/intellij/codeInspection/OptionalIsPresentInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/OptionalIsPresentInspection.java @@ -57,9 +57,12 @@ public class OptionalIsPresentInspection extends BaseJavaBatchLocalInspectionToo void registerProblem(ProblemsHolder holder, PsiExpression condition, OptionalIsPresentCase scenario) { if(this != NONE) { - holder.registerProblem(condition, "Can be replaced with single expression in functional style", - this == INFO ? ProblemHighlightType.INFORMATION : ProblemHighlightType.GENERIC_ERROR_OR_WARNING, - new OptionalIsPresentFix(scenario)); + holder.registerProblem(holder.getManager().createProblemDescriptor(condition, + "Can be replaced with single expression in functional style", + this != INFO, + this == INFO ? ProblemHighlightType.INFORMATION : ProblemHighlightType.GENERIC_ERROR_OR_WARNING, + true, + new OptionalIsPresentFix(scenario))); } } } diff --git a/java/java-impl/src/com/intellij/codeInspection/java18api/Java8MapForEachInspection.java b/java/java-impl/src/com/intellij/codeInspection/java18api/Java8MapForEachInspection.java index 91b2e197f861..e48e2deacab2 100644 --- a/java/java-impl/src/com/intellij/codeInspection/java18api/Java8MapForEachInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/java18api/Java8MapForEachInspection.java @@ -107,14 +107,15 @@ public class Java8MapForEachInspection extends BaseJavaBatchLocalInspectionTool isOnTheFly && (DO_NOT_HIGHLIGHT_LOOP || InspectionProjectProfileManager.isInformationLevel(getShortName(), loop)); TextRange range; PsiJavaToken rParenth = loop.getRParenth(); + PsiElement firstChild = loop.getFirstChild(); if (wholeStatement && rParenth != null) { range = new TextRange(0, rParenth.getStartOffsetInParent() + 1); } else { - range = new TextRange(0, loop.getFirstChild().getTextLength()); + range = new TextRange(0, firstChild.getTextLength()); } - holder.registerProblem(loop.getFirstChild(), InspectionsBundle.message("inspection.map.foreach.message"), - type, range, new ReplaceWithMapForEachFix()); + holder.registerProblem(new ProblemDescriptorBase(firstChild, firstChild, InspectionsBundle.message("inspection.map.foreach.message"), + new LocalQuickFix[]{new ReplaceWithMapForEachFix()}, type, false, range, type != ProblemHighlightType.INFORMATION, holder.isOnTheFly())); } } }; diff --git a/plugins/InspectionGadgets/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java b/plugins/InspectionGadgets/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java index adc7e76c69f4..fe7f1bdc5b57 100644 --- a/plugins/InspectionGadgets/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java +++ b/plugins/InspectionGadgets/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java @@ -95,17 +95,20 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp ? ((PsiNewExpression)methodRefCandidate).getQualifier() : null; boolean safeQualifier = checkQualifier(qualifier); - ProblemHighlightType errorOrWarning; + ProblemHighlightType type; if (safeQualifier) { - errorOrWarning = ProblemHighlightType.GENERIC_ERROR_OR_WARNING; + type = ProblemHighlightType.GENERIC_ERROR_OR_WARNING; } else { if (!isOnTheFly) return; - errorOrWarning = ProblemHighlightType.INFORMATION; + type = ProblemHighlightType.INFORMATION; } - holder.registerProblem(InspectionProjectProfileManager.isInformationLevel(getShortName(), expression) ? expression : candidate, - "Can be replaced with method reference", - errorOrWarning, new ReplaceWithMethodRefFix(safeQualifier ? "" : " (may change semantics)")); + PsiElement element = InspectionProjectProfileManager.isInformationLevel(getShortName(), expression) ? expression : candidate; + holder.registerProblem(holder.getManager().createProblemDescriptor( + element, + "Can be replaced with method reference", + type != ProblemHighlightType.INFORMATION, + type, true, new ReplaceWithMethodRefFix(safeQualifier ? "" : " (may change semantics)"))); } } } From 48f183047565f2772503a6e1ddf65916ec4d063c Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 20 Feb 2017 15:47:40 +0300 Subject: [PATCH 38/38] do not show tooltips for INFORMATION infos for some inspections --- .../codeInspection/AnonymousCanBeLambdaInspection.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java index e6af19f806c1..99db3fdcd88d 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java @@ -118,16 +118,6 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection }; } - interface R { void run(); } - void f(R r) { - f(new R() { - @Override - public void run() { - System.out.println(); - } - }); - } - static boolean hasRuntimeAnnotations(PsiMethod method, @NotNull Set runtimeAnnotationsToIgnore) { PsiAnnotation[] annotations = method.getModifierList().getAnnotations(); for (PsiAnnotation annotation : annotations) {