public static void doActualPsiChange(@NotNull final PsiFile file, final DiffLog diffLog) {
    file.getViewProvider().beforeContentsSynchronized();

    try {
      final Document document = file.getViewProvider().getDocument();
      PsiDocumentManagerImpl documentManager =
          (PsiDocumentManagerImpl) PsiDocumentManager.getInstance(file.getProject());
      PsiToDocumentSynchronizer.DocumentChangeTransaction transaction =
          documentManager.getSynchronizer().getTransaction(document);

      final PsiFileImpl fileImpl = (PsiFileImpl) file;

      if (transaction == null) {
        final PomModel model = PomManager.getModel(fileImpl.getProject());

        model.runTransaction(
            new PomTransactionBase(fileImpl, model.getModelAspect(TreeAspect.class)) {
              @Override
              public PomModelEvent runInner() {
                return new TreeAspectEvent(model, diffLog.performActualPsiChange(file));
              }
            });
      } else {
        diffLog.performActualPsiChange(file);
      }
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }
  @Nullable
  @Override
  public Document getDocument(@NotNull PsiFile file) {
    if (file instanceof PsiBinaryFile) return null;

    Document document = getCachedDocument(file);
    if (document != null) {
      if (!file.getViewProvider().isPhysical() && document.getUserData(HARD_REF_TO_PSI) == null) {
        cachePsi(document, file);
      }
      return document;
    }

    if (!file.getViewProvider().isEventSystemEnabled()) return null;
    document =
        FileDocumentManager.getInstance().getDocument(file.getViewProvider().getVirtualFile());

    if (document != null) {
      if (document.getTextLength() != file.getTextLength()) {
        throw new AssertionError(
            "Modified PSI with no document: "
                + file
                + "; physical="
                + file.getViewProvider().isPhysical());
      }

      if (!file.getViewProvider().isPhysical()) {
        cachePsi(document, file);
      }
    }

    return document;
  }
  public boolean commitTransaction(final Document document) {
    ApplicationManager.getApplication().assertIsDispatchThread();
    final DocumentChangeTransaction documentChangeTransaction = removeTransaction(document);
    if (documentChangeTransaction == null) return false;
    final PsiFile changeScope = documentChangeTransaction.myChangeScope;
    try {
      mySyncDocument = document;

      final PsiTreeChangeEventImpl fakeEvent = new PsiTreeChangeEventImpl(changeScope.getManager());
      fakeEvent.setParent(changeScope);
      fakeEvent.setFile(changeScope);
      checkPsiModificationAllowed(fakeEvent);
      doSync(
          fakeEvent,
          true,
          new DocSyncAction() {
            @Override
            public void syncDocument(
                @NotNull Document document, @NotNull PsiTreeChangeEventImpl event) {
              doCommitTransaction(document, documentChangeTransaction);
            }
          });
      myBus
          .syncPublisher(PsiDocumentTransactionListener.TOPIC)
          .transactionCompleted(document, changeScope);
    } catch (Throwable e) {
      myPsiDocumentManager.forceReload(
          changeScope.getViewProvider().getVirtualFile(), changeScope.getViewProvider());
      ExceptionUtil.rethrowAllAsUnchecked(e);
    } finally {
      mySyncDocument = null;
    }
    return true;
  }
예제 #4
0
  @Override
  public boolean isInProject(@NotNull PsiElement element) {
    PsiFile file = element.getContainingFile();
    if (file != null
        && file.isPhysical()
        && file.getViewProvider().getVirtualFile() instanceof LightVirtualFile) return true;

    if (element instanceof PsiDirectoryContainer) {
      PsiDirectory[] dirs = ((PsiDirectoryContainer) element).getDirectories();
      for (PsiDirectory dir : dirs) {
        if (!isInProject(dir)) return false;
      }
      return true;
    }

    VirtualFile virtualFile = null;
    if (file != null) {
      virtualFile = file.getViewProvider().getVirtualFile();
    } else if (element instanceof PsiFileSystemItem) {
      virtualFile = ((PsiFileSystemItem) element).getVirtualFile();
    }

    if (virtualFile != null) {
      return myExcludedFileIndex.isInContent(virtualFile);
    }
    return false;
  }
예제 #5
0
  private boolean checkMovingInsideOutside(
      PsiFile file,
      final Editor editor,
      LineRange range,
      @NotNull final MoveInfo info,
      final boolean down) {
    final int offset = editor.getCaretModel().getOffset();

    PsiElement elementAtOffset = file.getViewProvider().findElementAt(offset, StdLanguages.JAVA);
    if (elementAtOffset == null) return false;

    PsiElement guard = elementAtOffset;
    do {
      guard =
          PsiTreeUtil.getParentOfType(
              guard, PsiMethod.class, PsiClassInitializer.class, PsiClass.class, PsiComment.class);
    } while (guard instanceof PsiAnonymousClass);

    PsiElement brace = itIsTheClosingCurlyBraceWeAreMoving(file, editor);
    if (brace != null) {
      int line = editor.getDocument().getLineNumber(offset);
      final LineRange toMove = new LineRange(line, line + 1);
      toMove.firstElement = toMove.lastElement = brace;
      info.toMove = toMove;
    }

    // cannot move in/outside method/class/initializer/comment
    if (!calcInsertOffset(file, editor, info.toMove, info, down)) return false;
    int insertOffset =
        down
            ? getLineStartSafeOffset(editor.getDocument(), info.toMove2.endLine)
            : editor.getDocument().getLineStartOffset(info.toMove2.startLine);
    PsiElement elementAtInsertOffset =
        file.getViewProvider().findElementAt(insertOffset, StdLanguages.JAVA);
    PsiElement newGuard = elementAtInsertOffset;
    do {
      newGuard =
          PsiTreeUtil.getParentOfType(
              newGuard,
              PsiMethod.class,
              PsiClassInitializer.class,
              PsiClass.class,
              PsiComment.class);
    } while (newGuard instanceof PsiAnonymousClass);

    if (brace != null
        && PsiTreeUtil.getParentOfType(brace, PsiCodeBlock.class, false)
            != PsiTreeUtil.getParentOfType(elementAtInsertOffset, PsiCodeBlock.class, false)) {
      info.indentSource = true;
    }
    if (newGuard == guard && isInside(insertOffset, newGuard) == isInside(offset, guard))
      return true;

    // moving in/out nested class is OK
    if (guard instanceof PsiClass && guard.getParent() instanceof PsiClass) return true;
    if (newGuard instanceof PsiClass && newGuard.getParent() instanceof PsiClass) return true;

    return false;
  }
  public static boolean isClassEquivalentTo(@NotNull PsiClass aClass, PsiElement another) {
    if (aClass == another) return true;
    if (!(another instanceof PsiClass)) return false;
    String name1 = aClass.getName();
    if (name1 == null) return false;
    if (!another.isValid()) return false;
    String name2 = ((PsiClass) another).getName();
    if (name2 == null) return false;
    if (name1.hashCode() != name2.hashCode()) return false;
    if (!name1.equals(name2)) return false;
    String qName1 = aClass.getQualifiedName();
    String qName2 = ((PsiClass) another).getQualifiedName();
    if (qName1 == null || qName2 == null) {
      //noinspection StringEquality
      if (qName1 != qName2) return false;

      if (aClass instanceof PsiTypeParameter && another instanceof PsiTypeParameter) {
        PsiTypeParameter p1 = (PsiTypeParameter) aClass;
        PsiTypeParameter p2 = (PsiTypeParameter) another;

        return p1.getIndex() == p2.getIndex()
            && aClass.getManager().areElementsEquivalent(p1.getOwner(), p2.getOwner());
      } else {
        return false;
      }
    }
    if (qName1.hashCode() != qName2.hashCode() || !qName1.equals(qName2)) {
      return false;
    }

    if (originalElement(aClass).equals(originalElement((PsiClass) another))) {
      return true;
    }

    final PsiFile file1 = aClass.getContainingFile().getOriginalFile();
    final PsiFile file2 = another.getContainingFile().getOriginalFile();

    // see com.intellij.openapi.vcs.changes.PsiChangeTracker
    // see com.intellij.psi.impl.PsiFileFactoryImpl#createFileFromText(CharSequence,PsiFile)
    final PsiFile original1 = file1.getUserData(PsiFileFactory.ORIGINAL_FILE);
    final PsiFile original2 = file2.getUserData(PsiFileFactory.ORIGINAL_FILE);
    if (original1 == original2 && original1 != null
        || original1 == file2
        || original2 == file1
        || file1 == file2) {
      return compareClassSeqNumber(aClass, (PsiClass) another);
    }

    final FileIndexFacade fileIndex =
        ServiceManager.getService(file1.getProject(), FileIndexFacade.class);
    final VirtualFile vfile1 = file1.getViewProvider().getVirtualFile();
    final VirtualFile vfile2 = file2.getViewProvider().getVirtualFile();
    boolean lib1 = fileIndex.isInLibraryClasses(vfile1);
    boolean lib2 = fileIndex.isInLibraryClasses(vfile2);

    return (fileIndex.isInSource(vfile1) || lib1) && (fileIndex.isInSource(vfile2) || lib2);
  }
 @Nullable
 public static String findUri(PsiFile file, int offset) {
   PsiReference currentRef = file.getViewProvider().findReferenceAt(offset, file.getLanguage());
   if (currentRef == null) currentRef = file.getViewProvider().findReferenceAt(offset);
   if (currentRef instanceof URLReference || currentRef instanceof DependentNSReference) {
     return currentRef.getCanonicalText();
   }
   return null;
 }
  private static PsiFile createFileCopy(PsiFile file, long caret, long selEnd) {
    final VirtualFile virtualFile = file.getVirtualFile();
    boolean mayCacheCopy =
        file.isPhysical()
            &&
            // we don't want to cache code fragment copies even if they appear to be physical
            virtualFile != null
            && virtualFile.isInLocalFileSystem();
    long combinedOffsets = caret + (selEnd << 32);
    if (mayCacheCopy) {
      final Trinity<PsiFile, Document, Long> cached =
          SoftReference.dereference(file.getUserData(FILE_COPY_KEY));
      if (cached != null
          && cached.first.getClass().equals(file.getClass())
          && isCopyUpToDate(cached.second, cached.first)) {
        final PsiFile copy = cached.first;
        if (copy.getViewProvider().getModificationStamp()
                > file.getViewProvider().getModificationStamp()
            && cached.third.longValue() != combinedOffsets) {
          // the copy PSI might have some caches that are not cleared on its modification because
          // there are no events in the copy
          //   so, clear all the caches
          // hopefully it's a rare situation that the user invokes completion in different parts of
          // the file
          //   without modifying anything physical in between
          ((PsiModificationTrackerImpl) file.getManager().getModificationTracker()).incCounter();
        }
        final Document document = cached.second;
        assert document != null;
        file.putUserData(
            FILE_COPY_KEY,
            new SoftReference<Trinity<PsiFile, Document, Long>>(
                Trinity.create(copy, document, combinedOffsets)));

        Document originalDocument = file.getViewProvider().getDocument();
        assert originalDocument != null;
        assert originalDocument.getTextLength() == file.getTextLength() : originalDocument;
        document.setText(originalDocument.getImmutableCharSequence());
        return copy;
      }
    }

    final PsiFile copy = (PsiFile) file.copy();
    if (mayCacheCopy) {
      final Document document = copy.getViewProvider().getDocument();
      assert document != null;
      file.putUserData(
          FILE_COPY_KEY,
          new SoftReference<Trinity<PsiFile, Document, Long>>(
              Trinity.create(copy, document, combinedOffsets)));
    }
    return copy;
  }
 public boolean isErrorAnalyzingFinished(@NotNull PsiFile file) {
   if (myDisposed) return false;
   Document document = PsiDocumentManager.getInstance(myProject).getCachedDocument(file);
   return document != null
       && document.getModificationStamp() == file.getViewProvider().getModificationStamp()
       && myFileStatusMap.getFileDirtyScope(document, Pass.UPDATE_ALL) == null;
 }
  // returns (injected psi, leaf element at the offset, language of the leaf element)
  // since findElementAt() is expensive, we trying to reuse its result
  @NotNull
  private static Trinity<PsiElement, PsiElement, Language> tryOffset(
      @NotNull PsiFile hostFile, final int offset, @NotNull PsiDocumentManager documentManager) {
    FileViewProvider provider = hostFile.getViewProvider();
    Language leafLanguage = null;
    PsiElement leafElement = null;
    for (Language language : provider.getLanguages()) {
      PsiElement element = provider.findElementAt(offset, language);
      if (element != null) {
        if (leafLanguage == null) {
          leafLanguage = language;
          leafElement = element;
        }
        PsiElement injected = findInside(element, hostFile, offset, documentManager);
        if (injected != null) return Trinity.create(injected, element, language);
      }
      // maybe we are at the border between two psi elements, then try to find injection at the end
      // of the left element
      if (offset != 0 && (element == null || element.getTextRange().getStartOffset() == offset)) {
        PsiElement leftElement = provider.findElementAt(offset - 1, language);
        if (leftElement != null && leftElement.getTextRange().getEndOffset() == offset) {
          PsiElement injected = findInside(leftElement, hostFile, offset, documentManager);
          if (injected != null) return Trinity.create(injected, element, language);
        }
      }
    }

    return Trinity.create(null, leafElement, leafLanguage);
  }
  public static void enumerate(
      @NotNull PsiElement host,
      @NotNull PsiFile containingFile,
      boolean probeUp,
      @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor) {
    // do not inject into nonphysical files except during completion
    if (!containingFile.isPhysical() && containingFile.getOriginalFile() == containingFile) {
      final PsiElement context =
          InjectedLanguageManager.getInstance(containingFile.getProject())
              .getInjectionHost(containingFile);
      if (context == null) return;

      final PsiFile file = context.getContainingFile();
      if (file == null || !file.isPhysical() && file.getOriginalFile() == file) return;
    }

    if (containingFile.getViewProvider() instanceof InjectedFileViewProvider)
      return; // no injection inside injection

    PsiElement inTree = loadTree(host, containingFile);
    if (inTree != host) {
      host = inTree;
      containingFile = host.getContainingFile();
    }

    MultiHostRegistrarImpl registrar = probeElementsUp(host, containingFile, probeUp);
    if (registrar == null) {
      return;
    }
    List<Pair<Place, PsiFile>> places = registrar.getResult();
    for (Pair<Place, PsiFile> pair : places) {
      PsiFile injectedPsi = pair.second;
      visitor.visit(injectedPsi, pair.first);
    }
  }
  @Override
  @Nullable
  protected TextRange surroundStatement(
      @NotNull Project project, @NotNull Editor editor, @NotNull PsiElement[] elements)
      throws IncorrectOperationException {
    PyTryExceptStatement tryStatement =
        PyElementGenerator.getInstance(project)
            .createFromText(LanguageLevel.getDefault(), PyTryExceptStatement.class, getTemplate());
    final PsiElement parent = elements[0].getParent();
    final PyStatementList statementList = tryStatement.getTryPart().getStatementList();
    statementList.addRange(elements[0], elements[elements.length - 1]);
    statementList.getFirstChild().delete();
    tryStatement = (PyTryExceptStatement) parent.addBefore(tryStatement, elements[0]);
    parent.deleteChildRange(elements[0], elements[elements.length - 1]);

    final PsiFile psiFile = parent.getContainingFile();
    final Document document = psiFile.getViewProvider().getDocument();
    final TextRange range = tryStatement.getTextRange();
    assert document != null;
    final RangeMarker rangeMarker = document.createRangeMarker(range);

    final PsiElement element = psiFile.findElementAt(rangeMarker.getStartOffset());
    tryStatement = PsiTreeUtil.getParentOfType(element, PyTryExceptStatement.class);
    if (tryStatement != null) {
      return getResultRange(tryStatement);
    }
    return null;
  }
  @Override
  @Nullable
  public ObjectStubTree readOrBuild(
      Project project, final VirtualFile vFile, @Nullable PsiFile psiFile) {
    final ObjectStubTree fromIndices = readFromVFile(project, vFile);
    if (fromIndices != null) {
      return fromIndices;
    }

    try {
      final FileContent fc = new FileContentImpl(vFile, vFile.contentsToByteArray());
      fc.putUserData(IndexingDataKeys.PROJECT, project);
      if (psiFile != null && !vFile.getFileType().isBinary()) {
        fc.putUserData(
            IndexingDataKeys.FILE_TEXT_CONTENT_KEY, psiFile.getViewProvider().getContents());
        // but don't reuse psiFile itself to avoid loading its contents. If we load AST, the stub
        // will be thrown out anyway.
      }
      Stub element = StubTreeBuilder.buildStubTree(fc);
      if (element instanceof PsiFileStub) {
        StubTree tree = new StubTree((PsiFileStub) element);
        tree.setDebugInfo("created from file content");
        return tree;
      }
    } catch (IOException e) {
      LOG.info(
          e); // content can be not cached yet, and the file can be deleted on disk already, without
              // refresh
    }

    return null;
  }
 private static boolean navigateInCurrentEditor(
     @NotNull PsiElement element, @NotNull PsiFile currentFile, @NotNull Editor currentEditor) {
   if (element.getContainingFile() == currentFile) {
     int offset = element.getTextOffset();
     PsiElement leaf = currentFile.findElementAt(offset);
     // check that element is really physically inside the file
     // there are fake elements with custom navigation (e.g. opening URL in browser) that override
     // getContainingFile for various reasons
     if (leaf != null && PsiTreeUtil.isAncestor(element, leaf, false)) {
       Project project = element.getProject();
       CommandProcessor.getInstance()
           .executeCommand(
               project,
               () -> {
                 IdeDocumentHistory.getInstance(project).includeCurrentCommandAsNavigation();
                 new OpenFileDescriptor(
                         project, currentFile.getViewProvider().getVirtualFile(), offset)
                     .navigateIn(currentEditor);
               },
               "",
               null);
       return true;
     }
   }
   return false;
 }
  @Nullable
  public static <E extends PsiElement> E findArgumentList(
      PsiFile file, int offset, int lbraceOffset) {
    if (file == null) return null;
    ParameterInfoHandler[] handlers =
        ShowParameterInfoHandler.getHandlers(
            file.getProject(),
            PsiUtilCore.getLanguageAtOffset(file, offset),
            file.getViewProvider().getBaseLanguage());

    if (handlers != null) {
      for (ParameterInfoHandler handler : handlers) {
        if (handler instanceof ParameterInfoHandlerWithTabActionSupport) {
          final ParameterInfoHandlerWithTabActionSupport parameterInfoHandler2 =
              (ParameterInfoHandlerWithTabActionSupport) handler;

          // please don't remove typecast in the following line; it's required to compile the code
          // under old JDK 6 versions
          final E e =
              (E)
                  ParameterInfoUtils.findArgumentList(
                      file, offset, lbraceOffset, parameterInfoHandler2);
          if (e != null) return e;
        }
      }
    }

    return null;
  }
  @Nullable
  public static Commenter getCommenter(
      final PsiFile file,
      final Editor editor,
      final Language lineStartLanguage,
      final Language lineEndLanguage) {

    final FileViewProvider viewProvider = file.getViewProvider();

    for (MultipleLangCommentProvider provider :
        MultipleLangCommentProvider.EP_NAME.getExtensions()) {
      if (provider.canProcess(file, viewProvider)) {
        return provider.getLineCommenter(file, editor, lineStartLanguage, lineEndLanguage);
      }
    }

    final Language fileLanguage = file.getLanguage();
    Language lang =
        lineStartLanguage == null
                || LanguageCommenters.INSTANCE.forLanguage(lineStartLanguage) == null
                || fileLanguage.getBaseLanguage()
                    == lineStartLanguage // file language is a more specific dialect of the line
            // language
            ? fileLanguage
            : lineStartLanguage;

    if (viewProvider instanceof TemplateLanguageFileViewProvider
        && lang == ((TemplateLanguageFileViewProvider) viewProvider).getTemplateDataLanguage()) {
      lang = viewProvider.getBaseLanguage();
    }

    return LanguageCommenters.INSTANCE.forLanguage(lang);
  }
  private void doSync(
      @NotNull final PsiTreeChangeEvent event,
      boolean force,
      @NotNull final DocSyncAction syncAction) {
    if (!toProcessPsiEvent()) return;
    final PsiFile psiFile = event.getFile();
    if (!(psiFile instanceof PsiFileEx) || !((PsiFileEx) psiFile).isContentsLoaded()) return;

    final DocumentEx document = getCachedDocument(psiFile, force);
    if (document == null) return;

    performAtomically(
        psiFile,
        new Runnable() {
          @Override
          public void run() {
            syncAction.syncDocument(document, (PsiTreeChangeEventImpl) event);
          }
        });

    final boolean insideTransaction = myTransactionsMap.containsKey(document);
    if (!insideTransaction) {
      document.setModificationStamp(psiFile.getViewProvider().getModificationStamp());
    }
  }
 public boolean isAllAnalysisFinished(@NotNull PsiFile file) {
   if (myDisposed) return false;
   Document document = PsiDocumentManager.getInstance(myProject).getCachedDocument(file);
   return document != null
       && document.getModificationStamp() == file.getViewProvider().getModificationStamp()
       && myFileStatusMap.allDirtyScopesAreNull(document);
 }
예제 #19
0
  @Nullable
  private PsiClass mapClass(@NotNull PsiClass psiClass) {
    String qualifiedName = psiClass.getQualifiedName();
    if (qualifiedName == null) {
      return psiClass;
    }

    PsiFile file = psiClass.getContainingFile();
    if (file == null || !file.getViewProvider().isPhysical()) {
      return psiClass;
    }

    final VirtualFile vFile = file.getVirtualFile();
    if (vFile == null) {
      return psiClass;
    }

    final FileIndexFacade index = FileIndexFacade.getInstance(file.getProject());
    if (!index.isInSource(vFile)
        && !index.isInLibrarySource(vFile)
        && !index.isInLibraryClasses(vFile)) {
      return psiClass;
    }

    return JavaPsiFacade.getInstance(psiClass.getProject())
        .findClass(qualifiedName, myResolveScope);
  }
 private static VirtualFile getConsoleFile(PsiFile psiFile) {
   VirtualFile file = psiFile.getViewProvider().getVirtualFile();
   if (file instanceof LightVirtualFile) {
     file = ((LightVirtualFile) file).getOriginalFile();
   }
   return file;
 }
  private static void logStats(Collection<PsiFile> otherFiles, long start) {
    long time = System.currentTimeMillis() - start;

    final Multiset<String> stats = HashMultiset.create();
    for (PsiFile file : otherFiles) {
      stats.add(
          StringUtil.notNullize(file.getViewProvider().getVirtualFile().getExtension())
              .toLowerCase());
    }

    List<String> extensions = ContainerUtil.newArrayList(stats.elementSet());
    Collections.sort(
        extensions,
        new Comparator<String>() {
          @Override
          public int compare(String o1, String o2) {
            return stats.count(o2) - stats.count(o1);
          }
        });

    String message =
        "Search in "
            + otherFiles.size()
            + " files with unknown types took "
            + time
            + "ms.\n"
            + "Mapping their extensions to an existing file type (e.g. Plain Text) might speed up the search.\n"
            + "Most frequent non-indexed file extensions: ";
    for (int i = 0; i < Math.min(10, extensions.size()); i++) {
      String extension = extensions.get(i);
      message += extension + "(" + stats.count(extension) + ") ";
    }
    LOG.info(message);
  }
예제 #22
0
  @NotNull
  private static String[] collectNamesToImport(
      @NotNull PsiJavaFile file, @NotNull Set<String> namesToImportStaticly) {
    Set<String> names = new THashSet<String>();

    final JspFile jspFile = JspPsiUtil.getJspFile(file);
    collectNamesToImport(names, file, namesToImportStaticly, jspFile);
    if (jspFile != null) {
      PsiFile[] files =
          ArrayUtil.mergeArrays(
              JspSpiUtil.getIncludingFiles(jspFile),
              JspSpiUtil.getIncludedFiles(jspFile),
              PsiFile.class);
      for (PsiFile includingFile : files) {
        final PsiFile javaRoot = includingFile.getViewProvider().getPsi(StdLanguages.JAVA);
        if (javaRoot instanceof PsiJavaFile && file != javaRoot) {
          collectNamesToImport(names, (PsiJavaFile) javaRoot, namesToImportStaticly, jspFile);
        }
      }
    }

    addUnresolvedImportNames(names, file, namesToImportStaticly);

    return ArrayUtil.toStringArray(names);
  }
 @Nullable
 private static PsiFile getRoot(final PsiFile file, final Editor editor) {
   if (file == null) return null;
   int offset = editor.getCaretModel().getOffset();
   if (offset == editor.getDocument().getTextLength()) offset--;
   if (offset < 0) return null;
   PsiElement leafElement = file.findElementAt(offset);
   if (leafElement == null) return null;
   if (leafElement.getLanguage() instanceof DependentLanguage) {
     leafElement =
         file.getViewProvider().findElementAt(offset, file.getViewProvider().getBaseLanguage());
     if (leafElement == null) return null;
   }
   ASTNode node = leafElement.getNode();
   if (node == null) return null;
   return (PsiFile) PsiUtilBase.getRoot(node).getPsi();
 }
예제 #24
0
  private JavaResolveResult advancedResolveInner(final PsiElement psiElement, final String qName) {
    final PsiManager manager = psiElement.getManager();
    final GlobalSearchScope scope = getScope();
    if (myIndex == myJavaClassReferenceSet.getReferences().length - 1) {
      final PsiClass aClass =
          JavaPsiFacade.getInstance(manager.getProject()).findClass(qName, scope);
      if (aClass != null) {
        return new ClassCandidateInfo(aClass, PsiSubstitutor.EMPTY, false, psiElement);
      } else {
        if (!JavaClassReferenceProvider.ADVANCED_RESOLVE.getBooleanValue(getOptions())) {
          return JavaResolveResult.EMPTY;
        }
      }
    }
    PsiElement resolveResult = JavaPsiFacade.getInstance(manager.getProject()).findPackage(qName);
    if (resolveResult == null) {
      resolveResult = JavaPsiFacade.getInstance(manager.getProject()).findClass(qName, scope);
    }
    if (myInStaticImport && resolveResult == null) {
      resolveResult = resolveMember(qName, manager, getElement().getResolveScope());
    }
    if (resolveResult == null) {
      PsiFile containingFile = psiElement.getContainingFile();

      if (containingFile instanceof PsiJavaFile) {
        if (containingFile instanceof JspFile) {
          containingFile = containingFile.getViewProvider().getPsi(StdLanguages.JAVA);
          if (containingFile == null) return JavaResolveResult.EMPTY;
        }

        final ClassResolverProcessor processor =
            new ClassResolverProcessor(getCanonicalText(), psiElement);
        containingFile.processDeclarations(processor, ResolveState.initial(), null, psiElement);

        if (processor.getResult().length == 1) {
          final JavaResolveResult javaResolveResult = processor.getResult()[0];

          if (javaResolveResult != JavaResolveResult.EMPTY && getOptions() != null) {
            final Boolean value =
                JavaClassReferenceProvider.RESOLVE_QUALIFIED_CLASS_NAME.getValue(getOptions());
            final PsiClass psiClass = (PsiClass) javaResolveResult.getElement();
            if (value != null && value.booleanValue() && psiClass != null) {
              final String qualifiedName = psiClass.getQualifiedName();

              if (!qName.equals(qualifiedName)) {
                return JavaResolveResult.EMPTY;
              }
            }
          }

          return javaResolveResult;
        }
      }
    }
    return resolveResult != null
        ? new CandidateInfo(resolveResult, PsiSubstitutor.EMPTY, false, false, psiElement)
        : JavaResolveResult.EMPTY;
  }
 private static boolean isCopyUpToDate(Document document, @NotNull PsiFile file) {
   if (!file.isValid()) {
     return false;
   }
   // the psi file cache might have been cleared by some external activity,
   // in which case PSI-document sync may stop working
   PsiFile current = PsiDocumentManager.getInstance(file.getProject()).getPsiFile(document);
   return current != null && current.getViewProvider().getPsi(file.getLanguage()) == file;
 }
 private static int getNewIndent(final PsiFile psiFile, final int firstWhitespace) {
   final Document document = psiFile.getViewProvider().getDocument();
   final int startOffset = document.getLineStartOffset(document.getLineNumber(firstWhitespace));
   int endOffset = startOffset;
   final CharSequence charsSequence = document.getCharsSequence();
   while (Character.isWhitespace(charsSequence.charAt(endOffset++))) ;
   final String newIndentStr = charsSequence.subSequence(startOffset, endOffset - 1).toString();
   return IndentHelperImpl.getIndent(
       psiFile.getProject(), psiFile.getFileType(), newIndentStr, true);
 }
 public static FormattingDocumentModelImpl createOn(PsiFile file) {
   Document document = getDocumentToBeUsedFor(file);
   if (document != null) {
     checkDocument(file, document);
     return new FormattingDocumentModelImpl(document, file);
   } else {
     return new FormattingDocumentModelImpl(
         new DocumentImpl(file.getViewProvider().getContents(), true), file);
   }
 }
 @NotNull
 private static FileHighlightingSetting[] getDefaults(@NotNull PsiFile file) {
   final int rootsCount = file.getViewProvider().getLanguages().size();
   final FileHighlightingSetting[] fileHighlightingSettings =
       new FileHighlightingSetting[rootsCount];
   for (int i = 0; i < fileHighlightingSettings.length; i++) {
     fileHighlightingSettings[i] = FileHighlightingSetting.FORCE_HIGHLIGHTING;
   }
   return fileHighlightingSettings;
 }
  @Nullable
  @Override
  public Document getDocument(@NotNull PsiFile file) {
    if (file instanceof PsiBinaryFile) return null;

    Document document = getCachedDocument(file);
    if (document != null) {
      if (!file.getViewProvider().isPhysical() && document.getUserData(HARD_REF_TO_PSI) == null) {
        PsiUtilCore.ensureValid(file);
        cachePsi(document, file);
      }
      return document;
    }

    FileViewProvider viewProvider = file.getViewProvider();
    if (!viewProvider.isEventSystemEnabled()) return null;

    document = FileDocumentManager.getInstance().getDocument(viewProvider.getVirtualFile());
    if (document != null) {
      if (document.getTextLength() != file.getTextLength()) {
        String message =
            "Document/PSI mismatch: "
                + file
                + " ("
                + file.getClass()
                + "); physical="
                + viewProvider.isPhysical();
        if (document.getTextLength() + file.getTextLength() < 8096) {
          message +=
              "\n=== document ===\n" + document.getText() + "\n=== PSI ===\n" + file.getText();
        }
        throw new AssertionError(message);
      }

      if (!viewProvider.isPhysical()) {
        PsiUtilCore.ensureValid(file);
        cachePsi(document, file);
        file.putUserData(HARD_REF_TO_DOCUMENT, document);
      }
    }

    return document;
  }
  public static void assertInvalidRanges(
      final int startOffset,
      final int newEndOffset,
      FormattingDocumentModel model,
      String message) {
    @NonNls final StringBuilder buffer = new StringBuilder();
    buffer.append("Invalid formatting blocks:").append(message).append("\n");
    buffer.append("Start offset:");
    buffer.append(startOffset);
    buffer.append(" end offset:");
    buffer.append(newEndOffset);
    buffer.append("\n");

    int minOffset = Math.max(Math.min(startOffset, newEndOffset) - 20, 0);
    int maxOffset = Math.min(Math.max(startOffset, newEndOffset) + 20, model.getTextLength());

    buffer
        .append("Affected text fragment:[")
        .append(minOffset)
        .append(",")
        .append(maxOffset)
        .append("] - '")
        .append(model.getText(new TextRange(minOffset, maxOffset)))
        .append("'\n");

    final StringBuilder messageBuffer = new StringBuilder();
    messageBuffer.append("Invalid ranges during formatting");
    if (model instanceof FormattingDocumentModelImpl) {
      messageBuffer
          .append(" in ")
          .append(((FormattingDocumentModelImpl) model).getFile().getLanguage());
    }

    buffer.append("File text:(").append(model.getTextLength()).append(")\n'");
    buffer.append(model.getText(new TextRange(0, model.getTextLength())).toString());
    buffer.append("'\n");
    buffer.append("model (").append(model.getClass()).append("): ").append(model);

    Throwable currentThrowable = new Throwable();
    if (model instanceof FormattingDocumentModelImpl) {
      final FormattingDocumentModelImpl modelImpl = (FormattingDocumentModelImpl) model;
      buffer.append("Psi Tree:\n");
      final PsiFile file = modelImpl.getFile();
      final List<PsiFile> roots = file.getViewProvider().getAllFiles();
      for (PsiFile root : roots) {
        buffer.append("Root ");
        DebugUtil.treeToBuffer(buffer, root.getNode(), 0, false, true, true, true);
      }
      buffer.append('\n');
      currentThrowable = makeLanguageStackTrace(currentThrowable, file);
    }

    LogMessageEx.error(LOG, messageBuffer.toString(), currentThrowable, buffer.toString());
  }