import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.problems.WolfTheProblemSolver;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.util.CachedValue;
-import com.intellij.psi.util.CachedValueProvider;
-import com.intellij.psi.util.CachedValuesManager;
-import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Alarm;
import com.intellij.util.Consumer;
+import com.intellij.util.PsiErrorElementUtil;
import com.intellij.util.messages.MessageBusConnection;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
public class DelayedDocumentWatcher {
- private static final Key<CachedValue<Boolean>> CONTAINS_ERROR_ELEMENT = Key.create("CONTAINS_ERROR_ELEMENT");
-
// All instance fields are be accessed from EDT
private final Project myProject;
private final Alarm myAlarm;
@Override
public Boolean compute() {
for (VirtualFile file : files) {
- if (hasErrors(file)) {
+ if (PsiErrorElementUtil.hasErrors(myProject, file)) {
return true;
}
}
}
});
}
-
- // This method is called in a background thread with a read lock acquired
- private boolean hasErrors(@NotNull VirtualFile file) {
- if (!file.isValid()) {
- return false;
- }
- // don't use 'WolfTheProblemSolver.hasSyntaxErrors(file)' if possible
- Document document = FileDocumentManager.getInstance().getDocument(file);
- if (document != null) {
- final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
- if (psiFile != null) {
- CachedValuesManager cachedValuesManager = CachedValuesManager.getManager(myProject);
- return cachedValuesManager.getCachedValue(
- psiFile,
- CONTAINS_ERROR_ELEMENT,
- new CachedValueProvider<Boolean>() {
- @Override
- public Result<Boolean> compute() {
- boolean error = PsiTreeUtil.hasErrorElements(psiFile);
- return Result.create(error, psiFile);
- }
- },
- false
- );
- }
- }
- return WolfTheProblemSolver.getInstance(myProject).hasSyntaxErrors(file);
- }
}
--- /dev/null
+/*
+ * Copyright 2000-2015 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.
+ */
+package com.intellij.util;
+
+import com.intellij.codeInsight.highlighting.HighlightErrorFilter;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiErrorElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.impl.PsiManagerEx;
+import com.intellij.psi.util.CachedValue;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import org.jetbrains.annotations.NotNull;
+
+public class PsiErrorElementUtil {
+
+ private static final Key<CachedValue<Boolean>> CONTAINS_ERROR_ELEMENT = Key.create("CONTAINS_ERROR_ELEMENT");
+
+ private PsiErrorElementUtil() {}
+
+ public static boolean hasErrors(@NotNull final Project project, @NotNull final VirtualFile virtualFile) {
+ if (project.isDisposed() || !virtualFile.isValid()) {
+ return false;
+ }
+ return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ PsiManagerEx psiManager = (PsiManagerEx)PsiManager.getInstance(project);
+ PsiFile psiFile = psiManager.getFileManager().findFile(virtualFile);
+ return psiFile != null && hasErrors(psiFile);
+ }
+ });
+ }
+
+ private static boolean hasErrors(@NotNull final PsiFile psiFile) {
+ CachedValuesManager cachedValuesManager = CachedValuesManager.getManager(psiFile.getProject());
+ return cachedValuesManager.getCachedValue(
+ psiFile,
+ CONTAINS_ERROR_ELEMENT,
+ new CachedValueProvider<Boolean>() {
+ @Override
+ public Result<Boolean> compute() {
+ boolean error = hasErrorElements(psiFile);
+ return Result.create(error, psiFile);
+ }
+ },
+ false
+ );
+ }
+
+ private static boolean hasErrorElements(@NotNull final PsiElement element) {
+ if (element instanceof PsiErrorElement) {
+ HighlightErrorFilter[] errorFilters = Extensions.getExtensions(HighlightErrorFilter.EP_NAME, element.getProject());
+ for (HighlightErrorFilter errorFilter : errorFilters) {
+ if (!errorFilter.shouldHighlightErrorElement((PsiErrorElement)element)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ for (PsiElement child : element.getChildren()) {
+ if (hasErrorElements(child)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}