diff --git a/idea/src/org/jetbrains/jet/plugin/ktSignature/DeleteSignatureAction.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/DeleteSignatureAction.java index c79dffd8621..02d60fc5d9b 100644 --- a/idea/src/org/jetbrains/jet/plugin/ktSignature/DeleteSignatureAction.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/DeleteSignatureAction.java @@ -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 diff --git a/idea/src/org/jetbrains/jet/plugin/ktSignature/EditSignatureAction.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/EditSignatureAction.java index 7fdbe844423..9bb27eb2888 100644 --- a/idea/src/org/jetbrains/jet/plugin/ktSignature/EditSignatureAction.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/EditSignatureAction.java @@ -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), diff --git a/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureAnnotationIntention.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureAnnotationIntention.java index 4676a17bfba..30cba3c57a7 100644 --- a/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureAnnotationIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureAnnotationIntention.java @@ -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) { diff --git a/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerProvider.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerProvider.java index 95a4617f964..851fcae9629 100644 --- a/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerProvider.java @@ -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); diff --git a/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureUtil.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureUtil.java index a2028e9a71e..bd25a2003ce 100644 --- a/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureUtil.java @@ -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()) {