Skip to content

Commit f8575fd

Browse files
authored
Port and use GetTypeOfSymbolAtLocation in quick info (#953)
1 parent 86c0de1 commit f8575fd

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

internal/checker/checker.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15170,8 +15170,41 @@ func (c *Checker) getWriteTypeOfSymbol(symbol *ast.Symbol) *Type {
1517015170
}
1517115171

1517215172
func (c *Checker) GetTypeOfSymbolAtLocation(symbol *ast.Symbol, location *ast.Node) *Type {
15173-
// !!!
15174-
return c.getTypeOfSymbol(symbol)
15173+
symbol = c.getExportSymbolOfValueSymbolIfExported(symbol)
15174+
if location != nil {
15175+
// If we have an identifier or a property access at the given location, if the location is
15176+
// an dotted name expression, and if the location is not an assignment target, obtain the type
15177+
// of the expression (which will reflect control flow analysis). If the expression indeed
15178+
// resolved to the given symbol, return the narrowed type.
15179+
if ast.IsIdentifier(location) || ast.IsPrivateIdentifier(location) {
15180+
if isRightSideOfQualifiedNameOrPropertyAccess(location) {
15181+
location = location.Parent
15182+
}
15183+
if ast.IsExpressionNode(location) && (!ast.IsAssignmentTarget(location) || isWriteAccess(location)) {
15184+
var t *Type
15185+
if isWriteAccess(location) && location.Kind == ast.KindPropertyAccessExpression {
15186+
t = c.checkPropertyAccessExpression(location, CheckModeNormal, true /*writeOnly*/)
15187+
} else {
15188+
t = c.getTypeOfExpression(location)
15189+
}
15190+
if c.getExportSymbolOfValueSymbolIfExported(c.symbolNodeLinks.Get(location).resolvedSymbol) == symbol {
15191+
return c.removeOptionalTypeMarker(t)
15192+
}
15193+
}
15194+
}
15195+
if ast.IsDeclarationName(location) && ast.IsSetAccessorDeclaration(location.Parent) && c.getAnnotatedAccessorTypeNode(location.Parent) != nil {
15196+
return c.getWriteTypeOfAccessors(location.Parent.Symbol())
15197+
}
15198+
// The location isn't a reference to the given symbol, meaning we're being asked
15199+
// a hypothetical question of what type the symbol would have if there was a reference
15200+
// to it at the given location. Since we have no control flow information for the
15201+
// hypothetical reference (control flow information is created and attached by the
15202+
// binder), we simply return the declared type of the symbol.
15203+
if isRightSideOfAccessExpression(location) && isWriteAccess(location.Parent) {
15204+
return c.getWriteTypeOfSymbol(symbol)
15205+
}
15206+
}
15207+
return c.getNonMissingTypeOfSymbol(symbol)
1517515208
}
1517615209

1517715210
func (c *Checker) getTypeOfSymbol(symbol *ast.Symbol) *Type {

internal/checker/printer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func (c *Checker) GetQuickInfoAtLocation(node *ast.Node) string {
126126
}
127127
p.printName(symbol)
128128
p.print(": ")
129-
p.printType(c.getTypeOfSymbol(symbol))
129+
p.printType(c.GetTypeOfSymbolAtLocation(symbol, node))
130130
case flags&ast.SymbolFlagsEnumMember != 0:
131131
p.print("(enum member) ")
132132
t := c.getTypeOfSymbol(symbol)

internal/checker/utilities.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,11 @@ func isRightSideOfQualifiedNameOrPropertyAccess(node *ast.Node) bool {
377377
return false
378378
}
379379

380+
func isRightSideOfAccessExpression(node *ast.Node) bool {
381+
return node.Parent != nil && (ast.IsPropertyAccessExpression(node.Parent) && node.Parent.Name() == node ||
382+
ast.IsElementAccessExpression(node.Parent) && node.Parent.AsElementAccessExpression().ArgumentExpression == node)
383+
}
384+
380385
func isTopLevelInExternalModuleAugmentation(node *ast.Node) bool {
381386
return node != nil && node.Parent != nil && ast.IsModuleBlock(node.Parent) && ast.IsExternalModuleAugmentation(node.Parent.Parent)
382387
}

0 commit comments

Comments
 (0)