Skip to content

Commit f67d4b3

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Update navigation notification to support ConstructorReference.
Change-Id: I815941304f8dd131998f5ae527f21077ce5324df Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/212482 Reviewed-by: Brian Wilkerson <[email protected]> Reviewed-by: Samuel Rawlins <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent f726874 commit f67d4b3

File tree

3 files changed

+90
-37
lines changed

3 files changed

+90
-37
lines changed

pkg/analysis_server/test/analysis/notification_navigation_test.dart

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,10 @@ class AbstractNavigationTest extends AbstractAnalysisTest {
7575

7676
/// Validates that there is an identifier region at [regionSearch] with target
7777
/// at [targetSearch].
78-
void assertHasRegionTarget(String regionSearch, String targetSearch) {
78+
void assertHasRegionTarget(String regionSearch, String targetSearch,
79+
{int targetLength = -1}) {
7980
assertHasRegion(regionSearch);
80-
assertHasTarget(targetSearch);
81+
assertHasTarget(targetSearch, targetLength);
8182
}
8283

8384
/// Validates that there is a target in [testTargets] with [testFile], at the
@@ -391,6 +392,62 @@ class BBB {}
391392
assertHasRegionTarget('BBB p', 'BBB {}');
392393
}
393394

395+
Future<void> test_constructorReference_named() async {
396+
addTestFile('''
397+
class A {}
398+
class B<T> {
399+
B.named();
400+
}
401+
void f() {
402+
B<A>.named;
403+
}
404+
''');
405+
await prepareNavigation();
406+
assertHasRegionTarget('B<A>.named;', 'named();');
407+
assertHasRegionTarget('named;', 'named();');
408+
assertHasRegionTarget('A>', 'A {}');
409+
}
410+
411+
Future<void> test_constructorReference_unnamed_declared() async {
412+
addTestFile('''
413+
class A {
414+
A();
415+
}
416+
void f() {
417+
A.new;
418+
}
419+
''');
420+
await prepareNavigation();
421+
assertHasRegionTarget('A.new;', 'A();', targetLength: 0);
422+
assertHasRegionTarget('new;', 'A();', targetLength: 0);
423+
}
424+
425+
Future<void> test_constructorReference_unnamed_declared_new() async {
426+
addTestFile('''
427+
class A {
428+
A.new();
429+
}
430+
void f() {
431+
A.new;
432+
}
433+
''');
434+
await prepareNavigation();
435+
assertHasRegionTarget('A.new;', 'new();');
436+
assertHasRegionTarget('new;', 'new();');
437+
}
438+
439+
Future<void> test_constructorReference_unnamed_default() async {
440+
addTestFile('''
441+
class A {}
442+
void f() {
443+
A.new;
444+
}
445+
''');
446+
await prepareNavigation();
447+
assertHasRegionTarget('A.new;', 'A {}');
448+
assertHasRegionTarget('new;', 'A {}');
449+
}
450+
394451
Future<void> test_enum_constant() async {
395452
addTestFile('''
396453
enum E { a, b }

pkg/analyzer/lib/src/dart/element/element.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,6 +1525,16 @@ class ConstructorElementImpl extends ExecutableElementImpl
15251525
@override
15261526
ElementKind get kind => ElementKind.CONSTRUCTOR;
15271527

1528+
@override
1529+
int get nameLength {
1530+
final nameEnd = this.nameEnd;
1531+
if (nameEnd == null || periodOffset == null) {
1532+
return 0;
1533+
} else {
1534+
return nameEnd - nameOffset;
1535+
}
1536+
}
1537+
15281538
@override
15291539
Element get nonSynthetic {
15301540
return isSynthetic ? enclosingElement : this;

pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart

Lines changed: 21 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -310,13 +310,27 @@ class _DartNavigationComputerVisitor extends RecursiveAstVisitor<void> {
310310

311311
@override
312312
void visitConstructorName(ConstructorName node) {
313-
var parent = node.parent;
314-
if (parent is InstanceCreationExpression &&
315-
parent.constructorName == node) {
316-
_addConstructorName(parent, node);
317-
} else if (parent is ConstructorDeclaration &&
318-
parent.redirectedConstructor == node) {
319-
_addConstructorName(node, node);
313+
Element? element = node.staticElement;
314+
if (element == null) {
315+
return;
316+
}
317+
// add regions
318+
var typeName = node.type;
319+
// [prefix].ClassName
320+
{
321+
var name = typeName.name;
322+
var className = name;
323+
if (name is PrefixedIdentifier) {
324+
name.prefix.accept(this);
325+
className = name.identifier;
326+
}
327+
computer._addRegionForNode(className, element);
328+
}
329+
// <TypeA, TypeB>
330+
typeName.typeArguments?.accept(this);
331+
// optional "name"
332+
if (node.name != null) {
333+
computer._addRegionForNode(node.name, element);
320334
}
321335
}
322336

@@ -459,34 +473,6 @@ class _DartNavigationComputerVisitor extends RecursiveAstVisitor<void> {
459473
super.visitVariableDeclarationList(node);
460474
}
461475

462-
void _addConstructorName(AstNode parent, ConstructorName node) {
463-
Element? element = node.staticElement;
464-
if (element == null) {
465-
return;
466-
}
467-
// add regions
468-
var typeName = node.type;
469-
// [prefix].ClassName
470-
{
471-
var name = typeName.name;
472-
var className = name;
473-
if (name is PrefixedIdentifier) {
474-
name.prefix.accept(this);
475-
className = name.identifier;
476-
}
477-
computer._addRegionForNode(className, element);
478-
}
479-
// <TypeA, TypeB>
480-
var typeArguments = typeName.typeArguments;
481-
if (typeArguments != null) {
482-
typeArguments.accept(this);
483-
}
484-
// optional "name"
485-
if (node.name != null) {
486-
computer._addRegionForNode(node.name, element);
487-
}
488-
}
489-
490476
/// If the source of the given [element] (referenced by the [node]) exists,
491477
/// then add the navigation region from the [node] to the [element].
492478
void _addUriDirectiveRegion(UriBasedDirective node, Element? element) {

0 commit comments

Comments
 (0)