// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details #pragma once #include "Luau/Variant.h" #include "Luau/Location.h" #include "Luau/Symbol.h" #include <map> #include <memory> #include <vector> namespace Luau { struct TypeVar; using TypeId = const TypeVar*; struct Field; using LValue = Variant<Symbol, Field>; struct Field { std::shared_ptr<LValue> parent; // TODO: Eventually use unique_ptr to enforce non-copyable trait. std::string key; }; std::optional<LValue> tryGetLValue(const class AstExpr& expr); // Utility function: breaks down an LValue to get at the Symbol, and reverses the vector of keys. std::pair<Symbol, std::vector<std::string>> getFullName(const LValue& lvalue); std::string toString(const LValue& lvalue); template<typename T> const T* get(const LValue& lvalue) { return get_if<T>(&lvalue); } // Key is a stringified encoding of an LValue. using RefinementMap = std::map<std::string, TypeId>; void merge(RefinementMap& l, const RefinementMap& r, std::function<TypeId(TypeId, TypeId)> f); void addRefinement(RefinementMap& refis, const LValue& lvalue, TypeId ty); struct TruthyPredicate; struct IsAPredicate; struct TypeGuardPredicate; struct EqPredicate; struct AndPredicate; struct OrPredicate; struct NotPredicate; using Predicate = Variant<TruthyPredicate, IsAPredicate, TypeGuardPredicate, EqPredicate, AndPredicate, OrPredicate, NotPredicate>; using PredicateVec = std::vector<Predicate>; struct TruthyPredicate { LValue lvalue; Location location; }; struct IsAPredicate { LValue lvalue; Location location; TypeId ty; }; struct TypeGuardPredicate { LValue lvalue; Location location; std::string kind; // TODO: When singleton types arrive, replace this with `TypeId ty;` bool isTypeof; }; struct EqPredicate { LValue lvalue; TypeId type; Location location; }; struct AndPredicate { PredicateVec lhs; PredicateVec rhs; AndPredicate(PredicateVec&& lhs, PredicateVec&& rhs) : lhs(std::move(lhs)) , rhs(std::move(rhs)) { } }; struct OrPredicate { PredicateVec lhs; PredicateVec rhs; OrPredicate(PredicateVec&& lhs, PredicateVec&& rhs) : lhs(std::move(lhs)) , rhs(std::move(rhs)) { } }; struct NotPredicate { PredicateVec predicates; }; template<typename T> const T* get(const Predicate& predicate) { return get_if<T>(&predicate); } } // namespace Luau