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

[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: 's avatarSigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61486}
parent f0234f75
...@@ -878,19 +878,19 @@ struct GenericDeclaration : Declaration { ...@@ -878,19 +878,19 @@ struct GenericDeclaration : Declaration {
struct SpecializationDeclaration : Declaration { struct SpecializationDeclaration : Declaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(SpecializationDeclaration) DEFINE_AST_NODE_LEAF_BOILERPLATE(SpecializationDeclaration)
SpecializationDeclaration(SourcePosition pos, std::string name, SpecializationDeclaration(SourcePosition pos, Identifier* name,
std::vector<TypeExpression*> generic_parameters, std::vector<TypeExpression*> generic_parameters,
ParameterList parameters, ParameterList parameters,
TypeExpression* return_type, TypeExpression* return_type,
LabelAndTypesVector labels, Statement* b) LabelAndTypesVector labels, Statement* b)
: Declaration(kKind, pos), : Declaration(kKind, pos),
name(std::move(name)), name(name),
external(false), external(false),
generic_parameters(std::move(generic_parameters)), generic_parameters(std::move(generic_parameters)),
signature(new CallableNodeSignature{std::move(parameters), return_type, signature(new CallableNodeSignature{std::move(parameters), return_type,
std::move(labels)}), std::move(labels)}),
body(b) {} body(b) {}
std::string name; Identifier* name;
bool external; bool external;
std::vector<TypeExpression*> generic_parameters; std::vector<TypeExpression*> generic_parameters;
std::unique_ptr<CallableNodeSignature> signature; std::unique_ptr<CallableNodeSignature> signature;
......
...@@ -90,6 +90,11 @@ class Declarable { ...@@ -90,6 +90,11 @@ class Declarable {
identifier_position_ = position; identifier_position_ = position;
} }
bool IsUserDefined() const { return is_user_defined_; }
void SetIsUserDefined(bool is_user_defined) {
is_user_defined_ = is_user_defined;
}
protected: protected:
explicit Declarable(Kind kind) : kind_(kind) {} explicit Declarable(Kind kind) : kind_(kind) {}
...@@ -98,6 +103,7 @@ class Declarable { ...@@ -98,6 +103,7 @@ class Declarable {
Scope* const parent_scope_ = CurrentScope::Get(); Scope* const parent_scope_ = CurrentScope::Get();
SourcePosition position_ = CurrentSourcePosition::Get(); SourcePosition position_ = CurrentSourcePosition::Get();
SourcePosition identifier_position_ = SourcePosition::Invalid(); SourcePosition identifier_position_ = SourcePosition::Invalid();
bool is_user_defined_ = true;
}; };
#define DECLARE_DECLARABLE_BOILERPLATE(x, y) \ #define DECLARE_DECLARABLE_BOILERPLATE(x, y) \
...@@ -312,8 +318,6 @@ class Macro : public Callable { ...@@ -312,8 +318,6 @@ class Macro : public Callable {
return external_assembler_name_; return external_assembler_name_;
} }
bool is_user_defined() const { return is_user_defined_; }
protected: protected:
Macro(Declarable::Kind kind, std::string external_name, Macro(Declarable::Kind kind, std::string external_name,
std::string readable_name, std::string external_assembler_name, std::string readable_name, std::string external_assembler_name,
...@@ -321,8 +325,8 @@ class Macro : public Callable { ...@@ -321,8 +325,8 @@ class Macro : public Callable {
base::Optional<Statement*> body, bool is_user_defined) base::Optional<Statement*> body, bool is_user_defined)
: Callable(kind, std::move(external_name), std::move(readable_name), : Callable(kind, std::move(external_name), std::move(readable_name),
signature, transitioning, body), signature, transitioning, body),
external_assembler_name_(std::move(external_assembler_name)), external_assembler_name_(std::move(external_assembler_name)) {
is_user_defined_(is_user_defined) { SetIsUserDefined(is_user_defined);
if (signature.parameter_types.var_args) { if (signature.parameter_types.var_args) {
ReportError("Varargs are not supported for macros."); ReportError("Varargs are not supported for macros.");
} }
...@@ -339,7 +343,6 @@ class Macro : public Callable { ...@@ -339,7 +343,6 @@ class Macro : public Callable {
transitioning, body, is_user_defined) {} transitioning, body, is_user_defined) {}
std::string external_assembler_name_; std::string external_assembler_name_;
bool is_user_defined_;
}; };
class Method : public Macro { class Method : public Macro {
......
...@@ -210,7 +210,8 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) { ...@@ -210,7 +210,8 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
ReportError(stream.str()); 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 // Find the matching generic specialization based on the concrete parameter
// list. // list.
Generic* matching_generic = nullptr; Generic* matching_generic = nullptr;
...@@ -253,10 +254,15 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) { ...@@ -253,10 +254,15 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
ReportError(stream.str()); ReportError(stream.str());
} }
if (GlobalContext::collect_language_server_data()) {
LanguageServerData::AddDefinition(decl->name->pos,
matching_generic->IdentifierPosition());
}
Specialize(SpecializationKey{matching_generic, TypeVisitor::ComputeTypeVector( Specialize(SpecializationKey{matching_generic, TypeVisitor::ComputeTypeVector(
decl->generic_parameters)}, decl->generic_parameters)},
matching_generic->declaration()->callable, decl->signature.get(), matching_generic->declaration()->callable, decl->signature.get(),
decl->body); decl->body, decl->pos);
} }
void DeclarationVisitor::Visit(ExternConstDeclaration* decl) { void DeclarationVisitor::Visit(ExternConstDeclaration* decl) {
...@@ -315,9 +321,10 @@ Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) { ...@@ -315,9 +321,10 @@ Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) {
key.generic->Position()); key.generic->Position());
} }
CurrentScope::Scope generic_scope(key.generic->ParentScope()); CurrentScope::Scope generic_scope(key.generic->ParentScope());
Callable* result = Callable* result = Specialize(key, key.generic->declaration()->callable,
Specialize(key, key.generic->declaration()->callable, base::nullopt, base::nullopt, key.generic->declaration()->body,
key.generic->declaration()->body); CurrentSourcePosition::Get());
result->SetIsUserDefined(false);
CurrentScope::Scope callable_scope(result); CurrentScope::Scope callable_scope(result);
DeclareSpecializedTypes(key); DeclareSpecializedTypes(key);
return result; return result;
...@@ -326,10 +333,8 @@ Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) { ...@@ -326,10 +333,8 @@ Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) {
Callable* DeclarationVisitor::Specialize( Callable* DeclarationVisitor::Specialize(
const SpecializationKey& key, CallableNode* declaration, const SpecializationKey& key, CallableNode* declaration,
base::Optional<const CallableNodeSignature*> signature, base::Optional<const CallableNodeSignature*> signature,
base::Optional<Statement*> body) { base::Optional<Statement*> body, SourcePosition position) {
// TODO(tebbi): The error should point to the source position where the CurrentSourcePosition::Scope pos_scope(position);
// instantiation was requested.
CurrentSourcePosition::Scope pos_scope(key.generic->declaration()->pos);
size_t generic_parameter_count = size_t generic_parameter_count =
key.generic->declaration()->generic_parameters.size(); key.generic->declaration()->generic_parameters.size();
if (generic_parameter_count != key.specialized_types.size()) { if (generic_parameter_count != key.specialized_types.size()) {
......
...@@ -100,7 +100,7 @@ class DeclarationVisitor { ...@@ -100,7 +100,7 @@ class DeclarationVisitor {
static Callable* Specialize( static Callable* Specialize(
const SpecializationKey& key, CallableNode* declaration, const SpecializationKey& key, CallableNode* declaration,
base::Optional<const CallableNodeSignature*> signature, base::Optional<const CallableNodeSignature*> signature,
base::Optional<Statement*> body); base::Optional<Statement*> body, SourcePosition position);
private: private:
static void DeclareSpecializedTypes(const SpecializationKey& key); static void DeclareSpecializedTypes(const SpecializationKey& key);
......
...@@ -269,15 +269,7 @@ void HandleGotoDefinitionRequest(GotoDefinitionRequest request, ...@@ -269,15 +269,7 @@ void HandleGotoDefinitionRequest(GotoDefinitionRequest request,
if (auto maybe_definition = LanguageServerData::FindDefinition(id, pos)) { if (auto maybe_definition = LanguageServerData::FindDefinition(id, pos)) {
SourcePosition definition = *maybe_definition; SourcePosition definition = *maybe_definition;
response.result().SetTo(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);
} else { } else {
response.SetNull("result"); response.SetNull("result");
} }
...@@ -297,8 +289,31 @@ void HandleDocumentSymbolRequest(DocumentSymbolRequest request, ...@@ -297,8 +289,31 @@ void HandleDocumentSymbolRequest(DocumentSymbolRequest request,
DocumentSymbolResponse response; DocumentSymbolResponse response;
response.set_id(request.id()); response.set_id(request.id());
// TODO(szuend): Convert declarables and other symbols into SymbolInformation SourceId id =
// objects here. 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. // Trigger empty array creation in case no symbols were found.
USE(response.result_size()); USE(response.result_size());
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "src/base/logging.h" #include "src/base/logging.h"
#include "src/torque/ls/json.h" #include "src/torque/ls/json.h"
#include "src/torque/ls/message-macros.h" #include "src/torque/ls/message-macros.h"
#include "src/torque/source-positions.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -238,6 +239,14 @@ class Location : public NestedJsonAccessor { ...@@ -238,6 +239,14 @@ class Location : public NestedJsonAccessor {
JSON_STRING_ACCESSORS(uri) JSON_STRING_ACCESSORS(uri)
JSON_OBJECT_ACCESSORS(Range, range) 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 { class TextDocumentIdentifier : public NestedJsonAccessor {
......
...@@ -38,12 +38,9 @@ void LanguageServerData::PrepareAllDeclarableSymbols() { ...@@ -38,12 +38,9 @@ void LanguageServerData::PrepareAllDeclarableSymbols() {
global_context_->declarables_; global_context_->declarables_;
for (const auto& declarable : all_declarables) { for (const auto& declarable : all_declarables) {
// Auto-generated macros to access class fields should not show up in // Class field accessors and implicit specializations are
// search results. // auto-generated and should not show up.
if (declarable->IsMacro() && if (!declarable->IsUserDefined()) continue;
!Macro::cast(declarable.get())->is_user_defined()) {
continue;
}
SourceId source = declarable->Position().source; SourceId source = declarable->Position().source;
symbols_map_[source].push_back(declarable.get()); symbols_map_[source].push_back(declarable.get());
......
...@@ -707,7 +707,7 @@ base::Optional<ParseResult> MakeNamespaceDeclaration( ...@@ -707,7 +707,7 @@ base::Optional<ParseResult> MakeNamespaceDeclaration(
base::Optional<ParseResult> MakeSpecializationDeclaration( base::Optional<ParseResult> MakeSpecializationDeclaration(
ParseResultIterator* child_results) { ParseResultIterator* child_results) {
auto name = child_results->NextAs<std::string>(); auto name = child_results->NextAs<Identifier*>();
auto generic_parameters = auto generic_parameters =
child_results->NextAs<std::vector<TypeExpression*>>(); child_results->NextAs<std::vector<TypeExpression*>>();
auto parameters = child_results->NextAs<ParameterList>(); auto parameters = child_results->NextAs<ParameterList>();
...@@ -1841,9 +1841,8 @@ struct TorqueGrammar : Grammar { ...@@ -1841,9 +1841,8 @@ struct TorqueGrammar : Grammar {
TryOrDefault<GenericParameters>(&genericParameters), TryOrDefault<GenericParameters>(&genericParameters),
&parameterListAllowVararg, &optionalReturnType, &optionalBody}, &parameterListAllowVararg, &optionalReturnType, &optionalBody},
AsSingletonVector<Declaration*, MakeTorqueBuiltinDeclaration>()), AsSingletonVector<Declaration*, MakeTorqueBuiltinDeclaration>()),
Rule({&identifier, &genericSpecializationTypeList, Rule({&name, &genericSpecializationTypeList, &parameterListAllowVararg,
&parameterListAllowVararg, &optionalReturnType, optionalLabelList, &optionalReturnType, optionalLabelList, &block},
&block},
AsSingletonVector<Declaration*, MakeSpecializationDeclaration>()), AsSingletonVector<Declaration*, MakeSpecializationDeclaration>()),
Rule({Token("#include"), &externalString}, Rule({Token("#include"), &externalString},
AsSingletonVector<Declaration*, MakeCppIncludeDeclaration>())}; AsSingletonVector<Declaration*, MakeCppIncludeDeclaration>())};
......
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