From 35040d4e55c50d0183b356aab70b995bd470cb9f Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 28 Feb 2014 15:43:15 +0100 Subject: [PATCH] IDEA-121253 Allow to edit/add contract annotation for library method at usage location --- .../intention/AddAnnotationPsiFix.java | 24 ++++++++++++------ .../impl/AddNullableNotNullAnnotationFix.java | 2 +- .../impl/AddAnnotationIntention.java | 25 +++---------------- .../dataFlow/EditContractIntention.java | 18 ++++--------- .../codeInsight/AddAnnotationFixTest.java | 10 ++------ 5 files changed, 29 insertions(+), 50 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java index 987f02dc9c39..84f704f64dcd 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java @@ -64,15 +64,25 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement { } @Nullable - public static PsiModifierListOwner getContainer(final PsiElement element) { - PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(element, PsiParameter.class, false); - if (listOwner == null) { - final PsiIdentifier psiIdentifier = PsiTreeUtil.getParentOfType(element, PsiIdentifier.class, false); - if (psiIdentifier != null && psiIdentifier.getParent() instanceof PsiModifierListOwner) { - listOwner = (PsiModifierListOwner)psiIdentifier.getParent(); + public static PsiModifierListOwner getContainer(final PsiFile file, int offset) { + PsiReference reference = file.findReferenceAt(offset); + if (reference != null) { + PsiElement target = reference.resolve(); + if (target instanceof PsiMember) { + return (PsiMember)target; } } - return listOwner; + + PsiElement element = file.findElementAt(offset); + + PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(element, PsiParameter.class, false); + if (listOwner != null) return listOwner; + + final PsiIdentifier psiIdentifier = PsiTreeUtil.getParentOfType(element, PsiIdentifier.class, false); + if (psiIdentifier != null && psiIdentifier.getParent() instanceof PsiModifierListOwner) { + return (PsiModifierListOwner)psiIdentifier.getParent(); + } + return null; } @Override diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java index 6684613f0ab0..272ce37708ad 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java @@ -41,7 +41,7 @@ public class AddNullableNotNullAnnotationFix extends AddAnnotationPsiFix { if (!super.isAvailable(project, file, startElement, endElement)) { return false; } - PsiModifierListOwner owner = getContainer(startElement); + PsiModifierListOwner owner = getContainer(file, startElement.getTextRange().getStartOffset()); if (owner == null || AnnotationUtil.isAnnotated(owner, getAnnotationsToRemove()[0], false, false)) { return false; } diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java index 2b839b5dfcde..daf5aa5eac74 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java @@ -26,13 +26,11 @@ import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.intention.AddAnnotationFix; import com.intellij.codeInsight.intention.AddAnnotationPsiFix; -import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; -import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -49,22 +47,11 @@ public abstract class AddAnnotationIntention extends BaseIntentionAction { // include not in project files @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - CaretModel caretModel = editor.getCaretModel(); - int position = caretModel.getOffset(); - PsiElement element = file.findElementAt(position); - return element != null && isAvailable(project, element); - } - - public boolean isAvailable(@NotNull final Project project, @NotNull final PsiElement element) { - if (!element.isValid()) return false; - final PsiModifierListOwner owner; - if (!element.getManager().isInProject(element) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) { - owner = AddAnnotationPsiFix.getContainer(element); - } - else { + final PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(file, editor.getCaretModel().getOffset()); + if (owner == null || + owner.getManager().isInProject(owner) && !CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) { return false; } - if (owner == null) return false; Pair annotations = getAnnotations(project); String toAdd = annotations.first; String[] toRemove = annotations.second; @@ -82,11 +69,7 @@ public abstract class AddAnnotationIntention extends BaseIntentionAction { @Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - CaretModel caretModel = editor.getCaretModel(); - int position = caretModel.getOffset(); - PsiElement element = file.findElementAt(position); - - PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(element); + PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(file, editor.getCaretModel().getOffset()); if (owner == null || !owner.isValid()) return; Pair annotations = getAnnotations(project); String toAdd = annotations.first; diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java index 7040347c4d0e..767077b3448e 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java @@ -28,7 +28,6 @@ import com.intellij.openapi.ui.InputValidatorEx; import com.intellij.openapi.ui.Messages; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; -import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -48,22 +47,15 @@ public class EditContractIntention extends BaseIntentionAction { @Nullable private static PsiMethod getTargetMethod(@NotNull Project project, Editor editor, PsiFile file) { - PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); - if (element == null) return null; - if (!element.getManager().isInProject(element) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) { - final PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(element); - if (owner instanceof PsiMethod) { - PsiElement original = owner.getOriginalElement(); - if (original instanceof PsiMethod) { - return (PsiMethod)original; - } - return (PsiMethod)owner; - } + final PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(file, editor.getCaretModel().getOffset()); + if (owner instanceof PsiMethod && + (!owner.getManager().isInProject(owner) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS)) { + PsiElement original = owner.getOriginalElement(); + return original instanceof PsiMethod ? (PsiMethod)original : (PsiMethod)owner; } return null; } - @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { final PsiMethod method = getTargetMethod(project, editor, file); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java index 231a0cd45c0a..ec8b8dd49284 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java @@ -27,7 +27,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.ex.PathManagerEx; import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.module.Module; @@ -51,6 +50,7 @@ import com.intellij.testFramework.PsiTestUtil; import com.intellij.testFramework.UsefulTestCase; import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; import com.intellij.testFramework.fixtures.*; +import com.intellij.util.ObjectUtils; import com.intellij.util.messages.MessageBusConnection; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -122,13 +122,7 @@ public class AddAnnotationFixTest extends UsefulTestCase { @NotNull private PsiModifierListOwner getOwner() { - CaretModel caretModel = myFixture.getEditor().getCaretModel(); - int position = caretModel.getOffset(); - PsiElement element = myFixture.getFile().findElementAt(position); - assert element != null; - PsiModifierListOwner container = AddAnnotationPsiFix.getContainer(element); - assert container != null; - return container; + return ObjectUtils.assertNotNull(AddAnnotationPsiFix.getContainer(myFixture.getFile(), myFixture.getCaretOffset())); } private void startListening(@NotNull final List> expectedSequence) {