#pragma once
#include "Luau/TypeCheckLimits.h"
#include <memory>
#include <optional>
#include <string>
#include <vector>
namespace Luau
{
class AstExpr;
using ModuleName = std::string;
struct SourceCode
{
enum Type
{
None,
Module,
Script,
};
std::string source;
Type type;
};
struct ModuleInfo
{
ModuleName name;
bool optional = false;
};
struct RequireAlias
{
explicit RequireAlias(std::string alias)
: alias(std::move(alias))
{
}
explicit RequireAlias(std::string alias, std::vector<std::string> tags)
: alias(std::move(alias))
, tags(std::move(tags))
{
}
std::string alias;
std::vector<std::string> tags = {};
};
struct RequireNode
{
virtual ~RequireNode() {}
virtual std::string getPathComponent() const = 0;
virtual std::string getLabel() const
{
return getPathComponent();
}
virtual std::vector<std::string> getTags() const
{
return {};
}
virtual std::unique_ptr<RequireNode> resolvePathToNode(const std::string& path) const = 0;
virtual std::vector<std::unique_ptr<RequireNode>> getChildren() const = 0;
virtual std::vector<RequireAlias> getAvailableAliases() const = 0;
};
struct RequireSuggestion
{
std::string label;
std::string fullPath;
std::vector<std::string> tags;
};
using RequireSuggestions = std::vector<RequireSuggestion>;
struct RequireSuggester
{
virtual ~RequireSuggester() {}
std::optional<RequireSuggestions> getRequireSuggestions(const ModuleName& requirer, const std::optional<std::string>& pathString) const;
protected:
virtual std::unique_ptr<RequireNode> getNode(const ModuleName& name) const = 0;
private:
std::optional<RequireSuggestions> getRequireSuggestionsImpl(const ModuleName& requirer, const std::optional<std::string>& path) const;
};
struct FileResolver
{
FileResolver() = default;
FileResolver(std::shared_ptr<RequireSuggester> requireSuggester)
: requireSuggester(std::move(requireSuggester))
{
}
virtual ~FileResolver() {}
virtual std::optional<SourceCode> readSource(const ModuleName& name) = 0;
virtual std::optional<ModuleInfo> resolveModule(const ModuleInfo* context, AstExpr* expr, const TypeCheckLimits& limits)
{
return std::nullopt;
}
virtual std::string getHumanReadableModuleName(const ModuleName& name) const
{
return name;
}
virtual std::optional<std::string> getEnvironmentForModule(const ModuleName& name) const
{
return std::nullopt;
}
std::optional<RequireSuggestions> getRequireSuggestions(const ModuleName& requirer, const std::optional<std::string>& pathString) const;
std::shared_ptr<RequireSuggester> requireSuggester;
};
struct NullFileResolver : FileResolver
{
std::optional<SourceCode> readSource(const ModuleName& name) override
{
return std::nullopt;
}
};
}