From 8abaa7b81bc6dcdd46eb95a22d9a9d18e85501b1 Mon Sep 17 00:00:00 2001 From: Danny Tuppeny Date: Mon, 31 Jul 2023 17:14:33 +0000 Subject: [PATCH] [analysis_server] Fix finding references for the offset between a type name and generic type parameters Fixes https://github.com/Dart-Code/Dart-Code/issues/4668 Change-Id: Ibdb45b5c09ab8de0746239e351b5e581af4bb7df Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/317080 Reviewed-by: Brian Wilkerson Commit-Queue: Brian Wilkerson --- .../src/lsp/handlers/handler_references.dart | 23 ++++++++++++++++++- .../test/lsp/references_test.dart | 20 ++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart index 6a9f19787e5a..c9f01422fd6a 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart @@ -64,7 +64,8 @@ class ReferencesHandler ReferenceParams params, ResolvedUnitResult unit, OperationPerformanceImpl performance) async { - final node = NodeLocator(offset).searchWithin(result.unit); + var node = NodeLocator(offset).searchWithin(result.unit); + node = _getReferenceTargetNode(node); var element = server.getElementOfNode(node); if (element == null) { return success(null); @@ -104,4 +105,24 @@ class ReferencesHandler return success(referenceResults); } + + /// Gets the nearest node that should be used for finding references. + /// + /// This is usually the same node but allows some adjustments such as + /// considering the offset between a type name and type arguments as part + /// of the type. + AstNode? _getReferenceTargetNode(AstNode? node) { + // Consider the angle brackets for type arguments part of the leading type, + // otherwise we don't navigate in the common situation of having the type + // name selected, where VS Code provides the end of the selection as the + // position to search. + // + // In `A^` node will be `TypeParameterList` and we will not find any + // references. + if (node is TypeParameterList) { + node = node.parent; + } + + return node; + } } diff --git a/pkg/analysis_server/test/lsp/references_test.dart b/pkg/analysis_server/test/lsp/references_test.dart index c745ebac72ee..2a404b663da6 100644 --- a/pkg/analysis_server/test/lsp/references_test.dart +++ b/pkg/analysis_server/test/lsp/references_test.dart @@ -178,6 +178,26 @@ f^oo() { await _checkRanges(content, includeDeclarations: false); } + Future test_type() async { + final content = ''' +class A^aa {} + +[!Aaa!]? a; +'''; + + await _checkRanges(content); + } + + Future test_type_generic_end() async { + final content = ''' +class Aaa^ {} + +[!Aaa!]? a; +'''; + + await _checkRanges(content); + } + Future test_unopenFile() async { final code = TestCode.parse(''' f^oo() {