Rename class when the refactoring is invoked on the class name in an instance creation.

R=brianwilkerson@google.com

Bug: https://github.com/dart-lang/sdk/issues/34484
Change-Id: I9faa08e1741603dedcfe7cfacb2192d44dedc89d
Reviewed-on: https://dart-review.googlesource.com/75380
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 80cb8d2..221af2e 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -1017,19 +1017,13 @@
           }
         }
 
-        // Canonicalize to ConstructorName.
-        var constructorName = _canonicalizeToConstructorName(node);
-        if (constructorName != null) {
-          node = constructorName;
-          element = constructorName.staticElement;
-          // Use the constructor name offset/length.
-          if (constructorName.name != null) {
-            feedbackOffset = constructorName.name.offset;
-            feedbackLength = constructorName.name.length;
-          } else {
-            feedbackOffset = -1;
-            feedbackLength = 0;
-          }
+        // Rename the class when on `new` in an instance creation.
+        if (node is InstanceCreationExpression) {
+          InstanceCreationExpression creation = node;
+          var typeIdentifier = creation.constructorName.type.name;
+          element = typeIdentifier.staticElement;
+          feedbackOffset = typeIdentifier.offset;
+          feedbackLength = typeIdentifier.length;
         }
 
         // do create the refactoring
@@ -1177,32 +1171,6 @@
     }
     return new RefactoringStatus();
   }
-
-  /**
-   * If the [node] is a constructor reference, return the corresponding
-   * [ConstructorName], or `null` otherwise.
-   */
-  static ConstructorName _canonicalizeToConstructorName(AstNode node) {
-    var parent = node.parent;
-    var parent2 = parent?.parent;
-
-    // "named" in "Class.named".
-    if (parent is ConstructorName) {
-      return parent;
-    }
-
-    // "Class" in "Class.named".
-    if (parent is TypeName && parent2 is ConstructorName) {
-      return parent2;
-    }
-
-    // Canonicalize "new Class.named()" to "Class.named".
-    if (node is InstanceCreationExpression) {
-      return node.constructorName;
-    }
-
-    return null;
-  }
 }
 
 /**
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index e3a0a33..b696ea8 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -25,10 +25,7 @@
     defineReflectiveTests(InlineLocalTest);
     defineReflectiveTests(InlineMethodTest);
     defineReflectiveTests(MoveFileTest);
-    // TODO(brianwilkerson) Re-enable these tests. They were commented out
-    // because they are non-deterministic under the new driver. I suspect that
-    // there is a future that isn't being waited for.
-//    defineReflectiveTests(RenameTest);
+    defineReflectiveTests(RenameTest);
   });
 }
 
@@ -1355,6 +1352,151 @@
 ''');
   }
 
+  test_class_fromFactoryRedirectingConstructor() {
+    addTestFile('''
+class A {
+  A() = Test.named;
+}
+class Test {
+  Test.named() {}
+}
+''');
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('Test.named;', 'NewName');
+      },
+      '''
+class A {
+  A() = NewName.named;
+}
+class NewName {
+  NewName.named() {}
+}
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, 18);
+        expect(renameFeedback.length, 4);
+      },
+    );
+  }
+
+  test_class_fromInstanceCreation() {
+    addTestFile('''
+class Test {
+  Test() {}
+}
+main() {
+  new Test();
+}
+''');
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('Test();', 'NewName');
+      },
+      '''
+class NewName {
+  NewName() {}
+}
+main() {
+  new NewName();
+}
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, 42);
+        expect(renameFeedback.length, 4);
+      },
+    );
+  }
+
+  test_class_fromInstanceCreation_namedConstructor() {
+    addTestFile('''
+class Test {
+  Test.named() {}
+}
+main() {
+  new Test.named();
+}
+''');
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('Test.named();', 'NewName');
+      },
+      '''
+class NewName {
+  NewName.named() {}
+}
+main() {
+  new NewName.named();
+}
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, 48);
+        expect(renameFeedback.length, 4);
+      },
+    );
+  }
+
+  test_class_fromInstanceCreation_onNew() {
+    addTestFile('''
+class Test {
+  Test() {}
+}
+main() {
+  new Test();
+}
+''');
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('new Test();', 'NewName');
+      },
+      '''
+class NewName {
+  NewName() {}
+}
+main() {
+  new NewName();
+}
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, 42);
+        expect(renameFeedback.length, 4);
+      },
+    );
+  }
+
+  test_class_fromInstanceCreation_onNew_namedConstructor() {
+    addTestFile('''
+class Test {
+  Test.named() {}
+}
+main() {
+  new Test.named();
+}
+''');
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('new Test.named();', 'NewName');
+      },
+      '''
+class NewName {
+  NewName.named() {}
+}
+main() {
+  new NewName.named();
+}
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, 48);
+        expect(renameFeedback.length, 4);
+      },
+    );
+  }
+
   test_class_options_fatalError() {
     addTestFile('''
 class Test {}
@@ -1591,18 +1733,18 @@
 ''');
   }
 
-  test_constructor_fromFactoryRedirectingConstructor_onClassName() {
+  test_constructor_fromFactoryRedirectingConstructor() {
     addTestFile('''
 class A {
-  A() = B;
+  A() = B.test;
 }
 class B {
-  B() {}
+  B.test() {}
 }
 ''');
     return assertSuccessfulRefactoring(
       () {
-        return sendRenameRequest('B;', 'newName');
+        return sendRenameRequest('test;', 'newName');
       },
       '''
 class A {
@@ -1614,8 +1756,8 @@
 ''',
       feedbackValidator: (feedback) {
         RenameFeedback renameFeedback = feedback;
-        expect(renameFeedback.offset, -1);
-        expect(renameFeedback.length, 0);
+        expect(renameFeedback.offset, 20);
+        expect(renameFeedback.length, 4);
       },
     );
   }
@@ -1649,64 +1791,6 @@
     );
   }
 
-  test_constructor_fromInstanceCreation_default_onClassName() {
-    addTestFile('''
-class A {
-  A() {}
-}
-main() {
-  new A();
-}
-''');
-    return assertSuccessfulRefactoring(
-      () {
-        return sendRenameRequest('A();', 'newName');
-      },
-      '''
-class A {
-  A.newName() {}
-}
-main() {
-  new A.newName();
-}
-''',
-      feedbackValidator: (feedback) {
-        RenameFeedback renameFeedback = feedback;
-        expect(renameFeedback.offset, -1);
-        expect(renameFeedback.length, 0);
-      },
-    );
-  }
-
-  test_constructor_fromInstanceCreation_default_onNew() {
-    addTestFile('''
-class A {
-  A() {}
-}
-main() {
-  new A();
-}
-''');
-    return assertSuccessfulRefactoring(
-      () {
-        return sendRenameRequest('new A();', 'newName');
-      },
-      '''
-class A {
-  A.newName() {}
-}
-main() {
-  new A.newName();
-}
-''',
-      feedbackValidator: (feedback) {
-        RenameFeedback renameFeedback = feedback;
-        expect(renameFeedback.offset, -1);
-        expect(renameFeedback.length, 0);
-      },
-    );
-  }
-
   test_feedback() {
     addTestFile('''
 class Test {}