KotlinSignature markers do not fail in case of enum in sources

Refactor to make all KotlinSignature intention share some logic
This commit is contained in:
Pavel V. Talanov
2014-09-10 14:51:33 +04:00
parent d32221ff4a
commit e6df5c4bdc
5 changed files with 56 additions and 42 deletions
@@ -34,8 +34,8 @@ public class DeleteSignatureAction extends AnAction {
public DeleteSignatureAction(@NotNull PsiModifierListOwner elementInEditor) {
super("Delete");
this.annotationOwner = KotlinSignatureUtil.getAnnotationOwner(elementInEditor);
getTemplatePresentation().setVisible(KotlinSignatureUtil.isAnnotationEditable(elementInEditor));
this.annotationOwner = KotlinSignatureUtil.getAnalyzableAnnotationOwner(elementInEditor);
getTemplatePresentation().setVisible(annotationOwner != null && KotlinSignatureUtil.isAnnotationEditable(elementInEditor));
}
@Override
@@ -73,7 +73,7 @@ public class EditSignatureAction extends AnAction {
}
}
else {
PsiModifierListOwner annotationOwner = KotlinSignatureUtil.getAnnotationOwner(elementInEditor);
PsiModifierListOwner annotationOwner = KotlinSignatureUtil.getAnalyzableAnnotationOwner(elementInEditor);
boolean editable = KotlinSignatureUtil.isAnnotationEditable(elementInEditor);
//noinspection ConstantConditions
EditSignatureBalloon balloon = new EditSignatureBalloon(annotationOwner, KotlinSignatureUtil.getKotlinSignature(annotation),
@@ -69,13 +69,13 @@ public class KotlinSignatureAnnotationIntention extends BaseIntentionAction impl
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
PsiModifierListOwner annotationOwner = findAnnotationOwner(file, editor);
if (annotationOwner == null) {
PsiMember memberUnderCaret = findMemberUnderCaret(file, editor);
if (memberUnderCaret == null) {
return false;
}
PsiModifierList modifierList = annotationOwner.getModifierList();
if (modifierList == null || modifierList.hasExplicitModifier(PsiModifier.PRIVATE)) {
PsiModifierListOwner annotationOwner = KotlinSignatureUtil.getAnalyzableAnnotationOwner(memberUnderCaret);
if (annotationOwner == null) {
return false;
}
@@ -97,7 +97,7 @@ public class KotlinSignatureAnnotationIntention extends BaseIntentionAction impl
@Override
public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws IncorrectOperationException {
final PsiMember annotatedElement = findAnnotationOwner(file, editor);
final PsiMember annotatedElement = findMemberUnderCaret(file, editor);
assert annotatedElement != null;
@@ -106,7 +106,7 @@ public class KotlinSignatureAnnotationIntention extends BaseIntentionAction impl
return;
}
String signature = getDefaultSignature(project, (PsiMember) KotlinSignatureUtil.getAnnotationOwner(annotatedElement));
String signature = getDefaultSignature(project, annotatedElement);
final MessageBusConnection busConnection = project.getMessageBus().connect();
busConnection.subscribe(ExternalAnnotationsManager.TOPIC, new ExternalAnnotationsListener.Adapter() {
@@ -142,21 +142,24 @@ public class KotlinSignatureAnnotationIntention extends BaseIntentionAction impl
}
@NotNull
private static String getDefaultSignature(@NotNull Project project, @NotNull PsiMember psiMember) {
JavaDescriptorResolver javaDescriptorResolver = JavaResolveExtension.INSTANCE$.getResolver(project, psiMember);
private static String getDefaultSignature(@NotNull Project project, @NotNull PsiMember element) {
PsiMember analyzableAnnotationOwner = KotlinSignatureUtil.getAnalyzableAnnotationOwner(element);
assert analyzableAnnotationOwner != null;
JavaDescriptorResolver javaDescriptorResolver = JavaResolveExtension.INSTANCE$.getResolver(project, analyzableAnnotationOwner);
if (psiMember instanceof PsiMethod) {
PsiMethod psiMethod = (PsiMethod) psiMember;
if (analyzableAnnotationOwner instanceof PsiMethod) {
PsiMethod psiMethod = (PsiMethod) analyzableAnnotationOwner;
FunctionDescriptor functionDescriptor = JavaPackage.resolveMethod(javaDescriptorResolver, new JavaMethodImpl(psiMethod));
assert functionDescriptor != null: "Couldn't find function descriptor for " + renderMember(psiMember);
assert functionDescriptor != null : "Couldn't find function descriptor for " + renderMember(analyzableAnnotationOwner);
return functionDescriptor instanceof ConstructorDescriptor
? getDefaultConstructorAnnotation((ConstructorDescriptor) functionDescriptor)
: RENDERER.render(functionDescriptor);
}
if (psiMember instanceof PsiField) {
VariableDescriptor variableDescriptor = JavaPackage.resolveField(javaDescriptorResolver, new JavaFieldImpl((PsiField) psiMember));
assert variableDescriptor != null: "Couldn't find variable descriptor for field " + renderMember(psiMember);
if (analyzableAnnotationOwner instanceof PsiField) {
VariableDescriptor variableDescriptor =
JavaPackage.resolveField(javaDescriptorResolver, new JavaFieldImpl((PsiField) analyzableAnnotationOwner));
assert variableDescriptor != null : "Couldn't find variable descriptor for field " + renderMember(analyzableAnnotationOwner);
return RENDERER.render(variableDescriptor);
}
@@ -168,7 +171,7 @@ public class KotlinSignatureAnnotationIntention extends BaseIntentionAction impl
}
@Nullable
private static PsiMember findAnnotationOwner(@NotNull PsiElement file, Editor editor) {
private static PsiMember findMemberUnderCaret(@NotNull PsiElement file, Editor editor) {
int offset = editor.getCaretModel().getOffset();
PsiMember methodMember = findMethod(file, offset);
if (methodMember != null) {
@@ -31,7 +31,6 @@ import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Function;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -91,22 +90,11 @@ public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider {
}
for (PsiElement element : elements) {
if (!(element instanceof PsiMember) || element instanceof PsiClass) {
PsiModifierListOwner annotationOwner = KotlinSignatureUtil.getAnalyzableAnnotationOwner(element);
if (annotationOwner == null) {
continue;
}
PsiMember member = (PsiMember) element;
if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
continue;
}
PsiClass containingClass = member.getContainingClass();
if (containingClass != null && PsiUtil.isLocalOrAnonymousClass(containingClass)) {
continue;
}
PsiModifierListOwner annotationOwner = KotlinSignatureUtil.getAnnotationOwner(element);
JavaResolveExtension resolveExtension = JavaResolveExtension.INSTANCE$;
BindingContext bindingContext = resolveExtension.getContext(project, annotationOwner);
JavaDescriptorResolver javaDescriptorResolver = resolveExtension.getResolver(project, annotationOwner);
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.compiled.ClsElementImpl;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedExternalAnnotationResolver;
@@ -33,16 +34,32 @@ class KotlinSignatureUtil {
private KotlinSignatureUtil() {
}
@NotNull
static PsiModifierListOwner getAnnotationOwner(@NotNull PsiElement element) {
PsiModifierListOwner annotationOwner = element.getOriginalElement() instanceof PsiModifierListOwner
? (PsiModifierListOwner) element.getOriginalElement()
: (PsiModifierListOwner) element;
/* For element from library sources or decompiled library sources return corresponding cls element */
@Nullable
static PsiMember getAnalyzableAnnotationOwner(@NotNull PsiElement element) {
if (!(element instanceof PsiField || element instanceof PsiMethod) || element instanceof PsiEnumConstant) {
return null;
}
PsiMember member = (PsiMember) element;
if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
return null;
}
PsiClass containingClass = member.getContainingClass();
if (containingClass != null && PsiUtil.isLocalOrAnonymousClass(containingClass)) {
return null;
}
PsiMember annotationOwner = element.getOriginalElement() instanceof PsiMember
? (PsiMember) element.getOriginalElement()
: (PsiMember) element;
if (!annotationOwner.isPhysical()) {
// this is fake PsiFile which is mirror for ClsFile without sources
PsiCompiledElement compiledElement = element.getUserData(ClsElementImpl.COMPILED_ELEMENT);
if (compiledElement instanceof PsiModifierListOwner) {
return (PsiModifierListOwner) compiledElement;
if (compiledElement instanceof PsiMember) {
return (PsiMember) compiledElement;
}
}
return annotationOwner;
@@ -74,9 +91,12 @@ class KotlinSignatureUtil {
@Nullable
static PsiAnnotation findKotlinSignatureAnnotation(@NotNull PsiElement element) {
if (!(element instanceof PsiModifierListOwner)) return null;
PsiModifierListOwner annotationOwner = getAnnotationOwner(element);
PsiModifierList list = annotationOwner.getModifierList();
PsiModifierListOwner annotationOwner = getAnalyzableAnnotationOwner(element);
if (annotationOwner == null) {
return null;
}
PsiModifierList list = annotationOwner.getModifierList();
PsiAnnotation annotation = list == null ? null : list.findAnnotation(KOTLIN_SIGNATURE.asString());
if (annotation == null) {
annotation = PsiBasedExternalAnnotationResolver.findExternalAnnotation(annotationOwner, KOTLIN_SIGNATURE);
@@ -98,7 +118,10 @@ class KotlinSignatureUtil {
}
static boolean isAnnotationEditable(@NotNull PsiElement element) {
PsiModifierListOwner annotationOwner = getAnnotationOwner(element);
PsiModifierListOwner annotationOwner = getAnalyzableAnnotationOwner(element);
if (annotationOwner == null) {
return false;
}
PsiAnnotation annotation = findKotlinSignatureAnnotation(element);
assert annotation != null;
if (annotation.getContainingFile() == annotationOwner.getContainingFile()) {