Exemplo n.º 1
0
  private List<Pair<StubBasedPsiElementBase, CompositeElement>> calcStubAstBindings(
      final ASTNode root, final Document cachedDocument) {
    final StubTree stubTree = derefStub();
    if (stubTree == null) {
      return Collections.emptyList();
    }

    final Iterator<StubElement<?>> stubs = stubTree.getPlainList().iterator();
    stubs.next(); // Skip file stub;
    final List<Pair<StubBasedPsiElementBase, CompositeElement>> result =
        ContainerUtil.newArrayList();
    final StubBuilder builder = ((IStubFileElementType) getContentElementType()).getBuilder();

    LazyParseableElement.setSuppressEagerPsiCreation(true);
    try {
      ((TreeElement) root)
          .acceptTree(
              new RecursiveTreeElementWalkingVisitor() {
                @Override
                protected void visitNode(TreeElement node) {
                  CompositeElement parent = node.getTreeParent();
                  if (parent != null
                      && builder.skipChildProcessingWhenBuildingStubs(parent, node)) {
                    return;
                  }

                  IElementType type = node.getElementType();
                  if (type instanceof IStubElementType
                      && ((IStubElementType) type).shouldCreateStub(node)) {
                    if (!stubs.hasNext()) {
                      reportStubAstMismatch(
                          "Stub list is less than AST, last AST element: "
                              + node.getElementType()
                              + " "
                              + node,
                          stubTree,
                          cachedDocument);
                    }

                    final StubElement stub = stubs.next();
                    if (stub.getStubType() != node.getElementType()) {
                      reportStubAstMismatch(
                          "Stub and PSI element type mismatch in "
                              + getName()
                              + ": stub "
                              + stub
                              + ", AST "
                              + node.getElementType()
                              + "; "
                              + node,
                          stubTree,
                          cachedDocument);
                    }

                    PsiElement psi = stub.getPsi();
                    assert psi != null
                        : "Stub " + stub + " (" + stub.getClass() + ") has returned null PSI";
                    result.add(Pair.create((StubBasedPsiElementBase) psi, (CompositeElement) node));
                  }

                  super.visitNode(node);
                }
              });
    } finally {
      LazyParseableElement.setSuppressEagerPsiCreation(false);
    }
    if (stubs.hasNext()) {
      reportStubAstMismatch(
          "Stub list in " + getName() + " has more elements than PSI", stubTree, cachedDocument);
    }
    return result;
  }