Merge remote-tracking branch 'origin/master'

This commit is contained in:
Egor.Ushakov
2016-10-14 18:31:45 +03:00
32 changed files with 365 additions and 125 deletions
@@ -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<PsiElement, String> 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<PsiReference> refsToInline = ReferencesSearch.search(parameter).findAll();
ApplicationManager.getApplication().runWriteAction(() -> {
@@ -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<Set<P
});
final Set<SmartPsiElementPointer<PsiImportStatementBase>> 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);
@@ -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<UsageInfo[]> refUsages) {
final MultiMap<PsiElement, String> conflicts = new MultiMap<>();
JavaSafeDeleteProcessor.collectMethodConflicts(conflicts, myMethod, myParameter);
final UsageInfo[] usages = refUsages.get();
final InaccessibleExpressionsDetector detector = new InaccessibleExpressionsDetector(conflicts);
myInitializer.accept(detector);
@@ -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();
@@ -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";
@@ -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<PsiElement, String> conflicts = new MultiMap<>();
ConflictsUtil.checkMethodConflicts(containingClass, method, methodCopy, conflicts);
return (Collection<String>)conflicts.values();
}
final MultiMap<PsiElement, String> conflicts = new MultiMap<>();
collectMethodConflicts(conflicts, method, (PsiParameter)element);
return (Collection<String>)conflicts.values();
}
}
return null;
@@ -963,7 +957,17 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase {
return false;
}
public static void collectMethodConflicts(MultiMap<PsiElement, String> 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);
@@ -0,0 +1,6 @@
class Test {
void doTest(boolean <caret>b) {}
void doTest() {
doTest(false);
}
}
@@ -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<AbstractInplaceIntroducer>() {
@Override
public void pass(AbstractInplaceIntroducer inplaceIntroduceFieldPopup) {
@@ -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 <b><code>Test</code></b>", e.getMessage());
}
}
private void doTest(final boolean createLocal) throws Exception {
getProject().putUserData(InlineParameterExpressionProcessor.CREATE_LOCAL_FOR_TESTS,createLocal);
@@ -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")
@@ -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;
@@ -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;
}
}
@@ -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<UnnamedC
myCbBlinkCaret.addActionListener((e) -> myBlinkIntervalField.setEnabled(myCbBlinkCaret.isSelected()));
myCbShowWhitespaces.addActionListener((e) -> updateWhitespaceCheckboxesState());
myShowParameterNameHints.setVisible(InlayParameterHintsExtension.INSTANCE.hasAnyExtensions());
}
private void applyNameHintsSettings() {
@@ -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;
}
}
@@ -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
@@ -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()
}
@@ -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);
}
}
}
@@ -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
@@ -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);
}
}
@@ -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<Inlay> getInlineElementsInRange(int startOffset, int endOffset) {
ApplicationManager.getApplication().assertIsDispatchThread();
List<Inlay> result = new ArrayList<>();
myInlayTree.processOverlappingWith(startOffset, endOffset, inlay -> {
result.add(inlay);
@@ -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 <i>{0}</i> <p>Configuring paths to API docs in <a href="open://Project Settings">project settings</a> 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
@@ -686,6 +686,9 @@
<intentionAction>
<className>com.intellij.formatting.contextConfiguration.ConfigureCodeStyleOnSelectedFragment</className>
</intentionAction>
<intentionAction>
<className>com.intellij.codeInsight.hints.BlacklistCurrentMethodIntention</className>
</intentionAction>
<intentionAction>
<className>com.intellij.codeInsight.intention.impl.QuickEditAction</className>
<category>Language Injection</category>
@@ -964,7 +967,9 @@
<nonProjectFileWritingAccessExtension implementation="com.intellij.ide.actions.EditCustomPropertiesAction$AccessExtension"/>
<nonProjectFileWritingAccessExtension implementation="com.intellij.ide.actions.EditCustomVmOptionsAction$AccessExtension"/>
<lineIndentProvider implementation="com.intellij.psi.impl.source.codeStyle.lineIndent.FormatterBasedLineIndentProvider"/>
<lineIndentProvider
implementation="com.intellij.psi.impl.source.codeStyle.lineIndent.FormatterBasedLineIndentProvider"
order="last"/>
<stripTrailingSpacesFilterFactory implementation="com.intellij.psi.codeStyle.KeepTrailingSpacesOnEmptyLinesFilterFactory"/>
<treeStructureProvider implementation="com.intellij.ide.projectView.impl.NestingTreeStructureProvider" order="last"/>
@@ -302,9 +302,12 @@
<group id="ParameterNameHints" popup="true">
<action id="BlacklistCurrentMethodAction" class="com.intellij.codeInsight.hints.BlacklistCurrentMethodAction"/>
<action id="ShowParameterHintsSettings" class="com.intellij.codeInsight.hints.ShowParameterHintsSettings"/>
<action id="ToggleInlineHintsAction" class="com.intellij.codeInsight.hints.ToggleInlineHintsAction"/>
</group>
<action id="ToggleInlineHintsAction" class="com.intellij.codeInsight.hints.ToggleInlineHintsAction">
<add-to-group group-id="EditorPopupMenu"/>
</action>
<!-- Analyze -->
<action id="SliceBackward" class="com.intellij.slicer.SliceBackwardAction"/>
<action id="SliceForward" class="com.intellij.slicer.SliceForwardAction"/>
@@ -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, '▌');
@@ -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);
}
@@ -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<String> 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)
@@ -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<PsiLiteral> {
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()));
@@ -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();
@@ -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<Nothing>(project) {
@Throws(Throwable::class)
override fun run(result: Result<Nothing>) {
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? {
@@ -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