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