Initial implementation

This commit is contained in:
HawDevelopment 2022-07-05 12:13:27 +02:00
parent 48aa7a5162
commit 67afc373c9
4 changed files with 59 additions and 0 deletions

View file

@ -33,6 +33,7 @@ struct Config
bool typeErrors = true;
std::vector<std::string> globals;
std::vector<std::string> globalTypePaths;
};
struct ConfigResolver

View file

@ -4,6 +4,8 @@
#include "Luau/Lexer.h"
#include "Luau/StringUtils.h"
#include <filesystem>
namespace
{
@ -107,6 +109,15 @@ Error parseLintRuleString(LintOptions& enabledLints, LintOptions& fatalLints, co
return std::nullopt;
}
Error parseFilePath(std::vector<std::string>& paths, const std::string& value) {
// The exists check could be invalid, since we use the frontend file resolver to read the contents.
if (value.empty() || !std::filesystem::exists(value))
return Error{"Unkown file path: " + value};
paths.push_back(value);
return std::nullopt;
}
static void next(Lexer& lexer)
{
lexer.next();
@ -260,6 +271,8 @@ Error parseConfig(const std::string& contents, Config& config, bool compat)
config.globals.push_back(value);
return std::nullopt;
}
else if (keys.size() == 1 && keys[0] == "globalTypePaths")
return parseFilePath(config.globalTypePaths, value);
else if (compat && keys.size() == 2 && keys[0] == "language" && keys[1] == "mode")
return parseModeString(config.mode, value, compat);
else

View file

@ -642,6 +642,19 @@ ScopePtr Frontend::getModuleEnvironment(const SourceModule& module, const Config
result->bindings[name].typeId = typeChecker.anyType;
}
}
if (!config.globalTypePaths.empty())
{
result = std::make_shared<Scope>(result);
for (const std::string& path : config.globalTypePaths)
{
auto source = fileResolver->readSource(path);
if (!source)
continue;
loadDefinitionFile(typeChecker, typeChecker.globalScope, source->source, path);
}
}
return result;
}

View file

@ -8,6 +8,7 @@
#include "doctest.h"
#include <iostream>
#include <fstream>
using namespace Luau;
@ -134,6 +135,37 @@ TEST_CASE("extra_globals")
CHECK(config.globals[1] == "__DEV__");
}
TEST_CASE("global_type_paths")
{
// This could be done with a temp file!
std::ofstream file("./globalTypePathsTest.lua");
file.close();
Config config;
auto err = parseConfig(R"(
{"globalTypePaths": ["./globalTypePathsTest.lua"]}
)",
config);
std::remove("./globalTypePathsTest.lua");
REQUIRE(!err);
CHECK(config.globalTypePaths.size() == 1);
CHECK(config.globalTypePaths[0] == "./globalTypePathsTest.lua");
}
TEST_CASE("global_type_paths_unable_to_find_file") {
Config config;
auto err = parseConfig(R"(
{"globalTypePaths": ["./THIS_FILE_SHOULD_NOT_EXIST.lua"]}
)",
config);
REQUIRE(err);
CHECK(err.value() == "Unkown file path: ./THIS_FILE_SHOULD_NOT_EXIST.lua");
}
TEST_CASE("lint_rules_compat")
{
Config config;