コード例 #1
0
  @Nullable
  public static PsiElement restoreFromStubIndex(
      PsiFileWithStubSupport fileImpl,
      int index,
      @NotNull IStubElementType elementType,
      boolean throwIfNull) {
    if (fileImpl == null) {
      if (throwIfNull) throw new AssertionError("Null file");
      return null;
    }
    StubTree tree = fileImpl.getStubTree();

    boolean foreign = tree == null;
    if (foreign) {
      if (fileImpl instanceof PsiFileImpl) {
        // Note: as far as this is a realization of StubIndexReference
        // fileImpl#getContentElementType() must be instance of IStubFileElementType
        tree = ((PsiFileImpl) fileImpl).calcStubTree();
      } else {
        if (throwIfNull) throw new AssertionError("Not PsiFileImpl: " + fileImpl.getClass());
        return null;
      }
    }

    List<StubElement<?>> list = tree.getPlainList();
    if (index >= list.size()) {
      if (throwIfNull) throw new AssertionError("Too large index: " + index + ">=" + list.size());
      return null;
    }
    StubElement stub = list.get(index);

    if (stub.getStubType() != elementType) {
      if (throwIfNull)
        throw new AssertionError(
            "Element type mismatch: " + stub.getStubType() + "!=" + elementType);
      return null;
    }

    if (foreign) {
      final PsiElement cachedPsi = ((StubBase) stub).getCachedPsi();
      if (cachedPsi != null) return cachedPsi;

      final ASTNode ast = fileImpl.findTreeForStub(tree, stub);
      if (ast != null) {
        return ast.getPsi();
      }

      if (throwIfNull) throw new AssertionError("No AST for stub");
      return null;
    }
    return stub.getPsi();
  }