@@ -1322,6 +1322,105 @@ func getReferenceEntriesForShorthandPropertyAssignment(node *ast.Node, checker *
1322
1322
}
1323
1323
}
1324
1324
1325
+ func climbPastPropertyAccess (node * ast.Node ) * ast.Node {
1326
+ if isRightSideOfPropertyAccess (node ) {
1327
+ return node .Parent
1328
+ }
1329
+ return node
1330
+ }
1331
+
1332
+ func isNewExpressionTarget (node * ast.Node ) bool {
1333
+ if node .Parent == nil {
1334
+ return false
1335
+ }
1336
+ return node .Parent .Kind == ast .KindNewExpression && node .Parent .AsNewExpression ().Expression == node
1337
+ }
1338
+
1339
+ func isCallExpressionTarget (node * ast.Node ) bool {
1340
+ if node .Parent == nil {
1341
+ return false
1342
+ }
1343
+ return node .Parent .Kind == ast .KindCallExpression && node .Parent .AsCallExpression ().Expression == node
1344
+ }
1345
+
1346
+ func isMethodOrAccessor (node * ast.Node ) bool {
1347
+ return node .Kind == ast .KindMethodDeclaration || node .Kind == ast .KindGetAccessor || node .Kind == ast .KindSetAccessor
1348
+ }
1349
+
1350
+ func tryGetClassByExtendingIdentifier (node * ast.Node ) * ast.ClassLikeDeclaration {
1351
+ return ast .TryGetClassExtendingExpressionWithTypeArguments (climbPastPropertyAccess (node ).Parent )
1352
+ }
1353
+
1354
+ func getClassConstructorSymbol (classSymbol * ast.Symbol ) * ast.Symbol {
1355
+ if classSymbol .Members == nil {
1356
+ return nil
1357
+ }
1358
+ return classSymbol .Members [ast .InternalSymbolNameConstructor ]
1359
+ }
1360
+
1361
+ func hasOwnConstructor (classDeclaration * ast.ClassLikeDeclaration ) bool {
1362
+ return getClassConstructorSymbol (classDeclaration .Symbol ()) != nil
1363
+ }
1364
+
1365
+ func findOwnConstructorReferences (classSymbol * ast.Symbol , sourceFile * ast.SourceFile , addNode func (* ast.Node )) {
1366
+ constructorSymbol := getClassConstructorSymbol (classSymbol )
1367
+ if constructorSymbol != nil && len (constructorSymbol .Declarations ) > 0 {
1368
+ for _ , decl := range constructorSymbol .Declarations {
1369
+ if decl .Kind == ast .KindConstructor {
1370
+ if ctrKeyword := findChildOfKind (decl , ast .KindConstructorKeyword , sourceFile ); ctrKeyword != nil {
1371
+ addNode (ctrKeyword )
1372
+ }
1373
+ }
1374
+ }
1375
+ }
1376
+
1377
+ if classSymbol .Exports != nil {
1378
+ for _ , member := range classSymbol .Exports {
1379
+ decl := member .ValueDeclaration
1380
+ if decl != nil && decl .Kind == ast .KindMethodDeclaration {
1381
+ body := decl .Body ()
1382
+ if body != nil {
1383
+ forEachDescendantOfKind (body , ast .KindThisKeyword , func (thisKeyword * ast.Node ) {
1384
+ if isNewExpressionTarget (thisKeyword ) {
1385
+ addNode (thisKeyword )
1386
+ }
1387
+ })
1388
+ }
1389
+ }
1390
+ }
1391
+ }
1392
+ }
1393
+
1394
+ func findSuperConstructorAccesses (classDeclaration * ast.ClassLikeDeclaration , addNode func (* ast.Node )) {
1395
+ constructorSymbol := getClassConstructorSymbol (classDeclaration .Symbol ())
1396
+ if constructorSymbol == nil || len (constructorSymbol .Declarations ) == 0 {
1397
+ return
1398
+ }
1399
+
1400
+ for _ , decl := range constructorSymbol .Declarations {
1401
+ if decl .Kind == ast .KindConstructor {
1402
+ body := decl .Body ()
1403
+ if body != nil {
1404
+ forEachDescendantOfKind (body , ast .KindSuperKeyword , func (node * ast.Node ) {
1405
+ if isCallExpressionTarget (node ) {
1406
+ addNode (node )
1407
+ }
1408
+ })
1409
+ }
1410
+ }
1411
+ }
1412
+ }
1413
+
1414
+ func forEachDescendantOfKind (node * ast.Node , kind ast.Kind , action func (* ast.Node )) {
1415
+ node .ForEachChild (func (child * ast.Node ) bool {
1416
+ if child .Kind == kind {
1417
+ action (child )
1418
+ }
1419
+ forEachDescendantOfKind (child , kind , action )
1420
+ return false
1421
+ })
1422
+ }
1423
+
1325
1424
func (state * refState ) addImplementationReferences (refNode * ast.Node , addRef func (* ast.Node )) {
1326
1425
// Check if we found a function/propertyAssignment/method with an implementation or initializer
1327
1426
if ast .IsDeclarationName (refNode ) && isImplementation (refNode .Parent ) {
@@ -1483,11 +1582,9 @@ func (state *refState) getReferencesAtLocation(sourceFile *ast.SourceFile, posit
1483
1582
state .addReference (referenceLocation , relatedSymbol , relatedSymbolKind )
1484
1583
}
1485
1584
case "constructor" :
1486
- // !!! not implemented
1487
- // state.addConstructorReferences(referenceLocation, sourceFile, search)
1585
+ state .addConstructorReferences (referenceLocation , relatedSymbol , search , addReferencesHere )
1488
1586
case "class" :
1489
- // !!! not implemented
1490
- // state.addClassStaticThisReferences(referenceLocation, search)
1587
+ state .addClassStaticThisReferences (referenceLocation , relatedSymbol , search , addReferencesHere )
1491
1588
}
1492
1589
1493
1590
// Use the parent symbol if the location is commonjs require syntax on javascript files only.
@@ -1504,6 +1601,78 @@ func (state *refState) getReferencesAtLocation(sourceFile *ast.SourceFile, posit
1504
1601
state .getImportOrExportReferences (referenceLocation , referenceSymbol , search )
1505
1602
}
1506
1603
1604
+ func (state * refState ) addConstructorReferences (referenceLocation * ast.Node , symbol * ast.Symbol , search * refSearch , addReferencesHere bool ) {
1605
+ if isNewExpressionTarget (referenceLocation ) && addReferencesHere {
1606
+ state .addReference (referenceLocation , symbol , entryKindNone )
1607
+ }
1608
+
1609
+ pusher := func () func (* ast.Node , entryKind ) {
1610
+ return state .referenceAdder (search .symbol )
1611
+ }
1612
+
1613
+ if ast .IsClassLike (referenceLocation .Parent ) {
1614
+ // This is the class declaration containing the constructor.
1615
+ sourceFile := ast .GetSourceFileOfNode (referenceLocation )
1616
+ findOwnConstructorReferences (search .symbol , sourceFile , func (n * ast.Node ) {
1617
+ pusher ()(n , entryKindNone )
1618
+ })
1619
+ } else {
1620
+ // If this class appears in `extends C`, then the extending class' "super" calls are references.
1621
+ if classExtending := tryGetClassByExtendingIdentifier (referenceLocation ); classExtending != nil {
1622
+ findSuperConstructorAccesses (classExtending , func (n * ast.Node ) {
1623
+ pusher ()(n , entryKindNone )
1624
+ })
1625
+ state .findInheritedConstructorReferences (classExtending )
1626
+ }
1627
+ }
1628
+ }
1629
+
1630
+ func (state * refState ) addClassStaticThisReferences (referenceLocation * ast.Node , symbol * ast.Symbol , search * refSearch , addReferencesHere bool ) {
1631
+ if addReferencesHere {
1632
+ state .addReference (referenceLocation , symbol , entryKindNone )
1633
+ }
1634
+
1635
+ classLike := referenceLocation .Parent
1636
+ if state .options .use == referenceUseRename || ! ast .IsClassLike (classLike ) {
1637
+ return
1638
+ }
1639
+
1640
+ addRef := state .referenceAdder (search .symbol )
1641
+ members := classLike .Members ()
1642
+ if members == nil {
1643
+ return
1644
+ }
1645
+ for _ , member := range members {
1646
+ if ! (isMethodOrAccessor (member ) && ast .HasStaticModifier (member )) {
1647
+ continue
1648
+ }
1649
+ body := member .Body ()
1650
+ if body != nil {
1651
+ var cb func (* ast.Node )
1652
+ cb = func (node * ast.Node ) {
1653
+ if node .Kind == ast .KindThisKeyword {
1654
+ addRef (node , entryKindNone )
1655
+ } else if ! ast .IsFunctionLike (node ) && ! ast .IsClassLike (node ) {
1656
+ node .ForEachChild (func (child * ast.Node ) bool {
1657
+ cb (child )
1658
+ return false
1659
+ })
1660
+ }
1661
+ }
1662
+ cb (body )
1663
+ }
1664
+ }
1665
+ }
1666
+
1667
+ func (state * refState ) findInheritedConstructorReferences (classDeclaration * ast.ClassLikeDeclaration ) {
1668
+ if hasOwnConstructor (classDeclaration ) {
1669
+ return
1670
+ }
1671
+ classSymbol := classDeclaration .Symbol ()
1672
+ search := state .createSearch (nil , classSymbol , ImpExpKindUnknown , "" , nil )
1673
+ state .getReferencesInContainerOrFiles (classSymbol , search )
1674
+ }
1675
+
1507
1676
func (state * refState ) getImportOrExportReferences (referenceLocation * ast.Node , referenceSymbol * ast.Symbol , search * refSearch ) {
1508
1677
importOrExport := getImportOrExportSymbol (referenceLocation , referenceSymbol , state .checker , search .comingFrom == ImpExpKindExport )
1509
1678
if importOrExport == nil {
0 commit comments