mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
more responsiveness for progress cancel
This commit is contained in:
@@ -129,7 +129,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
this(project, file, null, document, startOffset, endOffset);
|
||||
}
|
||||
|
||||
public void doCollectInformation(ProgressIndicator progress) {
|
||||
public void doCollectInformation(final ProgressIndicator progress) {
|
||||
DaemonCodeAnalyzer daemonCodeAnalyzer = DaemonCodeAnalyzer.getInstance(myProject);
|
||||
final FileStatusMap fileStatusMap = ((DaemonCodeAnalyzerImpl)daemonCodeAnalyzer).getFileStatusMap();
|
||||
final List<HighlightInfo> highlights = new ArrayList<HighlightInfo>();
|
||||
@@ -150,7 +150,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
myRefCountHolder = RefCountHolder.getInstance(myFile);
|
||||
if (!myRefCountHolder.retrieveUnusedReferencesInfo(new Runnable() {
|
||||
public void run() {
|
||||
collectHighlights(elementSet, highlights);
|
||||
collectHighlights(elementSet, highlights, progress);
|
||||
myHighlights = highlights;
|
||||
for (HighlightInfo info : highlights) {
|
||||
if (info.getSeverity() == HighlightSeverity.ERROR) {
|
||||
@@ -205,7 +205,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
return myHighlights;
|
||||
}
|
||||
|
||||
private void collectHighlights(Collection<PsiElement> elements, final List<HighlightInfo> result) throws ProcessCanceledException {
|
||||
private void collectHighlights(@NotNull Collection<PsiElement> elements, @NotNull final List<HighlightInfo> result, @NotNull ProgressIndicator progress) throws ProcessCanceledException {
|
||||
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||
|
||||
InspectionProfile profile = InspectionProjectProfileManager.getInstance(myProject).getInspectionProfile();
|
||||
@@ -234,11 +234,11 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
return;
|
||||
}
|
||||
for (PsiElement element : elements) {
|
||||
ProgressManager.checkCanceled();
|
||||
progress.checkCanceled();
|
||||
|
||||
if (unusedSymbolEnabled && element instanceof PsiIdentifier) {
|
||||
PsiIdentifier identifier = (PsiIdentifier)element;
|
||||
HighlightInfo info = processIdentifier(identifier);
|
||||
HighlightInfo info = processIdentifier(identifier, progress);
|
||||
if (info != null) {
|
||||
result.add(info);
|
||||
}
|
||||
@@ -257,27 +257,27 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private HighlightInfo processIdentifier(PsiIdentifier identifier) {
|
||||
private HighlightInfo processIdentifier(PsiIdentifier identifier, ProgressIndicator progress) {
|
||||
if (InspectionManagerEx.inspectionResultSuppressed(identifier, myUnusedSymbolInspection)) return null;
|
||||
PsiElement parent = identifier.getParent();
|
||||
if (PsiUtilBase.hasErrorElementChild(parent)) return null;
|
||||
HighlightInfo info;
|
||||
|
||||
if (parent instanceof PsiLocalVariable && myUnusedSymbolInspection.LOCAL_VARIABLE) {
|
||||
info = processLocalVariable((PsiLocalVariable)parent);
|
||||
info = processLocalVariable((PsiLocalVariable)parent, progress);
|
||||
}
|
||||
else if (parent instanceof PsiField && myUnusedSymbolInspection.FIELD) {
|
||||
final PsiField psiField = (PsiField)parent;
|
||||
info = processField(psiField, identifier);
|
||||
info = processField(psiField, identifier, progress);
|
||||
}
|
||||
else if (parent instanceof PsiParameter && myUnusedSymbolInspection.PARAMETER) {
|
||||
info = processParameter((PsiParameter)parent);
|
||||
info = processParameter((PsiParameter)parent, progress);
|
||||
}
|
||||
else if (parent instanceof PsiMethod && myUnusedSymbolInspection.METHOD) {
|
||||
info = processMethod((PsiMethod)parent);
|
||||
info = processMethod((PsiMethod)parent, progress);
|
||||
}
|
||||
else if (parent instanceof PsiClass && identifier.equals(((PsiClass)parent).getNameIdentifier()) && myUnusedSymbolInspection.CLASS) {
|
||||
info = processClass((PsiClass)parent);
|
||||
info = processClass((PsiClass)parent, progress);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
@@ -287,10 +287,10 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
|
||||
|
||||
@Nullable
|
||||
private HighlightInfo processLocalVariable(PsiLocalVariable variable) {
|
||||
private HighlightInfo processLocalVariable(PsiLocalVariable variable, ProgressIndicator progress) {
|
||||
PsiIdentifier identifier = variable.getNameIdentifier();
|
||||
if (identifier == null) return null;
|
||||
if (isImplicitUsage(variable)) return null;
|
||||
if (isImplicitUsage(variable, progress)) return null;
|
||||
if (!myRefCountHolder.isReferenced(variable)) {
|
||||
String message = JavaErrorMessages.message("local.variable.is.never.used", identifier.getText());
|
||||
HighlightInfo highlightInfo = createUnusedSymbolInfo(identifier, message, HighlightInfoType.UNUSED_SYMBOL);
|
||||
@@ -299,7 +299,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
}
|
||||
|
||||
boolean referenced = myRefCountHolder.isReferencedForRead(variable);
|
||||
if (!referenced && !isImplicitRead(variable)) {
|
||||
if (!referenced && !isImplicitRead(variable, progress)) {
|
||||
String message = JavaErrorMessages.message("local.variable.is.not.used.for.reading", identifier.getText());
|
||||
HighlightInfo highlightInfo = createUnusedSymbolInfo(identifier, message, HighlightInfoType.UNUSED_SYMBOL);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, new RemoveUnusedVariableFix(variable), myUnusedSymbolKey);
|
||||
@@ -308,7 +308,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
|
||||
if (!variable.hasInitializer()) {
|
||||
referenced = myRefCountHolder.isReferencedForWrite(variable);
|
||||
if (!referenced && !isImplicitWrite(variable)) {
|
||||
if (!referenced && !isImplicitWrite(variable, progress)) {
|
||||
String message = JavaErrorMessages.message("local.variable.is.not.assigned", identifier.getText());
|
||||
final HighlightInfo unusedSymbolInfo = createUnusedSymbolInfo(identifier, message, HighlightInfoType.UNUSED_SYMBOL);
|
||||
QuickFixAction.registerQuickFixAction(unusedSymbolInfo, new EmptyIntentionAction(UnusedSymbolLocalInspection.DISPLAY_NAME), myUnusedSymbolKey);
|
||||
@@ -320,10 +320,10 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
}
|
||||
|
||||
|
||||
private boolean isImplicitUsage(final PsiModifierListOwner element) {
|
||||
private boolean isImplicitUsage(final PsiModifierListOwner element, ProgressIndicator progress) {
|
||||
if (UnusedSymbolLocalInspection.isInjected(element, myUnusedSymbolInspection)) return true;
|
||||
for (ImplicitUsageProvider provider : myImplicitUsageProviders) {
|
||||
ProgressManager.checkCanceled();
|
||||
progress.checkCanceled();
|
||||
if (provider.isImplicitUsage(element)) {
|
||||
return true;
|
||||
}
|
||||
@@ -332,9 +332,9 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isImplicitRead(final PsiVariable element) {
|
||||
private boolean isImplicitRead(final PsiVariable element, ProgressIndicator progress) {
|
||||
for(ImplicitUsageProvider provider: myImplicitUsageProviders) {
|
||||
ProgressManager.checkCanceled();
|
||||
progress.checkCanceled();
|
||||
if (provider.isImplicitRead(element)) {
|
||||
return true;
|
||||
}
|
||||
@@ -342,9 +342,9 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isImplicitWrite(final PsiVariable element) {
|
||||
private boolean isImplicitWrite(final PsiVariable element, ProgressIndicator progress) {
|
||||
for(ImplicitUsageProvider provider: myImplicitUsageProviders) {
|
||||
ProgressManager.checkCanceled();
|
||||
progress.checkCanceled();
|
||||
if (provider.isImplicitWrite(element)) {
|
||||
return true;
|
||||
}
|
||||
@@ -352,17 +352,13 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
return false;
|
||||
}
|
||||
|
||||
private HighlightInfo createUnusedSymbolInfo(PsiElement element, String message, final HighlightInfoType highlightInfoType) {
|
||||
private static HighlightInfo createUnusedSymbolInfo(PsiElement element, String message, final HighlightInfoType highlightInfoType) {
|
||||
return HighlightInfo.createHighlightInfo(highlightInfoType, element, message);
|
||||
}
|
||||
|
||||
private HighlightInfo createDeadCodeInfo(PsiElement element, String message) {
|
||||
return HighlightInfo.createHighlightInfo(myDeadCodeInfoType, element, message);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private HighlightInfo processField(final PsiField field, final PsiIdentifier identifier) {
|
||||
if (isImplicitUsage(field)) return null;
|
||||
private HighlightInfo processField(final PsiField field, final PsiIdentifier identifier, ProgressIndicator progress) {
|
||||
if (isImplicitUsage(field, progress)) return null;
|
||||
if (field.hasModifierProperty(PsiModifier.PRIVATE)) {
|
||||
if (!myRefCountHolder.isReferenced(field)) {
|
||||
if (HighlightUtil.isSerializationImplicitlyUsedField(field)) {
|
||||
@@ -376,7 +372,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
}
|
||||
|
||||
final boolean readReferenced = myRefCountHolder.isReferencedForRead(field);
|
||||
if (!readReferenced && !isImplicitRead(field)) {
|
||||
if (!readReferenced && !isImplicitRead(field, progress)) {
|
||||
String message = JavaErrorMessages.message("private.field.is.not.used.for.reading", identifier.getText());
|
||||
return suggestionsToMakeFieldUsed(field, identifier, message);
|
||||
}
|
||||
@@ -385,7 +381,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
return null;
|
||||
}
|
||||
final boolean writeReferenced = myRefCountHolder.isReferencedForWrite(field);
|
||||
if (!writeReferenced && !isImplicitWrite(field)) {
|
||||
if (!writeReferenced && !isImplicitWrite(field, progress)) {
|
||||
String message = JavaErrorMessages.message("private.field.is.not.assigned", identifier.getText());
|
||||
final HighlightInfo info = createUnusedSymbolInfo(identifier, message, HighlightInfoType.UNUSED_SYMBOL);
|
||||
|
||||
@@ -400,7 +396,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
else if (!myRefCountHolder.isReferenced(field) && weAreSureThereAreNoUsages(field)) {
|
||||
else if (!myRefCountHolder.isReferenced(field) && weAreSureThereAreNoUsages(field, progress)) {
|
||||
return formatUnusedSymbolHighlightInfo("field.is.not.used", field, "fields", myDeadCodeKey, myDeadCodeInfoType);
|
||||
}
|
||||
return null;
|
||||
@@ -421,7 +417,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private HighlightInfo processParameter(PsiParameter parameter) {
|
||||
private HighlightInfo processParameter(PsiParameter parameter, ProgressIndicator progress) {
|
||||
PsiElement declarationScope = parameter.getDeclarationScope();
|
||||
if (declarationScope instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod)declarationScope;
|
||||
@@ -435,7 +431,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
!method.hasModifierProperty(PsiModifier.NATIVE) &&
|
||||
!HighlightMethodUtil.isSerializationRelatedMethod(method, method.getContainingClass()) &&
|
||||
!PsiClassImplUtil.isMainMethod(method)) {
|
||||
HighlightInfo highlightInfo = checkUnusedParameter(parameter);
|
||||
HighlightInfo highlightInfo = checkUnusedParameter(parameter, progress);
|
||||
if (highlightInfo != null) {
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, new RemoveUnusedParameterFix(parameter), myUnusedSymbolKey);
|
||||
return highlightInfo;
|
||||
@@ -443,7 +439,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
}
|
||||
}
|
||||
else if (declarationScope instanceof PsiForeachStatement) {
|
||||
HighlightInfo highlightInfo = checkUnusedParameter(parameter);
|
||||
HighlightInfo highlightInfo = checkUnusedParameter(parameter, progress);
|
||||
if (highlightInfo != null) {
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, new EmptyIntentionAction(UnusedSymbolLocalInspection.DISPLAY_NAME), myUnusedSymbolKey);
|
||||
return highlightInfo;
|
||||
@@ -454,8 +450,8 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private HighlightInfo checkUnusedParameter(final PsiParameter parameter) {
|
||||
if (!myRefCountHolder.isReferenced(parameter) && !isImplicitUsage(parameter)) {
|
||||
private HighlightInfo checkUnusedParameter(final PsiParameter parameter, ProgressIndicator progress) {
|
||||
if (!myRefCountHolder.isReferenced(parameter) && !isImplicitUsage(parameter, progress)) {
|
||||
PsiIdentifier identifier = parameter.getNameIdentifier();
|
||||
assert identifier != null;
|
||||
String message = JavaErrorMessages.message("parameter.is.not.used", identifier.getText());
|
||||
@@ -465,7 +461,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private HighlightInfo processMethod(final PsiMethod method) {
|
||||
private HighlightInfo processMethod(final PsiMethod method, ProgressIndicator progress) {
|
||||
if (myRefCountHolder.isReferenced(method)) return null;
|
||||
boolean isPrivate = method.hasModifierProperty(PsiModifier.PRIVATE);
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
@@ -477,19 +473,20 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
isIntentionalPrivateConstructor(method, containingClass)) {
|
||||
return null;
|
||||
}
|
||||
if (isImplicitUsage(method)) {
|
||||
if (isImplicitUsage(method, progress)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//class maybe used in some weird way, e.g. from XML, therefore the only constructor is used too
|
||||
if (containingClass != null && method.isConstructor() && containingClass.getConstructors().length == 1 && isClassUnused(containingClass) == USED) return null;
|
||||
if (isImplicitUsage(method)) return null;
|
||||
if (containingClass != null && method.isConstructor() && containingClass.getConstructors().length == 1 && isClassUnused(containingClass,
|
||||
progress) == USED) return null;
|
||||
if (isImplicitUsage(method, progress)) return null;
|
||||
|
||||
if (method.findSuperMethods().length != 0) {
|
||||
return null;
|
||||
}
|
||||
if (!weAreSureThereAreNoUsages(method)) {
|
||||
if (!weAreSureThereAreNoUsages(method, progress)) {
|
||||
return null;
|
||||
}
|
||||
highlightInfoType = myDeadCodeInfoType;
|
||||
@@ -512,7 +509,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
return highlightInfo;
|
||||
}
|
||||
|
||||
private boolean weAreSureThereAreNoUsages(PsiMember member) {
|
||||
private boolean weAreSureThereAreNoUsages(PsiMember member, ProgressIndicator progress) {
|
||||
if (myInLibrary) return false;
|
||||
if (!myDeadCodeEnabled) return false;
|
||||
if (myDeadCodeInspection.isEntryPoint(member)) return false;
|
||||
@@ -525,7 +522,8 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
// some classes may have references from within XML outside dependent modules, e.g. our actions
|
||||
if (member instanceof PsiClass) scope = scope.uniteWith(GlobalSearchScope.projectScope(myProject));
|
||||
|
||||
PsiSearchHelper.SearchCostResult cheapEnough = myFile.getManager().getSearchHelper().isCheapEnoughToSearch(name, scope, myFile);
|
||||
PsiSearchHelper.SearchCostResult cheapEnough = myFile.getManager().getSearchHelper().isCheapEnoughToSearch(name, scope, myFile,
|
||||
progress);
|
||||
if (cheapEnough == PsiSearchHelper.SearchCostResult.TOO_MANY_OCCURRENCES) return false;
|
||||
|
||||
//search usages if it cheap
|
||||
@@ -550,8 +548,8 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private HighlightInfo processClass(PsiClass aClass) {
|
||||
int usage = isClassUnused(aClass);
|
||||
private HighlightInfo processClass(PsiClass aClass, ProgressIndicator progress) {
|
||||
int usage = isClassUnused(aClass, progress);
|
||||
if (usage == USED) return null;
|
||||
|
||||
String pattern;
|
||||
@@ -586,22 +584,22 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
private static final int UNUSED_LOCALLY = 2;
|
||||
private static final int UNUSED_GLOBALLY = 3;
|
||||
private final TObjectIntHashMap<PsiClass> unusedClassCache = new TObjectIntHashMap<PsiClass>();
|
||||
private int isClassUnused(PsiClass aClass) {
|
||||
private int isClassUnused(PsiClass aClass, ProgressIndicator progress) {
|
||||
if (aClass == null) return USED;
|
||||
int result = unusedClassCache.get(aClass);
|
||||
if (result == 0) {
|
||||
result = isReallyUnused(aClass);
|
||||
result = isReallyUnused(aClass, progress);
|
||||
unusedClassCache.put(aClass, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int isReallyUnused(PsiClass aClass) {
|
||||
if (isImplicitUsage(aClass) || myRefCountHolder.isReferenced(aClass)) return USED;
|
||||
private int isReallyUnused(PsiClass aClass, ProgressIndicator progress) {
|
||||
if (isImplicitUsage(aClass, progress) || myRefCountHolder.isReferenced(aClass)) return USED;
|
||||
if (aClass.getContainingClass() != null && aClass.hasModifierProperty(PsiModifier.PRIVATE) ||
|
||||
aClass.getParent() instanceof PsiDeclarationStatement ||
|
||||
aClass instanceof PsiTypeParameter) return UNUSED_LOCALLY;
|
||||
if (weAreSureThereAreNoUsages(aClass)) return UNUSED_GLOBALLY;
|
||||
if (weAreSureThereAreNoUsages(aClass, progress)) return UNUSED_GLOBALLY;
|
||||
return USED;
|
||||
}
|
||||
|
||||
|
||||
@@ -386,7 +386,9 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
|
||||
progress.setText(FindBundle.message("find.searching.for.references.to.class.progress", aClass.getName()));
|
||||
}
|
||||
for (PsiFile file : files) {
|
||||
ProgressManager.checkCanceled();
|
||||
if (progress != null) {
|
||||
progress.checkCanceled();
|
||||
}
|
||||
ReferencesSearch.search(aClass, new LocalSearchScope(file), false).forEach(new ReadActionProcessor<PsiReference>() {
|
||||
public boolean processInReadAction(final PsiReference psiReference) {
|
||||
return addResult(results, psiReference, options, aClass);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.psi.search;
|
||||
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.Processor;
|
||||
@@ -180,7 +181,10 @@ public interface PsiSearchHelper {
|
||||
short searchContext,
|
||||
boolean caseSensitive);
|
||||
|
||||
SearchCostResult isCheapEnoughToSearch(@NotNull String name, @NotNull GlobalSearchScope scope, @Nullable PsiFile fileToIgnoreOccurencesIn);
|
||||
SearchCostResult isCheapEnoughToSearch(@NotNull String name,
|
||||
@NotNull GlobalSearchScope scope,
|
||||
@Nullable PsiFile fileToIgnoreOccurencesIn,
|
||||
ProgressIndicator progress);
|
||||
|
||||
enum SearchCostResult {
|
||||
ZERO_OCCURRENCES, FEW_OCCURRENCES, TOO_MANY_OCCURRENCES
|
||||
|
||||
+6
-7
@@ -43,7 +43,6 @@ import com.intellij.openapi.fileTypes.SyntaxHighlighter;
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -161,7 +160,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
|
||||
}
|
||||
if (elements != null) {
|
||||
result.addAll(collectHighlights(elements, progress, filtered));
|
||||
addInjectedPsiHighlights(elements);
|
||||
addInjectedPsiHighlights(elements, progress);
|
||||
}
|
||||
|
||||
if (!isDumbMode()) {
|
||||
@@ -178,7 +177,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
|
||||
myHighlights = result;
|
||||
}
|
||||
|
||||
private void addInjectedPsiHighlights(@NotNull final List<PsiElement> elements) {
|
||||
private void addInjectedPsiHighlights(@NotNull final List<PsiElement> elements, final ProgressIndicator progress) {
|
||||
List<DocumentWindow> injected = InjectedLanguageUtil.getCachedInjectedDocuments(myFile);
|
||||
Collection<PsiElement> hosts = new THashSet<PsiElement>(elements.size() + injected.size());
|
||||
|
||||
@@ -224,7 +223,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
|
||||
public boolean process(final PsiFile injectedPsi) {
|
||||
DocumentWindow documentWindow = (DocumentWindow)PsiDocumentManager.getInstance(myProject).getCachedDocument(injectedPsi);
|
||||
HighlightInfoHolder holder = createInfoHolder(injectedPsi);
|
||||
runHighlightVisitosForInjected(injectedPsi, holder);
|
||||
runHighlightVisitosForInjected(injectedPsi, holder, progress);
|
||||
for (int i=0; i<holder.size();i++) {
|
||||
HighlightInfo info = holder.get(i);
|
||||
final int startOffset = documentWindow.injectedToHost(info.startOffset);
|
||||
@@ -327,7 +326,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
|
||||
return textRange;
|
||||
}
|
||||
|
||||
private void runHighlightVisitosForInjected(final PsiFile injectedPsi, final HighlightInfoHolder holder) {
|
||||
private void runHighlightVisitosForInjected(final PsiFile injectedPsi, final HighlightInfoHolder holder, final ProgressIndicator progress) {
|
||||
HighlightVisitor[] visitors = createHighlightVisitors();
|
||||
try {
|
||||
HighlightVisitor[] filtered = filterVisitors(visitors, injectedPsi);
|
||||
@@ -336,7 +335,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
|
||||
hvisitor.analyze(new Runnable() {
|
||||
public void run() {
|
||||
for (PsiElement element : elements) {
|
||||
ProgressManager.checkCanceled();
|
||||
progress.checkCanceled();
|
||||
hvisitor.visit(element, holder);
|
||||
}
|
||||
}
|
||||
@@ -452,7 +451,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
|
||||
int nextLimit = chunkSize;
|
||||
for (int i = 0; i < elements.size(); i++) {
|
||||
PsiElement element = elements.get(i);
|
||||
ProgressManager.checkCanceled();
|
||||
progress.checkCanceled();
|
||||
|
||||
if (element != myFile && !skipParentsSet.isEmpty() && element.getFirstChild() != null && skipParentsSet.contains(element)) {
|
||||
skipParentsSet.add(element.getParent());
|
||||
|
||||
@@ -32,7 +32,6 @@ import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.markup.GutterIconRenderer;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
@@ -87,8 +86,8 @@ public class LineMarkersPass extends ProgressableTextEditorHighlightingPass impl
|
||||
elements = Collections.singletonList(psiRoot);
|
||||
}
|
||||
final List<LineMarkerProvider> providers = getMarkerProviders(language, myProject);
|
||||
addLineMarkers(elements, providers, lineMarkers);
|
||||
collectLineMarkersForInjected(lineMarkers, elements, this, myFile);
|
||||
addLineMarkers(elements, providers, lineMarkers, progress);
|
||||
collectLineMarkersForInjected(lineMarkers, elements, this, myFile, progress);
|
||||
}
|
||||
|
||||
myMarkers = lineMarkers;
|
||||
@@ -98,10 +97,13 @@ public class LineMarkersPass extends ProgressableTextEditorHighlightingPass impl
|
||||
return DumbService.getInstance(project).filterByDumbAwareness(LineMarkerProviders.INSTANCE.allForLanguage(language));
|
||||
}
|
||||
|
||||
public void addLineMarkers(List<PsiElement> elements, final List<LineMarkerProvider> providers, final List<LineMarkerInfo> result) throws ProcessCanceledException {
|
||||
public void addLineMarkers(@NotNull List<PsiElement> elements,
|
||||
@NotNull final List<LineMarkerProvider> providers,
|
||||
@NotNull final List<LineMarkerInfo> result,
|
||||
@NotNull ProgressIndicator progress) throws ProcessCanceledException {
|
||||
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||
for (PsiElement element : elements) {
|
||||
ProgressManager.checkCanceled();
|
||||
progress.checkCanceled();
|
||||
|
||||
for (LineMarkerProvider provider: providers) {
|
||||
LineMarkerInfo info = provider.getLineMarkerInfo(element);
|
||||
@@ -112,14 +114,12 @@ public class LineMarkersPass extends ProgressableTextEditorHighlightingPass impl
|
||||
}
|
||||
}
|
||||
|
||||
public static void collectLineMarkersForInjected(final List<LineMarkerInfo> result, List<PsiElement> elements,
|
||||
final LineMarkersProcessor processor,
|
||||
PsiFile file) {
|
||||
public static void collectLineMarkersForInjected(@NotNull final List<LineMarkerInfo> result, @NotNull List<PsiElement> elements,
|
||||
@NotNull final LineMarkersProcessor processor,
|
||||
@NotNull PsiFile file, @NotNull final ProgressIndicator progress) {
|
||||
final InjectedLanguageManager manager = InjectedLanguageManager.getInstance(file.getProject());
|
||||
final List<LineMarkerInfo> injectedMarkers = new ArrayList<LineMarkerInfo>();
|
||||
|
||||
final boolean dumb = DumbService.getInstance(file.getProject()).isDumb();
|
||||
|
||||
for (PsiElement element : elements) {
|
||||
InjectedLanguageUtil.enumerate(element, file, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
|
||||
public void visit(@NotNull final PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
|
||||
@@ -128,7 +128,7 @@ public class LineMarkersPass extends ProgressableTextEditorHighlightingPass impl
|
||||
if (!(document instanceof DocumentWindow)) return;
|
||||
List<PsiElement> injElements = CollectHighlightsUtil.getElementsInRange(injectedPsi, 0, injectedPsi.getTextLength());
|
||||
final List<LineMarkerProvider> providers = getMarkerProviders(injectedPsi.getLanguage(), project);
|
||||
processor.addLineMarkers(injElements, providers, injectedMarkers);
|
||||
processor.addLineMarkers(injElements, providers, injectedMarkers, progress);
|
||||
for (final LineMarkerInfo injectedMarker : injectedMarkers) {
|
||||
GutterIconRenderer gutterRenderer = injectedMarker.createGutterRenderer();
|
||||
TextRange injectedRange = new TextRange(injectedMarker.startOffset, injectedMarker.endOffset);
|
||||
|
||||
+8
-4
@@ -16,10 +16,12 @@
|
||||
|
||||
package com.intellij.codeInsight.daemon.impl;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.codeInsight.daemon.LineMarkerProvider;
|
||||
import com.intellij.codeInsight.daemon.LineMarkerInfo;
|
||||
import com.intellij.codeInsight.daemon.LineMarkerProvider;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -27,6 +29,8 @@ import java.util.List;
|
||||
* @author cdr
|
||||
*/
|
||||
public interface LineMarkersProcessor {
|
||||
void addLineMarkers(List<PsiElement> elements, List<LineMarkerProvider> providers, List<LineMarkerInfo> result) throws
|
||||
ProcessCanceledException;
|
||||
void addLineMarkers(@NotNull List<PsiElement> elements,
|
||||
@NotNull List<LineMarkerProvider> providers,
|
||||
@NotNull List<LineMarkerInfo> result,
|
||||
@NotNull ProgressIndicator progress) throws ProcessCanceledException;
|
||||
}
|
||||
|
||||
+12
-12
@@ -195,7 +195,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
|
||||
JobUtil.invokeConcurrentlyUnderMyProgress(tools, new Processor<LocalInspectionTool>() {
|
||||
public boolean process(final LocalInspectionTool tool) {
|
||||
final ProgressManager progressManager = ProgressManager.getInstance();
|
||||
ProgressManager.checkCanceled();
|
||||
indicator.checkCanceled();
|
||||
ProgressIndicator localIndicator = progressManager.getProgressIndicator();
|
||||
|
||||
ProgressIndicator original = ((ProgressWrapper)localIndicator).getOriginalProgressIndicator();
|
||||
@@ -211,20 +211,20 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
|
||||
}
|
||||
tool.inspectionStarted(session);
|
||||
for (PsiElement element : elements) {
|
||||
ProgressManager.checkCanceled();
|
||||
indicator.checkCanceled();
|
||||
element.accept(elementVisitor);
|
||||
}
|
||||
tool.inspectionFinished(session);
|
||||
advanceProgress(elements.length);
|
||||
|
||||
if (holder.hasResults()) {
|
||||
appendDescriptors(holder.getResults(), tool, ignoreSuppressed);
|
||||
appendDescriptors(holder.getResults(), tool, ignoreSuppressed, indicator);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}, "Inspection tools");
|
||||
ProgressManager.checkCanceled();
|
||||
}, "Inspection tools", myPriority);
|
||||
|
||||
indicator.checkCanceled();
|
||||
inspectInjectedPsi(elements, tools);
|
||||
|
||||
myInfos = new ArrayList<HighlightInfo>(myDescriptors.size());
|
||||
@@ -264,19 +264,19 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
|
||||
TextRange textRange = ((ProblemDescriptorImpl)problemDescriptor).getTextRange();
|
||||
PsiElement element = problemDescriptor.getPsiElement();
|
||||
boolean isFileLevel = element instanceof PsiFile && textRange.equals(element.getTextRange());
|
||||
HighlightInfo highlightInfo = new HighlightInfo(null, highlightInfoType, textRange.getStartOffset(), textRange.getEndOffset(), message,
|
||||
toolTip, highlightInfoType.getSeverity(element), problemDescriptor.isAfterEndOfLine(), null,
|
||||
isFileLevel);
|
||||
|
||||
return highlightInfo;
|
||||
return new HighlightInfo(null, highlightInfoType, textRange.getStartOffset(), textRange.getEndOffset(), message, toolTip,
|
||||
highlightInfoType.getSeverity(element), problemDescriptor.isAfterEndOfLine(), null, isFileLevel);
|
||||
}
|
||||
|
||||
private synchronized void appendDescriptors(List<ProblemDescriptor> problemDescriptors, LocalInspectionTool tool, boolean ignoreSuppressed) {
|
||||
if (problemDescriptors == null) return;
|
||||
private synchronized void appendDescriptors(@NotNull List<ProblemDescriptor> problemDescriptors,
|
||||
@NotNull LocalInspectionTool tool,
|
||||
boolean ignoreSuppressed,
|
||||
@NotNull ProgressIndicator progress) {
|
||||
InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(myProject).getInspectionProfile();
|
||||
final HighlightSeverity severity = inspectionProfile.getErrorLevel(HighlightDisplayKey.find(tool.getShortName()), myFile).getSeverity();
|
||||
for (ProblemDescriptor problemDescriptor : problemDescriptors) {
|
||||
ProgressManager.checkCanceled();
|
||||
progress.checkCanceled();
|
||||
if (!(ignoreSuppressed && InspectionManagerEx.inspectionResultSuppressed(problemDescriptor.getPsiElement(), tool))) {
|
||||
myDescriptors.add(problemDescriptor);
|
||||
HighlightInfoType type = highlightTypeFromDescriptor(problemDescriptor, severity);
|
||||
|
||||
@@ -30,7 +30,6 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -86,13 +85,11 @@ public class ShowAutoImportPass extends TextEditorHighlightingPass {
|
||||
|
||||
int caretOffset = myEditor.getCaretModel().getOffset();
|
||||
for (int i = visibleHighlights.size() - 1; i >= 0; i--) {
|
||||
ProgressManager.checkCanceled();
|
||||
HighlightInfo info = visibleHighlights.get(i);
|
||||
if (info.startOffset <= caretOffset && showAddImportHint(info)) return;
|
||||
}
|
||||
|
||||
for (HighlightInfo visibleHighlight : visibleHighlights) {
|
||||
ProgressManager.checkCanceled();
|
||||
if (visibleHighlight.startOffset > caretOffset && showAddImportHint(visibleHighlight)) return;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -61,14 +61,17 @@ public class SlowLineMarkersPass extends TextEditorHighlightingPass implements L
|
||||
if (psiRoot == null || !HighlightLevelUtil.shouldHighlight(psiRoot)) continue;
|
||||
List<PsiElement> elements = CollectHighlightsUtil.getElementsInRange(psiRoot, myStartOffset, myEndOffset);
|
||||
final List<LineMarkerProvider> providers = LineMarkersPass.getMarkerProviders(language, myProject);
|
||||
addLineMarkers(elements, providers, markers);
|
||||
LineMarkersPass.collectLineMarkersForInjected(markers, elements, this, myFile);
|
||||
addLineMarkers(elements, providers, markers, progress);
|
||||
LineMarkersPass.collectLineMarkersForInjected(markers, elements, this, myFile, progress);
|
||||
}
|
||||
|
||||
myMarkers = markers;
|
||||
}
|
||||
|
||||
public void addLineMarkers(List<PsiElement> elements, List<LineMarkerProvider> providers, List<LineMarkerInfo> result) throws ProcessCanceledException {
|
||||
public void addLineMarkers(@NotNull List<PsiElement> elements,
|
||||
@NotNull List<LineMarkerProvider> providers,
|
||||
@NotNull List<LineMarkerInfo> result,
|
||||
@NotNull ProgressIndicator progress) throws ProcessCanceledException {
|
||||
for (LineMarkerProvider provider : providers) {
|
||||
provider.collectSlowLineMarkers(elements, result);
|
||||
}
|
||||
|
||||
@@ -431,52 +431,53 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
|
||||
}
|
||||
|
||||
public void initInspectionTools() {
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode() || INIT_INSPECTIONS) {
|
||||
synchronized (myInitialized) {
|
||||
if (!myInitialized.getAndSet(true)) {
|
||||
if (myBaseProfile != null) {
|
||||
myBaseProfile.initInspectionTools();
|
||||
if (ApplicationManager.getApplication().isUnitTestMode() && !INIT_INSPECTIONS) {
|
||||
return;
|
||||
}
|
||||
synchronized (myInitialized) {
|
||||
if (!myInitialized.getAndSet(true)) {
|
||||
if (myBaseProfile != null) {
|
||||
myBaseProfile.initInspectionTools();
|
||||
}
|
||||
|
||||
final InspectionTool[] tools;
|
||||
try {
|
||||
tools = myRegistrar.createTools();
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
myInitialized.set(false);
|
||||
return;
|
||||
}
|
||||
for (InspectionTool tool : tools) {
|
||||
final String shortName = tool.getShortName();
|
||||
HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
|
||||
if (key == null) {
|
||||
if (tool instanceof LocalInspectionToolWrapper) {
|
||||
key = HighlightDisplayKey.register(shortName, tool.getDisplayName(), ((LocalInspectionToolWrapper)tool).getTool().getID(),
|
||||
((LocalInspectionToolWrapper)tool).getTool().getAlternativeID());
|
||||
}
|
||||
else {
|
||||
key = HighlightDisplayKey.register(shortName);
|
||||
}
|
||||
}
|
||||
|
||||
final InspectionTool[] tools;
|
||||
try {
|
||||
tools = myRegistrar.createTools();
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
myInitialized.set(false);
|
||||
return;
|
||||
}
|
||||
for (InspectionTool tool : tools) {
|
||||
final String shortName = tool.getShortName();
|
||||
HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
|
||||
if (key == null) {
|
||||
if (tool instanceof LocalInspectionToolWrapper) {
|
||||
key = HighlightDisplayKey.register(shortName, tool.getDisplayName(), ((LocalInspectionToolWrapper)tool).getTool().getID(),
|
||||
((LocalInspectionToolWrapper)tool).getTool().getAlternativeID());
|
||||
}
|
||||
else {
|
||||
key = HighlightDisplayKey.register(shortName);
|
||||
}
|
||||
LOG.assertTrue(key != null, shortName + " ; number of initialized tools: " + myTools.size());
|
||||
final ToolsImpl toolsList =
|
||||
new ToolsImpl(tool, myBaseProfile != null ? myBaseProfile.getErrorLevel(key) : tool.getDefaultLevel(),
|
||||
!myLockedProfile && (myBaseProfile != null ? myBaseProfile.isToolEnabled(key) : tool.isEnabledByDefault()));
|
||||
final Element element = myDeinstalledInspectionsSettings.remove(tool.getShortName());
|
||||
if (element != null) {
|
||||
try {
|
||||
toolsList.readExternal(element, this);
|
||||
}
|
||||
|
||||
LOG.assertTrue(key != null, shortName + " ; number of initialized tools: " + myTools.size());
|
||||
final ToolsImpl toolsList =
|
||||
new ToolsImpl(tool, myBaseProfile != null ? myBaseProfile.getErrorLevel(key) : tool.getDefaultLevel(),
|
||||
!myLockedProfile && (myBaseProfile != null ? myBaseProfile.isToolEnabled(key) : tool.isEnabledByDefault()));
|
||||
final Element element = myDeinstalledInspectionsSettings.remove(tool.getShortName());
|
||||
if (element != null) {
|
||||
try {
|
||||
toolsList.readExternal(element, this);
|
||||
}
|
||||
catch (InvalidDataException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
catch (InvalidDataException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
myTools.put(tool.getShortName(), toolsList);
|
||||
}
|
||||
if (mySource != null) {
|
||||
copyToolsConfigurations(mySource);
|
||||
}
|
||||
myTools.put(tool.getShortName(), toolsList);
|
||||
}
|
||||
if (mySource != null) {
|
||||
copyToolsConfigurations(mySource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.intellij.psi.impl.search;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -29,6 +29,8 @@ import com.intellij.psi.impl.source.tree.TreeElement;
|
||||
import com.intellij.psi.search.TextOccurenceProcessor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.text.StringSearcher;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -40,13 +42,16 @@ public class LowLevelSearchUtil {
|
||||
|
||||
// TRUE/FALSE -> injected psi has been discovered and processor returned true/false;
|
||||
// null -> there were nothing injected found
|
||||
private static Boolean processInjectedFile(PsiElement element, final TextOccurenceProcessor processor, final StringSearcher searcher) {
|
||||
private static Boolean processInjectedFile(PsiElement element,
|
||||
final TextOccurenceProcessor processor,
|
||||
final StringSearcher searcher,
|
||||
ProgressIndicator progress) {
|
||||
if (!(element instanceof PsiLanguageInjectionHost)) return null;
|
||||
List<Pair<PsiElement,TextRange>> list = ((PsiLanguageInjectionHost)element).getInjectedPsi();
|
||||
if (list == null) return null;
|
||||
for (Pair<PsiElement, TextRange> pair : list) {
|
||||
final PsiElement injected = pair.getFirst();
|
||||
if (!processElementsContainingWordInElement(processor, injected, searcher, false)) return Boolean.FALSE;
|
||||
if (!processElementsContainingWordInElement(processor, injected, searcher, false, progress)) return Boolean.FALSE;
|
||||
}
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
@@ -55,7 +60,7 @@ public class LowLevelSearchUtil {
|
||||
final PsiElement scope,
|
||||
final StringSearcher searcher,
|
||||
final int offset,
|
||||
final boolean ignoreInjectedPsi) {
|
||||
final boolean ignoreInjectedPsi, ProgressIndicator progress) {
|
||||
final int scopeStartOffset = scope.getTextRange().getStartOffset();
|
||||
final int patternLength = searcher.getPatternLength();
|
||||
PsiElement leafElement = null;
|
||||
@@ -88,6 +93,7 @@ public class LowLevelSearchUtil {
|
||||
TreeElement prevNode = null;
|
||||
PsiElement run = null;
|
||||
while (run != scope) {
|
||||
if (progress != null) progress.checkCanceled();
|
||||
if (useTree) {
|
||||
start += prevNode == null ? 0 : prevNode.getStartOffsetInParent();
|
||||
prevNode = leafNode;
|
||||
@@ -101,7 +107,7 @@ public class LowLevelSearchUtil {
|
||||
contains |= run.getTextLength() - start >= patternLength; //do not compute if already contains
|
||||
if (contains) {
|
||||
if (!ignoreInjectedPsi) {
|
||||
Boolean result = processInjectedFile(run, processor, searcher);
|
||||
Boolean result = processInjectedFile(run, processor, searcher, progress);
|
||||
if (result != null) return result.booleanValue();
|
||||
}
|
||||
if (!processor.execute(run, start)) return false;
|
||||
@@ -123,8 +129,8 @@ public class LowLevelSearchUtil {
|
||||
public static boolean processElementsContainingWordInElement(final TextOccurenceProcessor processor,
|
||||
final PsiElement scope,
|
||||
final StringSearcher searcher,
|
||||
final boolean ignoreInjectedPsi) {
|
||||
ProgressManager.checkCanceled();
|
||||
final boolean ignoreInjectedPsi, ProgressIndicator progress) {
|
||||
if (progress != null) progress.checkCanceled();
|
||||
|
||||
PsiFile file = scope.getContainingFile();
|
||||
final CharSequence buffer = file.getViewProvider().getContents();
|
||||
@@ -135,11 +141,12 @@ public class LowLevelSearchUtil {
|
||||
int endOffset = range.getEndOffset();
|
||||
|
||||
do {
|
||||
startOffset = searchWord(buffer, startOffset, endOffset, searcher);
|
||||
if (progress != null) progress.checkCanceled();
|
||||
startOffset = searchWord(buffer, startOffset, endOffset, searcher, progress);
|
||||
if (startOffset < 0) {
|
||||
return true;
|
||||
}
|
||||
if (!processTreeUp(processor, scope, searcher, startOffset - scopeStart, ignoreInjectedPsi)) return false;
|
||||
if (!processTreeUp(processor, scope, searcher, startOffset - scopeStart, ignoreInjectedPsi, progress)) return false;
|
||||
|
||||
startOffset++;
|
||||
}
|
||||
@@ -148,8 +155,9 @@ public class LowLevelSearchUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int searchWord(CharSequence text, int startOffset, int endOffset, StringSearcher searcher) {
|
||||
public static int searchWord(@NotNull CharSequence text, int startOffset, int endOffset, @NotNull StringSearcher searcher, @Nullable ProgressIndicator progress) {
|
||||
for (int index = startOffset; index < endOffset; index++) {
|
||||
if (progress != null) progress.checkCanceled();
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
index = searcher.scan(text, index, endOffset);
|
||||
if (index < 0) return -1;
|
||||
|
||||
@@ -166,6 +166,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
if (text.length() == 0) {
|
||||
throw new IllegalArgumentException("Cannot search for elements with empty text");
|
||||
}
|
||||
final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (searchScope instanceof GlobalSearchScope) {
|
||||
StringSearcher searcher = new StringSearcher(text, caseSensitively, true);
|
||||
|
||||
@@ -181,7 +182,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
|
||||
return JobUtil.invokeConcurrentlyUnderMyProgress(Arrays.asList(scopeElements), new Processor<PsiElement>() {
|
||||
public boolean process(PsiElement scopeElement) {
|
||||
return processElementsWithWordInScopeElement(scopeElement, processor, text, caseSensitively, ignoreInjectedPsi);
|
||||
return processElementsWithWordInScopeElement(scopeElement, processor, text, caseSensitively, ignoreInjectedPsi, progress);
|
||||
}
|
||||
}, "textsearch");
|
||||
}
|
||||
@@ -191,19 +192,19 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
final TextOccurenceProcessor processor,
|
||||
final String word,
|
||||
final boolean caseSensitive,
|
||||
final boolean ignoreInjectedPsi) {
|
||||
final boolean ignoreInjectedPsi, final ProgressIndicator progress) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
public Boolean compute() {
|
||||
StringSearcher searcher = new StringSearcher(word, caseSensitive, true);
|
||||
|
||||
return LowLevelSearchUtil.processElementsContainingWordInElement(processor, scopeElement, searcher, ignoreInjectedPsi);
|
||||
return LowLevelSearchUtil.processElementsContainingWordInElement(processor, scopeElement, searcher, ignoreInjectedPsi, progress);
|
||||
}
|
||||
}).booleanValue();
|
||||
}
|
||||
|
||||
private boolean processElementsWithTextInGlobalScope(@NotNull final TextOccurenceProcessor processor,
|
||||
final GlobalSearchScope scope,
|
||||
final StringSearcher searcher,
|
||||
@NotNull final GlobalSearchScope scope,
|
||||
@NotNull final StringSearcher searcher,
|
||||
final short searchContext,
|
||||
final boolean caseSensitively) {
|
||||
LOG.assertTrue(!Thread.holdsLock(PsiLock.LOCK), "You must not run search from within updating PSI activity. Please consider invokeLatering it instead.");
|
||||
@@ -216,7 +217,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
|
||||
try {
|
||||
String text = searcher.getPattern();
|
||||
List<PsiFile> fileSet = getFilesWithText(scope, searchContext, caseSensitively, text);
|
||||
List<PsiFile> fileSet = getFilesWithText(scope, searchContext, caseSensitively, text, progress);
|
||||
|
||||
if (progress != null) {
|
||||
progress.setText(PsiBundle.message("psi.search.for.word.progress", text));
|
||||
@@ -237,9 +238,9 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
PsiElement[] psiRoots = file.getPsiRoots();
|
||||
Set<PsiElement> processed = new HashSet<PsiElement>(psiRoots.length * 2, (float)0.5);
|
||||
for (PsiElement psiRoot : psiRoots) {
|
||||
ProgressManager.checkCanceled();
|
||||
if (progress != null) progress.checkCanceled();
|
||||
if (!processed.add(psiRoot)) continue;
|
||||
if (!LowLevelSearchUtil.processElementsContainingWordInElement(processor, psiRoot, searcher, false)) {
|
||||
if (!LowLevelSearchUtil.processElementsContainingWordInElement(processor, psiRoot, searcher, false, progress)) {
|
||||
canceled.set(true);
|
||||
return;
|
||||
}
|
||||
@@ -275,20 +276,24 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private List<PsiFile> getFilesWithText(final GlobalSearchScope scope,
|
||||
final short searchContext,
|
||||
final boolean caseSensitively,
|
||||
String text) {
|
||||
private List<PsiFile> getFilesWithText(@NotNull GlobalSearchScope scope,
|
||||
final short searchContext,
|
||||
final boolean caseSensitively,
|
||||
@NotNull String text,
|
||||
ProgressIndicator progress) {
|
||||
List<PsiFile> result = new ArrayList<PsiFile>();
|
||||
if (!processFilesWithText(scope, searchContext, caseSensitively, text, new CommonProcessors.CollectProcessor<PsiFile>(result))) return Collections.emptyList();
|
||||
if (!processFilesWithText(scope, searchContext, caseSensitively, text, new CommonProcessors.CollectProcessor<PsiFile>(result), progress)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean processFilesWithText(final GlobalSearchScope scope,
|
||||
final short searchContext,
|
||||
final boolean caseSensitively,
|
||||
String text,
|
||||
final Processor<PsiFile> processor) {
|
||||
private boolean processFilesWithText(@NotNull final GlobalSearchScope scope,
|
||||
final short searchContext,
|
||||
final boolean caseSensitively,
|
||||
@NotNull String text,
|
||||
@NotNull final Processor<PsiFile> processor,
|
||||
ProgressIndicator progress) {
|
||||
List<String> words = StringUtil.getWordsIn(text);
|
||||
if (words.isEmpty()) return true;
|
||||
Collections.sort(words, new Comparator<String>() {
|
||||
@@ -301,7 +306,12 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
fileSet = new THashSet<PsiFile>();
|
||||
Set<PsiFile> copy = new THashSet<PsiFile>();
|
||||
for (int i = 0; i < words.size() - 1; i++) {
|
||||
ProgressManager.checkCanceled();
|
||||
if (progress != null) {
|
||||
progress.checkCanceled();
|
||||
}
|
||||
else {
|
||||
ProgressManager.checkCanceled();
|
||||
}
|
||||
final String word = words.get(i);
|
||||
myManager.getCacheManager().processFilesWithWord(new CommonProcessors.CollectProcessor<PsiFile>(copy), word, searchContext, scope, caseSensitively);
|
||||
if (i == 0) {
|
||||
@@ -350,7 +360,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
throw new IllegalArgumentException("Cannot search for elements with empty text");
|
||||
}
|
||||
ProgressManager progressManager = ProgressManager.getInstance();
|
||||
ProgressIndicator progress = progressManager.getProgressIndicator();
|
||||
final ProgressIndicator progress = progressManager.getProgressIndicator();
|
||||
|
||||
int dotIndex = qName.lastIndexOf('.');
|
||||
int dollarIndex = qName.lastIndexOf('$');
|
||||
@@ -376,14 +386,14 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
final Ref<Boolean> cancelled = new Ref<Boolean>(Boolean.FALSE);
|
||||
final GlobalSearchScope finalScope = searchScope;
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
progressManager.checkCanceled();
|
||||
if (progress != null) progress.checkCanceled();
|
||||
|
||||
final PsiFile psiFile = files[i];
|
||||
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
CharSequence text = psiFile.getViewProvider().getContents();
|
||||
for (int index = LowLevelSearchUtil.searchWord(text, 0, text.length(), searcher); index >= 0;) {
|
||||
for (int index = LowLevelSearchUtil.searchWord(text, 0, text.length(), searcher, progress); index >= 0;) {
|
||||
PsiReference referenceAt = psiFile.findReferenceAt(index);
|
||||
if (referenceAt == null || originalElement == null ||
|
||||
!PsiSearchScopeUtil.isInScope(getUseScope(originalElement).intersectWith(finalScope), psiFile)) {
|
||||
@@ -393,7 +403,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
}
|
||||
}
|
||||
|
||||
index = LowLevelSearchUtil.searchWord(text, index + searcher.getPattern().length(), text.length(), searcher);
|
||||
index = LowLevelSearchUtil.searchWord(text, index + searcher.getPattern().length(), text.length(), searcher, progress);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -425,7 +435,10 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
myManager.getCacheManager().processFilesWithWord(processor, word, UsageSearchContext.IN_STRINGS, scope, true);
|
||||
}
|
||||
|
||||
public SearchCostResult isCheapEnoughToSearch(@NotNull String name, @NotNull GlobalSearchScope scope, @Nullable final PsiFile fileToIgnoreOccurencesIn) {
|
||||
public SearchCostResult isCheapEnoughToSearch(@NotNull String name,
|
||||
@NotNull GlobalSearchScope scope,
|
||||
@Nullable final PsiFile fileToIgnoreOccurencesIn,
|
||||
ProgressIndicator progress) {
|
||||
final int[] count = {0};
|
||||
if (!processFilesWithText(scope, UsageSearchContext.ANY, true, name, new Processor<PsiFile>() {
|
||||
public boolean process(PsiFile file) {
|
||||
@@ -435,7 +448,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
return count[0] <= 10;
|
||||
}
|
||||
}
|
||||
})) {
|
||||
}, progress)) {
|
||||
return SearchCostResult.TOO_MANY_OCCURRENCES;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,9 @@ import com.intellij.codeInspection.ex.InspectionManagerEx;
|
||||
import com.intellij.codeInspection.ex.InspectionTool;
|
||||
import com.intellij.codeInspection.ex.ToolsImpl;
|
||||
import com.intellij.codeInspection.reference.RefManagerImpl;
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.impl.ProgressManagerImpl;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import junit.framework.Assert;
|
||||
@@ -138,7 +141,7 @@ expected:
|
||||
compareWithExpected(expectedDocument, doc, checkRange);
|
||||
}
|
||||
|
||||
public static void runTool(final InspectionTool tool, AnalysisScope scope, GlobalInspectionContextImpl globalContext, final InspectionManagerEx inspectionManager) {
|
||||
public static void runTool(final InspectionTool tool, final AnalysisScope scope, GlobalInspectionContextImpl globalContext, final InspectionManagerEx inspectionManager) {
|
||||
final String shortName = tool.getShortName();
|
||||
final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
|
||||
if (key == null){
|
||||
@@ -152,7 +155,12 @@ expected:
|
||||
((RefManagerImpl)tool.getRefManager()).findAllDeclarations();
|
||||
}
|
||||
|
||||
tool.runInspection(scope, inspectionManager);
|
||||
((ProgressManagerImpl)ProgressManager.getInstance()).executeProcessUnderProgress(new Runnable() {
|
||||
public void run() {
|
||||
tool.runInspection(scope, inspectionManager);
|
||||
}
|
||||
}, new EmptyProgressIndicator());
|
||||
|
||||
|
||||
tool.queryExternalUsagesRequests(inspectionManager);
|
||||
}
|
||||
|
||||
+2
-4
@@ -205,10 +205,8 @@ public class StaticMethodOnlyUsedInOneClassInspection
|
||||
final String name = method.getName();
|
||||
final GlobalSearchScope scope =
|
||||
GlobalSearchScope.allScope(method.getProject());
|
||||
if (searchHelper.isCheapEnoughToSearch(name, scope, null) ==
|
||||
PsiSearchHelper.SearchCostResult.TOO_MANY_OCCURRENCES) {
|
||||
return null;
|
||||
}
|
||||
if (searchHelper.isCheapEnoughToSearch(name, scope, null, progressManager.getProgressIndicator())
|
||||
== PsiSearchHelper.SearchCostResult.TOO_MANY_OCCURRENCES) return null;
|
||||
progressManager.runProcess(new Runnable() {
|
||||
public void run() {
|
||||
final Query<PsiReference> query =
|
||||
|
||||
+8
-6
@@ -21,6 +21,7 @@ import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
|
||||
import com.intellij.codeInspection.i18n.JavaI18nUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
@@ -110,12 +111,13 @@ public class DuplicateStringLiteralInspection extends BaseLocalInspectionTool {
|
||||
}
|
||||
});
|
||||
|
||||
ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
Set<PsiFile> resultFiles = null;
|
||||
for (String word : words) {
|
||||
if (word.length() < MIN_STRING_LENGTH) {
|
||||
continue;
|
||||
}
|
||||
ProgressManager.checkCanceled();
|
||||
progress.checkCanceled();
|
||||
final Set<PsiFile> files = new THashSet<PsiFile>();
|
||||
searchHelper.processAllFilesWithWordInLiterals(word, scope, new CommonProcessors.CollectProcessor<PsiFile>(files));
|
||||
if (resultFiles == null) {
|
||||
@@ -129,14 +131,14 @@ public class DuplicateStringLiteralInspection extends BaseLocalInspectionTool {
|
||||
if (resultFiles == null || resultFiles.isEmpty()) return;
|
||||
final List<PsiExpression> foundExpr = new ArrayList<PsiExpression>();
|
||||
for (PsiFile file : resultFiles) {
|
||||
ProgressManager.checkCanceled();
|
||||
progress.checkCanceled();
|
||||
CharSequence text = file.getViewProvider().getContents();
|
||||
StringSearcher searcher = new StringSearcher(stringToFind, true, true);
|
||||
for (int offset = LowLevelSearchUtil.searchWord(text, 0, text.length(), searcher);
|
||||
for (int offset = LowLevelSearchUtil.searchWord(text, 0, text.length(), searcher, progress);
|
||||
offset >= 0;
|
||||
offset = LowLevelSearchUtil.searchWord(text, offset + searcher.getPattern().length(), text.length(), searcher)
|
||||
offset = LowLevelSearchUtil.searchWord(text, offset + searcher.getPattern().length(), text.length(), searcher, progress)
|
||||
) {
|
||||
ProgressManager.checkCanceled();
|
||||
progress.checkCanceled();
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
if (element == null || !(element.getParent() instanceof PsiLiteralExpression)) continue;
|
||||
PsiLiteralExpression expression = (PsiLiteralExpression)element.getParent();
|
||||
@@ -148,7 +150,7 @@ public class DuplicateStringLiteralInspection extends BaseLocalInspectionTool {
|
||||
if (foundExpr.isEmpty()) return;
|
||||
Set<PsiClass> classes = new THashSet<PsiClass>();
|
||||
for (PsiElement aClass : foundExpr) {
|
||||
ProgressManager.checkCanceled();
|
||||
progress.checkCanceled();
|
||||
do {
|
||||
aClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class);
|
||||
}
|
||||
|
||||
+2
-2
@@ -246,9 +246,9 @@ public class DuplicatePropertyInspection extends DescriptorProviderInspection {
|
||||
Set<PsiFile> psiFilesWithDuplicates = valueToFiles.get(value);
|
||||
for (PsiFile file : psiFilesWithDuplicates) {
|
||||
CharSequence text = file.getViewProvider().getContents();
|
||||
for (int offset = LowLevelSearchUtil.searchWord(text, 0, text.length(), searcher);
|
||||
for (int offset = LowLevelSearchUtil.searchWord(text, 0, text.length(), searcher, progress);
|
||||
offset >= 0;
|
||||
offset = LowLevelSearchUtil.searchWord(text, offset + searcher.getPattern().length(), text.length(), searcher)
|
||||
offset = LowLevelSearchUtil.searchWord(text, offset + searcher.getPattern().length(), text.length(), searcher, progress)
|
||||
) {
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
if (element != null && element.getParent() instanceof Property) {
|
||||
|
||||
@@ -70,7 +70,8 @@ public class UnusedPropertyInspection extends PropertySuppressableInspectionBase
|
||||
|
||||
String name = property.getName();
|
||||
if (name == null) return true;
|
||||
PsiSearchHelper.SearchCostResult cheapEnough = file.getManager().getSearchHelper().isCheapEnoughToSearch(name, searchScope, file);
|
||||
PsiSearchHelper.SearchCostResult cheapEnough = file.getManager().getSearchHelper().isCheapEnoughToSearch(name, searchScope, file,
|
||||
original);
|
||||
if (cheapEnough == PsiSearchHelper.SearchCostResult.TOO_MANY_OCCURRENCES) return true;
|
||||
|
||||
final PsiReference usage = cheapEnough == PsiSearchHelper.SearchCostResult.ZERO_OCCURRENCES ? null :
|
||||
|
||||
Reference in New Issue
Block a user