Check for entry points while PSI is available instead of parsing files later

This commit is contained in:
Maxim Shafirov
2012-04-13 14:26:32 +04:00
parent b01a17cf85
commit 5bfc55d380
5 changed files with 78 additions and 31 deletions
@@ -353,41 +353,18 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
}
return;
}
refElement.accept(new RefJavaVisitor() {
@Override public void visitElement(final RefEntity elem) {
if (elem instanceof RefElement) {
final RefElement element = (RefElement)elem;
if (isEntryPoint(element)) {
getEntryPointsManager().addEntryPoint(element, false);
}
}
}
refElement.accept(new RefJavaVisitor() {
@Override public void visitMethod(RefMethod method) {
if (isAddMainsEnabled() && method.isAppMain()) {
getEntryPointsManager().addEntryPoint(method, false);
} else {
super.visitMethod(method);
}
}
@Override public void visitClass(RefClass aClass) {
final PsiClass psiClass = aClass.getElement();
if (psiClass == null) return;
if (
isAddAppletEnabled() && aClass.isApplet() ||
isAddServletEnabled() && aClass.isServlet()) {
if (isAddAppletEnabled() && aClass.isApplet() ||
isAddServletEnabled() && aClass.isServlet()) {
getEntryPointsManager().addEntryPoint(aClass, false);
} else if (psiClass.isAnnotationType()){
getEntryPointsManager().addEntryPoint(aClass, false);
final PsiMethod[] psiMethods = psiClass.getMethods();
for (PsiMethod psiMethod : psiMethods) {
getEntryPointsManager().addEntryPoint(getRefManager().getReference(psiMethod), false);
}
} else if (psiClass.isEnum()) {
getEntryPointsManager().addEntryPoint(aClass, false);
} else {
super.visitClass(aClass);
}
}
});
@@ -437,7 +414,7 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
myPhase = 1;
}
private boolean isEntryPoint(final RefElement owner) {
public boolean isEntryPoint(final RefElement owner) {
final PsiElement element = owner.getElement();
if (RefUtil.isImplicitUsage(element)) return true;
if (element instanceof PsiModifierListOwner) {
@@ -907,8 +884,6 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
@Override public void visitElement(RefEntity refEntity) {
if (refEntity instanceof RefJavaElement) {
final RefJavaElementImpl refElement = (RefJavaElementImpl)refEntity;
final PsiElement element = refElement.getElement();
if (element == null) return;
if (!getContext().isToCheckMember(refElement, UnusedDeclarationInspection.this)) return;
refElement.setReachable(false);
}
@@ -15,14 +15,20 @@
*/
package com.intellij.codeInspection.reference;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.codeInspection.SuppressionUtil;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.ex.EntryPointsManager;
import com.intellij.codeInspection.ex.EntryPointsManagerImpl;
import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.codeInspection.ex.Tools;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.UserDataCache;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
@@ -89,6 +95,41 @@ public class RefJavaManagerImpl extends RefJavaManager {
return refPackage;
}
public boolean isEntryPoint(final RefElement element) {
UnusedDeclarationInspection tool = getDeadCodeTool(element);
return tool != null && tool.isEntryPoint(element);
}
@Nullable
private UnusedDeclarationInspection getDeadCodeTool(RefElement element) {
PsiFile file = ((RefElementImpl)element).getContainingFile();
if (file == null) return null;
return getDeadCodeTool(file);
}
private static final UserDataCache<Ref<UnusedDeclarationInspection>, PsiFile, RefManagerImpl> DEAD_CODE_TOOL = new UserDataCache<Ref<UnusedDeclarationInspection>, PsiFile, RefManagerImpl>("DEAD_CODE_TOOL") {
@Override
protected Ref<UnusedDeclarationInspection> compute(PsiFile file, RefManagerImpl refManager) {
Tools tools = refManager.getContext().getTools().get(UnusedDeclarationInspection.SHORT_NAME);
InspectionProfileEntry tool = tools != null ? tools.getEnabledTool(file) : null;
if (tool instanceof InspectionToolWrapper) tool = ((InspectionToolWrapper)tool).getTool();
return Ref.create(tool instanceof UnusedDeclarationInspection ? (UnusedDeclarationInspection)tool : null);
}
};
@Nullable
private UnusedDeclarationInspection getDeadCodeTool(PsiElement element) {
PsiFile file = element.getContainingFile();
return file != null ? DEAD_CODE_TOOL.get(file, myRefManager).get() : null;
}
public boolean isEntryPoint(PsiElement element) {
UnusedDeclarationInspection tool = getDeadCodeTool(element);
return tool != null && tool.isEntryPoint(element);
}
public RefPackage getDefaultPackage() {
if (myDefaultPackage == null) {
myDefaultPackage = getPackage(InspectionsBundle.message("inspection.reference.default.package"));
@@ -269,6 +310,28 @@ public class RefJavaManagerImpl extends RefJavaManager {
}
}
@Override
public void onEntityInitialized(RefElement refElement, PsiElement psiElement) {
if (isEntryPoint(refElement)) {
getEntryPointsManager().addEntryPoint(refElement, false);
}
if (psiElement instanceof PsiClass) {
PsiClass psiClass = (PsiClass)psiElement;
EntryPointsManager entryPointsManager = getEntryPointsManager();
if (psiClass.isAnnotationType()){
entryPointsManager.addEntryPoint(refElement, false);
for (PsiMethod psiMethod : psiClass.getMethods()) {
entryPointsManager.addEntryPoint(myRefManager.getReference(psiMethod), false);
}
}
else if (psiClass.isEnum()) {
entryPointsManager.addEntryPoint(refElement, false);
}
}
}
private static void appendPackageElement(final Element element, final String packageName) {
final Element packageElement = new Element("package");
packageElement.addContent(packageName.length() > 0 ? packageName : InspectionsBundle.message("inspection.export.results.default"));