예제 #1
0
  public StubTree calcStubTree() {
    FileElement fileElement = calcTreeElement();
    synchronized (myStubFromTreeLock) {
      SoftReference<StubTree> ref = fileElement.getUserData(STUB_TREE_IN_PARSED_TREE);
      StubTree tree = SoftReference.dereference(ref);

      if (tree == null) {
        ApplicationManager.getApplication().assertReadAccessAllowed();
        IElementType contentElementType = getContentElementType();
        if (!(contentElementType instanceof IStubFileElementType)) {
          VirtualFile vFile = getVirtualFile();
          String message =
              "ContentElementType: "
                  + contentElementType
                  + "; file: "
                  + this
                  + "\n\t"
                  + "Boolean.TRUE.equals(getUserData(BUILDING_STUB)) = "
                  + Boolean.TRUE.equals(getUserData(BUILDING_STUB))
                  + "\n\t"
                  + "getTreeElement() = "
                  + getTreeElement()
                  + "\n\t"
                  + "vFile instanceof VirtualFileWithId = "
                  + (vFile instanceof VirtualFileWithId)
                  + "\n\t"
                  + "StubUpdatingIndex.canHaveStub(vFile) = "
                  + StubTreeLoader.getInstance().canHaveStub(vFile);
          rebuildStub();
          throw new AssertionError(message);
        }

        StubElement currentStubTree =
            ((IStubFileElementType) contentElementType).getBuilder().buildStubTree(this);
        if (currentStubTree == null) {
          throw new AssertionError(
              "Stub tree wasn't built for " + contentElementType + "; file: " + this);
        }

        tree = new StubTree((PsiFileStub) currentStubTree);
        tree.setDebugInfo("created in calcStubTree");
        try {
          TreeUtil.bindStubsToTree(this, tree);
        } catch (TreeUtil.StubBindingException e) {
          rebuildStub();
          throw new RuntimeException("Stub and PSI element type mismatch in " + getName(), e);
        }

        fileElement.putUserData(STUB_TREE_IN_PARSED_TREE, new SoftReference<StubTree>(tree));
      }

      return tree;
    }
  }
예제 #2
0
  @Override
  @Nullable
  public StubTree getStubTree() {
    ApplicationManager.getApplication().assertReadAccessAllowed();

    if (Boolean.TRUE.equals(getUserData(BUILDING_STUB))) return null;

    final StubTree derefd = derefStub();
    if (derefd != null) return derefd;
    if (getTreeElement() != null) return null;

    if (!(getContentElementType() instanceof IStubFileElementType)) return null;

    final VirtualFile vFile = getVirtualFile();
    if (!(vFile instanceof VirtualFileWithId)) return null;

    final PsiFile stubBindingRoot = getViewProvider().getStubBindingRoot();
    if (stubBindingRoot != this) {
      LOG.error(
          "Attempted to create stubs for non-root file: "
              + this
              + ", stub binding root: "
              + stubBindingRoot);
      return null;
    }

    ObjectStubTree tree = StubTreeLoader.getInstance().readOrBuild(getProject(), vFile, this);
    if (!(tree instanceof StubTree)) return null;
    StubTree stubHolder = (StubTree) tree;

    synchronized (PsiLock.LOCK) {
      if (getTreeElement() != null) return null;

      final StubTree derefdOnLock = derefStub();
      if (derefdOnLock != null) return derefdOnLock;

      //noinspection unchecked
      ((StubBase) stubHolder.getRoot()).setPsi(this);
      myStub = new SoftReference<StubTree>(stubHolder);
      return stubHolder;
    }
  }
예제 #3
0
  private void rebuildStub() {
    final VirtualFile vFile = getVirtualFile();

    if (vFile != null && vFile.isValid()) {
      ApplicationManager.getApplication()
          .invokeLater(
              new Runnable() {
                @Override
                public void run() {
                  final Document doc = FileDocumentManager.getInstance().getCachedDocument(vFile);
                  if (doc != null) {
                    FileDocumentManager.getInstance().saveDocument(doc);
                  }
                }
              },
              ModalityState.NON_MODAL);

      StubTreeLoader.getInstance().rebuildStubTree(vFile);
    }
  }
예제 #4
0
  protected void reportStubAstMismatch(String message, StubTree stubTree, Document cachedDocument) {
    rebuildStub();
    clearStub("stub-psi mismatch");
    scheduleDropCachesWithInvalidStubPsi();

    String msg = message;
    msg += "\n file=" + this;
    msg += ", modStamp=" + getModificationStamp();
    msg += "\n stub debugInfo=" + stubTree.getDebugInfo();
    msg += "\n document before=" + cachedDocument;

    ObjectStubTree latestIndexedStub =
        StubTreeLoader.getInstance().readFromVFile(getProject(), getVirtualFile());
    msg += "\nlatestIndexedStub=" + latestIndexedStub;
    if (latestIndexedStub != null) {
      msg +=
          "\n   same size="
              + (stubTree.getPlainList().size() == latestIndexedStub.getPlainList().size());
      msg += "\n   debugInfo=" + latestIndexedStub.getDebugInfo();
    }

    FileViewProvider viewProvider = getViewProvider();
    msg += "\n viewProvider=" + viewProvider;
    msg += "\n viewProvider stamp: " + viewProvider.getModificationStamp();

    VirtualFile file = viewProvider.getVirtualFile();
    msg += "; file stamp: " + file.getModificationStamp();
    msg += "; file modCount: " + file.getModificationCount();

    Document document = FileDocumentManager.getInstance().getCachedDocument(file);
    if (document != null) {
      msg += "\n doc saved: " + !FileDocumentManager.getInstance().isDocumentUnsaved(document);
      msg += "; doc stamp: " + document.getModificationStamp();
      msg += "; doc size: " + document.getTextLength();
      msg += "; committed: " + PsiDocumentManager.getInstance(getProject()).isCommitted(document);
    }

    throw new AssertionError(msg + "\n------------\n");
  }