2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 package com
.intellij
.psi
.impl
.search
;
22 import com
.intellij
.openapi
.diagnostic
.Logger
;
23 import com
.intellij
.openapi
.module
.Module
;
24 import com
.intellij
.openapi
.vfs
.VirtualFile
;
25 import com
.intellij
.psi
.*;
26 import com
.intellij
.psi
.impl
.PsiManagerImpl
;
27 import com
.intellij
.psi
.impl
.java
.stubs
.index
.JavaAnnotationIndex
;
28 import com
.intellij
.psi
.search
.GlobalSearchScope
;
29 import com
.intellij
.psi
.search
.PsiSearchHelper
;
30 import com
.intellij
.psi
.search
.SearchScope
;
31 import com
.intellij
.psi
.search
.searches
.AnnotatedPackagesSearch
;
32 import com
.intellij
.psi
.util
.PsiTreeUtil
;
33 import com
.intellij
.util
.Processor
;
34 import com
.intellij
.util
.QueryExecutor
;
35 import org
.jetbrains
.annotations
.NotNull
;
37 import java
.util
.Collection
;
39 public class AnnotatedPackagesSearcher
implements QueryExecutor
<PsiPackage
, AnnotatedPackagesSearch
.Parameters
> {
40 private static final Logger LOG
= Logger
.getInstance("#com.intellij.psi.impl.search.AnnotatedPackagesSearcher");
42 public boolean execute(final AnnotatedPackagesSearch
.Parameters p
, final Processor
<PsiPackage
> consumer
) {
43 final PsiClass annClass
= p
.getAnnotationClass();
44 assert annClass
.isAnnotationType() : "Annotation type should be passed to annotated packages search";
46 final String annotationFQN
= annClass
.getQualifiedName();
47 assert annotationFQN
!= null;
49 final PsiManagerImpl psiManager
= (PsiManagerImpl
)PsiManager
.getInstance(annClass
.getProject());
50 final SearchScope useScope
= p
.getScope();
52 final String annotationShortName
= annClass
.getName();
53 assert annotationShortName
!= null;
55 final GlobalSearchScope scope
= useScope
instanceof GlobalSearchScope ?
(GlobalSearchScope
)useScope
: null;
57 final Collection
<PsiAnnotation
> annotations
= JavaAnnotationIndex
.getInstance().get(annotationShortName
, annClass
.getProject(), scope
);
58 for (PsiAnnotation annotation
: annotations
) {
59 PsiModifierList modlist
= (PsiModifierList
)annotation
.getParent();
60 final PsiElement owner
= modlist
.getParent();
61 if (!(owner
instanceof PsiClass
)) continue;
62 PsiClass candidate
= (PsiClass
)owner
;
63 if (!"package-info".equals(candidate
.getName())) continue;
65 LOG
.assertTrue(candidate
.isValid());
67 final PsiJavaCodeReferenceElement ref
= annotation
.getNameReferenceElement();
68 if (ref
== null) continue;
70 if (!psiManager
.areElementsEquivalent(ref
.resolve(), annClass
)) continue;
71 if (useScope
instanceof GlobalSearchScope
&&
72 !((GlobalSearchScope
)useScope
).contains(candidate
.getContainingFile().getVirtualFile())) {
75 final String qname
= candidate
.getQualifiedName();
76 if (qname
!= null && !consumer
.process(JavaPsiFacade
.getInstance(psiManager
.getProject()).findPackage(
77 qname
.substring(0, qname
.lastIndexOf('.'))))) {
82 PsiSearchHelper helper
= psiManager
.getSearchHelper();
83 final GlobalSearchScope infoFilesFilter
= new PackageInfoFilesOnly();
85 GlobalSearchScope infoFiles
=
86 useScope
instanceof GlobalSearchScope ?
((GlobalSearchScope
)useScope
).intersectWith(infoFilesFilter
) : infoFilesFilter
;
88 final boolean[] wantmore
= new boolean[]{true};
89 helper
.processAllFilesWithWord(annotationShortName
, infoFiles
, new Processor
<PsiFile
>() {
90 public boolean process(final PsiFile psiFile
) {
91 PsiPackageStatement stmt
= PsiTreeUtil
.getChildOfType(psiFile
, PsiPackageStatement
.class);
92 if (stmt
== null) return true;
94 final PsiModifierList annotations
= stmt
.getAnnotationList();
95 if (annotations
== null) return true;
96 final PsiAnnotation ann
= annotations
.findAnnotation(annotationFQN
);
97 if (ann
== null) return true;
99 final PsiJavaCodeReferenceElement ref
= ann
.getNameReferenceElement();
100 if (ref
== null) return true;
102 if (!psiManager
.areElementsEquivalent(ref
.resolve(), annClass
)) return true;
104 wantmore
[0] = consumer
.process(JavaPsiFacade
.getInstance(psiManager
.getProject()).findPackage(stmt
.getPackageName()));
112 private static class PackageInfoFilesOnly
extends GlobalSearchScope
{
113 public int compare(final VirtualFile file1
, final VirtualFile file2
) {
117 public boolean contains(final VirtualFile file
) {
118 return "package-info.java".equals(file
.getName());
121 public boolean isSearchInLibraries() {
125 public boolean isSearchInModuleContent(@NotNull final Module aModule
) {