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/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); 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/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"; 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/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) { 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); 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") 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/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/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() { 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/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 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..b6e8057b2f99 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt @@ -15,24 +15,34 @@ */ 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 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.openapi.util.text.StringUtil +import com.intellij.psi.PsiFile import com.intellij.psi.PsiManager import com.intellij.psi.util.PsiTreeUtil -class ShowParameterHintsSettings : AnAction() { +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) { @@ -40,43 +50,59 @@ 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" - 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) { 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) } } +class BlacklistCurrentMethodIntention : IntentionAction, HighPriorityAction { + 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) + } + + override fun invoke(project: Project, editor: Editor, file: PsiFile) { + addMethodAtCaretToBlackList(editor, file) + } + + override fun startInWriteAction() = false +} + class ToggleInlineHintsAction : AnAction() { - + + companion object { + 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) { - 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) disableText else enableText + } + else { + e.presentation.isEnabledAndVisible = false + } } override fun actionPerformed(e: AnActionEvent) { @@ -88,6 +114,13 @@ class ToggleInlineHintsAction : AnAction() { } } +private fun hasParameterHintAtOffset(editor: Editor): Boolean { + val offset = editor.caretModel.offset + return editor.inlayModel + .getInlineElementsInRange(offset, offset) + .find { ParameterHintsPresentationManager.getInstance().isParameterHint(it) } != null +} + private fun refreshAllOpenEditors() { ProjectManager.getInstance().openProjects.forEach { val psiManager = PsiManager.getInstance(it) @@ -99,3 +132,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 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-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); } } 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-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 diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 5d953f636fb4..d7ff268dbd3f 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 @@ -964,7 +967,9 @@ - + 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 @@ - + + + + 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, '▌'); 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); } 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) 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(); 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? { 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