mirror of
https://github.com/luau-lang/luau.git
synced 2025-05-04 10:33:46 +01:00
luau-analyze: add --definitions=<file> option for loading type definition files
Add the ability to load a type definition file before type checking. This is useful in projects that'd like to declare their own types (such as types declared by their game engine's Luau integration code) and linting their scripts using 'luau-analyze'. This is modeled to behave similar to the luau-lsp.types.definitionFiles in the Luau LSP project (https://github.com/JohnnyMorganz/luau-lsp). Usage example: luau-analyze --definitions=engine_types.d.luau some_script.luau Note: doesn't introduce new clang-format delta, but the edited file already deviates from what clang-format produces. for #1140
This commit is contained in:
parent
e76802f2ce
commit
36f82fff3c
1 changed files with 62 additions and 0 deletions
|
@ -20,6 +20,7 @@
|
|||
#include <valgrind/callgrind.h>
|
||||
#endif
|
||||
|
||||
|
||||
LUAU_FASTFLAG(DebugLuauTimeTracing)
|
||||
|
||||
enum class ReportFormat
|
||||
|
@ -124,6 +125,7 @@ static void displayHelp(const char* argv0)
|
|||
printf(" --formatter=gnu: report analysis errors in GNU-compatible format\n");
|
||||
printf(" --mode=strict: default to strict mode when typechecking\n");
|
||||
printf(" --timetrace: record compiler time tracing information into trace.json\n");
|
||||
printf(" --definitions=<file>: load type definition file (specify multiple times for many files)\n");
|
||||
}
|
||||
|
||||
static int assertionHandler(const char* expr, const char* file, int line, const char* function)
|
||||
|
@ -290,6 +292,57 @@ private:
|
|||
std::queue<std::function<void()>> tasks;
|
||||
};
|
||||
|
||||
struct DefinitionsResolver
|
||||
{
|
||||
bool success = true;
|
||||
std::vector<std::pair<std::string, std::string>> loadErrors;
|
||||
std::vector<std::pair<std::string, Luau::ParseError>> parseErrors;
|
||||
std::vector<std::pair<std::string, Luau::TypeError>> typeErrors;
|
||||
|
||||
static DefinitionsResolver loadAndRegister(Luau::Frontend& frontend, const std::vector<std::string>& definitionsFiles)
|
||||
{
|
||||
DefinitionsResolver loadResult;
|
||||
|
||||
for (const auto& defFile : definitionsFiles)
|
||||
{
|
||||
auto contents = readFile(defFile);
|
||||
if (contents == std::nullopt)
|
||||
{
|
||||
loadResult.success = false;
|
||||
loadResult.loadErrors.push_back({defFile, "definition file not found"});
|
||||
}
|
||||
else
|
||||
{
|
||||
auto res = frontend.loadDefinitionFile(frontend.globals, frontend.globals.globalScope, contents.value(), "@user",
|
||||
/* captureComments = */ false, /*typeCheckForAutocomplete*/ false);
|
||||
if (!res.success)
|
||||
{
|
||||
loadResult.success = false;
|
||||
for (auto& error : res.parseResult.errors)
|
||||
loadResult.parseErrors.push_back({defFile, error});
|
||||
if (res.module)
|
||||
{
|
||||
for (auto& error : res.module->errors)
|
||||
loadResult.typeErrors.push_back({defFile, error});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return loadResult;
|
||||
}
|
||||
|
||||
bool reportErrors(ReportFormat format)
|
||||
{
|
||||
for (const auto& err : loadErrors)
|
||||
report(format, err.first.c_str(), Luau::Location(), "CLI", err.second.c_str());
|
||||
for (const auto& err : parseErrors)
|
||||
report(format, err.first.c_str(), err.second.getLocation(), "SyntaxError", err.second.getMessage().c_str());
|
||||
for (const auto& err : typeErrors)
|
||||
report(format, err.first.c_str(), err.second.location, "TypeError", Luau::toString(err.second).c_str());
|
||||
return success;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Luau::assertHandler() = assertionHandler;
|
||||
|
@ -307,6 +360,8 @@ int main(int argc, char** argv)
|
|||
bool annotate = false;
|
||||
int threadCount = 0;
|
||||
|
||||
std::vector<std::string> definitionsFiles;
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
if (argv[i][0] != '-')
|
||||
|
@ -326,6 +381,10 @@ int main(int argc, char** argv)
|
|||
setLuauFlags(argv[i] + 9);
|
||||
else if (strncmp(argv[i], "-j", 2) == 0)
|
||||
threadCount = int(strtol(argv[i] + 2, nullptr, 10));
|
||||
else if (strncmp(argv[i], "--definitions=", 11) == 0)
|
||||
{
|
||||
definitionsFiles.push_back(argv[i] + 14);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(LUAU_ENABLE_TIME_TRACE)
|
||||
|
@ -345,6 +404,7 @@ int main(int argc, char** argv)
|
|||
Luau::Frontend frontend(&fileResolver, &configResolver, frontendOptions);
|
||||
|
||||
Luau::registerBuiltinGlobals(frontend, frontend.globals);
|
||||
DefinitionsResolver defFilesRes = DefinitionsResolver::loadAndRegister(frontend, definitionsFiles);
|
||||
Luau::freeze(frontend.globals.globalTypes);
|
||||
|
||||
#ifdef CALLGRIND
|
||||
|
@ -387,6 +447,8 @@ int main(int argc, char** argv)
|
|||
|
||||
int failed = 0;
|
||||
|
||||
failed += !defFilesRes.reportErrors(format);
|
||||
|
||||
for (const Luau::ModuleName& name : checkedModules)
|
||||
failed += !reportModuleResult(frontend, name, format, annotate);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue