TEST_F(DefaultStatementLocatorTest, should_return_an_empty_range_when_no_statement_touches_the_selection)
{
    parseSourceAndCreateLocatorForSelection("void f() {\n  int a;\nint b;}", { rowCol(0, 1), rowCol(0, 3) });
    expectGetRangeForStmtAndReturn(0, { rowCol(1, 2), rowCol(1, 8) });
    expectGetRangeForStmtAndReturn(1, { rowCol(2, 0), rowCol(2, 6) });
    auto stmts = locator->findStatementsInFunction(*function->getDecl());
    ASSERT_TRUE(stmts.empty());
}
TEST_F(findStatementsInFunctionOverlappingSelectionTest, should_return_an_empty_range_for_an_empty_function)
{
    LocationRange selection{rowCol(1, 1), rowCol(1, 1)};
    parseFunctionWithStmts(" ");

    auto stmts = findStatementsInFunctionOverlappingSelection(
        *parsedFunctionDecl, selection, [&](clang::SourceManager& sm, clang::Stmt& s) { return getStmtRange(sm, s); });
    ASSERT_TRUE(stmts.empty());
}
TEST(SourceLocationOperatorsTest, should_equal_iff_all_fields_equal)
{
    ASSERT_TRUE(rowCol(10, 15) == rowCol(10, 15));
    ASSERT_FALSE(rowCol(10, 15) == rowCol(7, 15));
    ASSERT_FALSE(rowCol(10, 15) == rowCol(10, 6));
    ASSERT_FALSE(rowCol(10, 15) == rowCol(2, 3));
}
TEST_F(getFunctionFromAstInSelectionTest, should_get_the_function_containing_given_selection)
{
    parse("void f()\n{\n  /*here*/\n}\n");
    ASSERT_NO_THROW(assertFunctionContainsSelection("f", rowCol(2, 0), rowCol(2, 8)));
    ASSERT_NO_THROW(assertFunctionContainsSelection("f", rowCol(2, 2), rowCol(2, 2)));
    ASSERT_NO_THROW(assertFunctionContainsSelection("f", rowCol(1, 0), rowCol(1, 1)));
    ASSERT_NO_THROW(assertFunctionContainsSelection("f", rowCol(3, 0), rowCol(3, 1)));
}
TEST_F(findStatementsInFunctionOverlappingSelectionTest, should_return_statements_overlapping_the_selection)
{
    LocationRange selection{ rowCol(2, 0), rowCol(3, 4)};
    parseFunctionWithStmts("\n  int x;\n  int y;\n  int z;\n  int w;\n");
    const auto INT_X = 0, INT_Y = 1, INT_Z = 2, INT_W = 3;
    expectGetRangeForStmtNoAndReturn(INT_X, { rowCol(1, 2), rowCol(1, 8) });
    expectGetRangeForStmtNoAndReturn(INT_Y, { rowCol(2, 2), rowCol(2, 8) });
    expectGetRangeForStmtNoAndReturn(INT_Z, { rowCol(3, 2), rowCol(3, 8) });
    expectGetRangeForStmtNoAndReturn(INT_W, { rowCol(4, 2), rowCol(4, 8) });

    auto stmts = findStatementsInFunctionOverlappingSelection(
        *parsedFunctionDecl, selection, [&](clang::SourceManager& sm, clang::Stmt& s) { return getStmtRange(sm, s); });

    expectRangeIs(stmts, { stmtNo(INT_Y), stmtNo(INT_Z) });
}
TEST_F(DefaultStatementLocatorTest, should_return_the_statements_touching_the_selection)
{
    parseSourceAndCreateLocatorForSelection("void f() {\n  int x;\n  int y;\n  int z;\n  int w;\n}\n", { rowCol(2, 0), rowCol(3, 4) });
    expectGetRangeForStmtAndReturn(0, { rowCol(1, 2), rowCol(1, 8) });
    expectGetRangeForStmtAndReturn(1, { rowCol(2, 2), rowCol(2, 8) });
    expectGetRangeForStmtAndReturn(2, { rowCol(3, 2), rowCol(3, 8) });
    expectGetRangeForStmtAndReturn(3, { rowCol(4, 2), rowCol(4, 8) });
    auto stmts = locator->findStatementsInFunction(*function->getDecl());
    ASSERT_EQ(2u, std::distance(begin(stmts), end(stmts)));
    ASSERT_TRUE(*stmts == nthStmt(1));
    ASSERT_TRUE(*boost::next(stmts) == nthStmt(2));
}
TEST_F(findStatementsInFunctionOverlappingSelectionTest, should_return_an_empty_range_when_no_statement_overlaps_the_selection)
{
    LocationRange selection{ rowCol(0, 1), rowCol(0, 3) };
    parseFunctionWithStmts("\n  int a;\nint b;");
    const auto INT_A = 0, INT_B = 1;
    expectGetRangeForStmtNoAndReturn(INT_A, { rowCol(1, 2), rowCol(1, 8) });
    expectGetRangeForStmtNoAndReturn(INT_B, { rowCol(2, 0), rowCol(2, 6) });

    auto stmts = findStatementsInFunctionOverlappingSelection(
        *parsedFunctionDecl, selection, [&](clang::SourceManager& sm, clang::Stmt& s) { return getStmtRange(sm, s); });

    ASSERT_TRUE(stmts.empty());
}
TEST_F(DefaultStatementLocatorTest, should_return_the_nested_statement_from_a_try_block)
{
    parseSourceAndCreateLocatorForSelection(
        "void f() {\ntry { int a; } catch(...) { } }", { rowCol(1, 6), rowCol(1, 13) });
    expectGetRangeForStmtAndReturn(0, { rowCol(1, 0), rowCol(1, 15) });

    auto& sourceManager = function->getDecl()->getASTContext().getSourceManager();
    auto intDecl = *clang::dyn_cast<clang::CXXTryStmt>(nthStmt(0))->getTryBlock()->body_begin();
    EXPECT_CALL(*this, getStmtRange(Ref(sourceManager), Ref(*intDecl)))
        .WillRepeatedly(Return(LocationRange(rowCol(1, 6), rowCol(1, 13))));

    auto stmts = locator->findStatementsInFunction(*function->getDecl());
    ASSERT_EQ(1u, std::distance(begin(stmts), end(stmts)));
    ASSERT_TRUE(*stmts == intDecl);
}
示例#9
0
int
main(int argc, char **argv)
{
    
    FILE *fp;
    tty_mode(0);
    rowCol();
    if (argc == 1){
        do_more(stdin);
    }else{
        set_cr_noecho_mode();
        while(--argc){
	    if ((fp = fopen(*++argv,"r")) != NULL){
	        do_more(fp);
		fclose(fp);
	    }else{
	        exit(1);
	    }//if
	}//while
    }
    tty_mode(1);
    return 0;
}
TEST_F(DefaultStatementLocatorTest, should_return_the_most_nested_statement)
{
    parseSourceAndCreateLocatorForSelection(
        "void f() {\ntry {\nif (true) { int a; } else { int b; }\n} catch(...) { } }", { rowCol(2, 12), rowCol(2, 18) });
    expectGetRangeForStmtAndReturn(0, { rowCol(1, 0), rowCol(3, 16) }); // try

    auto& sourceManager = function->getDecl()->getASTContext().getSourceManager();
    auto ifStmt = *clang::dyn_cast<clang::CXXTryStmt>(nthStmt(0))->getTryBlock()->body_begin();
    EXPECT_CALL(*this, getStmtRange(Ref(sourceManager), Ref(*ifStmt)))
        .WillRepeatedly(Return(LocationRange(rowCol(2, 0), rowCol(2, 37))));

    auto intDecl = *clang::dyn_cast<clang::IfStmt>(ifStmt)->getThen()->child_begin();
    EXPECT_CALL(*this, getStmtRange(Ref(sourceManager), Ref(*intDecl)))
        .WillRepeatedly(Return(LocationRange(rowCol(2, 12), rowCol(2, 18))));

    auto stmts = locator->findStatementsInFunction(*function->getDecl());
    ASSERT_EQ(1u, std::distance(begin(stmts), end(stmts)));
    ASSERT_TRUE(*stmts == intDecl);
}
TEST_F(getFunctionFromAstInSelectionTest, should_ignore_functions_without_bodies)
{
    parse("void f(); void g(); void h() { \n }"); // \n is needed because of clang bug
    ASSERT_NO_THROW(assertFunctionContainsSelection("h", rowCol(0, 30), rowCol(0, 30)));
}
TEST_F(getFunctionFromAstInSelectionTest, should_search_through_all_the_functions)
{
    parse("void f()\n{\n \n}\nvoid g()\n{\n /*here*/ \n}\nvoid h()\n{\n \n}\n");
    ASSERT_NO_THROW(assertFunctionContainsSelection("g", rowCol(6, 1), rowCol(6, 14)));
}
TEST_F(getFunctionFromAstInSelectionTest, should_fail_when_the_selection_is_not_overlapping_the_body)
{
    parse("void f()\n{\n /*...*/\n}\n");
    assertFailsForSelection(rowCol(0, 1), rowCol(0, 9));
    assertFailsForSelection(rowCol(3, 1), rowCol(4, 0));
}
TEST(SourceLocationOperatorsTest, should_order_by_row_then_by_column)
{
    ASSERT_TRUE(rowCol(5, 8) < rowCol(6, 8));
    ASSERT_FALSE(rowCol(6, 8) < rowCol(6, 8));
    ASSERT_FALSE(rowCol(7, 8) < rowCol(7, 8));

    ASSERT_TRUE(rowCol(1, 3) < rowCol(1, 4));
    ASSERT_FALSE(rowCol(1, 3) < rowCol(1, 3));
    ASSERT_FALSE(rowCol(1, 3) < rowCol(1, 2));

    ASSERT_TRUE(rowCol(1, 2) < rowCol(2, 1));
    ASSERT_FALSE(rowCol(2, 1) < rowCol(1, 2));
}
 void expectStmtRangeIs(LocationRange range, const std::string& phrase)
 {
     auto phraseOffset = parsedSource.find(phrase);
     ASSERT_EQ(LocationRange(rowCol(0, phraseOffset), rowCol(0, phraseOffset + phrase.length())), range)
         << (*func->stmts())->getStmtClassName();
 }
TEST_F(DefaultStatementLocatorTest, should_return_an_empty_range_for_an_empty_function)
{
    parseSourceAndCreateLocatorForSelection("void f() {\n \n}\n", { rowCol(1, 1), rowCol(1, 1) });
    auto stmts = locator->findStatementsInFunction(*function->getDecl());
    ASSERT_TRUE(stmts.empty());
}
TEST_F(getStmtLocationRangeTest, should_handle_multiline_statements)
{
    auto range = getRangeFromSource("void dummy_function__() {\n  int\n x;\n}");
    ASSERT_EQ(LocationRange(rowCol(1, 2), rowCol(2, 3)), range);
}