mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+17
@@ -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);
|
||||
|
||||
+3
-4
@@ -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);
|
||||
|
||||
+16
-2
@@ -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();
|
||||
|
||||
+16
-10
@@ -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";
|
||||
|
||||
+14
-10
@@ -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")
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+3
-5
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+15
-11
@@ -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()
|
||||
}
|
||||
+67
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+3
-2
@@ -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"/>
|
||||
|
||||
+10
@@ -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);
|
||||
}
|
||||
|
||||
+29
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user