IDEA-121253 Allow to edit/add contract annotation for library method at usage location

This commit is contained in:
peter
2014-02-28 16:25:05 +01:00
parent d5e833a9bd
commit 35040d4e55
5 changed files with 29 additions and 50 deletions
@@ -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
@@ -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;
}
@@ -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<String, String[]> 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<String, String[]> annotations = getAnnotations(project);
String toAdd = annotations.first;
@@ -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);
@@ -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<Trinity<PsiModifierListOwner, String, Boolean>> expectedSequence) {