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.
21 package com
.intellij
.codeInspection
.reference
;
23 import com
.intellij
.codeInspection
.InspectionsBundle
;
24 import com
.intellij
.codeInspection
.SuppressionUtil
;
25 import com
.intellij
.codeInspection
.ex
.EntryPointsManager
;
26 import com
.intellij
.codeInspection
.ex
.EntryPointsManagerImpl
;
27 import com
.intellij
.openapi
.diagnostic
.Logger
;
28 import com
.intellij
.openapi
.project
.Project
;
29 import com
.intellij
.openapi
.util
.Comparing
;
30 import com
.intellij
.psi
.*;
31 import com
.intellij
.psi
.javadoc
.PsiDocComment
;
32 import com
.intellij
.psi
.javadoc
.PsiDocTag
;
33 import com
.intellij
.psi
.search
.GlobalSearchScope
;
34 import com
.intellij
.psi
.util
.PsiTreeUtil
;
35 import com
.intellij
.util
.IncorrectOperationException
;
36 import gnu
.trove
.THashMap
;
37 import org
.jdom
.Element
;
38 import org
.jetbrains
.annotations
.Nullable
;
40 public class RefJavaManagerImpl
extends RefJavaManager
{
41 private static final Logger LOG
= Logger
.getInstance("#" + RefJavaManagerImpl
.class.getName());
42 private PsiMethod myAppMainPattern
;
43 private PsiMethod myAppPremainPattern
;
44 private PsiClass myApplet
;
45 private PsiClass myServlet
;
46 private RefPackage myDefaultPackage
;
47 private THashMap
<String
, RefPackage
> myPackages
;
48 private final RefManagerImpl myRefManager
;
49 private PsiElementVisitor myProjectIterator
;
50 private EntryPointsManager myEntryPointsManager
;
52 public RefJavaManagerImpl(RefManagerImpl manager
) {
53 myRefManager
= manager
;
54 final Project project
= manager
.getProject();
55 final PsiManager psiManager
= PsiManager
.getInstance(project
);
56 PsiElementFactory factory
= JavaPsiFacade
.getInstance(psiManager
.getProject()).getElementFactory();
58 myAppMainPattern
= factory
.createMethodFromText("void main(String[] args);", null);
59 myAppPremainPattern
= factory
.createMethodFromText("void premain(String[] args, java.lang.instrument.Instrumentation i);", null);
61 catch (IncorrectOperationException e
) {
65 myApplet
= JavaPsiFacade
.getInstance(psiManager
.getProject()).findClass("java.applet.Applet", GlobalSearchScope
.allScope(project
));
66 myServlet
= JavaPsiFacade
.getInstance(psiManager
.getProject()).findClass("javax.servlet.Servlet", GlobalSearchScope
.allScope(project
));
70 public RefPackage
getPackage(String packageName
) {
71 if (myPackages
== null) {
72 myPackages
= new THashMap
<String
, RefPackage
>();
75 RefPackage refPackage
= myPackages
.get(packageName
);
76 if (refPackage
== null) {
77 refPackage
= new RefPackageImpl(packageName
, myRefManager
);
78 myPackages
.put(packageName
, refPackage
);
80 int dotIndex
= packageName
.lastIndexOf('.');
82 ((RefPackageImpl
)getPackage(packageName
.substring(0, dotIndex
))).add(refPackage
);
85 ((RefProjectImpl
)myRefManager
.getRefProject()).add(refPackage
);
92 public RefPackage
getDefaultPackage() {
93 if (myDefaultPackage
== null) {
94 myDefaultPackage
= getPackage(InspectionsBundle
.message("inspection.reference.default.package"));
96 return myDefaultPackage
;
99 public PsiMethod
getAppMainPattern() {
100 return myAppMainPattern
;
103 public PsiMethod
getAppPremainPattern() {
104 return myAppPremainPattern
;
107 public PsiClass
getApplet() {
111 public PsiClass
getServlet() {
115 public RefParameter
getParameterReference(PsiParameter param
, int index
) {
116 LOG
.assertTrue(myRefManager
.isValidPointForReference(), "References may become invalid after process is finished");
117 RefElement ref
= myRefManager
.getFromRefTable(param
);
120 ref
= new RefParameterImpl(param
, index
, myRefManager
);
121 ((RefParameterImpl
)ref
).initialize();
122 myRefManager
.putToRefTable(param
, ref
);
125 return (RefParameter
)ref
;
130 public void iterate(final RefVisitor visitor
) {
131 if (myPackages
!= null) {
132 for (RefPackage refPackage
: myPackages
.values()) {
133 refPackage
.accept(visitor
);
136 final THashMap
<PsiAnchor
, RefElement
> refTable
= myRefManager
.getRefTable();
137 for (RefElement refElement
: refTable
.values()) {
138 if (refElement
instanceof RefClass
) {
139 RefClass refClass
= (RefClass
)refElement
;
140 RefMethod refDefaultConstructor
= refClass
.getDefaultConstructor();
141 if (refDefaultConstructor
instanceof RefImplicitConstructor
) {
142 refClass
.getDefaultConstructor().accept(visitor
);
148 public void cleanup() {
149 if (myEntryPointsManager
!= null) {
150 myEntryPointsManager
.cleanup();
151 myEntryPointsManager
= null;
155 myAppMainPattern
= null;
156 myAppPremainPattern
= null;
158 myDefaultPackage
= null;
159 myProjectIterator
= null;
162 public void removeReference(final RefElement refElement
) {
163 if (refElement
instanceof RefMethod
) {
164 RefMethod refMethod
= (RefMethod
)refElement
;
165 RefParameter
[] params
= refMethod
.getParameters();
166 for (RefParameter param
: params
) {
167 myRefManager
.removeReference(param
);
173 public RefElement
createRefElement(final PsiElement elem
) {
174 if (elem
instanceof PsiClass
) {
175 return new RefClassImpl((PsiClass
)elem
, myRefManager
);
177 else if (elem
instanceof PsiMethod
) {
178 return new RefMethodImpl((PsiMethod
)elem
, myRefManager
);
180 else if (elem
instanceof PsiField
) {
181 return new RefFieldImpl((PsiField
)elem
, myRefManager
);
183 else if (elem
instanceof PsiJavaFile
) {
184 return new RefJavaFileImpl((PsiJavaFile
)elem
, myRefManager
);
190 public RefEntity
getReference(final String type
, final String fqName
) {
191 if (METHOD
.equals(type
)) {
192 return RefMethodImpl
.methodFromExternalName(myRefManager
, fqName
);
194 else if (CLASS
.equals(type
)) {
195 return RefClassImpl
.classFromExternalName(myRefManager
, fqName
);
197 else if (FIELD
.equals(type
)) {
198 return RefFieldImpl
.fieldFromExternalName(myRefManager
, fqName
);
200 else if (PARAMETER
.equals(type
)) {
201 return RefParameterImpl
.parameterFromExternalName(myRefManager
, fqName
);
203 else if (PACKAGE
.equals(type
)) {
204 return RefPackageImpl
.packageFromFQName(myRefManager
, fqName
);
210 public String
getType(final RefEntity ref
) {
211 if (ref
instanceof RefMethod
) {
212 return RefJavaManager
.METHOD
;
214 else if (ref
instanceof RefClass
) {
215 return RefJavaManager
.CLASS
;
217 else if (ref
instanceof RefField
) {
218 return RefJavaManager
.FIELD
;
220 else if (ref
instanceof RefParameter
) {
221 return RefJavaManager
.PARAMETER
;
223 else if (ref
instanceof RefPackage
) {
224 return RefJavaManager
.PACKAGE
;
229 public RefEntity
getRefinedElement(final RefEntity ref
) {
230 if (ref
instanceof RefImplicitConstructor
) {
231 return ((RefImplicitConstructor
)ref
).getOwnerClass();
236 public void visitElement(final PsiElement element
) {
237 if (myProjectIterator
== null) {
238 myProjectIterator
= new MyJavaElementVisitor();
240 element
.accept(myProjectIterator
);
244 public String
getGroupName(final RefEntity entity
) {
245 if (entity
instanceof RefFile
&& !(entity
instanceof RefJavaFileImpl
)) return null;
246 return RefJavaUtil
.getInstance().getPackageName(entity
);
249 public boolean belongsToScope(final PsiElement psiElement
) {
250 if (psiElement
instanceof PsiTypeParameter
) return false;
254 public void export(final RefEntity refEntity
, final Element element
) {
255 if (refEntity
instanceof RefElement
) {
256 final PsiElement psiElement
= ((RefElement
)refEntity
).getElement();
257 if (psiElement
!= null) {
258 final PsiFile psiFile
= psiElement
.getContainingFile();
259 if (psiFile
instanceof PsiJavaFile
) {
260 appendPackageElement(element
, ((PsiJavaFile
)psiFile
).getPackageName());
266 private static void appendPackageElement(final Element element
, final String packageName
) {
267 final Element packageElement
= new Element("package");
269 .addContent(packageName
.length() > 0 ? packageName
: InspectionsBundle
.message("inspection.export.results.default"));
270 element
.addContent(packageElement
);
273 public EntryPointsManager
getEntryPointsManager() {
274 if (myEntryPointsManager
== null) {
275 final Project project
= myRefManager
.getProject();
276 myEntryPointsManager
= new EntryPointsManagerImpl(project
);
277 ((EntryPointsManagerImpl
)myEntryPointsManager
).addAllPersistentEntries(EntryPointsManagerImpl
.getInstance(project
));
279 return myEntryPointsManager
;
282 private class MyJavaElementVisitor
extends JavaElementVisitor
{
283 private final RefJavaUtil myRefUtil
;
285 public MyJavaElementVisitor() {
286 myRefUtil
= RefJavaUtil
.getInstance();
290 public void visitReferenceExpression(PsiReferenceExpression expression
) {
291 visitElement(expression
);
295 public void visitReferenceElement(PsiJavaCodeReferenceElement reference
) {
300 public void visitReferenceParameterList(final PsiReferenceParameterList list
) {
301 super.visitReferenceParameterList(list
);
302 final PsiMember member
= PsiTreeUtil
.getParentOfType(list
, PsiMember
.class);
303 final PsiType
[] typeArguments
= list
.getTypeArguments();
304 for (PsiType type
: typeArguments
) {
305 myRefUtil
.addTypeReference(member
, type
, myRefManager
);
310 public void visitClass(PsiClass aClass
) {
311 if (!(aClass
instanceof PsiTypeParameter
)) {
312 super.visitClass(aClass
);
313 RefElement refClass
= myRefManager
.getReference(aClass
);
314 if (refClass
!= null) {
315 ((RefClassImpl
)refClass
).buildReferences();
320 public void visitMethod(final PsiMethod method
) {
321 super.visitMethod(method
);
322 final RefElement refElement
= myRefManager
.getReference(method
);
323 if (refElement
instanceof RefMethod
) {
324 ((RefMethodImpl
)refElement
).buildReferences();
328 public void visitField(final PsiField field
) {
329 super.visitField(field
);
330 final RefElement refElement
= myRefManager
.getReference(field
);
331 if (refElement
instanceof RefField
) {
332 ((RefFieldImpl
)refElement
).buildReferences();
337 public void visitDocComment(PsiDocComment comment
) {
338 super.visitDocComment(comment
);
339 final PsiDocTag
[] tags
= comment
.getTags();
340 for (PsiDocTag tag
: tags
) {
341 if (Comparing
.strEqual(tag
.getName(), SuppressionUtil
.SUPPRESS_INSPECTIONS_TAG_NAME
)) {
342 final PsiElement
[] dataElements
= tag
.getDataElements();
343 if (dataElements
!= null && dataElements
.length
> 0) {
344 final PsiModifierListOwner listOwner
= PsiTreeUtil
.getParentOfType(comment
, PsiModifierListOwner
.class);
345 if (listOwner
!= null) {
346 final RefElementImpl element
= (RefElementImpl
)myRefManager
.getReference(listOwner
);
347 if (element
!= null) {
348 String suppressions
= "";
349 for (PsiElement dataElement
: dataElements
) {
350 suppressions
+= "," + dataElement
.getText();
352 element
.addSuppression(suppressions
);
361 public void visitAnnotation(PsiAnnotation annotation
) {
362 super.visitAnnotation(annotation
);
363 if (Comparing
.strEqual(annotation
.getQualifiedName(), "java.lang.SuppressWarnings")) {
364 final PsiModifierListOwner listOwner
= PsiTreeUtil
.getParentOfType(annotation
, PsiModifierListOwner
.class);
365 if (listOwner
!= null) {
366 final RefElementImpl element
= (RefElementImpl
)myRefManager
.getReference(listOwner
);
367 if (element
!= null) {
368 StringBuffer buf
= new StringBuffer();
369 final PsiNameValuePair
[] nameValuePairs
= annotation
.getParameterList().getAttributes();
370 for (PsiNameValuePair nameValuePair
: nameValuePairs
) {
371 buf
.append(",").append(nameValuePair
.getText().replaceAll("[{}\"\"]", ""));
373 if (buf
.length() > 0) {
374 element
.addSuppression(buf
.substring(1));
382 public void visitVariable(PsiVariable variable
) {
383 super.visitVariable(variable
);
384 myRefUtil
.addTypeReference(variable
, variable
.getType(), myRefManager
);
388 public void visitInstanceOfExpression(PsiInstanceOfExpression expression
) {
389 super.visitInstanceOfExpression(expression
);
390 final PsiTypeElement typeElement
= expression
.getCheckType();
391 if (typeElement
!= null) {
392 myRefUtil
.addTypeReference(expression
, typeElement
.getType(), myRefManager
);
397 public void visitThisExpression(PsiThisExpression expression
) {
398 super.visitThisExpression(expression
);
399 final PsiJavaCodeReferenceElement qualifier
= expression
.getQualifier();
400 if (qualifier
!= null) {
401 myRefUtil
.addTypeReference(expression
, expression
.getType(), myRefManager
);
402 RefClass ownerClass
= myRefUtil
.getOwnerClass(myRefManager
, expression
);
403 if (ownerClass
!= null) {
404 RefClassImpl refClass
= (RefClassImpl
)myRefManager
.getReference(qualifier
.resolve());
405 if (refClass
!= null) {
406 refClass
.addInstanceReference(ownerClass
);