luau/tests/AstVisitor.test.cpp

118 lines
2.6 KiB
C++

// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
#include "Fixture.h"
#include "Luau/Ast.h"
#include "doctest.h"
using namespace Luau;
namespace
{
class AstVisitorTracking : public AstVisitor
{
private:
std::vector<AstNode*> visitedNodes;
std::set<size_t> seen;
public:
bool visit(AstNode* n) override
{
visitedNodes.push_back(n);
return true;
}
AstNode* operator[](size_t index)
{
REQUIRE(index < visitedNodes.size());
seen.insert(index);
return visitedNodes[index];
}
~AstVisitorTracking()
{
std::string s = "Seen " + std::to_string(seen.size()) + " nodes but got " + std::to_string(visitedNodes.size());
CHECK_MESSAGE(seen.size() == visitedNodes.size(), s);
}
};
class AstTypeVisitorTrackingWiths : public AstVisitorTracking
{
public:
using AstVisitorTracking::visit;
bool visit(AstType* n) override
{
return visit((AstNode*)n);
}
};
} // namespace
TEST_SUITE_BEGIN("AstVisitorTest");
TEST_CASE_FIXTURE(Fixture, "TypeAnnotationsAreNotVisited")
{
AstStatBlock* block = parse(R"(
local a: A<number>
)");
AstVisitorTracking v;
block->visit(&v);
CHECK(v[0]->is<AstStatBlock>());
CHECK(v[1]->is<AstStatLocal>());
// We should not have v[2] that points to the annotation
// We should not have v[3] that points to the type argument 'number' in A.
}
TEST_CASE_FIXTURE(Fixture, "LocalTwoBindings")
{
AstStatBlock* block = parse(R"(
local a, b
)");
AstVisitorTracking v;
block->visit(&v);
CHECK(v[0]->is<AstStatBlock>());
CHECK(v[1]->is<AstStatLocal>());
}
TEST_CASE_FIXTURE(Fixture, "LocalTwoAnnotatedBindings")
{
AstStatBlock* block = parse(R"(
local a: A, b: B<number>
)");
AstTypeVisitorTrackingWiths v;
block->visit(&v);
CHECK(v[0]->is<AstStatBlock>());
CHECK(v[1]->is<AstStatLocal>());
CHECK(v[2]->is<AstTypeReference>());
CHECK(v[3]->is<AstTypeReference>());
CHECK(v[4]->is<AstTypeReference>());
}
TEST_CASE_FIXTURE(Fixture, "LocalTwoAnnotatedBindingsWithTwoValues")
{
AstStatBlock* block = parse(R"(
local a: A, b: B<number> = 1, 2
)");
AstTypeVisitorTrackingWiths v;
block->visit(&v);
CHECK(v[0]->is<AstStatBlock>());
CHECK(v[1]->is<AstStatLocal>());
CHECK(v[2]->is<AstTypeReference>());
CHECK(v[3]->is<AstTypeReference>());
CHECK(v[4]->is<AstTypeReference>());
CHECK(v[5]->is<AstExprConstantNumber>());
CHECK(v[6]->is<AstExprConstantNumber>());
}
TEST_SUITE_END();