update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInspection / reference / RefJavaManagerImpl.java
bloba87eda3415e0a9505bbe817b52d4b18dc4a6f71c
1 /*
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.
18 * User: anna
19 * Date: 20-Dec-2007
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();
57 try {
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) {
62 LOG.error(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('.');
81 if (dotIndex >= 0) {
82 ((RefPackageImpl)getPackage(packageName.substring(0, dotIndex))).add(refPackage);
84 else {
85 ((RefProjectImpl)myRefManager.getRefProject()).add(refPackage);
89 return 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() {
108 return myApplet;
111 public PsiClass getServlet() {
112 return myServlet;
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);
119 if (ref == null) {
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;
153 myPackages = null;
154 myApplet = null;
155 myAppMainPattern = null;
156 myAppPremainPattern = null;
157 myServlet = 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);
172 @Nullable
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);
186 return null;
189 @Nullable
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);
206 return null;
209 @Nullable
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;
226 return null;
229 public RefEntity getRefinedElement(final RefEntity ref) {
230 if (ref instanceof RefImplicitConstructor) {
231 return ((RefImplicitConstructor)ref).getOwnerClass();
233 return ref;
236 public void visitElement(final PsiElement element) {
237 if (myProjectIterator == null) {
238 myProjectIterator = new MyJavaElementVisitor();
240 element.accept(myProjectIterator);
243 @Nullable
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;
251 return true;
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");
268 packageElement
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();
289 @Override
290 public void visitReferenceExpression(PsiReferenceExpression expression) {
291 visitElement(expression);
294 @Override
295 public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
299 @Override
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);
309 @Override
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();
336 @Override
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);
360 @Override
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));
381 @Override
382 public void visitVariable(PsiVariable variable) {
383 super.visitVariable(variable);
384 myRefUtil.addTypeReference(variable, variable.getType(), myRefManager);
387 @Override
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);
396 @Override
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);