blob: f874b06fb14d3f42271806baa1b40913d60b5014 [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* User: anna
* Date: 09-Jan-2007
*/
package com.intellij.codeInspection.offlineViewer;
import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingLevelManager;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
import com.intellij.codeInspection.ex.QuickFixWrapper;
import com.intellij.codeInspection.offline.OfflineProblemDescriptor;
import com.intellij.codeInspection.reference.RefElement;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.codeInspection.ui.InspectionToolPresentation;
import com.intellij.codeInspection.ui.ProblemDescriptionNode;
import com.intellij.lang.Language;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class OfflineProblemDescriptorNode extends ProblemDescriptionNode {
public OfflineProblemDescriptorNode(@NotNull OfflineProblemDescriptor descriptor,
@NotNull LocalInspectionToolWrapper toolWrapper,
@NotNull InspectionToolPresentation presentation) {
super(descriptor, toolWrapper, presentation);
}
private static PsiElement[] getElementsIntersectingRange(PsiFile file, final int startOffset, final int endOffset) {
final FileViewProvider viewProvider = file.getViewProvider();
final Set<PsiElement> result = new LinkedHashSet<PsiElement>();
for (Language language : viewProvider.getLanguages()) {
final PsiFile psiRoot = viewProvider.getPsi(language);
if (HighlightingLevelManager.getInstance(file.getProject()).shouldInspect(psiRoot)) {
result.addAll(CollectHighlightsUtil.getElementsInRange(psiRoot, startOffset, endOffset, true));
}
}
return PsiUtilCore.toPsiElementArray(result);
}
@Override
@Nullable
public RefEntity getElement() {
if (userObject instanceof CommonProblemDescriptor) {
return myElement;
}
if (userObject == null) {
return null;
}
myElement = ((OfflineProblemDescriptor)userObject).getRefElement(myPresentation.getContext().getRefManager());
return myElement;
}
@Override
@Nullable
public CommonProblemDescriptor getDescriptor() {
if (userObject == null) return null;
if (userObject instanceof CommonProblemDescriptor) {
return (CommonProblemDescriptor)userObject;
}
final InspectionManager inspectionManager = InspectionManager.getInstance(myPresentation.getContext().getProject());
final OfflineProblemDescriptor offlineProblemDescriptor = (OfflineProblemDescriptor)userObject;
final RefEntity element = getElement();
if (myToolWrapper instanceof LocalInspectionToolWrapper) {
if (element instanceof RefElement) {
final PsiElement psiElement = ((RefElement)element).getElement();
if (psiElement != null) {
PsiFile containingFile = psiElement.getContainingFile();
final ProblemsHolder holder = new ProblemsHolder(inspectionManager, containingFile, false);
final LocalInspectionTool localTool = ((LocalInspectionToolWrapper)myToolWrapper).getTool();
final int startOffset = psiElement.getTextRange().getStartOffset();
final int endOffset = psiElement.getTextRange().getEndOffset();
LocalInspectionToolSession session = new LocalInspectionToolSession(containingFile, startOffset, endOffset);
final PsiElementVisitor visitor = localTool.buildVisitor(holder, false, session);
localTool.inspectionStarted(session, false);
final PsiElement[] elementsInRange = getElementsIntersectingRange(containingFile,
startOffset,
endOffset);
for (PsiElement el : elementsInRange) {
el.accept(visitor);
}
localTool.inspectionFinished(session, holder);
if (holder.hasResults()) {
final List<ProblemDescriptor> list = holder.getResults();
final int idx = offlineProblemDescriptor.getProblemIndex();
int curIdx = 0;
for (ProblemDescriptor descriptor : list) {
final PsiNamedElement member = localTool.getProblemElement(descriptor.getPsiElement());
if (psiElement instanceof PsiFile || member != null && member.equals(psiElement)) {
if (curIdx == idx) {
setUserObject(descriptor);
return descriptor;
}
curIdx++;
}
}
}
}
}
setUserObject(null);
return null;
}
final List<String> hints = offlineProblemDescriptor.getHints();
if (element instanceof RefElement) {
final PsiElement psiElement = ((RefElement)element).getElement();
if (psiElement == null) return null;
ProblemDescriptor descriptor = inspectionManager.createProblemDescriptor(psiElement, offlineProblemDescriptor.getDescription(),
(LocalQuickFix)null,
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false);
final LocalQuickFix[] quickFixes = getFixes(descriptor, hints);
if (quickFixes != null) {
descriptor = inspectionManager.createProblemDescriptor(psiElement, offlineProblemDescriptor.getDescription(), false, quickFixes,
ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
setUserObject(descriptor);
return descriptor;
}
CommonProblemDescriptor descriptor =
inspectionManager.createProblemDescriptor(offlineProblemDescriptor.getDescription(), (QuickFix)null);
final QuickFix[] quickFixes = getFixes(descriptor, hints);
if (quickFixes != null) {
descriptor = inspectionManager.createProblemDescriptor(offlineProblemDescriptor.getDescription(), quickFixes);
}
setUserObject(descriptor);
return descriptor;
}
@Nullable
private LocalQuickFix[] getFixes(@NotNull CommonProblemDescriptor descriptor, List<String> hints) {
final List<LocalQuickFix> fixes = new ArrayList<LocalQuickFix>(hints == null ? 1 : hints.size());
if (hints == null) {
addFix(descriptor, fixes, null);
}
else {
for (String hint : hints) {
addFix(descriptor, fixes, hint);
}
}
return fixes.isEmpty() ? null : fixes.toArray(new LocalQuickFix[fixes.size()]);
}
private void addFix(@NotNull CommonProblemDescriptor descriptor, final List<LocalQuickFix> fixes, String hint) {
final IntentionAction intentionAction = myPresentation.findQuickFixes(descriptor, hint);
if (intentionAction instanceof QuickFixWrapper) {
fixes.add(((QuickFixWrapper)intentionAction).getFix());
}
}
@Override
public boolean isValid() {
return getDescriptor() != null && super.isValid();
}
@Override
public FileStatus getNodeStatus() {
return FileStatus.NOT_CHANGED;
}
}