private static Language calcBaseLanguage(@NotNull VirtualFile file, @NotNull Project project) {
    if (file instanceof LightVirtualFile) {
      final Language language = ((LightVirtualFile) file).getLanguage();
      if (language != null) {
        return language;
      }
    }

    FileType fileType = file.getFileType();
    // Do not load content
    if (fileType == UnknownFileType.INSTANCE) {
      fileType = FileTypeRegistry.getInstance().detectFileTypeFromContent(file);
    }
    if (fileType.isBinary()) return Language.ANY;
    if (isTooLarge(file)) return PlainTextLanguage.INSTANCE;

    if (fileType instanceof LanguageFileType) {
      return LanguageSubstitutors.INSTANCE.substituteLanguage(
          ((LanguageFileType) fileType).getLanguage(), file, project);
    }

    final ContentBasedFileSubstitutor[] processors =
        Extensions.getExtensions(ContentBasedFileSubstitutor.EP_NAME);
    for (ContentBasedFileSubstitutor processor : processors) {
      Language language = processor.obtainLanguageForFile(file);
      if (language != null) return language;
    }

    return PlainTextLanguage.INSTANCE;
  }
 /** {@inheritDoc} */
 @Override
 public int compare(final FileType o1, final FileType o2) {
   if (o1 == o2) {
     return 0;
   }
   if (o1 == FileTypes.UNKNOWN) {
     return 1;
   }
   if (o2 == FileTypes.UNKNOWN) {
     return -1;
   }
   if (o1.isBinary() && !o2.isBinary()) {
     return 1;
   }
   if (!o1.isBinary() && o2.isBinary()) {
     return -1;
   }
   return o1.getName().compareToIgnoreCase(o2.getName());
 }
  @Override
  @Nullable
  public Document getDocument(@NotNull final VirtualFile file) {
    DocumentEx document = (DocumentEx) getCachedDocument(file);
    if (document == null) {
      if (file.isDirectory()
          || isBinaryWithoutDecompiler(file)
          || SingleRootFileViewProvider.isTooLargeForContentLoading(file)) {
        return null;
      }
      final CharSequence text = LoadTextUtil.loadText(file);

      synchronized (lock) {
        document = (DocumentEx) getCachedDocument(file);
        if (document != null) return document; // Double checking

        document = (DocumentEx) createDocument(text);
        document.setModificationStamp(file.getModificationStamp());
        final FileType fileType = file.getFileType();
        document.setReadOnly(!file.isWritable() || fileType.isBinary());
        file.putUserData(DOCUMENT_KEY, new WeakReference<Document>(document));
        document.putUserData(FILE_KEY, file);

        if (!(file instanceof LightVirtualFile
            || file.getFileSystem() instanceof DummyFileSystem)) {
          document.addDocumentListener(
              new DocumentAdapter() {
                @Override
                public void documentChanged(DocumentEvent e) {
                  final Document document = e.getDocument();
                  myUnsavedDocuments.add(document);
                  final Runnable currentCommand =
                      CommandProcessor.getInstance().getCurrentCommand();
                  Project project =
                      currentCommand == null
                          ? null
                          : CommandProcessor.getInstance().getCurrentCommandProject();
                  String lineSeparator = CodeStyleFacade.getInstance(project).getLineSeparator();
                  document.putUserData(LINE_SEPARATOR_KEY, lineSeparator);

                  // avoid documents piling up during batch processing
                  if (areTooManyDocumentsInTheQueue(myUnsavedDocuments)) {
                    saveAllDocumentsLater();
                  }
                }
              });
        }
      }

      myMultiCaster.fileContentLoaded(file, document);
    }

    return document;
  }
  public boolean isHighlightingAvailable(PsiFile file) {
    if (myDisabledHighlightingFiles.contains(file)) return false;

    if (file == null || !file.isPhysical()) return false;
    if (file instanceof PsiCompiledElement) return false;
    final FileType fileType = file.getFileType();
    if (fileType == StdFileTypes.GUI_DESIGNER_FORM) {
      return true;
    }
    // To enable T.O.D.O. highlighting
    return !fileType.isBinary();
  }
  @Nullable
  protected PsiFile createFile(
      @NotNull Project project, @NotNull VirtualFile file, @NotNull FileType fileType) {
    if (fileType.isBinary() || file.isSpecialFile()) {
      return new PsiBinaryFileImpl((PsiManagerImpl) getManager(), this);
    }
    if (!isTooLarge(file)) {
      final PsiFile psiFile = createFile(getBaseLanguage());
      if (psiFile != null) return psiFile;
    }

    return new PsiPlainTextFileImpl(this);
  }
  public static boolean isEnabled(VirtualFile virtualFile) {
    boolean enabled = true;
    if (virtualFile != null) {
      // FileMode mode = modeFromFile(virtualFile);
      /*if (mode != null) {
          enabled = false;
      } else*/
      if (!virtualFile.isDirectory()) {
        FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(virtualFile);
        if (StringUtil.isNotEmpty(virtualFile.getExtension()) && fileType.isBinary()) {
          enabled = false;
        }
      }
    }

    return enabled;
  }
 @NotNull
 @Override
 public CharSequence getContentAsText() {
   if (myFileType.isBinary()) {
     throw new IllegalDataException(
         "Cannot obtain text for binary file type : " + myFileType.getDescription());
   }
   final CharSequence content = getUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY);
   if (content != null) {
     return content;
   }
   if (myContentAsText == null) {
     if (myContent != null) {
       myContentAsText = LoadTextUtil.getTextByBinaryPresentation(myContent, myCharset);
       myContent = null; // help gc, indices are expected to use bytes or chars but not both
     }
   }
   return myContentAsText;
 }
  public static boolean canHaveStub(@NotNull VirtualFile file) {
    final FileType fileType = file.getFileType();
    if (fileType instanceof LanguageFileType) {
      Language l = ((LanguageFileType) fileType).getLanguage();
      ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(l);
      if (parserDefinition == null) return false;

      final IFileElementType elementType = parserDefinition.getFileNodeType();
      return elementType instanceof IStubFileElementType
          && (((IStubFileElementType) elementType).shouldBuildStubFor(file)
              || IndexingStamp.isFileIndexed(
                  file, INDEX_ID, IndexInfrastructure.getIndexCreationStamp(INDEX_ID)));
    }
    if (fileType.isBinary()) {
      final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType);
      return builder != null && builder.acceptsFile(file);
    }

    return false;
  }
 private static int getCumulativeVersion() {
   int version = VERSION;
   for (final FileType fileType : FileTypeManager.getInstance().getRegisteredFileTypes()) {
     if (fileType instanceof LanguageFileType) {
       Language l = ((LanguageFileType) fileType).getLanguage();
       ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(l);
       if (parserDefinition != null) {
         final IFileElementType type = parserDefinition.getFileNodeType();
         if (type instanceof IStubFileElementType) {
           version += ((IStubFileElementType) type).getStubVersion();
         }
       }
     } else if (fileType.isBinary()) {
       final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType);
       if (builder != null) {
         version += builder.getStubVersion();
       }
     }
   }
   return version;
 }
  private PsiFile createFile() {
    try {
      final VirtualFile vFile = getVirtualFile();
      if (vFile.isDirectory()) return null;
      if (isIgnored()) return null;

      final Project project = myManager.getProject();
      if (isPhysical()) { // check directories consistency
        final VirtualFile parent = vFile.getParent();
        if (parent == null) return null;
        final PsiDirectory psiDir = getManager().findDirectory(parent);
        if (psiDir == null) return null;
      }

      FileType fileType = vFile.getFileType();
      PsiFile file = null;
      if (fileType.isBinary() || vFile.isSpecialFile()) {
        // TODO check why ClsFileImpl doesn't created automatically with create method
        file = new ClsFileImpl((PsiManagerImpl) getManager(), this);
        // file = new PsiBinaryFileImpl((PsiManagerImpl) getManager(), this);
      } else {
        if (!isTooLarge(vFile)) {
          final PsiFile psiFile = createFile(getBaseLanguage());
          if (psiFile != null) file = psiFile;
        } else {
          file = new PsiPlainTextFileImpl(this);
        }
      }
      return file;
    } catch (ProcessCanceledException e) {
      e.printStackTrace();
      throw e;

    } catch (Throwable e) {
      e.printStackTrace();
      LOG.error(e);
      return null;
    }
  }
 public static boolean isTextType(FileType fileType) {
   return fileType != null && !fileType.isBinary();
 }
 private static boolean isBinaryWithoutDecompiler(VirtualFile file) {
   final FileType ft = file.getFileType();
   return ft.isBinary() && BinaryFileTypeDecompilers.INSTANCE.forFileType(ft) == null;
 }
Example #13
0
  @NotNull
  public static CharSequence loadText(@NotNull final VirtualFile file) {
    if (file instanceof LightVirtualFile) {
      return ((LightVirtualFile) file).getContent();
    }

    if (file.isDirectory()) {
      throw new AssertionError("'" + file.getPresentableUrl() + "' is a directory");
    }

    FileType fileType = file.getFileType();
    if (fileType.isBinary()) {
      final BinaryFileDecompiler decompiler =
          BinaryFileTypeDecompilers.INSTANCE.forFileType(fileType);
      if (decompiler != null) {
        CharSequence text;

        Application app = ApplicationManager.getApplication();
        if (app != null
            && app.isDispatchThread()
            && !app.isWriteAccessAllowed()
            && !ourDecompileProgressStarted) {
          final Ref<CharSequence> result = Ref.create(ArrayUtil.EMPTY_CHAR_SEQUENCE);
          final Ref<Throwable> error = Ref.create();

          ourDecompileProgressStarted = true;
          try {
            ProgressManager.getInstance()
                .run(
                    new Task.Modal(null, "Decompiling " + file.getName(), true) {
                      @Override
                      public void run(@NotNull ProgressIndicator indicator) {
                        indicator.setIndeterminate(true);
                        try {
                          result.set(
                              ApplicationUtil.runWithCheckCanceled(
                                  new Callable<CharSequence>() {
                                    @Override
                                    public CharSequence call() {
                                      return decompiler.decompile(file);
                                    }
                                  },
                                  indicator));
                        } catch (Throwable t) {
                          error.set(t);
                        }
                      }
                    });
          } finally {
            ourDecompileProgressStarted = false;
          }

          ExceptionUtil.rethrowUnchecked(error.get());
          text = result.get();
        } else {
          text = decompiler.decompile(file);
        }

        StringUtil.assertValidSeparators(text);
        return text;
      }

      throw new IllegalArgumentException(
          "Attempt to load text for binary file which doesn't have a decompiler plugged in: "
              + file.getPresentableUrl()
              + ". File type: "
              + fileType.getName());
    }

    try {
      byte[] bytes = file.contentsToByteArray();
      return getTextByBinaryPresentation(bytes, file);
    } catch (IOException e) {
      return ArrayUtil.EMPTY_CHAR_SEQUENCE;
    }
  }
  @NotNull
  protected DaemonCodeAnalyzerStatus getDaemonCodeAnalyzerStatus(
      @NotNull SeverityRegistrar severityRegistrar) {
    DaemonCodeAnalyzerStatus status = new DaemonCodeAnalyzerStatus();
    if (myFile == null) {
      status.reasonWhyDisabled = "No file";
      status.errorAnalyzingFinished = true;
      return status;
    }
    if (myProject != null && myProject.isDisposed()) {
      status.reasonWhyDisabled = "Project is disposed";
      status.errorAnalyzingFinished = true;
      return status;
    }
    if (!myDaemonCodeAnalyzer.isHighlightingAvailable(myFile)) {
      if (!myFile.isPhysical()) {
        status.reasonWhyDisabled = "File is generated";
        status.errorAnalyzingFinished = true;
        return status;
      } else if (myFile instanceof PsiCompiledElement) {
        status.reasonWhyDisabled = "File is decompiled";
        status.errorAnalyzingFinished = true;
        return status;
      }
      final FileType fileType = myFile.getFileType();
      if (fileType.isBinary()) {
        status.reasonWhyDisabled = "File is binary";
        status.errorAnalyzingFinished = true;
        return status;
      }
      status.reasonWhyDisabled = "Highlighting is disabled for this file";
      status.errorAnalyzingFinished = true;
      return status;
    }

    FileViewProvider provider = myFile.getViewProvider();
    Set<Language> languages = provider.getLanguages();
    HighlightingSettingsPerFile levelSettings = HighlightingSettingsPerFile.getInstance(myProject);
    boolean shouldHighlight = languages.isEmpty();
    for (Language language : languages) {
      PsiFile root = provider.getPsi(language);
      FileHighlightingSetting level = levelSettings.getHighlightingSettingForRoot(root);
      shouldHighlight |= level != FileHighlightingSetting.SKIP_HIGHLIGHTING;
    }
    if (!shouldHighlight) {
      status.reasonWhyDisabled = "Highlighting level is None";
      status.errorAnalyzingFinished = true;
      return status;
    }

    if (HeavyProcessLatch.INSTANCE.isRunning()) {
      status.reasonWhySuspended =
          StringUtil.defaultIfEmpty(
              HeavyProcessLatch.INSTANCE.getRunningOperationName(), "Heavy operation is running");
      status.errorAnalyzingFinished = true;
      return status;
    }

    status.errorCount = errorCount.clone();
    fillDaemonCodeAnalyzerErrorsStatus(status, severityRegistrar);
    List<TextEditorHighlightingPass> passes =
        myDaemonCodeAnalyzer.getPassesToShowProgressFor(myDocument);
    status.passStati =
        passes.isEmpty()
            ? Collections.<ProgressableTextEditorHighlightingPass>emptyList()
            : new ArrayList<>(passes.size());
    //noinspection ForLoopReplaceableByForEach
    for (int i = 0; i < passes.size(); i++) {
      TextEditorHighlightingPass tepass = passes.get(i);
      if (!(tepass instanceof ProgressableTextEditorHighlightingPass)) continue;
      ProgressableTextEditorHighlightingPass pass = (ProgressableTextEditorHighlightingPass) tepass;

      if (pass.getProgress() < 0) continue;
      status.passStati.add(pass);
    }
    status.errorAnalyzingFinished = myDaemonCodeAnalyzer.isAllAnalysisFinished(myFile);
    status.reasonWhySuspended =
        myDaemonCodeAnalyzer.isUpdateByTimerEnabled() ? null : "Highlighting is paused temporarily";

    return status;
  }
  @Nullable
  public static Icon getIcon(VirtualFile file, int flags, @Nullable Project project) {
    if (file.isDirectory()) return DIRECTORY;

    FileType type = file.getFileType();
    String typeString = type.getName().toLowerCase();
    String extension = file.getExtension();

    if (extension != null) extension = extension.toLowerCase();
    else extension = "";

    switch (typeString) {
      case "objectivec":
        {
          switch (extension) {
            case "h":
            case "hpp":
            case "pch":
              return HEADER;
            case "cpp":
              return CPPFILE;
            case "c":
              return CFILE;
            case "mm":
            case "m":
              return MFILE;
          }

          return CFILE;
        }
      case "c#":
        return CSHARP;
      case "c++":
        return CPPFILE;

      case "json":
        if (file.getName().equalsIgnoreCase("package.json")) return NPM;
        if (file.getName().equalsIgnoreCase("bower.json")) return BOWER;

        return JSON;
      case "xml":
      case "plist":
        return XML;

      case "html":
      case "xhtml":
        return HTML;
      case "css":
        return CSS;
      case "yaml":
        return YAML;
      case "jade":
        return JADE;

      case "javascript":
      case "ecmascript 6":
        if (file.getName().equalsIgnoreCase("gruntfile.js")) return GRUNT;
        if (file.getName().equalsIgnoreCase("gulpfile.js")) return GULP;

        return JAVASCRIPT;
      case "coffeescript":
      case "literal coffeescript":
        return COFFEE;
      case "ruby":
      case "podfile":
        return RUBY;
      case "python":
        return PYTHON;
      case "php":
        return PHP;
      case "haskell":
        return HASKELL;
      case "java":
        return JAVA;

      case "images":
        return IMAGE;
      case "sql":
        return SQL;

      case "cmakelists.txt":
        return null; // Use the default CMake icon

      case "strings":
        return TEXT;

      case "git file":
        return GIT;

      case "npm file":
        return NPM;

      case "markdown":
        return MARKDOWN;

      case "bash":
        return SHELL;

      case "plain_text":
        {
          Icon icon = getIconForExtension(extension);
          if (icon != null) return icon;

          return TEXT;
        }

      case "unknown":
        Icon icon = getIconForExtension(extension);
        if (icon != null) return icon;

      default:
        return type.isBinary() ? BINARY : ANY;
    }
  }
  /**
   * Invokes {@link com.intellij.openapi.diff.DiffManager#getDiffTool()} to show difference between
   * the given revisions of the given file.
   *
   * @param project project under vcs control.
   * @param filePath file which revisions are compared.
   * @param revision1 first revision - 'before', to the left.
   * @param revision2 second revision - 'after', to the right.
   * @throws com.intellij.openapi.vcs.VcsException
   * @throws java.io.IOException
   */
  public static void showDiff(
      @NotNull final Project project,
      @NotNull FilePath filePath,
      @NotNull VcsFileRevision revision1,
      @NotNull VcsFileRevision revision2,
      @NotNull String title1,
      @NotNull String title2)
      throws VcsException, IOException {
    final byte[] content1 = loadRevisionContent(revision1);
    final byte[] content2 = loadRevisionContent(revision2);

    final SimpleDiffRequest diffData = new SimpleDiffRequest(project, filePath.getPresentableUrl());
    diffData.addHint(DiffTool.HINT_SHOW_FRAME);
    final Document doc = filePath.getDocument();
    final Charset charset = filePath.getCharset();
    final FileType fileType = filePath.getFileType();
    diffData.setContentTitles(title1, title2);
    final Ref<VirtualFile> f1 = new Ref<VirtualFile>(null);
    final Ref<VirtualFile> f2 = new Ref<VirtualFile>(null);

    if (fileType.isBinary()) {
      final File file1 =
          FileUtil.createTempFile(revision1.getRevisionNumber().asString(), filePath.getName());
      final File file2 =
          FileUtil.createTempFile(revision2.getRevisionNumber().asString(), filePath.getName());
      try {
        final FileOutputStream fos1 = new FileOutputStream(file1);
        fos1.write(content1);
        final FileOutputStream fos2 = new FileOutputStream(file2);
        fos2.write(content2);
        fos1.close();
        fos2.close();
        f1.set(LocalFileSystem.getInstance().findFileByIoFile(file1));
        f2.set(LocalFileSystem.getInstance().findFileByIoFile(file2));
      } catch (Exception e) { //
      }
    }
    if (f1.isNull() || f2.isNull()) {
      diffData.setContents(
          createContent(project, content1, revision1, doc, charset, fileType, filePath.getPath()),
          createContent(project, content2, revision2, doc, charset, fileType, filePath.getPath()));
    } else {
      diffData.setContents(
          createFileContent(project, f1.get(), revision1),
          createFileContent(project, f2.get(), revision2));
    }
    WaitForProgressToShow.runOrInvokeLaterAboveProgress(
        new Runnable() {
          public void run() {
            DiffManager.getInstance().getDiffTool().show(diffData);
            if (!f1.isNull() || !f2.isNull()) {
              Disposer.register(
                  project,
                  new Disposable() {
                    @Override
                    public void dispose() {
                      ApplicationManager.getApplication()
                          .runWriteAction(
                              new Runnable() {
                                public void run() {
                                  try {
                                    if (!f1.isNull()) {
                                      f1.get().delete(this);
                                    }
                                    if (!f2.isNull()) {
                                      f2.get().delete(this);
                                    }
                                  } catch (IOException e) { //
                                  }
                                }
                              });
                    }
                  });
            }
          }
        },
        null,
        project);
  }