From a5165da49edecd94b14d119337931abee735325d Mon Sep 17 00:00:00 2001 From: Pavel Fatin Date: Fri, 14 Oct 2016 13:50:16 +0200 Subject: [PATCH 01/21] IDEA-162595 'Wrong offset' exception when start typing on the first line of any file if there're >1 lines --- .../openapi/editor/ex/util/LexerEditorHighlighter.java | 2 +- .../openapi/editor/impl/ImmediatePainterTest.java | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java index ff989d2f0ba5..ae9949d09caf 100644 --- a/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java +++ b/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/util/LexerEditorHighlighter.java @@ -404,7 +404,7 @@ public class LexerEditorHighlighter implements EditorHighlighter, PrioritizedDoc int oldStartIndex = 0; int startIndex = 0; - if (mySegments.getSegmentCount() > 0) { + if (offset > 0 && mySegments.getSegmentCount() > 0) { final int segmentIndex = mySegments.findSegmentIndex(offset - 1) - 2; oldStartIndex = Math.max(0, segmentIndex); startIndex = oldStartIndex; diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/ImmediatePainterTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/ImmediatePainterTest.java index 30085f743a90..4bce76a78e11 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/ImmediatePainterTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/ImmediatePainterTest.java @@ -74,6 +74,16 @@ public class ImmediatePainterTest extends AbstractEditorTest { } } + public void testEmptyFile() throws Exception { + init(""); + assertRenderedCorrectly(0, 'c'); + } + + public void testBeginningOfFile() throws Exception { + init("\nfoo"); + assertRenderedCorrectly(0, 'c'); + } + public void testDrawingNarrowChar() throws Exception { init(""); assertRenderedCorrectly(0, '▌'); From e3ecf690bfe150860f55a8c54df12e46c52257fb Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Thu, 13 Oct 2016 19:53:43 +0300 Subject: [PATCH 02/21] Fix log warning (PY-20668) --- .../jetbrains/python/console/PythonConsoleRunnerFactory.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/console/PythonConsoleRunnerFactory.java b/python/src/com/jetbrains/python/console/PythonConsoleRunnerFactory.java index c8e2a0cab092..840b20d0424b 100644 --- a/python/src/com/jetbrains/python/console/PythonConsoleRunnerFactory.java +++ b/python/src/com/jetbrains/python/console/PythonConsoleRunnerFactory.java @@ -15,7 +15,7 @@ */ package com.jetbrains.python.console; -import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; @@ -27,7 +27,7 @@ import org.jetbrains.annotations.Nullable; public abstract class PythonConsoleRunnerFactory { @NotNull public static PythonConsoleRunnerFactory getInstance() { - return ServiceManager.getService(PythonConsoleRunnerFactory.class); + return ApplicationManager.getApplication().getComponent(PythonConsoleRunnerFactory.class); } @NotNull From 2fbb7ce7e4a3c53588a7fae5fcdcd45e2b683d75 Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Fri, 14 Oct 2016 15:00:05 +0300 Subject: [PATCH 03/21] Fix indent while entering commands (especially multi-line) (PY-20616) Fix the function `checkComplete`, which checks if the current statement is complete and can be executed --- .../python/console/PyConsoleEnterHandler.kt | 59 ++++++------------- 1 file changed, 19 insertions(+), 40 deletions(-) diff --git a/python/src/com/jetbrains/python/console/PyConsoleEnterHandler.kt b/python/src/com/jetbrains/python/console/PyConsoleEnterHandler.kt index c5a40544bcf7..be814fd57e35 100644 --- a/python/src/com/jetbrains/python/console/PyConsoleEnterHandler.kt +++ b/python/src/com/jetbrains/python/console/PyConsoleEnterHandler.kt @@ -23,19 +23,20 @@ import com.intellij.openapi.editor.Document import com.intellij.openapi.editor.actionSystem.EditorActionManager import com.intellij.openapi.editor.ex.EditorEx import com.intellij.openapi.util.TextRange -import com.intellij.psi.* +import com.intellij.psi.PsiDocumentManager +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.impl.source.codeStyle.IndentHelperImpl import com.intellij.psi.util.PsiTreeUtil import com.jetbrains.python.PyTokenTypes import com.jetbrains.python.PythonFileType -import com.jetbrains.python.psi.PyStatement import com.jetbrains.python.psi.PyStatementListContainer import com.jetbrains.python.psi.PyStringLiteralExpression +import com.jetbrains.python.psi.impl.PyPsiUtils import com.jetbrains.python.psi.impl.PyStringLiteralExpressionImpl -/** - * Created by Yuli Fiterman on 9/20/2016. - */ + class PyConsoleEnterHandler { fun handleEnterPressed(editor: EditorEx): Boolean { val project = editor.project ?: throw IllegalArgumentException() @@ -54,41 +55,26 @@ class PyConsoleEnterHandler { atElement?.let { insideDocString = isElementInsideDocString(atElement, caretOffset) } - val prevLine = getLineAtOffset(editor.document, caretOffset) - if (prevLine.isBlank() && !insideDocString) { - return true - } - - val isCellMagic = prevLine.trim().startsWith("%%") && !prevLine.trimEnd().endsWith("?") - val isCellHelp = prevLine.trim().startsWith("%%") && prevLine.trimEnd().endsWith("?") - val isLineCellMagic = prevLine.trim().startsWith("%") - val hasCompleteStatement = if (atElement != null && !insideDocString && !isCellMagic) { - isCellHelp || isLineCellMagic || checkComplete(atElement) - } - else { - false - } val enterHandler = EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_ENTER) - object : WriteCommandAction(project) { - @Throws(Throwable::class) override fun run(result: Result) { enterHandler.execute(editor, null, DataManager.getInstance().getDataContext(editor.component)) } }.execute() - /* If we have an indent we don't want to execute either */ + val prevLine = getLineAtOffset(editor.document, caretOffset) + val isCellMagic = prevLine.trim().startsWith("%%") && !prevLine.trimEnd().endsWith("?") + val isCellHelp = prevLine.trim().startsWith("%%") && prevLine.trimEnd().endsWith("?") + val isLineCellMagic = prevLine.trim().startsWith("%") + val hasCompleteStatement = atElement != null && !insideDocString && !isCellMagic && + (isCellHelp || isLineCellMagic || checkComplete(atElement)) + val currentLine = getLineAtOffset(editor.document, editor.expectedCaretOffset) val indent = IndentHelperImpl.getIndent(project, PythonFileType.INSTANCE, currentLine, false) - if (indent > 0) { - return false - } - - return hasCompleteStatement - + return indent == 0 || (hasCompleteStatement && prevLine.isBlank()) } private fun isElementInsideDocString(atElement: PsiElement, caretOffset: Int): Boolean { @@ -99,19 +85,12 @@ class PyConsoleEnterHandler { } private fun checkComplete(el: PsiElement): Boolean { - var el = el - while (el.parent !is PsiFile && el.parent != null) { - el = el.parent + val compoundStatement = PsiTreeUtil.getParentOfType(el, PyStatementListContainer::class.java) + if (compoundStatement != null) { + return compoundStatement.statementList.statements.size != 0 } - if (el !is PyStatement) { - return false - } - val container = PsiTreeUtil.findChildOfType(el, PyStatementListContainer::class.java, false) - if (container != null) { - return false - } - - return PsiTreeUtil.findChildOfType(el, PsiErrorElement::class.java, false) == null + val topLevel = PyPsiUtils.getParentRightBefore(el, el.containingFile) + return topLevel != null && PsiTreeUtil.hasErrorElements(topLevel) } private fun findFirstNoneSpaceElement(psiFile: PsiFile, offset: Int): PsiElement? { From c466ff33864637d709fe4a171e14253c3b197b57 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 14 Oct 2016 14:15:44 +0200 Subject: [PATCH 04/21] optimize imports on refactoring shouldn't lead to deadlocks (like IDEA-162441) if invoked in dumb mode --- .../refactoring/OptimizeImportsRefactoringHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/OptimizeImportsRefactoringHelper.java b/java/java-impl/src/com/intellij/refactoring/OptimizeImportsRefactoringHelper.java index 13ed31575d89..f78e66f2433a 100644 --- a/java/java-impl/src/com/intellij/refactoring/OptimizeImportsRefactoringHelper.java +++ b/java/java-impl/src/com/intellij/refactoring/OptimizeImportsRefactoringHelper.java @@ -16,10 +16,10 @@ package com.intellij.refactoring; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -61,7 +61,7 @@ public class OptimizeImportsRefactoringHelper implements RefactoringHelper> redundants = new HashSet<>(); - final Runnable findRedundantImports = () -> DumbService.getInstance(project).runReadActionInSmartMode(() -> { + final Runnable findRedundantImports = () -> ReadAction.run(() -> { final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project); final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); final SmartPointerManager pointerManager = SmartPointerManager.getInstance(project); From 80a78f71c9b17e1f7a799c14fd24167b6076f75c Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Fri, 14 Oct 2016 12:51:04 +0300 Subject: [PATCH 05/21] [Parameter Name Hints] toggle parameter hints moved to editor popup --- .../com/intellij/codeInsight/hints/PopupActions.kt | 12 ++++++++---- platform/platform-resources/src/idea/LangActions.xml | 5 ++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt index 3cf00c35b7d6..e8da4e201546 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt @@ -73,10 +73,14 @@ class BlacklistCurrentMethodAction : AnAction() { class ToggleInlineHintsAction : AnAction() { override fun update(e: AnActionEvent) { - e.presentation.isEnabled = true - - val isShow = EditorSettingsExternalizable.getInstance().isShowParameterNameHints - e.presentation.text = if (isShow) "Disable Parameter Name Hints" else "Enable Parameter Name Hints" + if (InlayParameterHintsExtension.hasAnyExtensions()) { + e.presentation.isEnabledAndVisible = true + val isShow = EditorSettingsExternalizable.getInstance().isShowParameterNameHints + e.presentation.text = if (isShow) "Disable Parameter Name Hints" else "Enable Parameter Name Hints" + } + else { + e.presentation.isEnabledAndVisible = false + } } override fun actionPerformed(e: AnActionEvent) { diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index c5b673ed09a8..f32e0526ba96 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -302,9 +302,12 @@ - + + + + From 1355b0844ba8a6c35b13644bc3705b87c057cf44 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Fri, 14 Oct 2016 13:19:10 +0300 Subject: [PATCH 06/21] [Parameter Name Hints] minor --- .../codeInsight/hints/PopupActions.kt | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt index e8da4e201546..6536d7d2a77f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt @@ -21,9 +21,11 @@ import com.intellij.codeInsight.hints.settings.ParameterNameHintsSettings import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.CommonDataKeys +import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.ex.EditorSettingsExternalizable import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.ProjectManager +import com.intellij.psi.PsiFile import com.intellij.psi.PsiManager import com.intellij.psi.util.PsiTreeUtil @@ -54,19 +56,8 @@ class BlacklistCurrentMethodAction : AnAction() { override fun actionPerformed(e: AnActionEvent) { val editor = CommonDataKeys.EDITOR.getData(e.dataContext) ?: return val file = CommonDataKeys.PSI_FILE.getData(e.dataContext) ?: return - - val offset = editor.caretModel.offset - - val element = file.findElementAt(offset) - val hintsProvider = InlayParameterHintsExtension.forLanguage(file.language) ?: return - - val method = PsiTreeUtil.findFirstParent(element, { e -> hintsProvider.getMethodInfo(e) != null }) ?: return - val info = hintsProvider.getMethodInfo(method) ?: return - - val pattern = info.fullyQualifiedName + '(' + info.paramNames.joinToString(",") + ')' - ParameterNameHintsSettings.getInstance().addIgnorePattern(pattern) - refreshAllOpenEditors() + addMethodAtCaretToBlackList(editor, file) } } @@ -103,3 +94,18 @@ private fun refreshAllOpenEditors() { } } } + +private fun addMethodAtCaretToBlackList(editor: Editor, file: PsiFile) { + val offset = editor.caretModel.offset + + val element = file.findElementAt(offset) + val hintsProvider = InlayParameterHintsExtension.forLanguage(file.language) ?: return + + val method = PsiTreeUtil.findFirstParent(element, { e -> hintsProvider.getMethodInfo(e) != null }) ?: return + val info = hintsProvider.getMethodInfo(method) ?: return + + val pattern = info.fullyQualifiedName + '(' + info.paramNames.joinToString(",") + ')' + ParameterNameHintsSettings.getInstance().addIgnorePattern(pattern) + + refreshAllOpenEditors() +} \ No newline at end of file From eefee484906f0a43325a6ad10e26757af73520bd Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Fri, 14 Oct 2016 15:27:10 +0300 Subject: [PATCH 07/21] [Parameter Name Hints] add intention action to disable hint for current method --- .../codeInsight/hints/PopupActions.kt | 34 +++++++++++++++++-- .../openapi/editor/impl/InlayModelImpl.java | 6 ++-- .../src/META-INF/LangExtensions.xml | 3 ++ 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt index 6536d7d2a77f..1de7b7629666 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt @@ -16,21 +16,24 @@ package com.intellij.codeInsight.hints import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer +import com.intellij.codeInsight.daemon.impl.ParameterHintsPresentationManager import com.intellij.codeInsight.hints.settings.ParameterNameHintsConfigurable import com.intellij.codeInsight.hints.settings.ParameterNameHintsSettings +import com.intellij.codeInsight.intention.HighPriorityAction +import com.intellij.codeInsight.intention.IntentionAction import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.ex.EditorSettingsExternalizable import com.intellij.openapi.fileEditor.FileEditorManager +import com.intellij.openapi.project.Project import com.intellij.openapi.project.ProjectManager import com.intellij.psi.PsiFile import com.intellij.psi.PsiManager import com.intellij.psi.util.PsiTreeUtil class ShowParameterHintsSettings : AnAction() { - init { val presentation = templatePresentation presentation.text = "Show Settings" @@ -42,11 +45,9 @@ class ShowParameterHintsSettings : AnAction() { val dialog = ParameterNameHintsConfigurable(project) dialog.show() } - } class BlacklistCurrentMethodAction : AnAction() { - init { val presentation = templatePresentation presentation.text = "Do Not Show Hints For Current Method" @@ -61,6 +62,21 @@ class BlacklistCurrentMethodAction : AnAction() { } } +class BlacklistCurrentMethodIntention : IntentionAction, HighPriorityAction { + override fun getText() = "Do Not Show Hints For Current Method" + override fun getFamilyName() = "Parameter Name Hints" + + override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { + return InlayParameterHintsExtension.hasAnyExtensions() && hasParameterHintAtOffset(editor) + } + + override fun invoke(project: Project, editor: Editor, file: PsiFile) { + addMethodAtCaretToBlackList(editor, file) + } + + override fun startInWriteAction() = false +} + class ToggleInlineHintsAction : AnAction() { override fun update(e: AnActionEvent) { @@ -83,6 +99,18 @@ class ToggleInlineHintsAction : AnAction() { } } +private fun hasParameterHintAtOffset(editor: Editor): Boolean { + val offset = editor.caretModel.offset + if (editor.inlayModel.hasInlineElementAt(offset)) { + val manager = ParameterHintsPresentationManager.getInstance() + return editor.inlayModel + .getInlineElementsInRange(offset, offset) + .find { manager.isParameterHint(it) } != null + } + + return false +} + private fun refreshAllOpenEditors() { ProjectManager.getInstance().openProjects.forEach { val psiManager = PsiManager.getInstance(it) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/InlayModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/InlayModelImpl.java index c595269e3db4..d15fe0c358cf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/InlayModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/InlayModelImpl.java @@ -17,7 +17,10 @@ package com.intellij.openapi.editor.impl; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.EditorCustomElementRenderer; +import com.intellij.openapi.editor.Inlay; +import com.intellij.openapi.editor.InlayModel; +import com.intellij.openapi.editor.VisualPosition; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.editor.ex.PrioritizedDocumentListener; @@ -114,7 +117,6 @@ public class InlayModelImpl implements InlayModel, Disposable { @NotNull @Override public List getInlineElementsInRange(int startOffset, int endOffset) { - ApplicationManager.getApplication().assertIsDispatchThread(); List result = new ArrayList<>(); myInlayTree.processOverlappingWith(startOffset, endOffset, inlay -> { result.add(inlay); diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 5d953f636fb4..baf8e92cfbfb 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -686,6 +686,9 @@ com.intellij.formatting.contextConfiguration.ConfigureCodeStyleOnSelectedFragment + + com.intellij.codeInsight.hints.BlacklistCurrentMethodIntention + com.intellij.codeInsight.intention.impl.QuickEditAction Language Injection From 1226e8ea2dd40f59c512ae13963396d26f9aa086 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Fri, 14 Oct 2016 15:50:33 +0300 Subject: [PATCH 08/21] IDEA-162449 Showing progress in console hides mouse cursor leading to mouse cursor blinking when it's being moved --- .../src/com/intellij/openapi/editor/impl/EditorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index d5463250a5d6..55b1ba14daa2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -2030,7 +2030,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi restoreCaretRelativePosition(); } - if (EMPTY_CURSOR != null) { + if (EMPTY_CURSOR != null && !myIsViewer) { myEditorComponent.setCursor(EMPTY_CURSOR); } } From 4be6caf4cc69a0b4fd9d9cca0b5092c01a7cf7d3 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 14 Oct 2016 14:57:07 +0200 Subject: [PATCH 09/21] cleanup cached ProgressManager instance when application is recreated --- .../src/com/intellij/openapi/progress/ProgressManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java b/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java index aab31146f231..50f1e03a7b72 100644 --- a/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java +++ b/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java @@ -16,6 +16,7 @@ package com.intellij.openapi.progress; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.CachedSingletonsRegistry; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; @@ -29,7 +30,7 @@ import javax.swing.*; import java.util.Set; public abstract class ProgressManager extends ProgressIndicatorProvider { - private static ProgressManager ourInstance; + private static ProgressManager ourInstance = CachedSingletonsRegistry.markCachedField(ProgressManager.class); @NotNull @SuppressWarnings("MethodOverridesStaticMethodOfSuperclass") From 9fba780ad3360ea51f68b341e3ca0a85f9241fe0 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Fri, 14 Oct 2016 15:46:49 +0300 Subject: [PATCH 10/21] [Parameter Name Hints] minor --- .../com/intellij/codeInsight/hints/PopupActions.kt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt index 1de7b7629666..d026f7c2ff50 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt @@ -63,7 +63,7 @@ class BlacklistCurrentMethodAction : AnAction() { } class BlacklistCurrentMethodIntention : IntentionAction, HighPriorityAction { - override fun getText() = "Do Not Show Hints For Current Method" + override fun getText() = "Do not show hints for current method" override fun getFamilyName() = "Parameter Name Hints" override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { @@ -78,12 +78,17 @@ class BlacklistCurrentMethodIntention : IntentionAction, HighPriorityAction { } class ToggleInlineHintsAction : AnAction() { - + + companion object { + private val disableText = "Disable Parameter Name Hints" + private val enableText = "Enable Parameter Name Hints" + } + override fun update(e: AnActionEvent) { if (InlayParameterHintsExtension.hasAnyExtensions()) { e.presentation.isEnabledAndVisible = true val isShow = EditorSettingsExternalizable.getInstance().isShowParameterNameHints - e.presentation.text = if (isShow) "Disable Parameter Name Hints" else "Enable Parameter Name Hints" + e.presentation.text = if (isShow) disableText else enableText } else { e.presentation.isEnabledAndVisible = false From d3fb60804fb09d289309ccc07611e25576c10d33 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Fri, 14 Oct 2016 16:11:57 +0300 Subject: [PATCH 11/21] [Parameter Name Hints] move text to bundle --- .../codeInsight/hints/PopupActions.kt | 26 +++++++++++++------ .../src/messages/CodeInsightBundle.properties | 8 ++++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt index d026f7c2ff50..a9f09b4f517f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.hints +import com.intellij.codeInsight.CodeInsightBundle import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer import com.intellij.codeInsight.daemon.impl.ParameterHintsPresentationManager import com.intellij.codeInsight.hints.settings.ParameterNameHintsConfigurable @@ -29,15 +30,19 @@ import com.intellij.openapi.editor.ex.EditorSettingsExternalizable import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.Project import com.intellij.openapi.project.ProjectManager +import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.PsiFile import com.intellij.psi.PsiManager import com.intellij.psi.util.PsiTreeUtil + +private fun String.capitalize() = StringUtil.capitalizeWords(this, true) + class ShowParameterHintsSettings : AnAction() { init { val presentation = templatePresentation - presentation.text = "Show Settings" - presentation.description = "Show Parameter Name Hints Settings" + presentation.text = CodeInsightBundle.message("inlay.hints.show.settings").capitalize() + presentation.description = CodeInsightBundle.message("inlay.hints.show.settings.description") } override fun actionPerformed(e: AnActionEvent) { @@ -50,8 +55,8 @@ class ShowParameterHintsSettings : AnAction() { class BlacklistCurrentMethodAction : AnAction() { init { val presentation = templatePresentation - presentation.text = "Do Not Show Hints For Current Method" - presentation.description = "Adds Current Method to Parameter Name Hints Blacklist" + presentation.text = CodeInsightBundle.message("inlay.hints.blacklist.method").capitalize() + presentation.description = CodeInsightBundle.message("inlay.hints.blacklist.method.description") } override fun actionPerformed(e: AnActionEvent) { @@ -63,8 +68,13 @@ class BlacklistCurrentMethodAction : AnAction() { } class BlacklistCurrentMethodIntention : IntentionAction, HighPriorityAction { - override fun getText() = "Do not show hints for current method" - override fun getFamilyName() = "Parameter Name Hints" + companion object { + private val presentableText = CodeInsightBundle.message("inlay.hints.blacklist.method") + private val presentableFamilyName = CodeInsightBundle.message("inlay.hints.intention.family.name") + } + + override fun getText(): String = presentableText + override fun getFamilyName(): String = presentableFamilyName override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { return InlayParameterHintsExtension.hasAnyExtensions() && hasParameterHintAtOffset(editor) @@ -80,8 +90,8 @@ class BlacklistCurrentMethodIntention : IntentionAction, HighPriorityAction { class ToggleInlineHintsAction : AnAction() { companion object { - private val disableText = "Disable Parameter Name Hints" - private val enableText = "Enable Parameter Name Hints" + private val disableText = CodeInsightBundle.message("inlay.hints.disable.action.text").capitalize() + private val enableText = CodeInsightBundle.message("inlay.hints.enable.action.text").capitalize() } override fun update(e: AnActionEvent) { diff --git a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties index de0173c8c5f6..af978ba4e90c 100644 --- a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties +++ b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties @@ -524,3 +524,11 @@ highlight.imported.classes.chooser.title=Choose Imported Classes to Highlight highlight.imported.members.chooser.title=Choose Imported Members to Highlight javadoc.resolved.value=Resolved value\: javadoc.error.resolving.url=Couldn''t resolve URL {0}

Configuring paths to API docs in project settings might help + +inlay.hints.show.settings=Show parameter name hints settings +inlay.hints.show.settings.description=Show dialog with parameter name hints settings +inlay.hints.blacklist.method=Do not show hints for current method +inlay.hints.blacklist.method.description=Adds current method to parameter name hints blacklist +inlay.hints.intention.family.name=Parameter Name Hints +inlay.hints.enable.action.text=Enable Parameter Name Hints +inlay.hints.disable.action.text=Disable Parameter Name Hints \ No newline at end of file From 71b3d7e57a987cc361966992c3f49ea396df8013 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Fri, 14 Oct 2016 15:12:55 +0300 Subject: [PATCH 12/21] git: add ellipsis for partially loaded commit message in annotation hint --- plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java b/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java index 47801a823789..3e0ce271b545 100644 --- a/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java +++ b/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java @@ -151,7 +151,7 @@ public class GitFileAnnotation extends FileAnnotation { fileRevision = myRevisions.get(myRevisionMap.get(revisionNumber)); } - String commitMessage = fileRevision != null ? fileRevision.getCommitMessage() : lineInfo.getSubject(); + String commitMessage = fileRevision != null ? fileRevision.getCommitMessage() : lineInfo.getSubject() + "\n..."; return GitBundle.message("annotation.tool.tip", revisionNumber.asString(), lineInfo.getAuthor(), DateFormatUtil.formatDateTime(lineInfo.getDate()), commitMessage); } From 2cd15dfdf9517c1e04a41db18dff343e11297146 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Fri, 14 Oct 2016 16:24:17 +0300 Subject: [PATCH 13/21] [Parameter Name Hints] set visible "Show parameter name hints" checkbox if there is any registered extension --- .../options/editor/EditorAppearanceConfigurable.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorAppearanceConfigurable.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorAppearanceConfigurable.java index 6b6bb0afe8a1..22e45e3ab8b6 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorAppearanceConfigurable.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorAppearanceConfigurable.java @@ -17,6 +17,7 @@ package com.intellij.application.options.editor; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings; +import com.intellij.codeInsight.hints.InlayParameterHintsExtension; import com.intellij.ide.ui.LafManager; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.application.ApplicationBundle; @@ -76,6 +77,7 @@ public class EditorAppearanceConfigurable extends CompositeConfigurable myBlinkIntervalField.setEnabled(myCbBlinkCaret.isSelected())); myCbShowWhitespaces.addActionListener((e) -> updateWhitespaceCheckboxesState()); + myShowParameterNameHints.setVisible(InlayParameterHintsExtension.INSTANCE.hasAnyExtensions()); } private void applyNameHintsSettings() { From df3cc9340246112b43a639b9a91f335ccbb25909 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Fri, 14 Oct 2016 16:29:06 +0300 Subject: [PATCH 14/21] [Parameter Name Hints] remove redundant if --- .../com/intellij/codeInsight/hints/PopupActions.kt | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt index a9f09b4f517f..b6e8057b2f99 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt @@ -116,14 +116,9 @@ class ToggleInlineHintsAction : AnAction() { private fun hasParameterHintAtOffset(editor: Editor): Boolean { val offset = editor.caretModel.offset - if (editor.inlayModel.hasInlineElementAt(offset)) { - val manager = ParameterHintsPresentationManager.getInstance() - return editor.inlayModel - .getInlineElementsInRange(offset, offset) - .find { manager.isParameterHint(it) } != null - } - - return false + return editor.inlayModel + .getInlineElementsInRange(offset, offset) + .find { ParameterHintsPresentationManager.getInstance().isParameterHint(it) } != null } private fun refreshAllOpenEditors() { From 1e3e879291388cbb1fd8f98d86911b391dfc467c Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Fri, 14 Oct 2016 16:36:17 +0300 Subject: [PATCH 15/21] Asynchronous commit on Enter for formatter-based indent adjustment [IDEA-CR-14237] --- .../lineIndent/LineIndentProviderEP.java | 8 +-- .../editorActions/EnterHandler.java | 17 +++-- .../FormatterBasedIndentAdjuster.java | 67 +++++++++++++++++++ .../JavaLikeLangLineIndentProvider.java | 5 +- .../src/META-INF/LangExtensions.xml | 4 +- 5 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/lineIndent/FormatterBasedIndentAdjuster.java diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/lineIndent/LineIndentProviderEP.java b/platform/lang-api/src/com/intellij/psi/codeStyle/lineIndent/LineIndentProviderEP.java index 3b7176609b73..0b398a05d395 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/lineIndent/LineIndentProviderEP.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/lineIndent/LineIndentProviderEP.java @@ -17,7 +17,6 @@ package com.intellij.psi.codeStyle.lineIndent; import com.intellij.lang.Language; import com.intellij.openapi.extensions.ExtensionPointName; -import com.intellij.psi.codeStyle.lineIndent.LineIndentProvider; import org.jetbrains.annotations.Nullable; /** @@ -28,12 +27,11 @@ public class LineIndentProviderEP { @Nullable public static LineIndentProvider findLineIndentProvider(@Nullable Language language) { - LineIndentProvider foundProvider = null; for (LineIndentProvider provider : EP_NAME.getExtensions()) { - if (foundProvider == null || provider.isSuitableFor(language) && foundProvider.getClass().isInstance(provider)) { - foundProvider = provider; + if (provider.isSuitableFor(language)) { + return provider; } } - return foundProvider; + return null; } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java index 13e5dbdaf2f1..466513d1fd3c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java @@ -36,10 +36,7 @@ import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.Ref; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.UserDataHolder; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; @@ -47,6 +44,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.formatter.FormatterUtil; import com.intellij.psi.impl.source.PostprocessReformattingAspect; +import com.intellij.psi.impl.source.codeStyle.lineIndent.FormatterBasedIndentAdjuster; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilBase; @@ -171,6 +169,10 @@ public class EnterHandler extends BaseEnterHandler { break; } } + + if (settings.SMART_INDENT_ON_ENTER && action.isIndentAdjustmentNeeded()) { + FormatterBasedIndentAdjuster.scheduleIndentAdjustment(project, document, editor.getCaretModel().getOffset()); + } } @NotNull @@ -308,6 +310,8 @@ public class EnterHandler extends BaseEnterHandler { private boolean myForceIndent = false; private static final String LINE_SEPARATOR = "\n"; + + private boolean myIsIndentAdjustmentNeeded = true; public DoEnterAction(PsiFile file, Editor view, Document document, DataContext dataContext, int offset, boolean insertSpace, int caretAdvance, Project project) @@ -484,6 +488,7 @@ public class EnterHandler extends BaseEnterHandler { if (newIndent == null) return myOffset; int delta = newIndent.length() - (indentEnd - indentStart); myDocument.replaceString(indentStart, indentEnd, newIndent); + myIsIndentAdjustmentNeeded = false; return myOffset + delta; } @@ -724,6 +729,10 @@ public class EnterHandler extends BaseEnterHandler { } return docAsterisk; } + + public boolean isIndentAdjustmentNeeded() { + return myIsIndentAdjustmentNeeded; + } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/lineIndent/FormatterBasedIndentAdjuster.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/lineIndent/FormatterBasedIndentAdjuster.java new file mode 100644 index 000000000000..d800750409d6 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/lineIndent/FormatterBasedIndentAdjuster.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2016 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.psi.impl.source.codeStyle.lineIndent; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.codeStyle.CodeStyleManager; +import org.jetbrains.annotations.NotNull; + +public class FormatterBasedIndentAdjuster { + + private static final String ADJUST_INDENT_COMMAND_NAME = "Adjust Indent"; + + private FormatterBasedIndentAdjuster() { + } + + public static void scheduleIndentAdjustment(@NotNull Project myProject, + @NotNull Document myDocument, + int myOffset) { + IndentAdjusterRunnable fixer = new IndentAdjusterRunnable(myProject, myDocument, myOffset); + PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); + if (ApplicationManager.getApplication().isUnitTestMode()) { + documentManager.commitDocument(myDocument); + fixer.run(); + } + else { + documentManager.performLaterWhenAllCommitted(fixer); + } + } + + public static class IndentAdjusterRunnable implements Runnable { + private Project myProject; + private int myLine; + private Document myDocument; + + public IndentAdjusterRunnable(Project project, Document document, int offset) { + myProject = project; + myDocument = document; + myLine = myDocument.getLineNumber(offset); + } + + public void run() { + int lineStart = myDocument.getLineStartOffset(myLine); + CommandProcessor.getInstance().executeCommand(myProject, () -> + ApplicationManager.getApplication().runWriteAction(() -> { + CodeStyleManager.getInstance(myProject).adjustLineIndent(myDocument, lineStart); + }), ADJUST_INDENT_COMMAND_NAME, null); + } + } + +} diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/lineIndent/JavaLikeLangLineIndentProvider.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/lineIndent/JavaLikeLangLineIndentProvider.java index 47a5be14efbf..b7b2ff632af5 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/lineIndent/JavaLikeLangLineIndentProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/lineIndent/JavaLikeLangLineIndentProvider.java @@ -21,6 +21,7 @@ import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.project.Project; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; +import com.intellij.psi.codeStyle.lineIndent.LineIndentProvider; import com.intellij.psi.impl.source.codeStyle.SemanticEditorPosition; import com.intellij.psi.impl.source.codeStyle.SemanticEditorPosition.SyntaxElement; import com.intellij.psi.impl.source.codeStyle.lineIndent.IndentCalculator.BaseLineOffsetCalculator; @@ -36,7 +37,7 @@ import static com.intellij.psi.impl.source.codeStyle.lineIndent.JavaLikeLangLine * A base class Java-like language line indent provider. If JavaLikeLangLineIndentProvider is unable to calculate * the indentation, it forwards the request to FormatterBasedLineIndentProvider. */ -public abstract class JavaLikeLangLineIndentProvider extends FormatterBasedLineIndentProvider { +public abstract class JavaLikeLangLineIndentProvider implements LineIndentProvider{ public enum JavaLikeElement implements SyntaxElement { Whitespace, @@ -73,7 +74,7 @@ public abstract class JavaLikeLangLineIndentProvider extends FormatterBasedLineI else { return ""; } - return super.getLineIndent(project, editor, language, offset); + return null; } @Nullable diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index baf8e92cfbfb..d7ff268dbd3f 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -967,7 +967,9 @@ - + From d209b373a629454932d5b6b2c514574dac2d6eb6 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Fri, 14 Oct 2016 10:57:37 +0200 Subject: [PATCH 16/21] inline parameter: warn if method with target signature already exist (IDEA-162205) --- .../SameParameterValueInspection.java | 17 +++++++++++++ .../InlineParameterExpressionProcessor.java | 7 +++--- .../safeDelete/JavaSafeDeleteProcessor.java | 24 +++++++++++-------- .../SameSignatureExistConflict.java | 6 +++++ .../inline/InlineParameterTest.java | 10 ++++++++ 5 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 java/java-tests/testData/refactoring/inlineParameter/SameSignatureExistConflict.java diff --git a/java/java-impl/src/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java b/java/java-impl/src/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java index af26f2001483..d6ea95349870 100644 --- a/java/java-impl/src/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java @@ -25,11 +25,15 @@ import com.intellij.openapi.util.Comparing; import com.intellij.psi.*; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor; import com.intellij.refactoring.changeSignature.ParameterInfoImpl; +import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor; +import com.intellij.refactoring.ui.ConflictsDialog; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.InlineUtil; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -107,6 +111,19 @@ public class SameParameterValueInspection extends SameParameterValueInspectionBa } public static void inlineSameParameterValue(final PsiMethod method, final PsiParameter parameter, final PsiExpression defToInline) { + final MultiMap conflicts = new MultiMap<>(); + JavaSafeDeleteProcessor.collectMethodConflicts(conflicts, method, parameter); + if (!conflicts.isEmpty()) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + if (!BaseRefactoringProcessor.ConflictsInTestsException.isTestIgnore()) { + throw new BaseRefactoringProcessor.ConflictsInTestsException(conflicts.values()); + } + } + else if (!new ConflictsDialog(parameter.getProject(), conflicts).showAndGet()) { + return; + } + } + final Collection refsToInline = ReferencesSearch.search(parameter).findAll(); ApplicationManager.getApplication().runWriteAction(() -> { diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterExpressionProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterExpressionProcessor.java index 2b878a92ff76..566d22709267 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterExpressionProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterExpressionProcessor.java @@ -30,10 +30,8 @@ import com.intellij.refactoring.changeSignature.ChangeSignatureProcessorBase; import com.intellij.refactoring.changeSignature.JavaChangeInfo; import com.intellij.refactoring.changeSignature.JavaChangeInfoImpl; import com.intellij.refactoring.changeSignature.ParameterInfoImpl; -import com.intellij.refactoring.util.CanonicalTypes; -import com.intellij.refactoring.util.InlineUtil; -import com.intellij.refactoring.util.RefactoringUIUtil; -import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor; +import com.intellij.refactoring.util.*; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; import com.intellij.usageView.UsageViewUtil; @@ -204,6 +202,7 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor @Override protected boolean preprocessUsages(@NotNull Ref refUsages) { final MultiMap conflicts = new MultiMap<>(); + JavaSafeDeleteProcessor.collectMethodConflicts(conflicts, myMethod, myParameter); final UsageInfo[] usages = refUsages.get(); final InaccessibleExpressionsDetector detector = new InaccessibleExpressionsDetector(conflicts); myInitializer.accept(detector); diff --git a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java index 8c0ef09461f9..858d6116dd58 100644 --- a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java @@ -296,15 +296,9 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase { final PsiElement scope = ((PsiParameter)element).getDeclarationScope(); if (scope instanceof PsiMethod) { final PsiMethod method = (PsiMethod)scope; - final PsiClass containingClass = method.getContainingClass(); - if (containingClass != null) { - final int parameterIndex = method.getParameterList().getParameterIndex((PsiParameter)element); - final PsiMethod methodCopy = (PsiMethod)method.copy(); - methodCopy.getParameterList().getParameters()[parameterIndex].delete(); - final MultiMap conflicts = new MultiMap<>(); - ConflictsUtil.checkMethodConflicts(containingClass, method, methodCopy, conflicts); - return (Collection)conflicts.values(); - } + final MultiMap conflicts = new MultiMap<>(); + collectMethodConflicts(conflicts, method, (PsiParameter)element); + return (Collection)conflicts.values(); } } return null; @@ -963,7 +957,17 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase { return false; } - + + public static void collectMethodConflicts(MultiMap conflicts, PsiMethod method, PsiParameter parameter) { + final PsiClass containingClass = method.getContainingClass(); + if (containingClass != null) { + final int parameterIndex = method.getParameterList().getParameterIndex(parameter); + final PsiMethod methodCopy = (PsiMethod)method.copy(); + methodCopy.getParameterList().getParameters()[parameterIndex].delete(); + ConflictsUtil.checkMethodConflicts(containingClass, method, methodCopy, conflicts); + } + } + private static class SafeDeleteFunctionalExpressionUsageInfo extends SafeDeleteReferenceUsageInfo { public SafeDeleteFunctionalExpressionUsageInfo(@NotNull PsiElement element, PsiElement referencedElement) { super(element, referencedElement, false); diff --git a/java/java-tests/testData/refactoring/inlineParameter/SameSignatureExistConflict.java b/java/java-tests/testData/refactoring/inlineParameter/SameSignatureExistConflict.java new file mode 100644 index 000000000000..5a78725eb569 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineParameter/SameSignatureExistConflict.java @@ -0,0 +1,6 @@ +class Test { + void doTest(boolean b) {} + void doTest() { + doTest(false); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java index 515105eae59d..be8149f7d70a 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java @@ -295,6 +295,16 @@ public class InlineParameterTest extends LightRefactoringTestCase { } } + public void testSameSignatureExistConflict() throws Exception { + try { + doTest(false); + fail(); + } + catch (BaseRefactoringProcessor.ConflictsInTestsException e) { + assertEquals("Method doTest() is already defined in the class Test", e.getMessage()); + } + } + private void doTest(final boolean createLocal) throws Exception { getProject().putUserData(InlineParameterExpressionProcessor.CREATE_LOCAL_FOR_TESTS,createLocal); From 558213af500d55f90875fdcad6d64d7f88ec24af Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Fri, 14 Oct 2016 15:11:22 +0200 Subject: [PATCH 17/21] testng method refs: bind to implemented EA-76777 - IOE: PsiReferenceBase.bindToElement --- .../theoryinpractice/testng/DataProviderReference.java | 9 +++++++++ .../testng/TestNGReferenceContributor.java | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/plugins/testng/src/com/theoryinpractice/testng/DataProviderReference.java b/plugins/testng/src/com/theoryinpractice/testng/DataProviderReference.java index da741b90a27e..2d9cc2e5f543 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/DataProviderReference.java +++ b/plugins/testng/src/com/theoryinpractice/testng/DataProviderReference.java @@ -21,6 +21,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; import com.theoryinpractice.testng.util.TestNGUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -36,6 +37,14 @@ public class DataProviderReference extends PsiReferenceBase { super(element, false); } + @Override + public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { + if (element instanceof PsiMethod) { + return handleElementRename(((PsiMethod)element).getName()); + } + return super.bindToElement(element); + } + @Nullable public PsiElement resolve() { final PsiClass cls = TestNGUtil.getProviderClass(getElement(), PsiUtil.getTopLevelClass(getElement())); diff --git a/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java b/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java index 9e757c0a9e35..bf522671223a 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java +++ b/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java @@ -38,6 +38,7 @@ import com.intellij.psi.filters.position.FilterPattern; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.ArrayUtil; +import com.intellij.util.IncorrectOperationException; import com.intellij.util.ProcessingContext; import com.theoryinpractice.testng.inspection.DependsOnGroupsInspection; import com.theoryinpractice.testng.util.TestNGUtil; @@ -87,6 +88,14 @@ public class TestNGReferenceContributor extends PsiReferenceContributor { super(element, false); } + @Override + public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { + if (element instanceof PsiMethod) { + return handleElementRename(((PsiMethod)element).getName()); + } + return super.bindToElement(element); + } + @Nullable public PsiElement resolve() { @NonNls String val = getValue(); From 0b8838bf70bbbb20e9b3a562608c25529fa20107 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Fri, 14 Oct 2016 15:32:23 +0200 Subject: [PATCH 18/21] read action EA-72561 - assert: SharedImplUtil.findFileElement --- .../actions/ShowImplementationsAction.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java index 37f655cec865..b6cc2414ac35 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java @@ -26,6 +26,7 @@ import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditor; @@ -353,19 +354,22 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { final PsiElement[] handlerImplementations = handler.searchImplementations(element, editor, offset, includeSelfAlways, true); if (handlerImplementations.length > 0) return handlerImplementations; - PsiFile psiFile = element.getContainingFile(); - if (psiFile == null) { - // Magically, it's null for ant property declarations. - element = element.getNavigationElement(); - psiFile = element.getContainingFile(); + return ReadAction.compute(() -> { + PsiElement psiElement = element; + PsiFile psiFile = psiElement.getContainingFile(); if (psiFile == null) { - return PsiElement.EMPTY_ARRAY; + // Magically, it's null for ant property declarations. + psiElement = psiElement.getNavigationElement(); + psiFile = psiElement.getContainingFile(); + if (psiFile == null) { + return PsiElement.EMPTY_ARRAY; + } } - } - if (psiFile.getVirtualFile() != null && (element.getTextRange() != null || element instanceof PsiFile)) { - return new PsiElement[]{element}; - } - return PsiElement.EMPTY_ARRAY; + if (psiFile.getVirtualFile() != null && (psiElement.getTextRange() != null || psiElement instanceof PsiFile)) { + return new PsiElement[]{psiElement}; + } + return PsiElement.EMPTY_ARRAY; + }); } @NotNull From 011101a31e0548f2162fcb540dfdada42be48709 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Fri, 14 Oct 2016 16:18:19 +0200 Subject: [PATCH 19/21] move everything preserving source root on multiselection (IDEA-160969) --- .../JavaMoveClassesOrPackagesHandler.java | 18 +++++++++++-- ...ClassesOrPackagesToNewDirectoryDialog.java | 26 ++++++++++++------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java index d27c1eacaca3..c5134f20653e 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java @@ -18,6 +18,7 @@ package com.intellij.refactoring.move.moveClassesOrPackages; import com.intellij.CommonBundle; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.module.Module; @@ -34,6 +35,7 @@ import com.intellij.psi.impl.file.JavaDirectoryServiceImpl; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.JavaRefactoringSettings; +import com.intellij.refactoring.MoveDestination; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.move.MoveCallback; import com.intellij.refactoring.move.MoveHandlerDelegate; @@ -218,16 +220,28 @@ public class JavaMoveClassesOrPackagesHandler extends MoveHandlerDelegate { PsiPackage aPackage, boolean searchInComments, boolean searchForTextOccurences) { + final MoveDestination destination = createDestination(aPackage, targetDirectory); try { for (PsiDirectory dir: directories) { - MoveFilesOrDirectoriesUtil.checkIfMoveIntoSelf(dir, targetDirectory); + MoveFilesOrDirectoriesUtil.checkIfMoveIntoSelf(dir, WriteAction.compute(() -> destination.getTargetDirectory(dir))); } } catch (IncorrectOperationException e) { Messages.showErrorDialog(project, e.getMessage(), RefactoringBundle.message("cannot.move")); return null; } - return new MoveDirectoryWithClassesProcessor(project, directories, targetDirectory, searchInComments, searchForTextOccurences, true, callback); + return new MoveDirectoryWithClassesProcessor(project, directories, null, searchInComments, searchForTextOccurences, true, callback) { + @Override + public TargetDirectoryWrapper getTargetDirectory(PsiDirectory dir) { + final PsiDirectory targetDirectory = destination.getTargetDirectory(dir); + return new TargetDirectoryWrapper(targetDirectory); + } + + @Override + protected String getTargetName() { + return targetDirectory.getName(); + } + }; } }; dlg.show(); diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java index ca714753ecfd..96b886fd77bc 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java @@ -218,16 +218,7 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends MoveDialogBase { PsiPackage aPackage, boolean searchInComments, boolean searchForTextOccurences) { - final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(directory.getVirtualFile()); - if (sourceRoot == null) { - Messages.showErrorDialog(project, RefactoringBundle.message("destination.directory.does.not.correspond.to.any.package"), - RefactoringBundle.message("cannot.move")); - return null; - } - final JavaRefactoringFactory factory = JavaRefactoringFactory.getInstance(project); - final MoveDestination destination = myPreserveSourceRoot.isSelected() && myPreserveSourceRoot.isVisible() - ? factory.createSourceFolderPreservingMoveDestination(aPackage.getQualifiedName()) - : factory.createSourceRootMoveDestination(aPackage.getQualifiedName(), sourceRoot); + final MoveDestination destination = createDestination(aPackage, directory); MoveClassesOrPackagesProcessor processor = createMoveClassesOrPackagesProcessor(myDirectory.getProject(), myElementsToMove, destination, searchInComments, searchForTextOccurences, myMoveCallback); @@ -239,6 +230,21 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends MoveDialogBase { return null; } + protected MoveDestination createDestination(PsiPackage aPackage, PsiDirectory directory) { + final Project project = aPackage.getProject(); + final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(directory.getVirtualFile()); + if (sourceRoot == null) { + Messages.showErrorDialog(project, RefactoringBundle.message("destination.directory.does.not.correspond.to.any.package"), + RefactoringBundle.message("cannot.move")); + return null; + } + + final JavaRefactoringFactory factory = JavaRefactoringFactory.getInstance(project); + return myPreserveSourceRoot.isSelected() && myPreserveSourceRoot.isVisible() + ? factory.createSourceFolderPreservingMoveDestination(aPackage.getQualifiedName()) + : factory.createSourceRootMoveDestination(aPackage.getQualifiedName(), sourceRoot); + } + @Override protected String getMovePropertySuffix() { return "ClassWithTarget"; From 2bd3365dc6e9ad9c1ef551e291320425445fa41e Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Fri, 14 Oct 2016 16:31:35 +0200 Subject: [PATCH 20/21] fix testdata --- ...nces.java => placeInsideLambdaBodyMultipleOccurrences1.java} | 0 ...ava => placeInsideLambdaBodyMultipleOccurrences1_after.java} | 0 .../com/intellij/refactoring/InplaceIntroduceVariableTest.java | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename java/java-tests/testData/refactoring/inplaceIntroduceVariable/{PlaceInsideLambdaBodyMultipleOccurrences.java => placeInsideLambdaBodyMultipleOccurrences1.java} (100%) rename java/java-tests/testData/refactoring/inplaceIntroduceVariable/{PlaceInsideLambdaBodyMultipleOccurrences_after.java => placeInsideLambdaBodyMultipleOccurrences1_after.java} (100%) diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceVariable/PlaceInsideLambdaBodyMultipleOccurrences.java b/java/java-tests/testData/refactoring/inplaceIntroduceVariable/placeInsideLambdaBodyMultipleOccurrences1.java similarity index 100% rename from java/java-tests/testData/refactoring/inplaceIntroduceVariable/PlaceInsideLambdaBodyMultipleOccurrences.java rename to java/java-tests/testData/refactoring/inplaceIntroduceVariable/placeInsideLambdaBodyMultipleOccurrences1.java diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceVariable/PlaceInsideLambdaBodyMultipleOccurrences_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceVariable/placeInsideLambdaBodyMultipleOccurrences1_after.java similarity index 100% rename from java/java-tests/testData/refactoring/inplaceIntroduceVariable/PlaceInsideLambdaBodyMultipleOccurrences_after.java rename to java/java-tests/testData/refactoring/inplaceIntroduceVariable/placeInsideLambdaBodyMultipleOccurrences1_after.java diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceVariableTest.java index d9c460cb06c5..5e9ca964059c 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceVariableTest.java @@ -116,7 +116,7 @@ public class InplaceIntroduceVariableTest extends AbstractJavaInplaceIntroduceTe }); } - public void testPlaceInsideLambdaBodyMultipleOccurrences() throws Exception { + public void testPlaceInsideLambdaBodyMultipleOccurrences1() throws Exception { doTestReplaceChoice(OccurrencesChooser.ReplaceChoice.ALL, new Pass() { @Override public void pass(AbstractInplaceIntroducer inplaceIntroduceFieldPopup) { From b4e178db3644dc0cf95b66f8b37826d301339211 Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Fri, 14 Oct 2016 17:57:36 +0300 Subject: [PATCH 21/21] gradle: handle errors for projects with composite definition on gradle side for gradle builtin models --- .../BaseGradleProjectResolverExtension.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java index 217c2ee49964..fb0dfa11bba4 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java @@ -26,13 +26,19 @@ import com.intellij.openapi.externalSystem.model.DataNode; import com.intellij.openapi.externalSystem.model.ExternalSystemException; import com.intellij.openapi.externalSystem.model.ProjectKeys; import com.intellij.openapi.externalSystem.model.project.*; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import com.intellij.openapi.externalSystem.model.task.TaskData; +import com.intellij.openapi.externalSystem.service.notification.ExternalSystemNotificationManager; +import com.intellij.openapi.externalSystem.service.notification.NotificationCategory; +import com.intellij.openapi.externalSystem.service.notification.NotificationData; +import com.intellij.openapi.externalSystem.service.notification.NotificationSource; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.Order; import com.intellij.openapi.module.EmptyModuleType; import com.intellij.openapi.module.JavaModuleType; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.module.StdModuleTypes; +import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.DependencyScope; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileFilters; @@ -467,6 +473,7 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver if (dependencies == null) return; + List orphanModules = ContainerUtil.newArrayList(); for (IdeaDependency dependency : dependencies) { if (dependency == null) { continue; @@ -480,6 +487,10 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver d.setScope(scope); } ideModule.createChild(ProjectKeys.MODULE_DEPENDENCY, d); + ModuleData targetModule = d.getTarget(); + if (targetModule.getId().isEmpty() && targetModule.getLinkedExternalProjectPath().isEmpty()) { + orphanModules.add(targetModule.getExternalName()); + } } else if (dependency instanceof IdeaSingleEntryLibraryDependency) { LibraryDependencyData d = buildDependency(gradleModule, ideModule, (IdeaSingleEntryLibraryDependency)dependency, ideProject); @@ -490,6 +501,20 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver ideModule.createChild(ProjectKeys.LIBRARY_DEPENDENCY, d); } } + + if (!orphanModules.isEmpty()) { + ExternalSystemTaskId taskId = resolverCtx.getExternalSystemTaskId(); + Project project = taskId.findProject(); + if (project != null) { + String msg = + "Can't find the following module" + (orphanModules.size() > 1 ? "s" : "") + ": " + StringUtil.join(orphanModules, ", ") + + "\nIt can be caused by composite build configuration inside your *.gradle scripts with Gradle version older than 3.3." + + "\nTry Gradle 3.3 or better or enable 'Create separate module per source set' option"; + NotificationData notification = new NotificationData( + "Gradle project structure problems", msg, NotificationCategory.WARNING, NotificationSource.PROJECT_SYNC); + ExternalSystemNotificationManager.getInstance(project).showNotification(taskId.getProjectSystemId(), notification); + } + } } @NotNull @@ -794,6 +819,10 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver if (moduleData != null) { return new ModuleDependencyData(ownerModule.getData(), moduleData); } + else if (StringUtil.isNotEmpty(moduleName)) { + return new ModuleDependencyData( + ownerModule.getData(), new ModuleData("", GradleConstants.SYSTEM_ID, StdModuleTypes.JAVA.getId(), moduleName, "", "")); + } } throw new IllegalStateException( String.format("Can't parse gradle module dependency '%s'. Reason: referenced module is null", dependency)