Commit 724d6586 authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[torque] Refactor compiler interface to not 'leak' contextuals

The Torque compiler makes heavy use of scoped globals (contextuals).
This created a problem for the design of the compiler interface:

    - Either the compiler provides all the necessary scopes itself,
      disallowing callers any access to the contextuals, which might
      contain data the caller is interested in (such as the
      compilation result).
    - Or the caller provides all the necessary scopes.

This design was fine when the compiler executable was the only user.
With the recent addition of unit tests and the language server, this
interface became brittle, as missing scopes are only detected at
runtime.

This CL refactors the compiler interface to not leak contextual
scopes past the interface boundary. Content of contextuals is
collected and returned, providing access for the caller and freedom
to either use the data directly or move it into the callers own scopes.

R=sigurds@chromium.org

Bug: v8:7793
Change-Id: Ieb988522d08fc6026b3fb74d976008e566146770
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1529000
Commit-Queue: Simon Zünd <szuend@chromium.org>
Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60867}
parent 8b3cd48d
...@@ -66,15 +66,16 @@ namespace { ...@@ -66,15 +66,16 @@ namespace {
void RecompileTorque() { void RecompileTorque() {
Logger::Log("[info] Start compilation run ...\n"); Logger::Log("[info] Start compilation run ...\n");
LanguageServerData::Get() = LanguageServerData();
SourceFileMap::Get() = SourceFileMap();
TorqueCompilerOptions options; TorqueCompilerOptions options;
options.output_directory = ""; options.output_directory = "";
options.verbose = false; options.verbose = false;
options.collect_language_server_data = true; options.collect_language_server_data = true;
options.abort_on_lint_errors = false; options.abort_on_lint_errors = false;
CompileTorque(TorqueFileList::Get(), options);
TorqueCompilerResult result = CompileTorque(TorqueFileList::Get(), options);
LanguageServerData::Get() = result.language_server_data;
SourceFileMap::Get() = result.source_file_map;
Logger::Log("[info] Finished compilation run ...\n"); Logger::Log("[info] Finished compilation run ...\n");
} }
......
...@@ -87,38 +87,55 @@ void CompileCurrentAst(TorqueCompilerOptions options) { ...@@ -87,38 +87,55 @@ void CompileCurrentAst(TorqueCompilerOptions options) {
if (LintErrorStatus::HasLintErrors()) std::abort(); if (LintErrorStatus::HasLintErrors()) std::abort();
} }
TorqueCompilerResult CollectResultFromContextuals() {
TorqueCompilerResult result;
result.source_file_map = SourceFileMap::Get();
result.language_server_data = LanguageServerData::Get();
return result;
}
TorqueCompilerResult ResultFromError(TorqueError& error) {
TorqueCompilerResult result;
result.source_file_map = SourceFileMap::Get();
result.error = error;
return result;
}
} // namespace } // namespace
TorqueCompilerResult CompileTorque(const std::string& source, TorqueCompilerResult CompileTorque(const std::string& source,
TorqueCompilerOptions options) { TorqueCompilerOptions options) {
SourceFileMap::Scope source_map_scope;
CurrentSourceFile::Scope no_file_scope(SourceFileMap::AddSource("<torque>")); CurrentSourceFile::Scope no_file_scope(SourceFileMap::AddSource("<torque>"));
CurrentAst::Scope ast_scope_; CurrentAst::Scope ast_scope;
LintErrorStatus::Scope lint_error_status_scope_; LintErrorStatus::Scope lint_error_status_scope;
LanguageServerData::Scope server_data_scope;
TorqueCompilerResult result;
try { try {
ParseTorque(source); ParseTorque(source);
CompileCurrentAst(options); CompileCurrentAst(options);
} catch (TorqueError& error) { } catch (TorqueError& error) {
result.error = error; return ResultFromError(error);
} }
return result;
return CollectResultFromContextuals();
} }
TorqueCompilerResult CompileTorque(std::vector<std::string> files, TorqueCompilerResult CompileTorque(std::vector<std::string> files,
TorqueCompilerOptions options) { TorqueCompilerOptions options) {
SourceFileMap::Scope source_map_scope;
CurrentSourceFile::Scope unknown_source_file_scope(SourceId::Invalid()); CurrentSourceFile::Scope unknown_source_file_scope(SourceId::Invalid());
CurrentAst::Scope ast_scope_; CurrentAst::Scope ast_scope;
LintErrorStatus::Scope lint_error_status_scope_; LintErrorStatus::Scope lint_error_status_scope;
LanguageServerData::Scope server_data_scope;
TorqueCompilerResult result;
try { try {
for (const auto& path : files) ReadAndParseTorqueFile(path); for (const auto& path : files) ReadAndParseTorqueFile(path);
CompileCurrentAst(options); CompileCurrentAst(options);
} catch (TorqueError& error) { } catch (TorqueError& error) {
result.error = error; return ResultFromError(error);
} }
return result; return CollectResultFromContextuals();
} }
} // namespace torque } // namespace torque
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/torque/ast.h" #include "src/torque/ast.h"
#include "src/torque/contextual.h" #include "src/torque/contextual.h"
#include "src/torque/server-data.h"
#include "src/torque/source-positions.h" #include "src/torque/source-positions.h"
#include "src/torque/utils.h" #include "src/torque/utils.h"
...@@ -22,6 +23,17 @@ struct TorqueCompilerOptions { ...@@ -22,6 +23,17 @@ struct TorqueCompilerOptions {
}; };
struct TorqueCompilerResult { struct TorqueCompilerResult {
// Map translating SourceIds to filenames. This field is
// set on errors, so the SourcePosition of the error can be
// resolved.
SourceFileMap source_file_map;
// Eagerly collected data needed for the LanguageServer.
// Set the corresponding options flag to enable.
LanguageServerData language_server_data;
// If any error occurred during either parsing or compilation,
// this field will be set.
base::Optional<TorqueError> error; base::Optional<TorqueError> error;
}; };
......
...@@ -29,8 +29,6 @@ int WrappedMain(int argc, const char** argv) { ...@@ -29,8 +29,6 @@ int WrappedMain(int argc, const char** argv) {
files.emplace_back(argv[i]); files.emplace_back(argv[i]);
} }
SourceFileMap::Scope source_file_map_scope;
TorqueCompilerOptions options; TorqueCompilerOptions options;
options.output_directory = output_directory; options.output_directory = output_directory;
options.verbose = verbose; options.verbose = verbose;
...@@ -39,6 +37,10 @@ int WrappedMain(int argc, const char** argv) { ...@@ -39,6 +37,10 @@ int WrappedMain(int argc, const char** argv) {
TorqueCompilerResult result = CompileTorque(files, options); TorqueCompilerResult result = CompileTorque(files, options);
if (result.error) { if (result.error) {
// PositionAsString requires the SourceFileMap to be set to
// resolve the file name.
SourceFileMap::Scope source_file_map_scope(result.source_file_map);
TorqueError& error = *result.error; TorqueError& error = *result.error;
if (error.position) std::cerr << PositionAsString(*error.position) << ": "; if (error.position) std::cerr << PositionAsString(*error.position) << ": ";
std::cerr << "Torque error: " << error.message << "\n"; std::cerr << "Torque error: " << error.message << "\n";
......
...@@ -23,7 +23,9 @@ struct TestCompiler { ...@@ -23,7 +23,9 @@ struct TestCompiler {
options.verbose = false; options.verbose = false;
options.collect_language_server_data = true; options.collect_language_server_data = true;
CompileTorque(source, options); const TorqueCompilerResult result = CompileTorque(source, options);
SourceFileMap::Get() = result.source_file_map;
LanguageServerData::Get() = result.language_server_data;
} }
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment