use of com.intellij.codeInspection.reference.RefManagerImpl in project intellij-community by JetBrains.
the class LocalDescriptorsUtil method addProblemDescriptors.
static void addProblemDescriptors(@NotNull List<ProblemDescriptor> descriptors, boolean filterSuppressed, @NotNull GlobalInspectionContext context, @Nullable LocalInspectionTool tool, @NotNull TripleFunction<LocalInspectionTool, PsiElement, GlobalInspectionContext, RefElement> getProblemElementFunction, @NotNull InspectionToolPresentation dpi) {
if (descriptors.isEmpty())
return;
Map<RefElement, List<ProblemDescriptor>> problems = new HashMap<>();
final RefManagerImpl refManager = (RefManagerImpl) context.getRefManager();
for (ProblemDescriptor descriptor : descriptors) {
final PsiElement element = descriptor.getPsiElement();
if (element == null)
continue;
if (filterSuppressed) {
String alternativeId;
String id;
if (refManager.isDeclarationsFound() && (context.isSuppressed(element, id = tool.getID()) || (alternativeId = tool.getAlternativeID()) != null && !alternativeId.equals(id) && context.isSuppressed(element, alternativeId))) {
continue;
}
if (SuppressionUtil.inspectionResultSuppressed(element, tool))
continue;
}
RefElement refElement = getProblemElementFunction.fun(tool, element, context);
List<ProblemDescriptor> elementProblems = problems.get(refElement);
if (elementProblems == null) {
elementProblems = new ArrayList<>();
problems.put(refElement, elementProblems);
}
elementProblems.add(descriptor);
}
for (Map.Entry<RefElement, List<ProblemDescriptor>> entry : problems.entrySet()) {
final List<ProblemDescriptor> problemDescriptors = entry.getValue();
RefElement refElement = entry.getKey();
CommonProblemDescriptor[] descriptions = problemDescriptors.toArray(new CommonProblemDescriptor[problemDescriptors.size()]);
dpi.addProblemElement(refElement, filterSuppressed, descriptions);
}
}
use of com.intellij.codeInspection.reference.RefManagerImpl in project intellij-community by JetBrains.
the class InspectionEngine method runInspectionOnFile.
@NotNull
public static List<ProblemDescriptor> runInspectionOnFile(@NotNull final PsiFile file, @NotNull InspectionToolWrapper toolWrapper, @NotNull final GlobalInspectionContext inspectionContext) {
final InspectionManager inspectionManager = InspectionManager.getInstance(file.getProject());
toolWrapper.initialize(inspectionContext);
RefManagerImpl refManager = (RefManagerImpl) inspectionContext.getRefManager();
refManager.inspectionReadActionStarted();
try {
if (toolWrapper instanceof LocalInspectionToolWrapper) {
return inspect(Collections.singletonList((LocalInspectionToolWrapper) toolWrapper), file, inspectionManager, new EmptyProgressIndicator());
}
if (toolWrapper instanceof GlobalInspectionToolWrapper) {
final GlobalInspectionTool globalTool = ((GlobalInspectionToolWrapper) toolWrapper).getTool();
final List<ProblemDescriptor> descriptors = new ArrayList<>();
if (globalTool instanceof GlobalSimpleInspectionTool) {
GlobalSimpleInspectionTool simpleTool = (GlobalSimpleInspectionTool) globalTool;
ProblemsHolder problemsHolder = new ProblemsHolder(inspectionManager, file, false);
ProblemDescriptionsProcessor collectProcessor = new ProblemDescriptionsProcessor() {
@Nullable
@Override
public CommonProblemDescriptor[] getDescriptions(@NotNull RefEntity refEntity) {
return descriptors.toArray(new CommonProblemDescriptor[descriptors.size()]);
}
@Override
public void ignoreElement(@NotNull RefEntity refEntity) {
throw new RuntimeException();
}
@Override
public void addProblemElement(@Nullable RefEntity refEntity, @NotNull CommonProblemDescriptor... commonProblemDescriptors) {
if (!(refEntity instanceof RefElement))
return;
PsiElement element = ((RefElement) refEntity).getElement();
convertToProblemDescriptors(element, commonProblemDescriptors, descriptors);
}
@Override
public RefEntity getElement(@NotNull CommonProblemDescriptor descriptor) {
throw new RuntimeException();
}
};
simpleTool.checkFile(file, inspectionManager, problemsHolder, inspectionContext, collectProcessor);
return descriptors;
}
RefElement fileRef = refManager.getReference(file);
final AnalysisScope scope = new AnalysisScope(file);
assert fileRef != null;
fileRef.accept(new RefVisitor() {
@Override
public void visitElement(@NotNull RefEntity elem) {
CommonProblemDescriptor[] elemDescriptors = globalTool.checkElement(elem, scope, inspectionManager, inspectionContext);
if (elemDescriptors != null) {
convertToProblemDescriptors(file, elemDescriptors, descriptors);
}
for (RefEntity child : elem.getChildren()) {
child.accept(this);
}
}
});
return descriptors;
}
} finally {
refManager.inspectionReadActionFinished();
toolWrapper.cleanup(file.getProject());
inspectionContext.cleanup();
}
return Collections.emptyList();
}
use of com.intellij.codeInspection.reference.RefManagerImpl in project intellij-community by JetBrains.
the class GlobalInspectionToolWrapper method initialize.
@Override
public void initialize(@NotNull GlobalInspectionContext context) {
super.initialize(context);
RefManagerImpl refManager = (RefManagerImpl) context.getRefManager();
final RefGraphAnnotator annotator = getTool().getAnnotator(refManager);
if (annotator != null) {
refManager.registerGraphAnnotator(annotator);
}
getTool().initialize(context);
}
use of com.intellij.codeInspection.reference.RefManagerImpl in project intellij-community by JetBrains.
the class GlobalInspectionContextImpl method runTools.
@Override
protected void runTools(@NotNull final AnalysisScope scope, boolean runGlobalToolsOnly, boolean isOfflineInspections) {
final ProgressIndicator progressIndicator = ProgressIndicatorProvider.getGlobalProgressIndicator();
if (progressIndicator == null) {
throw new IncorrectOperationException("Must be run under progress");
}
if (!isOfflineInspections && ApplicationManager.getApplication().isDispatchThread()) {
throw new IncorrectOperationException("Must not start inspections from within EDT");
}
if (ApplicationManager.getApplication().isWriteAccessAllowed()) {
throw new IncorrectOperationException("Must not start inspections from within write action");
}
// in offline inspection application we don't care about global read action
if (!isOfflineInspections && ApplicationManager.getApplication().isReadAccessAllowed()) {
throw new IncorrectOperationException("Must not start inspections from within global read action");
}
final InspectionManager inspectionManager = InspectionManager.getInstance(getProject());
((RefManagerImpl) getRefManager()).initializeAnnotators();
final List<Tools> globalTools = new ArrayList<>();
final List<Tools> localTools = new ArrayList<>();
final List<Tools> globalSimpleTools = new ArrayList<>();
initializeTools(globalTools, localTools, globalSimpleTools);
appendPairedInspectionsForUnfairTools(globalTools, globalSimpleTools, localTools);
runGlobalTools(scope, inspectionManager, globalTools, isOfflineInspections);
if (runGlobalToolsOnly || localTools.isEmpty() && globalSimpleTools.isEmpty())
return;
SearchScope searchScope = ReadAction.compute(scope::toSearchScope);
final Set<VirtualFile> localScopeFiles = searchScope instanceof LocalSearchScope ? new THashSet<>() : null;
for (Tools tools : globalSimpleTools) {
GlobalInspectionToolWrapper toolWrapper = (GlobalInspectionToolWrapper) tools.getTool();
GlobalSimpleInspectionTool tool = (GlobalSimpleInspectionTool) toolWrapper.getTool();
tool.inspectionStarted(inspectionManager, this, getPresentation(toolWrapper));
}
final boolean headlessEnvironment = ApplicationManager.getApplication().isHeadlessEnvironment();
final Map<String, InspectionToolWrapper> map = getInspectionWrappersMap(localTools);
final BlockingQueue<PsiFile> filesToInspect = new ArrayBlockingQueue<>(1000);
// use original progress indicator here since we don't want it to cancel on write action start
ProgressIndicator iteratingIndicator = new SensitiveProgressWrapper(progressIndicator);
Future<?> future = startIterateScopeInBackground(scope, localScopeFiles, headlessEnvironment, filesToInspect, iteratingIndicator);
Processor<PsiFile> processor = file -> {
ProgressManager.checkCanceled();
if (!ApplicationManagerEx.getApplicationEx().tryRunReadAction(() -> {
if (!file.isValid()) {
return;
}
LOG.assertTrue(scope.contains(file.getVirtualFile()), file.getName());
inspectFile(file, inspectionManager, localTools, globalSimpleTools, map);
})) {
throw new ProcessCanceledException();
}
boolean includeDoNotShow = includeDoNotShow(getCurrentProfile());
Stream.concat(getWrappersFromTools(localTools, file, includeDoNotShow).stream(), getWrappersFromTools(globalSimpleTools, file, includeDoNotShow).stream()).filter(wrapper -> wrapper.getTool() instanceof ExternalAnnotatorBatchInspection).forEach(wrapper -> {
ProblemDescriptor[] descriptors = ((ExternalAnnotatorBatchInspection) wrapper.getTool()).checkFile(file, this, inspectionManager);
InspectionToolPresentation toolPresentation = getPresentation(wrapper);
ReadAction.run(() -> LocalDescriptorsUtil.addProblemDescriptors(Arrays.asList(descriptors), false, this, null, CONVERT, toolPresentation));
});
return true;
};
try {
final Queue<PsiFile> filesFailedToInspect = new LinkedBlockingQueue<>();
while (true) {
Disposable disposable = Disposer.newDisposable();
ProgressIndicator wrapper = new SensitiveProgressWrapper(progressIndicator);
wrapper.start();
ProgressIndicatorUtils.forceWriteActionPriority(wrapper, disposable);
try {
// use wrapper here to cancel early when write action start but do not affect the original indicator
((JobLauncherImpl) JobLauncher.getInstance()).processQueue(filesToInspect, filesFailedToInspect, wrapper, TOMBSTONE, processor);
break;
} catch (ProcessCanceledException ignored) {
progressIndicator.checkCanceled();
// go on with the write and then resume processing the rest of the queue
assert !ApplicationManager.getApplication().isReadAccessAllowed();
assert !ApplicationManager.getApplication().isDispatchThread();
// wait for write action to complete
ApplicationManager.getApplication().runReadAction(EmptyRunnable.getInstance());
} finally {
Disposer.dispose(disposable);
}
}
} finally {
// tell file scanning thread to stop
iteratingIndicator.cancel();
// let file scanning thread a chance to put TOMBSTONE and complete
filesToInspect.clear();
try {
future.get(30, TimeUnit.SECONDS);
} catch (Exception e) {
LOG.error("Thread dump: \n" + ThreadDumper.dumpThreadsToString(), e);
}
}
progressIndicator.checkCanceled();
for (Tools tools : globalSimpleTools) {
GlobalInspectionToolWrapper toolWrapper = (GlobalInspectionToolWrapper) tools.getTool();
GlobalSimpleInspectionTool tool = (GlobalSimpleInspectionTool) toolWrapper.getTool();
ProblemDescriptionsProcessor problemDescriptionProcessor = getProblemDescriptionProcessor(toolWrapper, map);
tool.inspectionFinished(inspectionManager, this, problemDescriptionProcessor);
}
addProblemsToView(globalSimpleTools);
}
use of com.intellij.codeInspection.reference.RefManagerImpl in project intellij-community by JetBrains.
the class GlobalInspectionContextImpl method cleanup.
private void cleanup(@NotNull final AnalysisScope scope, @NotNull InspectionProfile profile, @Nullable final Runnable postRunnable, @Nullable final String commandName) {
setCurrentScope(scope);
final int fileCount = scope.getFileCount();
final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
final SearchScope searchScope = ReadAction.compute(scope::toSearchScope);
final TextRange range;
if (searchScope instanceof LocalSearchScope) {
final PsiElement[] elements = ((LocalSearchScope) searchScope).getScope();
range = elements.length == 1 ? ReadAction.compute(elements[0]::getTextRange) : null;
} else {
range = null;
}
final Iterable<Tools> inspectionTools = ContainerUtil.filter(profile.getAllEnabledInspectionTools(getProject()), tools -> {
assert tools != null;
return tools.getTool().getTool() instanceof CleanupLocalInspectionTool;
});
boolean includeDoNotShow = includeDoNotShow(profile);
final RefManagerImpl refManager = (RefManagerImpl) getRefManager();
refManager.inspectionReadActionStarted();
List<ProblemDescriptor> descriptors = new ArrayList<>();
Set<PsiFile> files = new HashSet<>();
try {
scope.accept(new PsiElementVisitor() {
private int myCount;
@Override
public void visitFile(PsiFile file) {
if (progressIndicator != null) {
progressIndicator.setFraction((double) ++myCount / fileCount);
}
if (isBinary(file))
return;
final List<LocalInspectionToolWrapper> lTools = new ArrayList<>();
for (final Tools tools : inspectionTools) {
final InspectionToolWrapper tool = tools.getEnabledTool(file, includeDoNotShow);
if (tool instanceof LocalInspectionToolWrapper) {
lTools.add((LocalInspectionToolWrapper) tool);
tool.initialize(GlobalInspectionContextImpl.this);
}
}
if (!lTools.isEmpty()) {
try {
final LocalInspectionsPass pass = new LocalInspectionsPass(file, PsiDocumentManager.getInstance(getProject()).getDocument(file), range != null ? range.getStartOffset() : 0, range != null ? range.getEndOffset() : file.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true, HighlightInfoProcessor.getEmpty());
Runnable runnable = () -> pass.doInspectInBatch(GlobalInspectionContextImpl.this, InspectionManager.getInstance(getProject()), lTools);
ApplicationManager.getApplication().runReadAction(runnable);
final Set<ProblemDescriptor> localDescriptors = new TreeSet<>(CommonProblemDescriptor.DESCRIPTOR_COMPARATOR);
for (LocalInspectionToolWrapper tool : lTools) {
InspectionToolPresentation toolPresentation = getPresentation(tool);
for (CommonProblemDescriptor descriptor : toolPresentation.getProblemDescriptors()) {
if (descriptor instanceof ProblemDescriptor) {
localDescriptors.add((ProblemDescriptor) descriptor);
}
}
}
if (searchScope instanceof LocalSearchScope) {
for (Iterator<ProblemDescriptor> iterator = localDescriptors.iterator(); iterator.hasNext(); ) {
final ProblemDescriptor descriptor = iterator.next();
final TextRange infoRange = descriptor instanceof ProblemDescriptorBase ? ((ProblemDescriptorBase) descriptor).getTextRange() : null;
if (infoRange != null && !((LocalSearchScope) searchScope).containsRange(file, infoRange)) {
iterator.remove();
}
}
}
if (!localDescriptors.isEmpty()) {
descriptors.addAll(localDescriptors);
files.add(file);
}
} finally {
myPresentationMap.clear();
}
}
}
});
} finally {
refManager.inspectionReadActionFinished();
}
if (files.isEmpty()) {
GuiUtils.invokeLaterIfNeeded(() -> {
if (commandName != null) {
NOTIFICATION_GROUP.createNotification(InspectionsBundle.message("inspection.no.problems.message", scope.getFileCount(), scope.getDisplayName()), MessageType.INFO).notify(getProject());
}
if (postRunnable != null) {
postRunnable.run();
}
}, ModalityState.defaultModalityState());
return;
}
Runnable runnable = () -> {
if (!FileModificationService.getInstance().preparePsiElementsForWrite(files))
return;
CleanupInspectionIntention.applyFixesNoSort(getProject(), "Code Cleanup", descriptors, null);
if (postRunnable != null) {
postRunnable.run();
}
};
TransactionGuard.submitTransaction(getProject(), runnable);
}
Aggregations