angular: avoid refreshing VFS from Filter.applyFilter
authorSergey Simonchik <sergey.simonchik@jetbrains.com>
Mon, 10 Oct 2016 21:33:11 +0000 (00:33 +0300)
committerSergey Simonchik <sergey.simonchik@jetbrains.com>
Mon, 10 Oct 2016 21:33:11 +0000 (00:33 +0300)
platform/lang-impl/src/com/intellij/execution/filters/AbstractFileHyperlinkFilter.java

index c9259860584c42a82f23bf62d31eda548a50ef87..7fb76c1add98effdc87208cacf9b3e5f992da445 100644 (file)
 package com.intellij.execution.filters;
 
 import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.application.WriteAction;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.io.LocalFileFinder;
 
+import java.io.File;
 import java.util.List;
 
 public abstract class AbstractFileHyperlinkFilter implements Filter {
@@ -54,6 +58,10 @@ public abstract class AbstractFileHyperlinkFilter implements Filter {
     });
   }
 
+  protected boolean supportVfsRefresh() {
+    return false;
+  }
+
   @Nullable
   @Override
   public final Result applyFilter(String line, int entireLength) {
@@ -68,13 +76,21 @@ public abstract class AbstractFileHyperlinkFilter implements Filter {
     List<Filter.ResultItem> items = ContainerUtil.newArrayList();
     for (FileHyperlinkRawData link : links) {
       String filePath = FileUtil.toSystemIndependentName(link.getFilePath());
-      VirtualFile file = StringUtil.isEmptyOrSpaces(filePath) ? null : findFile(filePath);
+      if (StringUtil.isEmptyOrSpaces(filePath)) continue;
+      VirtualFile file = findFile(filePath);
+      HyperlinkInfo info = null;
+      boolean grayedHyperLink = false;
       if (file != null) {
-        OpenFileHyperlinkInfo info = new OpenFileHyperlinkInfo(myProject,
-                                                               file,
-                                                               link.getDocumentLine(),
-                                                               link.getDocumentColumn());
-        boolean grayedHyperLink = isGrayedHyperlink(file);
+        info = new OpenFileHyperlinkInfo(myProject, file, link.getDocumentLine(), link.getDocumentColumn());
+        grayedHyperLink = isGrayedHyperlink(file);
+      }
+      else if (supportVfsRefresh()) {
+         File ioFile = findIoFile(filePath);
+        if (ioFile != null) {
+          info = new MyFileHyperlinkInfo(ioFile, link.getDocumentLine(), link.getDocumentColumn());
+        }
+      }
+      if (info != null) {
         int offset = entireLength - line.length();
         items.add(new Filter.ResultItem(offset + link.getHyperlinkStartInd(),
                                         offset + link.getHyperlinkEndInd(),
@@ -85,6 +101,16 @@ public abstract class AbstractFileHyperlinkFilter implements Filter {
     return items.isEmpty() ? null : new Result(items);
   }
 
+  @Nullable
+  private File findIoFile(@NotNull String filePath) {
+    File ioFile = new File(filePath);
+    if (ioFile.isAbsolute() && ioFile.isFile()) {
+      return ioFile;
+    }
+    ioFile = new File(myBaseDir.getPath(), filePath);
+    return ioFile.isFile() ? ioFile : null;
+  }
+
   private boolean isGrayedHyperlink(@NotNull VirtualFile file) {
     return !myFileIndex.isInContent(file) || myFileIndex.isInLibrary(file);
   }
@@ -100,4 +126,32 @@ public abstract class AbstractFileHyperlinkFilter implements Filter {
     }
     return file;
   }
+
+  private static class MyFileHyperlinkInfo implements HyperlinkInfo {
+
+    private final File myIoFile;
+    private final int myDocumentLine;
+    private final int myDocumentColumn;
+    private Ref<VirtualFile> myFileRef;
+
+    public MyFileHyperlinkInfo(@NotNull File ioFile, int documentLine, int documentColumn) {
+      myIoFile = ioFile;
+      myDocumentLine = documentLine;
+      myDocumentColumn = documentColumn;
+    }
+
+    @Override
+    public void navigate(Project project) {
+      Ref<VirtualFile> fileRef = myFileRef;
+      if (fileRef == null) {
+        VirtualFile file = WriteAction.compute(() -> VfsUtil.findFileByIoFile(myIoFile, true));
+        fileRef = Ref.create(file);
+        myFileRef = fileRef;
+      }
+      if (fileRef.get() != null) {
+        OpenFileHyperlinkInfo linkInfo = new OpenFileHyperlinkInfo(project, fileRef.get(), myDocumentLine, myDocumentColumn);
+        linkInfo.navigate(project);
+      }
+    }
+  }
 }