mirror of
https://github.com/luau-lang/luau.git
synced 2024-11-15 14:25:44 +08:00
luau-analyze: Add support for reading source code from stdin (#325)
Co-authored-by: Arseny Kapoulkine <arseny.kapoulkine@gmail.com>
This commit is contained in:
parent
8fe95c9963
commit
4b96f7efc1
@ -43,14 +43,14 @@ static void report(ReportFormat format, const char* name, const Luau::Location&
|
||||
}
|
||||
}
|
||||
|
||||
static void reportError(ReportFormat format, const Luau::TypeError& error)
|
||||
static void reportError(Luau::Frontend& frontend, ReportFormat format, const Luau::TypeError& error)
|
||||
{
|
||||
const char* name = error.moduleName.c_str();
|
||||
std::string humanReadableName = frontend.fileResolver->getHumanReadableModuleName(error.moduleName);
|
||||
|
||||
if (const Luau::SyntaxError* syntaxError = Luau::get_if<Luau::SyntaxError>(&error.data))
|
||||
report(format, name, error.location, "SyntaxError", syntaxError->message.c_str());
|
||||
report(format, humanReadableName.c_str(), error.location, "SyntaxError", syntaxError->message.c_str());
|
||||
else
|
||||
report(format, name, error.location, "TypeError", Luau::toString(error).c_str());
|
||||
report(format, humanReadableName.c_str(), error.location, "TypeError", Luau::toString(error).c_str());
|
||||
}
|
||||
|
||||
static void reportWarning(ReportFormat format, const char* name, const Luau::LintWarning& warning)
|
||||
@ -72,14 +72,15 @@ static bool analyzeFile(Luau::Frontend& frontend, const char* name, ReportFormat
|
||||
}
|
||||
|
||||
for (auto& error : cr.errors)
|
||||
reportError(format, error);
|
||||
reportError(frontend, format, error);
|
||||
|
||||
Luau::LintResult lr = frontend.lint(name);
|
||||
|
||||
std::string humanReadableName = frontend.fileResolver->getHumanReadableModuleName(name);
|
||||
for (auto& error : lr.errors)
|
||||
reportWarning(format, name, error);
|
||||
reportWarning(format, humanReadableName.c_str(), error);
|
||||
for (auto& warning : lr.warnings)
|
||||
reportWarning(format, name, warning);
|
||||
reportWarning(format, humanReadableName.c_str(), warning);
|
||||
|
||||
if (annotate)
|
||||
{
|
||||
@ -120,11 +121,25 @@ struct CliFileResolver : Luau::FileResolver
|
||||
{
|
||||
std::optional<Luau::SourceCode> readSource(const Luau::ModuleName& name) override
|
||||
{
|
||||
std::optional<std::string> source = readFile(name);
|
||||
Luau::SourceCode::Type sourceType;
|
||||
std::optional<std::string> source = std::nullopt;
|
||||
|
||||
// If the module name is "-", then read source from stdin
|
||||
if (name == "-")
|
||||
{
|
||||
source = readStdin();
|
||||
sourceType = Luau::SourceCode::Script;
|
||||
}
|
||||
else
|
||||
{
|
||||
source = readFile(name);
|
||||
sourceType = Luau::SourceCode::Module;
|
||||
}
|
||||
|
||||
if (!source)
|
||||
return std::nullopt;
|
||||
|
||||
return Luau::SourceCode{*source, Luau::SourceCode::Module};
|
||||
return Luau::SourceCode{*source, sourceType};
|
||||
}
|
||||
|
||||
std::optional<Luau::ModuleInfo> resolveModule(const Luau::ModuleInfo* context, Luau::AstExpr* node) override
|
||||
@ -143,6 +158,13 @@ struct CliFileResolver : Luau::FileResolver
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::string getHumanReadableModuleName(const Luau::ModuleName& name) const override
|
||||
{
|
||||
if (name == "-")
|
||||
return "stdin";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
struct CliConfigResolver : Luau::ConfigResolver
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define READ_BUFFER_SIZE 4096
|
||||
|
||||
#ifdef _WIN32
|
||||
static std::wstring fromUtf8(const std::string& path)
|
||||
{
|
||||
@ -74,6 +76,21 @@ std::optional<std::string> readFile(const std::string& name)
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<std::string> readStdin()
|
||||
{
|
||||
std::string result;
|
||||
char buffer[READ_BUFFER_SIZE] = { };
|
||||
|
||||
while (fgets(buffer, READ_BUFFER_SIZE, stdin) != nullptr)
|
||||
result.append(buffer);
|
||||
|
||||
// If eof was not reached for stdin, then a read error occurred
|
||||
if (!feof(stdin))
|
||||
return std::nullopt;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Ch>
|
||||
static void joinPaths(std::basic_string<Ch>& str, const Ch* lhs, const Ch* rhs)
|
||||
{
|
||||
@ -190,7 +207,10 @@ bool traverseDirectory(const std::string& path, const std::function<void(const s
|
||||
bool isDirectory(const std::string& path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (GetFileAttributesW(fromUtf8(path).c_str()) & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
DWORD fileAttributes = GetFileAttributesW(fromUtf8(path).c_str());
|
||||
if (fileAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
return false;
|
||||
return (fileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
#else
|
||||
struct stat st = {};
|
||||
lstat(path.c_str(), &st);
|
||||
@ -244,7 +264,9 @@ std::vector<std::string> getSourceFiles(int argc, char** argv)
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
if (argv[i][0] == '-')
|
||||
// Treat '-' as a special file whose source is read from stdin
|
||||
// All other arguments that start with '-' are skipped
|
||||
if (argv[i][0] == '-' && argv[i][1] != '\0')
|
||||
continue;
|
||||
|
||||
if (isDirectory(argv[i]))
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <vector>
|
||||
|
||||
std::optional<std::string> readFile(const std::string& name);
|
||||
std::optional<std::string> readStdin();
|
||||
|
||||
bool isDirectory(const std::string& path);
|
||||
bool traverseDirectory(const std::string& path, const std::function<void(const std::string& name)>& callback);
|
||||
|
Loading…
Reference in New Issue
Block a user