@Override
  public void visitNode(AstNode astNode) {
    if (skipFile) {
      return;
    }

    logDebug("***** Node: " + astNode);

    switch ((CxxGrammarImpl) astNode.getType()) {
      case classSpecifier:
        visitClassSpecifier(astNode);
        break;
      case memberDeclaration:
        visitMemberDeclaration(astNode);
        break;
      case functionDefinition:
        visitFunctionDefinition(astNode);
        break;
      case enumSpecifier:
        visitEnumSpecifier(astNode);
        break;
      case initDeclaratorList:
        visitDeclaratorList(astNode);
        break;
      case aliasDeclaration:
        visitAliasDeclaration(astNode);
        break;
      default:
        // should not happen
        LOG.error("Visiting unknown node: {}", astNode.getType());
        break;
    }
  }
  @Test
  public void should_skip_nodes() {
    char[] input = "foo".toCharArray();

    MutableParsingRule ruleMatcher1 = mockRuleMatcher("rule1");
    when(ruleMatcher1.hasToBeSkippedFromAst(Mockito.any(AstNode.class))).thenReturn(true);
    MutableParsingRule ruleMatcher2 = mockRuleMatcher("rule2");
    AstNodeType realAstNodeType = mock(AstNodeType.class);
    when(ruleMatcher2.getRealAstNodeType()).thenReturn(realAstNodeType);

    ParseNode node = new ParseNode(0, 3, Collections.<ParseNode>emptyList(), ruleMatcher1);
    ParseNode parseTreeRoot = new ParseNode(0, 3, ImmutableList.of(node), ruleMatcher2);

    InputBuffer inputBuffer = new ImmutableInputBuffer(input);
    ParsingResult parsingResult = new ParsingResult(inputBuffer, true, parseTreeRoot, null);

    AstNode astNode = AstCreator.create(parsingResult, new LocatedText(null, input));
    System.out.println(AstXmlPrinter.print(astNode));

    assertThat(astNode.getType()).isSameAs(realAstNodeType);
    assertThat(astNode.getName()).isEqualTo("rule2");
    assertThat(astNode.getFromIndex()).isEqualTo(0);
    assertThat(astNode.getToIndex()).isEqualTo(3);
    assertThat(astNode.hasChildren()).isFalse();
    assertThat(astNode.getToken()).isNull();
  }
  @Test
  public void test_children_when_one_child() {
    AstNodeType type1 = mock(AstNodeType.class);
    AstNodeType type2 = mock(AstNodeType.class);
    AstNode child = mock(AstNode.class);
    when(node.getNumberOfChildren()).thenReturn(1);

    when(node.getFirstChild()).thenReturn(child);
    AstSelect children = select.children();
    assertThat((Object) children).isInstanceOf(SingleAstSelect.class);
    assertThat(children).containsOnly(child);

    when(node.getChildren()).thenReturn(ImmutableList.of(child));

    children = select.children(type1);
    assertThat((Object) children).isSameAs(AstSelectFactory.empty());

    when(child.getType()).thenReturn(type1);
    children = select.children(type1);
    assertThat((Object) children).isInstanceOf(SingleAstSelect.class);
    assertThat(children).containsOnly(child);

    children = select.children(type1, type2);
    assertThat((Object) children).isSameAs(AstSelectFactory.empty());

    when(child.is(type1, type2)).thenReturn(true);
    children = select.children(type1, type2);
    assertThat((Object) children).isInstanceOf(SingleAstSelect.class);
    assertThat(children).containsOnly(child);
  }
  private static boolean isPublicApiMember(AstNode node) {
    AstNode access = node;

    // retrieve the accessSpecifier
    do {
      access = access.getPreviousAstNode();
    } while (access != null && access.getType() != CxxGrammarImpl.accessSpecifier);

    if (access != null) {
      return access.getToken().getType() == CxxKeyword.PUBLIC
          || access.getToken().getType() == CxxKeyword.PROTECTED;
    } else {
      AstNode classSpecifier = node.getFirstAncestor(CxxGrammarImpl.classSpecifier);

      if (classSpecifier != null) {

        AstNode enclosingSpecifierNode =
            classSpecifier.getFirstDescendant(CxxKeyword.STRUCT, CxxKeyword.CLASS, CxxKeyword.ENUM);

        if (enclosingSpecifierNode != null) {
          switch ((CxxKeyword) enclosingSpecifierNode.getToken().getType()) {
            case STRUCT:
              // struct members have public access, thus access level
              // is the access level of the enclosing classSpecifier
              return isPublicApiMember(classSpecifier);
            case CLASS:
              // default access in classes is private
              return false;
            default:
              LOG.error(
                  "isPublicApiMember unhandled case: {} at {}",
                  enclosingSpecifierNode.getType(),
                  enclosingSpecifierNode.getTokenLine());
              return false;
          }
        } else {
          LOG.error(
              "isPublicApiMember: failed to get enclosing classSpecifier for node at {}",
              node.getTokenLine());
          return false;
        }
      }

      // global member
      return true;
    }
  }
  @Test
  public void test_filter_by_type() {
    AstNodeType type = mock(AstNodeType.class);
    assertThat((Object) select.filter(type)).isSameAs(AstSelectFactory.empty());

    when(node.getType()).thenReturn(type);
    assertThat((Object) select.filter(type)).isSameAs(select);
  }
  /**
   * Find documentation node, associated documentation, identifier of a <em>public</em> member
   * declarator and visit it as a public API.
   *
   * @param node the <em>public</em> member declarator to visit
   */
  private void visitMemberDeclarator(AstNode node) {

    AstNode container =
        node.getFirstAncestor(CxxGrammarImpl.templateDeclaration, CxxGrammarImpl.classSpecifier);

    if (isOverriddenMethod(node)) {
      // assume that ancestor method is documented
      // and do not count as public API
      return;
    }

    AstNode docNode;

    if (container == null || container.getType() == CxxGrammarImpl.classSpecifier) {
      docNode = node;
    } else {
      docNode = container;
    }

    // look for block documentation
    List<Token> comments = getBlockDocumentation(docNode);

    // documentation may be inlined
    if (comments.isEmpty()) {
      comments = getDeclaratorInlineComment(node);
    }

    // find the identifier to present to concrete visitors
    String id = null;
    AstNode idNode = null;

    // first look for an operator function id
    idNode = node.getFirstDescendant(CxxGrammarImpl.operatorFunctionId);

    if (idNode != null) {
      id = getOperatorId(idNode);
    } else {
      // look for a declarator id
      idNode = node.getFirstDescendant(CxxGrammarImpl.declaratorId);

      if (idNode != null) {
        id = idNode.getTokenValue();
      } else {
        // look for an identifier (e.g in bitfield declaration)
        idNode = node.getFirstDescendant(GenericTokenType.IDENTIFIER);

        if (idNode != null) {
          id = idNode.getTokenValue();
        } else {
          LOG.error("Unsupported declarator at {}", node.getTokenLine());
        }
      }
    }

    if (idNode != null && id != null) {
      visitPublicApi(idNode, id, comments);
    }
  }
  @Test
  public void test_firstAncestor_by_type() {
    AstNodeType type = mock(AstNodeType.class);
    assertThat((Object) select.firstAncestor(type)).isSameAs(AstSelectFactory.empty());

    AstNode parent = mock(AstNode.class);
    when(node.getParent()).thenReturn(parent);
    AstNode ancestor = mock(AstNode.class);
    when(ancestor.getType()).thenReturn(type);
    when(parent.getParent()).thenReturn(ancestor);
    assertThat((Object) select.firstAncestor(type)).isInstanceOf(SingleAstSelect.class);
    assertThat(select.firstAncestor(type)).containsOnly(ancestor);
  }
  /** This test demonstrates how to use {@link ParserAdapter} to parse and construct AST. */
  @Test
  public void ast() {
    ParserAdapter<LexerlessGrammar> parser =
        new ParserAdapter<LexerlessGrammar>(Charsets.UTF_8, b.build());
    AstNode rootNode = parser.parse("2 + var");
    assertThat(rootNode.getType()).isSameAs(ExpressionGrammar.EXPRESSION);

    AstNode astNode = rootNode;
    assertThat(astNode.getNumberOfChildren()).isEqualTo(1);
    assertThat(astNode.getChild(0).getType()).isSameAs(ExpressionGrammar.ADDITIVE_EXPRESSION);

    astNode = rootNode.getChild(0);
    assertThat(astNode.getNumberOfChildren()).isEqualTo(3);
    assertThat(astNode.getChild(0).getType()).isSameAs(ExpressionGrammar.NUMBER);
    assertThat(astNode.getChild(1).getType()).isSameAs(ExpressionGrammar.PLUS);
    assertThat(astNode.getChild(2).getType()).isSameAs(ExpressionGrammar.VARIABLE);
  }
  @Test
  public void should_create_tokens_and_trivias() {
    char[] input = "foo bar".toCharArray();

    TokenExpression tokenMatcher = mockTokenMatcher(GenericTokenType.IDENTIFIER);
    TokenExpression triviaMatcher = mockTokenMatcher(GenericTokenType.COMMENT);
    MutableParsingRule ruleMatcher = mockRuleMatcher("rule");
    AstNodeType realAstNodeType = mock(AstNodeType.class);
    when(ruleMatcher.getRealAstNodeType()).thenReturn(realAstNodeType);

    ParseNode triviaNode = new ParseNode(0, 4, Collections.<ParseNode>emptyList(), triviaMatcher);
    ParseNode tokenNode = new ParseNode(4, 7, Collections.<ParseNode>emptyList(), tokenMatcher);
    ParseNode parseTreeRoot =
        new ParseNode(0, 7, ImmutableList.of(triviaNode, tokenNode), ruleMatcher);

    InputBuffer inputBuffer = new ImmutableInputBuffer(input);
    ParsingResult parsingResult = new ParsingResult(inputBuffer, true, parseTreeRoot, null);

    AstNode astNode = AstCreator.create(parsingResult, new LocatedText(null, input));
    System.out.println(AstXmlPrinter.print(astNode));

    assertThat(astNode.getType()).isSameAs(realAstNodeType);
    assertThat(astNode.getName()).isEqualTo("rule");
    assertThat(astNode.getFromIndex()).isEqualTo(0);
    assertThat(astNode.getToIndex()).isEqualTo(7);
    assertThat(astNode.hasChildren()).isTrue();

    assertThat(astNode.getTokens()).hasSize(1);
    Token token = astNode.getTokens().get(0);
    assertThat(astNode.getToken()).isSameAs(token);
    assertThat(token.getValue()).isEqualTo("bar");
    assertThat(token.getOriginalValue()).isEqualTo("bar");
    assertThat(token.getLine()).isEqualTo(1);
    assertThat(token.getColumn()).isEqualTo(4);
    assertThat(token.getType()).isEqualTo(GenericTokenType.IDENTIFIER);

    assertThat(token.getTrivia()).hasSize(1);
    Trivia trivia = token.getTrivia().get(0);
    Token triviaToken = trivia.getToken();
    assertThat(triviaToken.getValue()).isEqualTo("foo ");
    assertThat(triviaToken.getOriginalValue()).isEqualTo("foo ");
    assertThat(triviaToken.getLine()).isEqualTo(1);
    assertThat(triviaToken.getColumn()).isEqualTo(0);
    assertThat(triviaToken.getType()).isEqualTo(GenericTokenType.COMMENT);
  }
Exemple #10
0
  @Test
  public void should_create_tokens_without_TokenMatcher() {
    char[] input = "foobar".toCharArray();

    ParseNode firstTerminal = new ParseNode(0, 3, Collections.<ParseNode>emptyList(), null);
    ParseNode secondTerminal = new ParseNode(3, 6, Collections.<ParseNode>emptyList(), null);
    MutableParsingRule ruleMatcher = mockRuleMatcher("rule");
    AstNodeType realAstNodeType = mock(AstNodeType.class);
    when(ruleMatcher.getRealAstNodeType()).thenReturn(realAstNodeType);
    ParseNode parseTreeRoot =
        new ParseNode(0, 6, ImmutableList.of(firstTerminal, secondTerminal), ruleMatcher);

    InputBuffer inputBuffer = new ImmutableInputBuffer(input);
    ParsingResult parsingResult = new ParsingResult(inputBuffer, true, parseTreeRoot, null);

    AstNode astNode = AstCreator.create(parsingResult, new LocatedText(null, input));
    System.out.println(AstXmlPrinter.print(astNode));

    assertThat(astNode.getType()).isSameAs(realAstNodeType);
    assertThat(astNode.getName()).isEqualTo("rule");
    assertThat(astNode.getFromIndex()).isEqualTo(0);
    assertThat(astNode.getToIndex()).isEqualTo(6);
    assertThat(astNode.hasChildren()).isTrue();

    assertThat(astNode.getTokens()).hasSize(2);
    Token token = astNode.getTokens().get(0);
    assertThat(astNode.getToken()).isSameAs(token);
    assertThat(token.getValue()).isEqualTo("foo");
    assertThat(token.getOriginalValue()).isEqualTo("foo");
    assertThat(token.getLine()).isEqualTo(1);
    assertThat(token.getColumn()).isEqualTo(0);
    assertThat(token.getType()).isSameAs(AstCreator.UNDEFINED_TOKEN_TYPE);
    assertThat(token.getType().getName()).isEqualTo("TOKEN");

    token = astNode.getTokens().get(1);
    assertThat(token.getValue()).isEqualTo("bar");
    assertThat(token.getOriginalValue()).isEqualTo("bar");
    assertThat(token.getLine()).isEqualTo(1);
    assertThat(token.getColumn()).isEqualTo(3);
    assertThat(token.getType()).isSameAs(AstCreator.UNDEFINED_TOKEN_TYPE);
  }
 @Override
 public boolean apply(AstNode node) {
   return !node.getType().equals(PythonGrammar.PASS_STMT);
 }