[torque-ls] List macros and builtins as document symbols

This CL adds support for macros, builtins, generics and specializations
for the "textDocument/symbol" request. To filter out implicitly
created specializations, the "is_user_defined" flag is hoisted from
Macro to the Declarable super class. As a side-effect, errors thrown
during specialization now have the correct SourcePosition.

Drive-by-change: Using "Goto Definition" on the identifier of the
specialization will jump to the associated generic.

Bug: v8:8880
Change-Id: I0c60571c58107375c1b5d2a8e620cf12a0f0f3fc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1609795
Commit-Queue: Simon Zünd <szuend@chromium.org>
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61486}
This commit is contained in:
Simon Zünd 2019-05-14 14:51:56 +02:00 committed by Commit Bot
parent f0234f75af
commit a41aaf78e1
8 changed files with 67 additions and 39 deletions

View File

@ -878,19 +878,19 @@ struct GenericDeclaration : Declaration {
struct SpecializationDeclaration : Declaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(SpecializationDeclaration)
SpecializationDeclaration(SourcePosition pos, std::string name,
SpecializationDeclaration(SourcePosition pos, Identifier* name,
std::vector<TypeExpression*> generic_parameters,
ParameterList parameters,
TypeExpression* return_type,
LabelAndTypesVector labels, Statement* b)
: Declaration(kKind, pos),
name(std::move(name)),
name(name),
external(false),
generic_parameters(std::move(generic_parameters)),
signature(new CallableNodeSignature{std::move(parameters), return_type,
std::move(labels)}),
body(b) {}
std::string name;
Identifier* name;
bool external;
std::vector<TypeExpression*> generic_parameters;
std::unique_ptr<CallableNodeSignature> signature;

View File

@ -90,6 +90,11 @@ class Declarable {
identifier_position_ = position;
}
bool IsUserDefined() const { return is_user_defined_; }
void SetIsUserDefined(bool is_user_defined) {
is_user_defined_ = is_user_defined;
}
protected:
explicit Declarable(Kind kind) : kind_(kind) {}
@ -98,6 +103,7 @@ class Declarable {
Scope* const parent_scope_ = CurrentScope::Get();
SourcePosition position_ = CurrentSourcePosition::Get();
SourcePosition identifier_position_ = SourcePosition::Invalid();
bool is_user_defined_ = true;
};
#define DECLARE_DECLARABLE_BOILERPLATE(x, y) \
@ -312,8 +318,6 @@ class Macro : public Callable {
return external_assembler_name_;
}
bool is_user_defined() const { return is_user_defined_; }
protected:
Macro(Declarable::Kind kind, std::string external_name,
std::string readable_name, std::string external_assembler_name,
@ -321,8 +325,8 @@ class Macro : public Callable {
base::Optional<Statement*> body, bool is_user_defined)
: Callable(kind, std::move(external_name), std::move(readable_name),
signature, transitioning, body),
external_assembler_name_(std::move(external_assembler_name)),
is_user_defined_(is_user_defined) {
external_assembler_name_(std::move(external_assembler_name)) {
SetIsUserDefined(is_user_defined);
if (signature.parameter_types.var_args) {
ReportError("Varargs are not supported for macros.");
}
@ -339,7 +343,6 @@ class Macro : public Callable {
transitioning, body, is_user_defined) {}
std::string external_assembler_name_;
bool is_user_defined_;
};
class Method : public Macro {

View File

@ -210,7 +210,8 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
ReportError(stream.str());
}
std::vector<Generic*> generic_list = Declarations::LookupGeneric(decl->name);
std::vector<Generic*> generic_list =
Declarations::LookupGeneric(decl->name->value);
// Find the matching generic specialization based on the concrete parameter
// list.
Generic* matching_generic = nullptr;
@ -253,10 +254,15 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
ReportError(stream.str());
}
if (GlobalContext::collect_language_server_data()) {
LanguageServerData::AddDefinition(decl->name->pos,
matching_generic->IdentifierPosition());
}
Specialize(SpecializationKey{matching_generic, TypeVisitor::ComputeTypeVector(
decl->generic_parameters)},
matching_generic->declaration()->callable, decl->signature.get(),
decl->body);
decl->body, decl->pos);
}
void DeclarationVisitor::Visit(ExternConstDeclaration* decl) {
@ -315,9 +321,10 @@ Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) {
key.generic->Position());
}
CurrentScope::Scope generic_scope(key.generic->ParentScope());
Callable* result =
Specialize(key, key.generic->declaration()->callable, base::nullopt,
key.generic->declaration()->body);
Callable* result = Specialize(key, key.generic->declaration()->callable,
base::nullopt, key.generic->declaration()->body,
CurrentSourcePosition::Get());
result->SetIsUserDefined(false);
CurrentScope::Scope callable_scope(result);
DeclareSpecializedTypes(key);
return result;
@ -326,10 +333,8 @@ Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) {
Callable* DeclarationVisitor::Specialize(
const SpecializationKey& key, CallableNode* declaration,
base::Optional<const CallableNodeSignature*> signature,
base::Optional<Statement*> body) {
// TODO(tebbi): The error should point to the source position where the
// instantiation was requested.
CurrentSourcePosition::Scope pos_scope(key.generic->declaration()->pos);
base::Optional<Statement*> body, SourcePosition position) {
CurrentSourcePosition::Scope pos_scope(position);
size_t generic_parameter_count =
key.generic->declaration()->generic_parameters.size();
if (generic_parameter_count != key.specialized_types.size()) {

View File

@ -100,7 +100,7 @@ class DeclarationVisitor {
static Callable* Specialize(
const SpecializationKey& key, CallableNode* declaration,
base::Optional<const CallableNodeSignature*> signature,
base::Optional<Statement*> body);
base::Optional<Statement*> body, SourcePosition position);
private:
static void DeclareSpecializedTypes(const SpecializationKey& key);

View File

@ -269,15 +269,7 @@ void HandleGotoDefinitionRequest(GotoDefinitionRequest request,
if (auto maybe_definition = LanguageServerData::FindDefinition(id, pos)) {
SourcePosition definition = *maybe_definition;
std::string definition_file = SourceFileMap::GetSource(definition.source);
response.result().set_uri(definition_file);
Range range = response.result().range();
range.start().set_line(definition.start.line);
range.start().set_character(definition.start.column);
range.end().set_line(definition.end.line);
range.end().set_character(definition.end.column);
response.result().SetTo(definition);
} else {
response.SetNull("result");
}
@ -297,8 +289,31 @@ void HandleDocumentSymbolRequest(DocumentSymbolRequest request,
DocumentSymbolResponse response;
response.set_id(request.id());
// TODO(szuend): Convert declarables and other symbols into SymbolInformation
// objects here.
SourceId id =
SourceFileMap::GetSourceId(request.params().textDocument().uri());
for (const auto& symbol : LanguageServerData::SymbolsForSourceId(id)) {
DCHECK(symbol->IsUserDefined());
if (symbol->IsMacro()) {
Macro* macro = Macro::cast(symbol);
SymbolInformation symbol = response.add_result();
symbol.set_name(macro->ReadableName());
symbol.set_kind(SymbolKind::kFunction);
symbol.location().SetTo(macro->Position());
} else if (symbol->IsBuiltin()) {
Builtin* builtin = Builtin::cast(symbol);
SymbolInformation symbol = response.add_result();
symbol.set_name(builtin->ReadableName());
symbol.set_kind(SymbolKind::kFunction);
symbol.location().SetTo(builtin->Position());
} else if (symbol->IsGeneric()) {
Generic* generic = Generic::cast(symbol);
SymbolInformation symbol = response.add_result();
symbol.set_name(generic->name());
symbol.set_kind(SymbolKind::kFunction);
symbol.location().SetTo(generic->Position());
}
}
// Trigger empty array creation in case no symbols were found.
USE(response.result_size());

View File

@ -8,6 +8,7 @@
#include "src/base/logging.h"
#include "src/torque/ls/json.h"
#include "src/torque/ls/message-macros.h"
#include "src/torque/source-positions.h"
namespace v8 {
namespace internal {
@ -238,6 +239,14 @@ class Location : public NestedJsonAccessor {
JSON_STRING_ACCESSORS(uri)
JSON_OBJECT_ACCESSORS(Range, range)
void SetTo(SourcePosition position) {
set_uri(SourceFileMap::GetSource(position.source));
range().start().set_line(position.start.line);
range().start().set_character(position.start.column);
range().end().set_line(position.end.line);
range().end().set_character(position.end.column);
}
};
class TextDocumentIdentifier : public NestedJsonAccessor {

View File

@ -38,12 +38,9 @@ void LanguageServerData::PrepareAllDeclarableSymbols() {
global_context_->declarables_;
for (const auto& declarable : all_declarables) {
// Auto-generated macros to access class fields should not show up in
// search results.
if (declarable->IsMacro() &&
!Macro::cast(declarable.get())->is_user_defined()) {
continue;
}
// Class field accessors and implicit specializations are
// auto-generated and should not show up.
if (!declarable->IsUserDefined()) continue;
SourceId source = declarable->Position().source;
symbols_map_[source].push_back(declarable.get());

View File

@ -707,7 +707,7 @@ base::Optional<ParseResult> MakeNamespaceDeclaration(
base::Optional<ParseResult> MakeSpecializationDeclaration(
ParseResultIterator* child_results) {
auto name = child_results->NextAs<std::string>();
auto name = child_results->NextAs<Identifier*>();
auto generic_parameters =
child_results->NextAs<std::vector<TypeExpression*>>();
auto parameters = child_results->NextAs<ParameterList>();
@ -1841,9 +1841,8 @@ struct TorqueGrammar : Grammar {
TryOrDefault<GenericParameters>(&genericParameters),
&parameterListAllowVararg, &optionalReturnType, &optionalBody},
AsSingletonVector<Declaration*, MakeTorqueBuiltinDeclaration>()),
Rule({&identifier, &genericSpecializationTypeList,
&parameterListAllowVararg, &optionalReturnType, optionalLabelList,
&block},
Rule({&name, &genericSpecializationTypeList, &parameterListAllowVararg,
&optionalReturnType, optionalLabelList, &block},
AsSingletonVector<Declaration*, MakeSpecializationDeclaration>()),
Rule({Token("#include"), &externalString},
AsSingletonVector<Declaration*, MakeCppIncludeDeclaration>())};