mirror of
https://github.com/luau-lang/luau.git
synced 2024-11-15 22:35:43 +08:00
118 lines
2.6 KiB
C++
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();
|