[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 {
|
struct TypeDeclaration : Declaration {
|
||||||
DEFINE_AST_NODE_LEAF_BOILERPLATE(TypeDeclaration)
|
DEFINE_AST_NODE_LEAF_BOILERPLATE(TypeDeclaration)
|
||||||
TypeDeclaration(SourcePosition pos, Identifier* name, bool transient,
|
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> generates,
|
||||||
base::Optional<std::string> constexpr_generates)
|
base::Optional<std::string> constexpr_generates)
|
||||||
: Declaration(kKind, pos),
|
: Declaration(kKind, pos),
|
||||||
name(name),
|
name(name),
|
||||||
transient(transient),
|
transient(transient),
|
||||||
extends(std::move(extends)),
|
extends(extends),
|
||||||
generates(std::move(generates)),
|
generates(std::move(generates)),
|
||||||
constexpr_generates(std::move(constexpr_generates)) {}
|
constexpr_generates(std::move(constexpr_generates)) {}
|
||||||
Identifier* name;
|
Identifier* name;
|
||||||
bool transient;
|
bool transient;
|
||||||
base::Optional<std::string> extends;
|
base::Optional<Identifier*> extends;
|
||||||
base::Optional<std::string> generates;
|
base::Optional<std::string> generates;
|
||||||
base::Optional<std::string> constexpr_generates;
|
base::Optional<std::string> constexpr_generates;
|
||||||
};
|
};
|
||||||
|
@ -348,9 +348,12 @@ void DeclarationVisitor::Visit(TypeDeclaration* decl) {
|
|||||||
MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + decl->name->value);
|
MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + decl->name->value);
|
||||||
constexpr_name->pos = decl->name->pos;
|
constexpr_name->pos = decl->name->pos;
|
||||||
|
|
||||||
base::Optional<std::string> constexpr_extends;
|
base::Optional<Identifier*> constexpr_extends;
|
||||||
if (decl->extends)
|
if (decl->extends) {
|
||||||
constexpr_extends = CONSTEXPR_TYPE_PREFIX + *decl->extends;
|
constexpr_extends =
|
||||||
|
MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + (*decl->extends)->value);
|
||||||
|
(*constexpr_extends)->pos = (*decl->extends)->pos;
|
||||||
|
}
|
||||||
Declarations::DeclareAbstractType(constexpr_name, false,
|
Declarations::DeclareAbstractType(constexpr_name, false,
|
||||||
*decl->constexpr_generates, type,
|
*decl->constexpr_generates, type,
|
||||||
constexpr_extends);
|
constexpr_extends);
|
||||||
|
@ -160,11 +160,16 @@ Namespace* Declarations::DeclareNamespace(const std::string& name) {
|
|||||||
const AbstractType* Declarations::DeclareAbstractType(
|
const AbstractType* Declarations::DeclareAbstractType(
|
||||||
const Identifier* name, bool transient, std::string generated,
|
const Identifier* name, bool transient, std::string generated,
|
||||||
base::Optional<const AbstractType*> non_constexpr_version,
|
base::Optional<const AbstractType*> non_constexpr_version,
|
||||||
const base::Optional<std::string>& parent) {
|
const base::Optional<Identifier*>& parent) {
|
||||||
CheckAlreadyDeclared<TypeAlias>(name->value, "type");
|
CheckAlreadyDeclared<TypeAlias>(name->value, "type");
|
||||||
const Type* parent_type = nullptr;
|
const Type* parent_type = nullptr;
|
||||||
if (parent) {
|
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) {
|
if (generated == "" && parent) {
|
||||||
generated = parent_type->GetGeneratedTNodeTypeName();
|
generated = parent_type->GetGeneratedTNodeTypeName();
|
||||||
|
@ -77,7 +77,7 @@ class Declarations {
|
|||||||
static const AbstractType* DeclareAbstractType(
|
static const AbstractType* DeclareAbstractType(
|
||||||
const Identifier* name, bool transient, std::string generated,
|
const Identifier* name, bool transient, std::string generated,
|
||||||
base::Optional<const AbstractType*> non_constexpr_version,
|
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,
|
static void DeclareType(const Identifier* name, const Type* type,
|
||||||
bool redeclaration);
|
bool redeclaration);
|
||||||
|
@ -45,6 +45,7 @@ enum class ParseResultHolderBase::TypeId {
|
|||||||
kStdVectorOfString,
|
kStdVectorOfString,
|
||||||
kExpressionPtr,
|
kExpressionPtr,
|
||||||
kIdentifierPtr,
|
kIdentifierPtr,
|
||||||
|
kOptionalIdentifierPtr,
|
||||||
kLocationExpressionPtr,
|
kLocationExpressionPtr,
|
||||||
kStatementPtr,
|
kStatementPtr,
|
||||||
kDeclarationPtr,
|
kDeclarationPtr,
|
||||||
|
@ -64,6 +64,10 @@ template <>
|
|||||||
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Identifier*>::id =
|
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Identifier*>::id =
|
||||||
ParseResultTypeId::kIdentifierPtr;
|
ParseResultTypeId::kIdentifierPtr;
|
||||||
template <>
|
template <>
|
||||||
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
||||||
|
ParseResultHolder<base::Optional<Identifier*>>::id =
|
||||||
|
ParseResultTypeId::kOptionalIdentifierPtr;
|
||||||
|
template <>
|
||||||
V8_EXPORT_PRIVATE const ParseResultTypeId
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
||||||
ParseResultHolder<LocationExpression*>::id =
|
ParseResultHolder<LocationExpression*>::id =
|
||||||
ParseResultTypeId::kLocationExpressionPtr;
|
ParseResultTypeId::kLocationExpressionPtr;
|
||||||
@ -521,12 +525,12 @@ base::Optional<ParseResult> MakeTypeDeclaration(
|
|||||||
if (!IsValidTypeName(name->value)) {
|
if (!IsValidTypeName(name->value)) {
|
||||||
NamingConventionError("Type", name->value, "UpperCamelCase");
|
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 generates = child_results->NextAs<base::Optional<std::string>>();
|
||||||
auto constexpr_generates =
|
auto constexpr_generates =
|
||||||
child_results->NextAs<base::Optional<std::string>>();
|
child_results->NextAs<base::Optional<std::string>>();
|
||||||
Declaration* result = MakeNode<TypeDeclaration>(
|
Declaration* result =
|
||||||
name, transient, std::move(extends), std::move(generates),
|
MakeNode<TypeDeclaration>(name, transient, extends, std::move(generates),
|
||||||
std::move(constexpr_generates));
|
std::move(constexpr_generates));
|
||||||
return ParseResult{result};
|
return ParseResult{result};
|
||||||
}
|
}
|
||||||
@ -1604,7 +1608,7 @@ struct TorqueGrammar : Grammar {
|
|||||||
List<StructFieldExpression>(&structField), Token("}")},
|
List<StructFieldExpression>(&structField), Token("}")},
|
||||||
MakeStructDeclaration),
|
MakeStructDeclaration),
|
||||||
Rule({CheckIf(Token("transient")), Token("type"), &name,
|
Rule({CheckIf(Token("transient")), Token("type"), &name,
|
||||||
Optional<std::string>(Sequence({Token("extends"), &identifier})),
|
Optional<Identifier*>(Sequence({Token("extends"), &name})),
|
||||||
Optional<std::string>(
|
Optional<std::string>(
|
||||||
Sequence({Token("generates"), &externalString})),
|
Sequence({Token("generates"), &externalString})),
|
||||||
Optional<std::string>(
|
Optional<std::string>(
|
||||||
|
@ -52,6 +52,23 @@ TEST(LanguageServer, GotoTypeDefinition) {
|
|||||||
EXPECT_EQ(*maybe_position, (SourcePosition{id, {3, 5}, {3, 7}}));
|
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 torque
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
Loading…
Reference in New Issue
Block a user