// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details #pragma once #include "Luau/Error.h" #include "Luau/Linter.h" #include "Luau/FileResolver.h" #include "Luau/ParseOptions.h" #include "Luau/ParseResult.h" #include "Luau/Scope.h" #include "Luau/TypeArena.h" #include "Luau/AnyTypeSummary.h" #include "Luau/DataFlowGraph.h" #include #include #include #include namespace Luau { struct Module; struct AnyTypeSummary; using ScopePtr = std::shared_ptr; using ModulePtr = std::shared_ptr; class AstType; class AstTypePack; /// Root of the AST of a parsed source file struct SourceModule { ModuleName name; // Module identifier or a filename std::string humanReadableName; SourceCode::Type type = SourceCode::None; std::optional environmentName; bool cyclic = false; std::shared_ptr allocator; std::shared_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); bool isWithinComment(const ParseResult& result, Position pos); struct RequireCycle { Location location; std::vector path; // one of the paths for a require() to go all the way back to the originating module }; struct Module { ~Module(); ModuleName name; std::string humanReadableName; TypeArena interfaceTypes; TypeArena internalTypes; // Summary of Ast Nodes that either contain // user annotated anys or typechecker inferred anys AnyTypeSummary ats{}; // Scopes and AST types refer to parse data, so we need to keep that alive std::shared_ptr allocator; std::shared_ptr names; std::vector> scopes; // never empty DenseHashMap astTypes{nullptr}; DenseHashMap astTypePacks{nullptr}; DenseHashMap astExpectedTypes{nullptr}; // For AST nodes that are function calls, this map provides the // unspecialized type of the function that was called. If a function call // resolves to a __call metamethod application, this map will point at that // metamethod. // // This is useful for type checking and Signature Help. DenseHashMap astOriginalCallTypes{nullptr}; // The specialization of a function that was selected. If the function is // generic, those generic type parameters will be replaced with the actual // types that were passed. If the function is an overload, this map will // point at the specific overloads that were selected. DenseHashMap astOverloadResolvedTypes{nullptr}; // Only used with for...in loops. The computed type of the next() function // is kept here for type checking. DenseHashMap astForInNextTypes{nullptr}; DenseHashMap astResolvedTypes{nullptr}; DenseHashMap astResolvedTypePacks{nullptr}; // The computed result type of a compound assignment. (eg foo += 1) // // Type checking uses this to check that the result of such an operation is // actually compatible with the left-side operand. DenseHashMap astCompoundAssignResultTypes{nullptr}; DenseHashMap>> upperBoundContributors{nullptr}; // Map AST nodes to the scope they create. Cannot be NotNull because // we need a sentinel value for the map. DenseHashMap astScopes{nullptr}; std::unordered_map declaredGlobals; ErrorVec errors; LintResult lintResult; Mode mode; SourceCode::Type type; double checkDurationSec = 0.0; bool timeout = false; bool cancelled = false; TypePackId returnType = nullptr; std::unordered_map exportedTypeBindings; // We also need to keep DFG data alive between runs std::shared_ptr dataFlowGraph = nullptr; std::vector> dfgScopes; bool hasModuleScope() const; ScopePtr getModuleScope() const; // Once a module has been typechecked, we clone its public interface into a // separate arena. This helps us to force Type ownership into a DAG rather // than a DCG. void clonePublicInterface(NotNull builtinTypes, InternalErrorReporter& ice); }; } // namespace Luau