Index, search, rename for pattern fields.
Change-Id: Iaeae578d18c139850664f30fc5bbc92ad95132ac
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/283127
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index b78bc5e..4d11be4 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -1605,6 +1605,56 @@
);
}
+ Future<void> test_class_getter_in_objectPattern() {
+ addTestFile('''
+void f(Object? x) {
+ if (x case A(test: 0)) {}
+ if (x case A(: var test)) {}
+}
+
+class A {
+ int get test => 0;
+}
+''');
+ return assertSuccessfulRefactoring(() {
+ return sendRenameRequest('test =>', 'newName');
+ }, '''
+void f(Object? x) {
+ if (x case A(newName: 0)) {}
+ if (x case A(newName: var test)) {}
+}
+
+class A {
+ int get newName => 0;
+}
+''');
+ }
+
+ Future<void> test_class_method_in_objectPattern() {
+ addTestFile('''
+void f(Object? x) {
+ if (x case A(test: _)) {}
+ if (x case A(: var test)) {}
+}
+
+class A {
+ void test() {}
+}
+''');
+ return assertSuccessfulRefactoring(() {
+ return sendRenameRequest('test() {}', 'newName');
+ }, '''
+void f(Object? x) {
+ if (x case A(newName: _)) {}
+ if (x case A(newName: var test)) {}
+}
+
+class A {
+ void newName() {}
+}
+''');
+ }
+
Future<void> test_class_options_fatalError() {
addTestFile('''
class Test {}
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index de8f23e..5355f79 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -241,6 +241,24 @@
assertHasResult(SearchResultKind.READ, 'fff); // in m()');
}
+ Future<void> test_class_getter_in_objectPattern() async {
+ addTestFile('''
+void f(Object? x) {
+ if (x case A(foo: 0)) {}
+ if (x case A(: var foo)) {}
+}
+
+class A {
+ int get foo => 0;
+}
+''');
+ await findElementReferences('foo =>', false);
+ expect(searchElement!.kind, ElementKind.FIELD);
+ expect(results, hasLength(2));
+ assertHasResult(SearchResultKind.READ, 'foo: 0');
+ assertHasResult(SearchResultKind.READ, ': var foo');
+ }
+
Future<void> test_class_method() async {
addTestFile('''
class A {
diff --git a/pkg/analysis_server/test/services/refactoring/legacy/rename_class_member_test.dart b/pkg/analysis_server/test/services/refactoring/legacy/rename_class_member_test.dart
index c464865..f1666db 100644
--- a/pkg/analysis_server/test/services/refactoring/legacy/rename_class_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/legacy/rename_class_member_test.dart
@@ -644,6 +644,66 @@
''');
}
+ Future<void> test_createChange_getter_in_objectPattern() async {
+ await indexTestUnit('''
+void f(Object? x) {
+ if (x case A(test: 0)) {}
+ if (x case A(: var test)) {}
+}
+
+class A {
+ int get test => 0;
+}
+''');
+ // configure refactoring
+ createRenameRefactoringAtString('test =>');
+ expect(refactoring.refactoringName, 'Rename Field');
+ expect(refactoring.elementKindName, 'field');
+ expect(refactoring.oldName, 'test');
+ refactoring.newName = 'newName';
+ // validate change
+ return assertSuccessfulRefactoring('''
+void f(Object? x) {
+ if (x case A(newName: 0)) {}
+ if (x case A(newName: var test)) {}
+}
+
+class A {
+ int get newName => 0;
+}
+''');
+ }
+
+ Future<void> test_createChange_method_in_objectPattern() async {
+ await indexTestUnit('''
+void f(Object? x) {
+ if (x case A(test: _)) {}
+ if (x case A(: var test)) {}
+}
+
+class A {
+ void test() {}
+}
+''');
+ // configure refactoring
+ createRenameRefactoringAtString('test() {}');
+ expect(refactoring.refactoringName, 'Rename Method');
+ expect(refactoring.elementKindName, 'method');
+ expect(refactoring.oldName, 'test');
+ refactoring.newName = 'newName';
+ // validate change
+ return assertSuccessfulRefactoring('''
+void f(Object? x) {
+ if (x case A(newName: _)) {}
+ if (x case A(newName: var test)) {}
+}
+
+class A {
+ void newName() {}
+}
+''');
+ }
+
Future<void> test_createChange_MethodElement() async {
await indexTestUnit('''
/// [A.test]
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index bff4eb5..b5538b9 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -806,6 +806,26 @@
}
@override
+ visitPatternField(PatternField node) {
+ final nameNode = node.name;
+ if (nameNode != null) {
+ final nameToken = nameNode.name;
+ final int offset;
+ final int length;
+ if (nameToken != null) {
+ offset = nameToken.offset;
+ length = nameToken.length;
+ } else {
+ offset = nameNode.offset;
+ length = 0;
+ }
+ recordRelationOffset(node.element, IndexRelationKind.IS_REFERENCED_BY,
+ offset, length, true);
+ }
+ return super.visitPatternField(node);
+ }
+
+ @override
void visitPostfixExpression(PostfixExpression node) {
recordOperatorReference(node.operator, node.staticElement);
super.visitPostfixExpression(node);
diff --git a/pkg/analyzer/lib/src/dart/ast/element_locator.dart b/pkg/analyzer/lib/src/dart/ast/element_locator.dart
index 525f284..0b4f29d 100644
--- a/pkg/analyzer/lib/src/dart/ast/element_locator.dart
+++ b/pkg/analyzer/lib/src/dart/ast/element_locator.dart
@@ -211,8 +211,9 @@
final parent = node.parent;
if (parent is PatternField) {
return parent.element;
+ } else {
+ return null;
}
- return super.visitPatternFieldName(node);
}
@override
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index eaf1d0a..fb09c58 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -710,6 +710,42 @@
''');
}
+ test_isReferencedBy_class_getter_in_objectPattern() async {
+ await _indexTestUnit('''
+void f(Object? x) {
+ if (x case A(foo: 0)) {}
+ if (x case A(: var foo)) {}
+}
+
+class A {
+ int get foo => 0;
+}
+''');
+ final element = findElement.getter('foo');
+ assertElementIndexText(element, r'''
+35 2:16 |foo| IS_REFERENCED_BY qualified
+62 3:16 || IS_REFERENCED_BY qualified
+''');
+ }
+
+ test_isReferencedBy_class_method_in_objectPattern() async {
+ await _indexTestUnit('''
+void f(Object? x) {
+ if (x case A(foo: _)) {}
+ if (x case A(: var foo)) {}
+}
+
+class A {
+ void foo() {}
+}
+''');
+ final element = findElement.method('foo');
+ assertElementIndexText(element, r'''
+35 2:16 |foo| IS_REFERENCED_BY qualified
+62 3:16 || IS_REFERENCED_BY qualified
+''');
+ }
+
test_isReferencedBy_ClassElement() async {
await _indexTestUnit('''
class A {
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index 3ea2a29..a0be39c 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -577,6 +577,46 @@
]);
}
+ test_searchReferences_class_getter_in_objectPattern() async {
+ await resolveTestCode('''
+void f(Object? x) {
+ if (x case A(foo: 0)) {}
+ if (x case A(: var foo)) {}
+}
+
+class A {
+ int get foo => 0;
+}
+''');
+ var element = findElement.getter('foo');
+ var f = findElement.function('f');
+ var expected = [
+ _expectIdQ(f, SearchResultKind.REFERENCE, 'foo: 0', length: 3),
+ _expectIdQ(f, SearchResultKind.REFERENCE, ': var foo', length: 0),
+ ];
+ await _verifyReferences(element, expected);
+ }
+
+ test_searchReferences_class_method_in_objectPattern() async {
+ await resolveTestCode('''
+void f(Object? x) {
+ if (x case A(foo: _)) {}
+ if (x case A(: var foo)) {}
+}
+
+class A {
+ void foo() {}
+}
+''');
+ var element = findElement.method('foo');
+ var f = findElement.function('f');
+ var expected = [
+ _expectIdQ(f, SearchResultKind.REFERENCE, 'foo: _', length: 3),
+ _expectIdQ(f, SearchResultKind.REFERENCE, ': var foo', length: 0),
+ ];
+ await _verifyReferences(element, expected);
+ }
+
test_searchReferences_ClassElement_definedInSdk_declarationSite() async {
await resolveTestCode('''
import 'dart:math';
diff --git a/pkg/analyzer/test/src/dart/ast/element_locator_test.dart b/pkg/analyzer/test/src/dart/ast/element_locator_test.dart
index 9c1920f..8620219 100644
--- a/pkg/analyzer/test/src/dart/ast/element_locator_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/element_locator_test.dart
@@ -346,6 +346,17 @@
expect(element, isLibraryElement);
}
+ test_locate_PatternField() async {
+ await resolveTestCode(r'''
+void f(Object? x) {
+ if (x case int(isEven: true)) {}
+}
+''');
+ var node = findNode.patternField('isEven:');
+ var element = ElementLocator.locate(node);
+ expect(element, isPropertyAccessorElement);
+ }
+
test_locate_PostfixExpression() async {
await resolveTestCode('int addOne(int x) => x++;');
var node = findNode.postfix('x++');