Skip to content

Commit 7faf195

Browse files
committed
Fix documentation not showing for properties of intersected type tables
Fixes #715
1 parent 095e371 commit 7faf195

File tree

13 files changed

+126
-45
lines changed

13 files changed

+126
-45
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1414

1515
- Fixed a regression in 1.32.0 causing `luau-lsp.ignoreGlobs` and `luau-lsp.completion.imports.ignoreGlobs` to not work ([#719](https://github.com/JohnnyMorganz/luau-lsp/issues/719))
1616
- Fixed auto-imports injecting a require in the middle of a multi-line require when introducing a require with lower lexicographical ordering ([#725](https://github.com/JohnnyMorganz/luau-lsp/issues/725))
17+
- Fixed documentation not showing for properties of an intersected type table in Hover and Autocomplete ([#715](https://github.com/JohnnyMorganz/luau-lsp/issues/715))
1718

1819
## [1.32.1] - 2024-07-23
1920

src/LuauExt.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -283,18 +283,19 @@ std::optional<Luau::Location> lookupTypeLocation(const Luau::Scope& deepScope, c
283283
}
284284
}
285285

286-
std::optional<Luau::Property> lookupProp(const Luau::TypeId& parentType, const Luau::Name& name)
286+
// Returns [base, property] - base is important during intersections
287+
std::optional<std::pair<Luau::TypeId, Luau::Property>> lookupProp(const Luau::TypeId& parentType, const Luau::Name& name)
287288
{
288289
if (auto ctv = Luau::get<Luau::ClassType>(parentType))
289290
{
290291
if (auto prop = Luau::lookupClassProp(ctv, name))
291-
return *prop;
292+
return std::make_pair(parentType, *prop);
292293
}
293294
else if (auto tbl = Luau::get<Luau::TableType>(parentType))
294295
{
295296
if (tbl->props.find(name) != tbl->props.end())
296297
{
297-
return tbl->props.at(name);
298+
return std::make_pair(parentType, tbl->props.at(name));
298299
}
299300
}
300301
else if (auto mt = Luau::get<Luau::MetatableType>(parentType))
@@ -317,21 +318,23 @@ std::optional<Luau::Property> lookupProp(const Luau::TypeId& parentType, const L
317318
}
318319
}
319320

320-
if (auto mtBaseTable = Luau::get<Luau::TableType>(Luau::follow(mt->table)))
321+
auto baseTableTy = Luau::follow(mt->table);
322+
if (auto mtBaseTable = Luau::get<Luau::TableType>(baseTableTy))
321323
{
322324
if (mtBaseTable->props.find(name) != mtBaseTable->props.end())
323325
{
324-
return mtBaseTable->props.at(name);
326+
return std::make_pair(baseTableTy, mtBaseTable->props.at(name));
325327
}
326328
}
327329
}
328-
// else if (auto i = get<Luau::IntersectionType>(parentType))
329-
// {
330-
// for (Luau::TypeId ty : i->parts)
331-
// {
332-
// // TODO: find the corresponding ty
333-
// }
334-
// }
330+
else if (auto i = Luau::get<Luau::IntersectionType>(parentType))
331+
{
332+
for (Luau::TypeId ty : i->parts)
333+
{
334+
if (auto prop = lookupProp(Luau::follow(ty), name))
335+
return prop;
336+
}
337+
}
335338
// else if (auto u = get<Luau::UnionType>(parentType))
336339
// {
337340
// // Find the corresponding ty

src/include/LSP/LuauExt.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ std::vector<Luau::Location> findTypeReferences(const Luau::SourceModule& source,
5252
std::optional<Luau::Location> getLocation(Luau::TypeId type);
5353

5454
std::optional<Luau::Location> lookupTypeLocation(const Luau::Scope& deepScope, const Luau::Name& name);
55-
std::optional<Luau::Property> lookupProp(const Luau::TypeId& parentType, const Luau::Name& name);
55+
std::optional<std::pair<Luau::TypeId, Luau::Property>> lookupProp(const Luau::TypeId& parentType, const Luau::Name& name);
5656
std::optional<Luau::ModuleName> lookupImportedModule(const Luau::Scope& deepScope, const Luau::Name& name);
5757

5858
// Converts a UTF-8 position to a UTF-16 position, using the provided text document if available

src/include/LSP/Workspace.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ class WorkspaceFolder
9696
public:
9797
std::vector<std::string> getComments(const Luau::ModuleName& moduleName, const Luau::Location& node);
9898
std::optional<std::string> getDocumentationForType(const Luau::TypeId ty);
99-
std::optional<std::string> getDocumentationForAutocompleteEntry(
100-
const Luau::AutocompleteEntry& entry, const std::vector<Luau::AstNode*>& ancestry, const Luau::ModuleName& moduleName);
99+
std::optional<std::string> getDocumentationForAutocompleteEntry(const std::string& name, const Luau::AutocompleteEntry& entry,
100+
const std::vector<Luau::AstNode*>& ancestry, const Luau::ModuleName& moduleName);
101101
std::vector<Reference> findAllReferences(const Luau::TypeId ty, std::optional<Luau::Name> property = std::nullopt);
102102
std::vector<Reference> findAllTypeReferences(const Luau::ModuleName& moduleName, const Luau::Name& typeName);
103103

src/operations/CallHierarchy.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,8 @@ static Luau::TypeId lookupFunctionCallType(Luau::ModulePtr module, const Luau::A
5151
if (auto parentIt = module->astTypes.find(index->expr))
5252
{
5353
auto parentType = Luau::follow(*parentIt);
54-
auto prop = lookupProp(parentType, index->index.value);
55-
if (prop)
56-
return Luau::follow(prop->type());
54+
if (auto prop = lookupProp(parentType, index->index.value))
55+
return Luau::follow(prop->second.type());
5756
}
5857
}
5958

@@ -163,7 +162,7 @@ std::vector<lsp::CallHierarchyItem> WorkspaceFolder::prepareCallHierarchy(const
163162
auto prop = lookupProp(ty, *it);
164163
if (!prop)
165164
return {};
166-
ty = Luau::follow(prop->type());
165+
ty = Luau::follow(prop->second.type());
167166
}
168167
}
169168

src/operations/Completion.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ static std::pair<std::string, std::string> computeLabelDetailsForFunction(const
331331
}
332332

333333
std::optional<std::string> WorkspaceFolder::getDocumentationForAutocompleteEntry(
334-
const Luau::AutocompleteEntry& entry, const std::vector<Luau::AstNode*>& ancestry, const Luau::ModuleName& moduleName)
334+
const std::string& name, const Luau::AutocompleteEntry& entry, const std::vector<Luau::AstNode*>& ancestry, const Luau::ModuleName& moduleName)
335335
{
336336
if (entry.documentationSymbol)
337337
if (auto docs = printDocumentation(client->documentation, *entry.documentationSymbol))
@@ -366,7 +366,13 @@ std::optional<std::string> WorkspaceFolder::getDocumentationForAutocompleteEntry
366366
}
367367

368368
if (parentTy)
369-
definitionModuleName = Luau::getDefinitionModuleName(*parentTy);
369+
{
370+
// parentTy might be an intersected type, find the actual base ttv
371+
if (auto propInformation = lookupProp(*parentTy, name))
372+
definitionModuleName = Luau::getDefinitionModuleName(propInformation->first);
373+
else
374+
definitionModuleName = Luau::getDefinitionModuleName(*parentTy);
375+
}
370376
}
371377
}
372378

@@ -432,7 +438,7 @@ std::vector<lsp::CompletionItem> WorkspaceFolder::completion(const lsp::Completi
432438
lsp::CompletionItem item;
433439
item.label = name;
434440

435-
if (auto documentationString = getDocumentationForAutocompleteEntry(entry, result.ancestry, moduleName))
441+
if (auto documentationString = getDocumentationForAutocompleteEntry(name, entry, result.ancestry, moduleName))
436442
item.documentation = {lsp::MarkupKind::Markdown, documentationString.value()};
437443

438444
item.deprecated = deprecated(entry, item.documentation);

src/operations/GotoDefinition.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,14 @@ lsp::DefinitionResult WorkspaceFolder::gotoDefinition(const lsp::DefinitionParam
7373
for (auto it = keys.rbegin(); it != keys.rend(); ++it)
7474
{
7575
auto base = properties.empty() ? *baseType : Luau::follow(properties.back().type());
76-
auto prop = lookupProp(base, *it);
77-
if (!prop)
76+
auto propInformation = lookupProp(base, *it);
77+
if (!propInformation)
7878
return result;
7979

80-
definitionModuleName = Luau::getDefinitionModuleName(base);
81-
location = prop->location;
82-
properties.push_back(*prop);
80+
auto [baseTy, prop] = propInformation.value();
81+
definitionModuleName = Luau::getDefinitionModuleName(baseTy);
82+
location = prop.location;
83+
properties.push_back(prop);
8384
}
8485
}
8586

src/operations/Hover.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ std::optional<lsp::Hover> WorkspaceFolder::hover(const lsp::HoverParams& params)
181181
documentationLocation = {definitionModuleName.value(), prop.location};
182182
auto resolvedProperty = lookupProp(parentType, prop.name.value);
183183
if (resolvedProperty)
184-
type = resolvedProperty->type();
184+
type = resolvedProperty->second.type();
185185
break;
186186
}
187187
}
@@ -229,16 +229,16 @@ std::optional<lsp::Hover> WorkspaceFolder::hover(const lsp::HoverParams& params)
229229
{
230230
auto parentType = Luau::follow(*parentIt);
231231
auto indexName = index->index.value;
232-
auto prop = lookupProp(parentType, indexName);
233-
if (prop)
232+
if (auto propInformation = lookupProp(parentType, indexName))
234233
{
235-
type = prop->type();
236-
if (auto definitionModuleName = Luau::getDefinitionModuleName(parentType))
234+
auto [baseTy, prop] = propInformation.value();
235+
type = prop.type();
236+
if (auto definitionModuleName = Luau::getDefinitionModuleName(baseTy))
237237
{
238-
if (prop->location)
239-
documentationLocation = {definitionModuleName.value(), prop->location.value()};
240-
else if (prop->typeLocation)
241-
documentationLocation = {definitionModuleName.value(), prop->typeLocation.value()};
238+
if (prop.location)
239+
documentationLocation = {definitionModuleName.value(), prop.location.value()};
240+
else if (prop.typeLocation)
241+
documentationLocation = {definitionModuleName.value(), prop.typeLocation.value()};
242242
}
243243
}
244244
}

src/operations/References.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,15 @@ std::vector<Reference> WorkspaceFolder::findAllReferences(Luau::TypeId ty, std::
115115
// If its a property, include its original declaration location if not yet found
116116
if (property)
117117
{
118-
if (auto prop = lookupProp(ty, *property); prop && prop->location)
118+
if (auto propInformation = lookupProp(ty, *property))
119119
{
120-
auto reference = Reference{ttv->definitionModuleName, prop->location.value()};
121-
if (!contains(references, reference))
122-
references.push_back(reference);
120+
auto [baseTy, prop] = propInformation.value();
121+
if (prop.location)
122+
{
123+
auto reference = Reference{Luau::getDefinitionModuleName(baseTy).value_or(ttv->definitionModuleName), prop.location.value()};
124+
if (!contains(references, reference))
125+
references.push_back(reference);
126+
}
123127
}
124128
}
125129

src/operations/SemanticTokens.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,15 +289,16 @@ struct SemanticTokensVisitor : public Luau::AstVisitor
289289
}
290290

291291
auto ty = Luau::follow(*parentTy);
292-
if (auto prop = lookupProp(ty, std::string(index->index.value)))
292+
if (auto propInformation = lookupProp(ty, std::string(index->index.value)))
293293
{
294+
auto prop = propInformation->second;
294295
auto defaultType = lsp::SemanticTokenTypes::Property;
295296
if (parentIsEnum)
296297
defaultType = lsp::SemanticTokenTypes::Enum;
297-
else if (Luau::hasTag(prop->tags, "EnumItem"))
298+
else if (Luau::hasTag(prop.tags, "EnumItem"))
298299
defaultType = lsp::SemanticTokenTypes::EnumMember;
299300

300-
auto type = inferTokenType(prop->type(), defaultType);
301+
auto type = inferTokenType(prop.type(), defaultType);
301302
auto modifiers = lsp::SemanticTokenModifiers::None;
302303
if (parentIsBuiltin)
303304
{

0 commit comments

Comments
 (0)