// 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 visitedNodes; std::set 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 )"); AstVisitorTracking v; block->visit(&v); CHECK(v[0]->is()); CHECK(v[1]->is()); // 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()); CHECK(v[1]->is()); } TEST_CASE_FIXTURE(Fixture, "LocalTwoAnnotatedBindings") { AstStatBlock* block = parse(R"( local a: A, b: B )"); AstTypeVisitorTrackingWiths v; block->visit(&v); CHECK(v[0]->is()); CHECK(v[1]->is()); CHECK(v[2]->is()); CHECK(v[3]->is()); CHECK(v[4]->is()); } TEST_CASE_FIXTURE(Fixture, "LocalTwoAnnotatedBindingsWithTwoValues") { AstStatBlock* block = parse(R"( local a: A, b: B = 1, 2 )"); AstTypeVisitorTrackingWiths v; block->visit(&v); CHECK(v[0]->is()); CHECK(v[1]->is()); CHECK(v[2]->is()); CHECK(v[3]->is()); CHECK(v[4]->is()); CHECK(v[5]->is()); CHECK(v[6]->is()); } TEST_SUITE_END();