// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details #pragma once #include "Luau/FileResolver.h" #include "Luau/TypePack.h" #include "Luau/TypedAllocator.h" #include "Luau/ParseOptions.h" #include "Luau/Error.h" #include "Luau/ParseResult.h" #include #include #include #include namespace Luau { struct Module; using ScopePtr = std::shared_ptr; using ModulePtr = std::shared_ptr; /// Root of the AST of a parsed source file struct SourceModule { ModuleName name; // DataModel path if possible. Filename if not. SourceCode::Type type = SourceCode::None; std::optional environmentName; bool cyclic = false; std::unique_ptr allocator; std::unique_ptr names; std::vector parseErrors; AstStatBlock* root = nullptr; std::optional mode; std::vector hotcomments; std::vector commentLocations; SourceModule() : allocator(new Allocator) , names(new AstNameTable(*allocator)) { } }; bool isWithinComment(const SourceModule& sourceModule, Position pos); struct TypeArena { TypedAllocator typeVars; TypedAllocator typePacks; void clear(); template TypeId addType(T tv) { if constexpr (std::is_same_v) LUAU_ASSERT(tv.options.size() >= 2); return addTV(TypeVar(std::move(tv))); } TypeId addTV(TypeVar&& tv); TypeId freshType(TypeLevel level); TypePackId addTypePack(std::initializer_list types); TypePackId addTypePack(std::vector types); TypePackId addTypePack(TypePack pack); TypePackId addTypePack(TypePackVar pack); }; void freeze(TypeArena& arena); void unfreeze(TypeArena& arena); // Only exposed so they can be unit tested. using SeenTypes = std::unordered_map; using SeenTypePacks = std::unordered_map; struct CloneState { int recursionCount = 0; bool encounteredFreeType = false; }; TypePackId clone(TypePackId tp, TypeArena& dest, SeenTypes& seenTypes, SeenTypePacks& seenTypePacks, CloneState& cloneState); TypeId clone(TypeId tp, TypeArena& dest, SeenTypes& seenTypes, SeenTypePacks& seenTypePacks, CloneState& cloneState); TypeFun clone(const TypeFun& typeFun, TypeArena& dest, SeenTypes& seenTypes, SeenTypePacks& seenTypePacks, CloneState& cloneState); struct Module { ~Module(); TypeArena interfaceTypes; TypeArena internalTypes; std::vector> scopes; // never empty DenseHashMap astTypes{nullptr}; DenseHashMap astExpectedTypes{nullptr}; DenseHashMap astOriginalCallTypes{nullptr}; DenseHashMap astOverloadResolvedTypes{nullptr}; std::unordered_map declaredGlobals; ErrorVec errors; Mode mode; SourceCode::Type type; ScopePtr getModuleScope() const; // Once a module has been typechecked, we clone its public interface into a separate arena. // This helps us to force TypeVar ownership into a DAG rather than a DCG. // Returns true if there were any free types encountered in the public interface. This // indicates a bug in the type checker that we want to surface. bool clonePublicInterface(); }; } // namespace Luau