Commit 3f057d44 authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[torque] Introduce LanguageServerData class

This CL introduces a new contextual 'LanguageSererData'. Its purpose
is to hold all the eagerly calculated data needed to answer
language server requests. The first thing collected are the
definitoins of some IdentifierExpresisons and macro/builtin
call-sites.

Collecting this data is not necessary for normal compilation, so it
is disabled by default and can be enabled via a Torque compiler
option. Since the holder class is a contextual for which no scope
exists during normal compilation, accidental collection of
unnecessary language server data *should* be prevented.

R=tebbi@chromium.org

Bug: v8:7793
Change-Id: Iffcebad4c420a0a51b1ed3c37a37c3475c6ab2e8
Reviewed-on: https://chromium-review.googlesource.com/c/1491594Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Simon Zünd <szuend@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59941}
parent 7da5552e
......@@ -3128,6 +3128,8 @@ v8_source_set("torque_base") {
"src/torque/implementation-visitor.h",
"src/torque/instructions.cc",
"src/torque/instructions.h",
"src/torque/server-data.cc",
"src/torque/server-data.h",
"src/torque/source-positions.cc",
"src/torque/source-positions.h",
"src/torque/torque-compiler.cc",
......
......@@ -17,7 +17,10 @@ namespace torque {
class GlobalContext : public ContextualClass<GlobalContext> {
public:
explicit GlobalContext(Ast ast) : verbose_(false), ast_(std::move(ast)) {
explicit GlobalContext(Ast ast)
: verbose_(false),
collect_language_server_data_(false),
ast_(std::move(ast)) {
CurrentScope::Scope current_scope(nullptr);
CurrentSourcePosition::Scope current_source_position(
SourcePosition{CurrentSourceFile::Get(), {-1, -1}, {-1, -1}});
......@@ -63,10 +66,17 @@ class GlobalContext : public ContextualClass<GlobalContext> {
static void SetVerbose() { Get().verbose_ = true; }
static bool verbose() { return Get().verbose_; }
static void SetCollectLanguageServerData() {
Get().collect_language_server_data_ = true;
}
static bool collect_language_server_data() {
return Get().collect_language_server_data_;
}
static Ast* ast() { return &Get().ast_; }
private:
bool verbose_;
bool collect_language_server_data_;
Namespace* default_namespace_;
Ast ast_;
std::vector<std::unique_ptr<Declarable>> declarables_;
......
......@@ -9,6 +9,7 @@
#include "src/torque/declaration-visitor.h"
#include "src/torque/implementation-visitor.h"
#include "src/torque/parameter-difference.h"
#include "src/torque/server-data.h"
namespace v8 {
namespace internal {
......@@ -1766,6 +1767,10 @@ LocationReference ImplementationVisitor::GetLocationReference(
if (expr->namespace_qualification.empty()) {
if (base::Optional<Binding<LocalValue>*> value =
TryLookupLocalValue(expr->name->value)) {
if (GlobalContext::collect_language_server_data()) {
LanguageServerData::AddDefinition(expr->pos,
(*value)->declaration_position());
}
if (expr->generic_arguments.size() != 0) {
ReportError("cannot have generic parameters on local name ",
expr->name);
......@@ -2201,6 +2206,12 @@ VisitResult ImplementationVisitor::Visit(CallExpression* expr,
return scope.Yield(
GeneratePointerCall(expr->callee, arguments, is_tailcall));
} else {
if (GlobalContext::collect_language_server_data()) {
Callable* callable = LookupCallable(name, Declarations::Lookup(name),
arguments, specialization_types);
LanguageServerData::AddDefinition(expr->callee->name->pos,
callable->pos());
}
return scope.Yield(
GenerateCall(name, arguments, specialization_types, is_tailcall));
}
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/torque/server-data.h"
namespace v8 {
namespace internal {
namespace torque {
DEFINE_CONTEXTUAL_VARIABLE(LanguageServerData)
void LanguageServerData::AddDefinition(SourcePosition token,
SourcePosition definition) {
Get().definitions_map_[token.source].emplace_back(token, definition);
}
base::Optional<SourcePosition> LanguageServerData::FindDefinition(
SourceId source, LineAndColumn pos) {
for (const DefinitionMapping& mapping : Get().definitions_map_.at(source)) {
SourcePosition current = mapping.first;
if (current.Contains(pos)) return mapping.second;
}
return base::nullopt;
}
} // namespace torque
} // namespace internal
} // namespace v8
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_TORQUE_SERVER_DATA_H_
#define V8_TORQUE_SERVER_DATA_H_
#include <map>
#include <vector>
#include "src/base/optional.h"
#include "src/torque/source-positions.h"
namespace v8 {
namespace internal {
namespace torque {
// The definition of the token in the first element, can be found at the second.
using DefinitionMapping = std::pair<SourcePosition, SourcePosition>;
// TODO(szuend): Support overlapping source positions when we start adding them.
using Definitions = std::vector<DefinitionMapping>;
using DefinitionsMap = std::map<SourceId, Definitions>;
// This contextual class holds all the necessary data to answer incoming
// LSP requests. It is reset for each compilation step and all information
// is calculated eagerly during compilation.
class LanguageServerData : public ContextualClass<LanguageServerData> {
public:
LanguageServerData() = default;
static void AddDefinition(SourcePosition token, SourcePosition definition);
static base::Optional<SourcePosition> FindDefinition(SourceId source,
LineAndColumn pos);
private:
DefinitionsMap definitions_map_;
};
} // namespace torque
} // namespace internal
} // namespace v8
#endif // V8_TORQUE_SERVER_DATA_H_
......@@ -17,6 +17,7 @@ class SourceId {
public:
static SourceId Invalid() { return SourceId(-1); }
int operator==(const SourceId& s) const { return id_ == s.id_; }
bool operator<(const SourceId& s) const { return id_ < s.id_; }
private:
explicit SourceId(int id) : id_(id) {}
......@@ -45,6 +46,14 @@ struct SourcePosition {
bool CompareStartIgnoreColumn(const SourcePosition& pos) const {
return start.line == pos.start.line && source == pos.source;
}
bool Contains(LineAndColumn pos) const {
if (pos.line < start.line || pos.line > end.line) return false;
if (pos.line == start.line && pos.column < start.column) return false;
if (pos.line == end.line && pos.column >= end.column) return false;
return true;
}
};
DECLARE_CONTEXTUAL_VARIABLE(CurrentSourceFile, SourceId);
......
......@@ -31,9 +31,7 @@ void ReadAndParseTorqueFile(const std::string& path) {
void CompileTorque(std::vector<std::string> files,
TorqueCompilerOptions options) {
SourceFileMap::Scope source_file_map_scope;
CurrentSourceFile::Scope unknown_source_file_scope(
SourceFileMap::AddSource("<unknown>"));
CurrentSourceFile::Scope unknown_source_file_scope(SourceId::Invalid());
CurrentAst::Scope ast_scope_;
LintErrorStatus::Scope lint_error_status_scope_;
......@@ -41,6 +39,9 @@ void CompileTorque(std::vector<std::string> files,
GlobalContext::Scope global_context(std::move(CurrentAst::Get()));
if (options.verbose) GlobalContext::SetVerbose();
if (options.collect_language_server_data) {
GlobalContext::SetCollectLanguageServerData();
}
TypeOracle::Scope type_oracle;
DeclarationVisitor declaration_visitor;
......
......@@ -17,9 +17,10 @@ namespace torque {
struct TorqueCompilerOptions {
std::string output_directory;
bool verbose;
bool collect_language_server_data;
bool abort_on_lint_errors;
static TorqueCompilerOptions Default() { return {"", false, false}; }
static TorqueCompilerOptions Default() { return {"", false, false, false}; }
};
void CompileTorque(std::vector<std::string> files,
......
......@@ -28,7 +28,15 @@ int WrappedMain(int argc, const char** argv) {
files.emplace_back(argv[i]);
}
CompileTorque(files, {output_directory, verbose, true});
SourceFileMap::Scope source_file_map_scope;
TorqueCompilerOptions options;
options.output_directory = output_directory;
options.verbose = verbose;
options.collect_language_server_data = false;
options.abort_on_lint_errors = true;
CompileTorque(files, options);
return 0;
}
......
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