diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 31fcff13aac..4e6696b6d51 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -217,6 +217,7 @@ + consumer) { + final PsiClass annClass = p.getAnnotationClass(); + assert annClass.isAnnotationType() : "Annotation type should be passed to annotated members search"; + + final String annotationFQN = annClass.getQualifiedName(); + assert annotationFQN != null; + + final SearchScope useScope = p.getScope(); + + for (final PsiElement elt : getJetAnnotationCandidates(annClass, useScope)) { + if (notJetAnnotationEntry(elt)) continue; + + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + //TODO LazyResolve + AnalyzeExhaust analyzeExhaust = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) elt.getContainingFile()); + JetDeclaration parentOfType = PsiTreeUtil.getParentOfType(elt, JetDeclaration.class); + if (parentOfType == null) return; + BindingContext context = analyzeExhaust.getBindingContext(); + AnnotationDescriptor annotationDescriptor = context.get(BindingContext.ANNOTATION, (JetAnnotationEntry) elt); + if (annotationDescriptor == null) return; + + ClassifierDescriptor descriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor(); + if (descriptor == null) return; + if (!(DescriptorUtils.getFQName(descriptor).getFqName().equals(annotationFQN))) return; + + if (parentOfType instanceof JetClass) { + JetLightClass lightClass = JetLightClass.wrapDelegate((JetClass) parentOfType); + consumer.process(lightClass); + } + else if (parentOfType instanceof JetNamedFunction) { + PsiMethod wrappedMethod = JetLightClass.wrapMethod((JetNamedFunction) parentOfType); + consumer.process(wrappedMethod); + } + } + }); + } + + return true; + } + + private static Collection getJetAnnotationCandidates(final PsiClass annClass, final SearchScope useScope) { + return ApplicationManager.getApplication().runReadAction(new Computable>() { + @Override + public Collection compute() { + if (useScope instanceof GlobalSearchScope) { + return JetAnnotationsIndex.getInstance().get(annClass.getName(), annClass.getProject(), (GlobalSearchScope)useScope); + } + /* + TODO getJetAnnotationCandidates works only with global search scope + for (PsiElement element : ((LocalSearchScope)useScope).getScope()) { + element.accept(new PsiRecursiveElementWalkingVisitor() { + @Override + public void visitElement(PsiElement element) { + if (element instanceof JetAnnotationEntry) { + result.add(element); + } + } + }); + }*/ + return new ArrayList(); + } + }); + } + + private static boolean notJetAnnotationEntry(final PsiElement found) { + if (found instanceof JetAnnotationEntry) return false; + + VirtualFile faultyContainer = PsiUtilCore.getVirtualFile(found); + LOG.error("Non annotation in annotations list: " + faultyContainer+"; element:"+found); + if (faultyContainer != null && faultyContainer.isValid()) { + FileBasedIndex.getInstance().requestReindex(faultyContainer); + } + + return true; + } + +}