Add support for more data-driven fixes to the bulk fix processor

Change-Id: I8a12e47c146d59db1a2ee689c5afbd8018349539
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/165380
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index bbbf044..9e583cc 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -262,17 +262,15 @@
     CompileTimeErrorCode.IMPLEMENTS_NON_CLASS: [
       DataDriven.newInstance,
     ],
-    // TODO(brianwilkerson) Uncomment the entries below as we add tests for
-    //  them.
-    // CompileTimeErrorCode.INVALID_OVERRIDE: [
-    //   DataDriven.newInstance,
-    // ],
+    CompileTimeErrorCode.INVALID_OVERRIDE: [
+      DataDriven.newInstance,
+    ],
     CompileTimeErrorCode.MIXIN_OF_NON_CLASS: [
       DataDriven.newInstance,
     ],
-    // CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT: [
-    //   DataDriven.newInstance,
-    // ],
+    CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT: [
+      DataDriven.newInstance,
+    ],
     CompileTimeErrorCode.NOT_ENOUGH_POSITIONAL_ARGUMENTS: [
       DataDriven.newInstance,
     ],
@@ -294,18 +292,20 @@
     CompileTimeErrorCode.UNDEFINED_SETTER: [
       DataDriven.newInstance,
     ],
-    // CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS: [
-    //   DataDriven.newInstance,
-    // ],
-    // CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR: [
-    //   DataDriven.newInstance,
-    // ],
-    // CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_EXTENSION: [
-    //   DataDriven.newInstance,
-    // ],
-    // CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD: [
-    //   DataDriven.newInstance,
-    // ],
+    CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS: [
+      DataDriven.newInstance,
+    ],
+    CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR: [
+      DataDriven.newInstance,
+    ],
+    CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_EXTENSION: [
+      DataDriven.newInstance,
+    ],
+    CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD: [
+      DataDriven.newInstance,
+    ],
+    // TODO(brianwilkerson) Uncomment the entries below as we add tests for
+    //  them.
     // HintCode.DEPRECATED_MEMBER_USE: [
     //   DataDriven.newInstance,
     // ],
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/data_driven_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/data_driven_test.dart
index 1d5cf23..cc14f37 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/data_driven_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/data_driven_test.dart
@@ -13,7 +13,9 @@
     defineReflectiveTests(ExtraPositionalArgumentsCouldBeNamedTest);
     defineReflectiveTests(ExtraPositionalArgumentsTest);
     defineReflectiveTests(ImplementsNonClassTest);
+    defineReflectiveTests(InvalidOverrideTest);
     defineReflectiveTests(MixinOfNonClassTest);
+    defineReflectiveTests(NewWithUndefinedConstructorDefaultTest);
     defineReflectiveTests(NotEnoughPositionalArgumentsTest);
     defineReflectiveTests(OverrideOnNonOverridingMethodTest);
     defineReflectiveTests(UndefinedClassTest);
@@ -22,6 +24,10 @@
     defineReflectiveTests(UndefinedIdentifierTest);
     defineReflectiveTests(UndefinedMethodTest);
     defineReflectiveTests(UndefinedSetterTest);
+    defineReflectiveTests(WrongNumberOfTypeArgumentsConstructorTest);
+    defineReflectiveTests(WrongNumberOfTypeArgumentsExtensionTest);
+    defineReflectiveTests(WrongNumberOfTypeArgumentsMethodTest);
+    defineReflectiveTests(WrongNumberOfTypeArgumentsTest);
   });
 }
 
@@ -172,6 +178,104 @@
 }
 
 @reflectiveTest
+class InvalidOverrideTest extends _DataDrivenTest {
+  @failingTest
+  Future<void> test_addParameter() async {
+    // This functionality hasn't been implemented yet.
+    setPackageContent('''
+class C {
+  void m(int x, int y) {}
+}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+- title: 'Add parameter'
+  date: 2020-09-01
+  element:
+    uris: ['$importUri']
+    method: 'm'
+    inClass: 'C'
+  changes:
+    - kind: 'addParameter'
+      index: 1
+      name: 'y'
+      style: required_positional
+      argumentValue:
+        expression: '0'
+''');
+    await resolveTestUnit('''
+import '$importUri';
+class A extends C {
+  @override
+  void m(int x) {}
+}
+class B extends C {
+  @override
+  void m(int x) {}
+}
+''');
+    await assertHasFix('''
+import '$importUri';
+class A extends C {
+  @override
+  void m(int x, int y) {}
+}
+class B extends C {
+  @override
+  void m(int x, int y) {}
+}
+''');
+  }
+
+  Future<void> test_addTypeParameter() async {
+    setPackageContent('''
+class C {
+  void m<T>() {}
+}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+- title: 'Add type parameter'
+  date: 2020-09-01
+  element:
+    uris: ['$importUri']
+    method: 'm'
+    inClass: 'C'
+  changes:
+    - kind: 'addTypeParameter'
+      index: 0
+      name: 'T'
+      argumentValue:
+        expression: 'int'
+''');
+    await resolveTestUnit('''
+import '$importUri';
+class A extends C {
+  @override
+  void m() {}
+}
+class B extends C {
+  @override
+  void m() {}
+}
+''');
+    await assertHasFix('''
+import '$importUri';
+class A extends C {
+  @override
+  void m<T>() {}
+}
+class B extends C {
+  @override
+  void m<T>() {}
+}
+''');
+  }
+}
+
+@reflectiveTest
 class MixinOfNonClassTest extends _DataDrivenTest {
   Future<void> test_rename() async {
     setPackageContent('''
@@ -203,6 +307,38 @@
 }
 
 @reflectiveTest
+class NewWithUndefinedConstructorDefaultTest extends _DataDrivenTest {
+  Future<void> test_rename() async {
+    setPackageContent('''
+class C {
+  C.new([C c]);
+}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+- title: 'Rename to new'
+  date: 2020-09-01
+  element:
+    uris: ['$importUri']
+    constructor: ''
+    inClass: 'C'
+  changes:
+    - kind: 'rename'
+      newName: 'new'
+''');
+    await resolveTestUnit('''
+import '$importUri';
+C c() => C(C());
+''');
+    await assertHasFix('''
+import '$importUri';
+C c() => C.new(C.new());
+''');
+  }
+}
+
+@reflectiveTest
 class NotEnoughPositionalArgumentsTest extends _DataDrivenTest {
   Future<void> test_removeParameter() async {
     setPackageContent('''
@@ -488,6 +624,180 @@
   }
 }
 
+@reflectiveTest
+class WrongNumberOfTypeArgumentsConstructorTest extends _DataDrivenTest {
+  Future<void> test_addTypeParameter() async {
+    setPackageContent('''
+class C<S, T> {
+  C.c([C c]);
+}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+- title: 'Add type parameter'
+  date: 2020-09-01
+  element:
+    uris: ['$importUri']
+    class: 'C'
+  changes:
+    - kind: 'addTypeParameter'
+      index: 1
+      name: 'T'
+      argumentValue:
+        expression: 'int'
+''');
+    await resolveTestUnit('''
+import '$importUri';
+C f() => C<String>.c(C<String>.c());
+''');
+    await assertHasFix('''
+import '$importUri';
+C f() => C<String, int>.c(C<String, int>.c());
+''');
+  }
+}
+
+@reflectiveTest
+class WrongNumberOfTypeArgumentsExtensionTest extends _DataDrivenTest {
+  Future<void> test_addTypeParameter() async {
+    setPackageContent('''
+extension E<S, T> on String {
+  int m(int x) {}
+}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+- title: 'Add type parameter'
+  date: 2020-09-01
+  element:
+    uris: ['$importUri']
+    extension: 'E'
+  changes:
+    - kind: 'addTypeParameter'
+      index: 1
+      name: 'T'
+      argumentValue:
+        expression: 'int'
+''');
+    await resolveTestUnit('''
+import '$importUri';
+void f(String s) {
+  E<String>(s).m(E<String>(s).m(0));
+}
+''');
+    await assertHasFix('''
+import '$importUri';
+void f(String s) {
+  E<String, int>(s).m(E<String, int>(s).m(0));
+}
+''');
+  }
+}
+
+@reflectiveTest
+class WrongNumberOfTypeArgumentsMethodTest extends _DataDrivenTest {
+  Future<void> test_addTypeParameter() async {
+    setPackageContent('''
+class C {
+  int m<S, T>(int x) {}
+}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+- title: 'Add type parameter'
+  date: 2020-09-01
+  element:
+    uris: ['$importUri']
+    method: 'm'
+    inClass: 'C'
+  changes:
+    - kind: 'addTypeParameter'
+      index: 1
+      name: 'T'
+      argumentValue:
+        expression: 'int'
+''');
+    await resolveTestUnit('''
+import '$importUri';
+void f(C c) {
+  c.m<String>(c.m<String>(0));
+}
+''');
+    await assertHasFix('''
+import '$importUri';
+void f(C c) {
+  c.m<String, int>(c.m<String, int>(0));
+}
+''');
+  }
+}
+
+@reflectiveTest
+class WrongNumberOfTypeArgumentsTest extends _DataDrivenTest {
+  Future<void> test_addTypeParameter() async {
+    setPackageContent('''
+class C<S, T> {}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+- title: 'Add type parameter'
+  date: 2020-09-01
+  element:
+    uris: ['$importUri']
+    class: 'C'
+  changes:
+    - kind: 'addTypeParameter'
+      index: 1
+      name: 'T'
+      argumentValue:
+        expression: 'int'
+''');
+    await resolveTestUnit('''
+import '$importUri';
+void f(C<String> c) {}
+''');
+    await assertHasFix('''
+import '$importUri';
+void f(C<String, int> c) {}
+''');
+  }
+
+  Future<void> test_addTypeParameter_unnamedConstructor() async {
+    setPackageContent('''
+class C<S, T> {
+  C([C c]);
+}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+- title: 'Add type parameter'
+  date: 2020-09-01
+  element:
+    uris: ['$importUri']
+    class: 'C'
+  changes:
+    - kind: 'addTypeParameter'
+      index: 1
+      name: 'T'
+      argumentValue:
+        expression: 'int'
+''');
+    await resolveTestUnit('''
+import '$importUri';
+C f() => C<String>(C<String>());
+''');
+    await assertHasFix('''
+import '$importUri';
+C f() => C<String, int>(C<String, int>());
+''');
+  }
+}
+
 class _DataDrivenTest extends BulkFixProcessorTest {
   /// Return the URI used to import the library created by [setPackageContent].
   String get importUri => 'package:p/lib.dart';