Don't split const/final variable declarations. Add explicit type.

R=brianwilkerson@google.com, keertip@google.com

Change-Id: I418a5e541194f2c94927f23b3468a6a876e05a1b
Reviewed-on: https://dart-review.googlesource.com/c/88438
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 05e9455..135f6dc 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -2897,40 +2897,48 @@
   }
 
   Future<void> _addProposal_splitVariableDeclaration() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    // prepare DartVariableStatement, should be part of Block
-    VariableDeclarationStatement statement =
-        node.thisOrAncestorOfType<VariableDeclarationStatement>();
-    if (statement != null && statement.parent is Block) {
-    } else {
-      _coverageMarker();
+    var variableList = node?.thisOrAncestorOfType<VariableDeclarationList>();
+
+    // Must be a local variable declaration.
+    if (variableList?.parent is! VariableDeclarationStatement) {
       return;
     }
-    // check that statement declares single variable
-    List<VariableDeclaration> variables = statement.variables.variables;
+    VariableDeclarationStatement statement = variableList.parent;
+
+    // Cannot be `const` or `final`.
+    var keywordKind = variableList.keyword?.keyword;
+    if (keywordKind == Keyword.CONST || keywordKind == Keyword.FINAL) {
+      return;
+    }
+
+    var variables = variableList.variables;
     if (variables.length != 1) {
-      _coverageMarker();
       return;
     }
-    VariableDeclaration variable = variables[0];
-    // prepare initializer
-    Expression initializer = variable.initializer;
-    if (initializer == null) {
-      _coverageMarker();
+
+    // The caret must be between the type and the variable name.
+    var variable = variables[0];
+    if (!range.startEnd(statement, variable.name).contains(selectionOffset)) {
       return;
     }
+
+    // The variable must have an initializer.
+    if (variable.initializer == null) {
+      return;
+    }
+
     var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      // remove initializer value
-      builder.addDeletion(range.endStart(variable.name, statement.semicolon));
-      // add assignment statement
-      String indent = utils.getNodePrefix(statement);
-      String name = variable.name.name;
-      String initSrc = _getNodeText(initializer);
-      SourceRange assignRange = range.endLength(statement, 0);
-      builder.addSimpleReplacement(
-          assignRange, eol + indent + name + ' = ' + initSrc + ';');
+    await changeBuilder.addFileEdit(file, (builder) {
+      if (variableList.type == null) {
+        builder.addReplacement(range.token(variableList.keyword), (builder) {
+          var type = variable.declaredElement.type;
+          builder.writeType(type);
+        });
+      }
+
+      var indent = utils.getNodePrefix(statement);
+      var name = variable.name.name;
+      builder.addSimpleInsertion(variable.name.end, ';' + eol + indent + name);
     });
     _addAssistFromBuilder(
         changeBuilder, DartAssistKind.SPLIT_VARIABLE_DECLARATION);
diff --git a/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart b/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart
index 2d88afc..aed39c3 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart
@@ -19,6 +19,24 @@
   @override
   AssistKind get kind => DartAssistKind.SPLIT_VARIABLE_DECLARATION;
 
+  test_const() async {
+    await resolveTestUnit('''
+main() {
+  const v = 1;
+}
+''');
+    await assertNoAssistAt('v = 1');
+  }
+
+  test_final() async {
+    await resolveTestUnit('''
+main() {
+  final v = 1;
+}
+''');
+    await assertNoAssistAt('v = 1');
+  }
+
   test_notOneVariable() async {
     await resolveTestUnit('''
 main() {
@@ -36,7 +54,7 @@
 ''');
     await assertHasAssistAt('v =', '''
 main() {
-  var v;
+  int v;
   v = 1;
 }
 ''');
@@ -79,7 +97,7 @@
 ''');
     await assertHasAssistAt('var ', '''
 main() {
-  var v;
+  int v;
   v = 1;
 }
 ''');