Skip to content

Commit bdee372

Browse files
authored
findAllReferences inital port (#882)
1 parent b0278c5 commit bdee372

File tree

15 files changed

+2857
-53
lines changed

15 files changed

+2857
-53
lines changed

internal/ast/utilities.go

Lines changed: 90 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,25 @@ func IsStatic(node *Node) bool {
10401040
return IsClassElement(node) && HasStaticModifier(node) || IsClassStaticBlockDeclaration(node)
10411041
}
10421042

1043+
func CanHaveSymbol(node *Node) bool {
1044+
switch node.Kind {
1045+
case KindArrowFunction, KindBinaryExpression, KindBindingElement, KindCallExpression, KindCallSignature,
1046+
KindClassDeclaration, KindClassExpression, KindClassStaticBlockDeclaration, KindConstructor, KindConstructorType,
1047+
KindConstructSignature, KindElementAccessExpression, KindEnumDeclaration, KindEnumMember, KindExportAssignment,
1048+
KindExportDeclaration, KindExportSpecifier, KindFunctionDeclaration, KindFunctionExpression, KindFunctionType,
1049+
KindGetAccessor, KindImportClause, KindImportEqualsDeclaration, KindImportSpecifier, KindIndexSignature,
1050+
KindInterfaceDeclaration, KindJSExportAssignment, KindJSTypeAliasDeclaration, KindCommonJSExport,
1051+
KindJsxAttribute, KindJsxAttributes, KindJsxSpreadAttribute, KindMappedType, KindMethodDeclaration,
1052+
KindMethodSignature, KindModuleDeclaration, KindNamedTupleMember, KindNamespaceExport, KindNamespaceExportDeclaration,
1053+
KindNamespaceImport, KindNewExpression, KindNoSubstitutionTemplateLiteral, KindNumericLiteral, KindObjectLiteralExpression,
1054+
KindParameter, KindPropertyAccessExpression, KindPropertyAssignment, KindPropertyDeclaration, KindPropertySignature,
1055+
KindSetAccessor, KindShorthandPropertyAssignment, KindSourceFile, KindSpreadAssignment, KindStringLiteral,
1056+
KindTypeAliasDeclaration, KindTypeLiteral, KindTypeParameter, KindVariableDeclaration:
1057+
return true
1058+
}
1059+
return false
1060+
}
1061+
10431062
func CanHaveIllegalDecorators(node *Node) bool {
10441063
switch node.Kind {
10451064
case KindPropertyAssignment, KindShorthandPropertyAssignment,
@@ -1260,6 +1279,10 @@ func IsExternalModuleImportEqualsDeclaration(node *Node) bool {
12601279
return node.Kind == KindImportEqualsDeclaration && node.AsImportEqualsDeclaration().ModuleReference.Kind == KindExternalModuleReference
12611280
}
12621281

1282+
func IsModuleOrEnumDeclaration(node *Node) bool {
1283+
return node.Kind == KindModuleDeclaration || node.Kind == KindEnumDeclaration
1284+
}
1285+
12631286
func IsLiteralImportTypeNode(node *Node) bool {
12641287
return IsImportTypeNode(node) && IsLiteralTypeNode(node.AsImportTypeNode().Argument) && IsStringLiteral(node.AsImportTypeNode().Argument.AsLiteralTypeNode().Literal)
12651288
}
@@ -1301,6 +1324,27 @@ func IsThisParameter(node *Node) bool {
13011324
return IsParameter(node) && node.Name() != nil && IsThisIdentifier(node.Name())
13021325
}
13031326

1327+
func IsBindableStaticAccessExpression(node *Node, excludeThisKeyword bool) bool {
1328+
return IsPropertyAccessExpression(node) &&
1329+
(!excludeThisKeyword && node.Expression().Kind == KindThisKeyword || IsIdentifier(node.Name()) && IsBindableStaticNameExpression(node.Expression() /*excludeThisKeyword*/, true)) ||
1330+
IsBindableStaticElementAccessExpression(node, excludeThisKeyword)
1331+
}
1332+
1333+
func IsBindableStaticElementAccessExpression(node *Node, excludeThisKeyword bool) bool {
1334+
return IsLiteralLikeElementAccess(node) &&
1335+
((!excludeThisKeyword && node.Expression().Kind == KindThisKeyword) ||
1336+
IsEntityNameExpression(node.Expression()) ||
1337+
IsBindableStaticAccessExpression(node.Expression() /*excludeThisKeyword*/, true))
1338+
}
1339+
1340+
func IsLiteralLikeElementAccess(node *Node) bool {
1341+
return IsElementAccessExpression(node) && IsStringOrNumericLiteralLike(node.AsElementAccessExpression().ArgumentExpression)
1342+
}
1343+
1344+
func IsBindableStaticNameExpression(node *Node, excludeThisKeyword bool) bool {
1345+
return IsEntityNameExpression(node) || IsBindableStaticAccessExpression(node, excludeThisKeyword)
1346+
}
1347+
13041348
// Does not handle signed numeric names like `a[+0]` - handling those would require handling prefix unary expressions
13051349
// throughout late binding handling as well, which is awkward (but ultimately probably doable if there is demand)
13061350
func GetElementOrPropertyAccessName(node *Node) *Node {
@@ -1319,6 +1363,13 @@ func GetElementOrPropertyAccessName(node *Node) *Node {
13191363
panic("Unhandled case in GetElementOrPropertyAccessName")
13201364
}
13211365

1366+
func GetInitializerOfBinaryExpression(expr *BinaryExpression) *Expression {
1367+
for IsBinaryExpression(expr.Right) {
1368+
expr = expr.Right.AsBinaryExpression()
1369+
}
1370+
return expr.Right.Expression()
1371+
}
1372+
13221373
func IsExpressionWithTypeArgumentsInClassExtendsClause(node *Node) bool {
13231374
return TryGetClassExtendingExpressionWithTypeArguments(node) != nil
13241375
}
@@ -1662,6 +1713,40 @@ func GetThisContainer(node *Node, includeArrowFunctions bool, includeClassComput
16621713
}
16631714
}
16641715

1716+
func GetSuperContainer(node *Node, stopOnFunctions bool) *Node {
1717+
for {
1718+
node = node.Parent
1719+
if node == nil {
1720+
return nil
1721+
}
1722+
switch node.Kind {
1723+
case KindComputedPropertyName:
1724+
node = node.Parent
1725+
break
1726+
case KindFunctionDeclaration, KindFunctionExpression, KindArrowFunction:
1727+
if !stopOnFunctions {
1728+
continue
1729+
}
1730+
// falls through
1731+
1732+
case KindPropertyDeclaration, KindPropertySignature, KindMethodDeclaration, KindMethodSignature, KindConstructor, KindGetAccessor, KindSetAccessor, KindClassStaticBlockDeclaration:
1733+
return node
1734+
case KindDecorator:
1735+
// Decorators are always applied outside of the body of a class or method.
1736+
if node.Parent.Kind == KindParameter && IsClassElement(node.Parent.Parent) {
1737+
// If the decorator's parent is a Parameter, we resolve the this container from
1738+
// the grandparent class declaration.
1739+
node = node.Parent.Parent
1740+
} else if IsClassElement(node.Parent) {
1741+
// If the decorator's parent is a class element, we resolve the 'this' container
1742+
// from the parent class declaration.
1743+
node = node.Parent
1744+
}
1745+
break
1746+
}
1747+
}
1748+
}
1749+
16651750
func GetImmediatelyInvokedFunctionExpression(fn *Node) *Node {
16661751
if IsFunctionExpressionOrArrowFunction(fn) {
16671752
prev := fn
@@ -1770,13 +1855,13 @@ func IsExpressionNode(node *Node) bool {
17701855
for node.Parent.Kind == KindQualifiedName {
17711856
node = node.Parent
17721857
}
1773-
return IsTypeQueryNode(node.Parent) || isJSDocLinkLike(node.Parent) || isJSXTagName(node)
1858+
return IsTypeQueryNode(node.Parent) || IsJSDocLinkLike(node.Parent) || isJSXTagName(node)
17741859
case KindJSDocMemberName:
1775-
return IsTypeQueryNode(node.Parent) || isJSDocLinkLike(node.Parent) || isJSXTagName(node)
1860+
return IsTypeQueryNode(node.Parent) || IsJSDocLinkLike(node.Parent) || isJSXTagName(node)
17761861
case KindPrivateIdentifier:
17771862
return IsBinaryExpression(node.Parent) && node.Parent.AsBinaryExpression().Left == node && node.Parent.AsBinaryExpression().OperatorToken.Kind == KindInKeyword
17781863
case KindIdentifier:
1779-
if IsTypeQueryNode(node.Parent) || isJSDocLinkLike(node.Parent) || isJSXTagName(node) {
1864+
if IsTypeQueryNode(node.Parent) || IsJSDocLinkLike(node.Parent) || isJSXTagName(node) {
17801865
return true
17811866
}
17821867
fallthrough
@@ -1919,7 +2004,7 @@ func isPartOfTypeExpressionWithTypeArguments(node *Node) bool {
19192004
return IsHeritageClause(parent) && (!IsClassLike(parent.Parent) || parent.AsHeritageClause().Token == KindImplementsKeyword)
19202005
}
19212006

1922-
func isJSDocLinkLike(node *Node) bool {
2007+
func IsJSDocLinkLike(node *Node) bool {
19232008
return NodeKindIs(node, KindJSDocLink, KindJSDocLinkCode, KindJSDocLinkPlain)
19242009
}
19252010

@@ -1985,7 +2070,7 @@ func IsJSDocCommentContainingNode(node *Node) bool {
19852070
node.Kind == KindJSDocText ||
19862071
node.Kind == KindJSDocTypeLiteral ||
19872072
node.Kind == KindJSDocSignature ||
1988-
isJSDocLinkLike(node) ||
2073+
IsJSDocLinkLike(node) ||
19892074
IsJSDocTag(node)
19902075
}
19912076

@@ -3455,25 +3540,6 @@ func IsCallOrNewExpression(node *Node) bool {
34553540
return IsCallExpression(node) || IsNewExpression(node)
34563541
}
34573542

3458-
func CanHaveSymbol(node *Node) bool {
3459-
switch node.Kind {
3460-
case KindArrowFunction, KindBinaryExpression, KindBindingElement, KindCallExpression, KindCallSignature,
3461-
KindClassDeclaration, KindClassExpression, KindClassStaticBlockDeclaration, KindConstructor, KindConstructorType,
3462-
KindConstructSignature, KindElementAccessExpression, KindEnumDeclaration, KindEnumMember, KindExportAssignment, KindJSExportAssignment,
3463-
KindExportDeclaration, KindExportSpecifier, KindFunctionDeclaration, KindFunctionExpression, KindFunctionType,
3464-
KindGetAccessor, KindIdentifier, KindImportClause, KindImportEqualsDeclaration, KindImportSpecifier,
3465-
KindIndexSignature, KindInterfaceDeclaration, KindJSDocSignature, KindJSDocTypeLiteral,
3466-
KindJsxAttribute, KindJsxAttributes, KindJsxSpreadAttribute, KindMappedType, KindMethodDeclaration,
3467-
KindMethodSignature, KindModuleDeclaration, KindNamedTupleMember, KindNamespaceExport, KindNamespaceExportDeclaration,
3468-
KindNamespaceImport, KindNewExpression, KindNoSubstitutionTemplateLiteral, KindNumericLiteral, KindObjectLiteralExpression,
3469-
KindParameter, KindPropertyAccessExpression, KindPropertyAssignment, KindPropertyDeclaration, KindPropertySignature,
3470-
KindSetAccessor, KindShorthandPropertyAssignment, KindSourceFile, KindSpreadAssignment, KindStringLiteral,
3471-
KindTypeAliasDeclaration, KindJSTypeAliasDeclaration, KindTypeLiteral, KindTypeParameter, KindVariableDeclaration:
3472-
return true
3473-
}
3474-
return false
3475-
}
3476-
34773543
func IndexOfNode(nodes []*Node, node *Node) int {
34783544
index, ok := slices.BinarySearchFunc(nodes, node, compareNodePositions)
34793545
if ok {

internal/astnav/tokens.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ func GetTouchingPropertyName(sourceFile *ast.SourceFile, position int) *ast.Node
1414
})
1515
}
1616

17+
func GetTouchingToken(sourceFile *ast.SourceFile, position int) *ast.Node {
18+
return getTokenAtPosition(sourceFile, position, false /*allowPositionInLeadingTrivia*/, nil)
19+
}
20+
1721
func GetTokenAtPosition(sourceFile *ast.SourceFile, position int) *ast.Node {
1822
return getTokenAtPosition(sourceFile, position, true /*allowPositionInLeadingTrivia*/, nil)
1923
}

internal/binder/nameresolver.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ loop:
4040
// (it refers to the constant type of the expression instead)
4141
return nil
4242
}
43-
if isModuleOrEnumDeclaration(location) && lastLocation != nil && location.Name() == lastLocation {
43+
if ast.IsModuleOrEnumDeclaration(location) && lastLocation != nil && location.Name() == lastLocation {
4444
// If lastLocation is the name of a namespace or enum, skip the parent since it will have is own locals that could
4545
// conflict.
4646
lastLocation = location
@@ -99,7 +99,7 @@ loop:
9999
// name of that export default matches.
100100
result = moduleExports[ast.InternalSymbolNameDefault]
101101
if result != nil {
102-
localSymbol := getLocalSymbolForExportDefault(result)
102+
localSymbol := GetLocalSymbolForExportDefault(result)
103103
if localSymbol != nil && result.Flags&meaning != 0 && localSymbol.Name == name {
104104
break loop
105105
}
@@ -448,11 +448,7 @@ func (r *NameResolver) argumentsSymbol() *ast.Symbol {
448448
return r.ArgumentsSymbol
449449
}
450450

451-
func isModuleOrEnumDeclaration(node *ast.Node) bool {
452-
return node.Kind == ast.KindModuleDeclaration || node.Kind == ast.KindEnumDeclaration
453-
}
454-
455-
func getLocalSymbolForExportDefault(symbol *ast.Symbol) *ast.Symbol {
451+
func GetLocalSymbolForExportDefault(symbol *ast.Symbol) *ast.Symbol {
456452
if !isExportDefaultSymbol(symbol) || len(symbol.Declarations) == 0 {
457453
return nil
458454
}

internal/checker/checker.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1832,12 +1832,12 @@ func (c *Checker) isBlockScopedNameDeclaredBeforeUse(declaration *ast.Node, usag
18321832
switch {
18331833
case declaration.Kind == ast.KindBindingElement:
18341834
// still might be illegal if declaration and usage are both binding elements (eg var [a = b, b = b] = [1, 2])
1835-
errorBindingElement := getAncestor(usage, ast.KindBindingElement)
1835+
errorBindingElement := ast.FindAncestorKind(usage, ast.KindBindingElement)
18361836
if errorBindingElement != nil {
18371837
return ast.FindAncestor(errorBindingElement, ast.IsBindingElement) != ast.FindAncestor(declaration, ast.IsBindingElement) || declaration.Pos() < errorBindingElement.Pos()
18381838
}
18391839
// or it might be illegal if usage happens before parent variable is declared (eg var [a] = a)
1840-
return c.isBlockScopedNameDeclaredBeforeUse(getAncestor(declaration, ast.KindVariableDeclaration), usage)
1840+
return c.isBlockScopedNameDeclaredBeforeUse(ast.FindAncestorKind(declaration, ast.KindVariableDeclaration), usage)
18411841
case declaration.Kind == ast.KindVariableDeclaration:
18421842
// still might be illegal if usage is in the initializer of the variable declaration (eg var a = a)
18431843
return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage, declContainer)
@@ -4198,7 +4198,7 @@ func (c *Checker) checkBaseTypeAccessibility(t *Type, node *ast.Node) {
41984198
signatures := c.getSignaturesOfType(t, SignatureKindConstruct)
41994199
if len(signatures) != 0 {
42004200
declaration := signatures[0].declaration
4201-
if declaration != nil && hasModifier(declaration, ast.ModifierFlagsPrivate) {
4201+
if declaration != nil && HasModifier(declaration, ast.ModifierFlagsPrivate) {
42024202
typeClassDeclaration := ast.GetClassLikeDeclarationOfSymbol(t.symbol)
42034203
if !c.isNodeWithinClass(node, typeClassDeclaration) {
42044204
c.error(node, diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, c.getFullyQualifiedName(t.symbol, nil))
@@ -5656,7 +5656,7 @@ func (c *Checker) checkVarDeclaredNamesNotShadowed(node *ast.Node) {
56565656
localDeclarationSymbol := c.resolveName(node, name.Text(), ast.SymbolFlagsVariable, nil /*nameNotFoundMessage*/, false /*isUse*/, false)
56575657
if localDeclarationSymbol != nil && localDeclarationSymbol != symbol && localDeclarationSymbol.Flags&ast.SymbolFlagsBlockScopedVariable != 0 {
56585658
if c.getDeclarationNodeFlagsFromSymbol(localDeclarationSymbol)&ast.NodeFlagsBlockScoped != 0 {
5659-
varDeclList := getAncestor(localDeclarationSymbol.ValueDeclaration, ast.KindVariableDeclarationList)
5659+
varDeclList := ast.FindAncestorKind(localDeclarationSymbol.ValueDeclaration, ast.KindVariableDeclarationList)
56605660
var container *ast.Node
56615661
if ast.IsVariableStatement(varDeclList.Parent) && varDeclList.Parent.Parent != nil {
56625662
container = varDeclList.Parent.Parent
@@ -6391,7 +6391,7 @@ func (c *Checker) checkAliasSymbol(node *ast.Node) {
63916391
name := node.PropertyNameOrName().Text()
63926392
c.addTypeOnlyDeclarationRelatedInfo(c.error(node, message, name), core.IfElse(isType, nil, typeOnlyAlias), name)
63936393
}
6394-
if isType && node.Kind == ast.KindImportEqualsDeclaration && hasModifier(node, ast.ModifierFlagsExport) {
6394+
if isType && node.Kind == ast.KindImportEqualsDeclaration && HasModifier(node, ast.ModifierFlagsExport) {
63956395
c.error(node, diagnostics.Cannot_use_export_import_on_a_type_or_type_only_namespace_when_0_is_enabled, c.getIsolatedModulesLikeFlagName())
63966396
}
63976397
case ast.KindExportSpecifier:
@@ -6681,7 +6681,7 @@ func (c *Checker) checkUnusedClassMembers(node *ast.Node) {
66816681
break // Already would have reported an error on the getter.
66826682
}
66836683
symbol := c.getSymbolOfDeclaration(member)
6684-
if !c.isReferenced(symbol) && (hasModifier(member, ast.ModifierFlagsPrivate) || member.Name() != nil && ast.IsPrivateIdentifier(member.Name())) && member.Flags&ast.NodeFlagsAmbient == 0 {
6684+
if !c.isReferenced(symbol) && (HasModifier(member, ast.ModifierFlagsPrivate) || member.Name() != nil && ast.IsPrivateIdentifier(member.Name())) && member.Flags&ast.NodeFlagsAmbient == 0 {
66856685
c.reportUnused(member, UnusedKindLocal, NewDiagnosticForNode(member.Name(), diagnostics.X_0_is_declared_but_its_value_is_never_read, c.symbolToString(symbol)))
66866686
}
66876687
case ast.KindConstructor:
@@ -8236,7 +8236,7 @@ func (c *Checker) resolveNewExpression(node *ast.Node, candidatesOutArray *[]*Si
82368236
}
82378237
if expressionType.symbol != nil {
82388238
valueDecl := ast.GetClassLikeDeclarationOfSymbol(expressionType.symbol)
8239-
if valueDecl != nil && hasModifier(valueDecl, ast.ModifierFlagsAbstract) {
8239+
if valueDecl != nil && HasModifier(valueDecl, ast.ModifierFlagsAbstract) {
82408240
c.error(node, diagnostics.Cannot_create_an_instance_of_an_abstract_class)
82418241
return c.resolveErrorCall(node)
82428242
}
@@ -18540,7 +18540,7 @@ func (c *Checker) getIndexInfosOfIndexSymbol(indexSymbol *ast.Symbol, siblingSym
1854018540
}
1854118541
forEachType(c.getTypeFromTypeNode(typeNode), func(keyType *Type) {
1854218542
if c.isValidIndexKeyType(keyType) && findIndexInfo(indexInfos, keyType) == nil {
18543-
indexInfo := c.newIndexInfo(keyType, valueType, hasModifier(declaration, ast.ModifierFlagsReadonly), declaration)
18543+
indexInfo := c.newIndexInfo(keyType, valueType, HasModifier(declaration, ast.ModifierFlagsReadonly), declaration)
1854418544
indexInfos = append(indexInfos, indexInfo)
1854518545
}
1854618546
})
@@ -26304,7 +26304,7 @@ func (c *Checker) markPropertyAsReferenced(prop *ast.Symbol, nodeForCheckWriteOn
2630426304
if prop.Flags&ast.SymbolFlagsClassMember == 0 || prop.ValueDeclaration == nil {
2630526305
return
2630626306
}
26307-
hasPrivateModifier := hasModifier(prop.ValueDeclaration, ast.ModifierFlagsPrivate)
26307+
hasPrivateModifier := HasModifier(prop.ValueDeclaration, ast.ModifierFlagsPrivate)
2630826308
hasPrivateIdentifier := prop.ValueDeclaration.Name() != nil && ast.IsPrivateIdentifier(prop.ValueDeclaration.Name())
2630926309
if !hasPrivateModifier && !hasPrivateIdentifier {
2631026310
return
@@ -29971,7 +29971,7 @@ func (c *Checker) getSymbolOfNameOrPropertyAccessExpression(name *ast.Node) *ast
2997129971
}
2997229972
} else if ast.IsEntityName(name) && isInRightSideOfImportOrExportAssignment(name) {
2997329973
// Since we already checked for ExportAssignment, this really could only be an Import
29974-
importEqualsDeclaration := getAncestor(name, ast.KindImportEqualsDeclaration)
29974+
importEqualsDeclaration := ast.FindAncestorKind(name, ast.KindImportEqualsDeclaration)
2997529975
if importEqualsDeclaration == nil {
2997629976
panic("ImportEqualsDeclaration should be defined")
2997729977
}

internal/checker/exports.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import (
66
"github.com/microsoft/typescript-go/internal/diagnostics"
77
)
88

9+
func (c *Checker) GetStringType() *Type {
10+
return c.stringType
11+
}
12+
913
func (c *Checker) GetUnknownSymbol() *ast.Symbol {
1014
return c.unknownSymbol
1115
}
@@ -18,6 +22,10 @@ func (c *Checker) GetGlobalSymbol(name string, meaning ast.SymbolFlags, diagnost
1822
return c.getGlobalSymbol(name, meaning, diagnostic)
1923
}
2024

25+
func (c *Checker) GetMergedSymbol(symbol *ast.Symbol) *ast.Symbol {
26+
return c.getMergedSymbol(symbol)
27+
}
28+
2129
func (c *Checker) GetTypeFromTypeNode(node *ast.Node) *Type {
2230
return c.getTypeFromTypeNode(node)
2331
}
@@ -30,6 +38,10 @@ func (c *Checker) GetPropertiesOfType(t *Type) []*ast.Symbol {
3038
return c.getPropertiesOfType(t)
3139
}
3240

41+
func (c *Checker) GetPropertyOfType(t *Type, name string) *ast.Symbol {
42+
return c.getPropertyOfType(t, name)
43+
}
44+
3345
func (c *Checker) TypeHasCallOrConstructSignatures(t *Type) bool {
3446
return c.typeHasCallOrConstructSignatures(t)
3547
}

0 commit comments

Comments
 (0)