[torque-ls] Support "goto-definition" for Types in extends clause
Type declaration may contain a parent type in an "extends" clause. This CL changes the token type of the name after such a clause from std::string to Identifier*. The resulting SourcePosition is then used to implement the "goto-definition" link from that name to the definition of the parent type. R=mvstanton@chromium.org Bug: v8:8880 Change-Id: I9ea6cd83e4d6ef535906e36626f64d458c7d0270 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1511481 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Michael Stanton <mvstanton@chromium.org> Commit-Queue: Simon Zünd <szuend@chromium.org> Cr-Commit-Position: refs/heads/master@{#60179}
This commit is contained in:
parent
9d34bb85ba
commit
8e9e151f49
@ -665,18 +665,18 @@ struct BlockStatement : Statement {
|
||||
struct TypeDeclaration : Declaration {
|
||||
DEFINE_AST_NODE_LEAF_BOILERPLATE(TypeDeclaration)
|
||||
TypeDeclaration(SourcePosition pos, Identifier* name, bool transient,
|
||||
base::Optional<std::string> extends,
|
||||
base::Optional<Identifier*> extends,
|
||||
base::Optional<std::string> generates,
|
||||
base::Optional<std::string> constexpr_generates)
|
||||
: Declaration(kKind, pos),
|
||||
name(name),
|
||||
transient(transient),
|
||||
extends(std::move(extends)),
|
||||
extends(extends),
|
||||
generates(std::move(generates)),
|
||||
constexpr_generates(std::move(constexpr_generates)) {}
|
||||
Identifier* name;
|
||||
bool transient;
|
||||
base::Optional<std::string> extends;
|
||||
base::Optional<Identifier*> extends;
|
||||
base::Optional<std::string> generates;
|
||||
base::Optional<std::string> constexpr_generates;
|
||||
};
|
||||
|
@ -348,9 +348,12 @@ void DeclarationVisitor::Visit(TypeDeclaration* decl) {
|
||||
MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + decl->name->value);
|
||||
constexpr_name->pos = decl->name->pos;
|
||||
|
||||
base::Optional<std::string> constexpr_extends;
|
||||
if (decl->extends)
|
||||
constexpr_extends = CONSTEXPR_TYPE_PREFIX + *decl->extends;
|
||||
base::Optional<Identifier*> constexpr_extends;
|
||||
if (decl->extends) {
|
||||
constexpr_extends =
|
||||
MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + (*decl->extends)->value);
|
||||
(*constexpr_extends)->pos = (*decl->extends)->pos;
|
||||
}
|
||||
Declarations::DeclareAbstractType(constexpr_name, false,
|
||||
*decl->constexpr_generates, type,
|
||||
constexpr_extends);
|
||||
|
@ -160,11 +160,16 @@ Namespace* Declarations::DeclareNamespace(const std::string& name) {
|
||||
const AbstractType* Declarations::DeclareAbstractType(
|
||||
const Identifier* name, bool transient, std::string generated,
|
||||
base::Optional<const AbstractType*> non_constexpr_version,
|
||||
const base::Optional<std::string>& parent) {
|
||||
const base::Optional<Identifier*>& parent) {
|
||||
CheckAlreadyDeclared<TypeAlias>(name->value, "type");
|
||||
const Type* parent_type = nullptr;
|
||||
if (parent) {
|
||||
parent_type = LookupType(QualifiedName{*parent});
|
||||
auto parent_type_alias = LookupTypeAlias(QualifiedName{(*parent)->value});
|
||||
parent_type = parent_type_alias->type();
|
||||
if (GlobalContext::collect_language_server_data()) {
|
||||
LanguageServerData::AddDefinition(
|
||||
(*parent)->pos, parent_type_alias->GetDeclarationPosition());
|
||||
}
|
||||
}
|
||||
if (generated == "" && parent) {
|
||||
generated = parent_type->GetGeneratedTNodeTypeName();
|
||||
|
@ -77,7 +77,7 @@ class Declarations {
|
||||
static const AbstractType* DeclareAbstractType(
|
||||
const Identifier* name, bool transient, std::string generated,
|
||||
base::Optional<const AbstractType*> non_constexpr_version,
|
||||
const base::Optional<std::string>& parent = {});
|
||||
const base::Optional<Identifier*>& parent = {});
|
||||
|
||||
static void DeclareType(const Identifier* name, const Type* type,
|
||||
bool redeclaration);
|
||||
|
@ -45,6 +45,7 @@ enum class ParseResultHolderBase::TypeId {
|
||||
kStdVectorOfString,
|
||||
kExpressionPtr,
|
||||
kIdentifierPtr,
|
||||
kOptionalIdentifierPtr,
|
||||
kLocationExpressionPtr,
|
||||
kStatementPtr,
|
||||
kDeclarationPtr,
|
||||
|
@ -64,6 +64,10 @@ template <>
|
||||
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Identifier*>::id =
|
||||
ParseResultTypeId::kIdentifierPtr;
|
||||
template <>
|
||||
V8_EXPORT_PRIVATE const ParseResultTypeId
|
||||
ParseResultHolder<base::Optional<Identifier*>>::id =
|
||||
ParseResultTypeId::kOptionalIdentifierPtr;
|
||||
template <>
|
||||
V8_EXPORT_PRIVATE const ParseResultTypeId
|
||||
ParseResultHolder<LocationExpression*>::id =
|
||||
ParseResultTypeId::kLocationExpressionPtr;
|
||||
@ -521,12 +525,12 @@ base::Optional<ParseResult> MakeTypeDeclaration(
|
||||
if (!IsValidTypeName(name->value)) {
|
||||
NamingConventionError("Type", name->value, "UpperCamelCase");
|
||||
}
|
||||
auto extends = child_results->NextAs<base::Optional<std::string>>();
|
||||
auto extends = child_results->NextAs<base::Optional<Identifier*>>();
|
||||
auto generates = child_results->NextAs<base::Optional<std::string>>();
|
||||
auto constexpr_generates =
|
||||
child_results->NextAs<base::Optional<std::string>>();
|
||||
Declaration* result = MakeNode<TypeDeclaration>(
|
||||
name, transient, std::move(extends), std::move(generates),
|
||||
Declaration* result =
|
||||
MakeNode<TypeDeclaration>(name, transient, extends, std::move(generates),
|
||||
std::move(constexpr_generates));
|
||||
return ParseResult{result};
|
||||
}
|
||||
@ -1604,7 +1608,7 @@ struct TorqueGrammar : Grammar {
|
||||
List<StructFieldExpression>(&structField), Token("}")},
|
||||
MakeStructDeclaration),
|
||||
Rule({CheckIf(Token("transient")), Token("type"), &name,
|
||||
Optional<std::string>(Sequence({Token("extends"), &identifier})),
|
||||
Optional<Identifier*>(Sequence({Token("extends"), &name})),
|
||||
Optional<std::string>(
|
||||
Sequence({Token("generates"), &externalString})),
|
||||
Optional<std::string>(
|
||||
|
@ -52,6 +52,23 @@ TEST(LanguageServer, GotoTypeDefinition) {
|
||||
EXPECT_EQ(*maybe_position, (SourcePosition{id, {3, 5}, {3, 7}}));
|
||||
}
|
||||
|
||||
TEST(LanguageServer, GotoTypeDefinitionExtends) {
|
||||
const std::string source =
|
||||
"type void;\n"
|
||||
"type never;\n"
|
||||
"type T1 generates 'TNode<T1>';\n"
|
||||
"type T2 extends T1 generates 'TNode<T2>';";
|
||||
|
||||
TestCompiler compiler;
|
||||
compiler.Compile(source);
|
||||
|
||||
// Find the definition for 'T1' of the extends clause on line 3.
|
||||
const SourceId id = SourceFileMap::GetSourceId("<torque>");
|
||||
auto maybe_position = LanguageServerData::FindDefinition(id, {3, 16});
|
||||
ASSERT_TRUE(maybe_position.has_value());
|
||||
EXPECT_EQ(*maybe_position, (SourcePosition{id, {2, 5}, {2, 7}}));
|
||||
}
|
||||
|
||||
} // namespace torque
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
Loading…
Reference in New Issue
Block a user