utility method calculating whether a file has errors
authorSergey Simonchik <sergey.simonchik@jetbrains.com>
Fri, 11 Sep 2015 15:37:08 +0000 (18:37 +0300)
committerSergey Simonchik <sergey.simonchik@jetbrains.com>
Fri, 11 Sep 2015 15:37:08 +0000 (18:37 +0300)
platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java
platform/platform-impl/src/com/intellij/util/PsiErrorElementUtil.java [new file with mode: 0644]

index 34deaec02d04889c432255356ed2ac2ca95f6f36..1a573cd5b663ac2e79b503a73e1589d58c92f1a6 100644 (file)
@@ -29,17 +29,10 @@ import com.intellij.openapi.project.Project;
 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;
@@ -50,8 +43,6 @@ import java.util.Set;
 
 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;
@@ -184,7 +175,7 @@ public class DelayedDocumentWatcher {
           @Override
           public Boolean compute() {
             for (VirtualFile file : files) {
-              if (hasErrors(file)) {
+              if (PsiErrorElementUtil.hasErrors(myProject, file)) {
                 return true;
               }
             }
@@ -200,32 +191,4 @@ public class DelayedDocumentWatcher {
       }
     });
   }
-
-  // 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);
-  }
 }
diff --git a/platform/platform-impl/src/com/intellij/util/PsiErrorElementUtil.java b/platform/platform-impl/src/com/intellij/util/PsiErrorElementUtil.java
new file mode 100644 (file)
index 0000000..d78df6a
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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;
+  }
+}