Report another error in the data-driven data file

Change-Id: Ia252f69f70caeee6343978c7f8528b092e48c973
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164804
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
index 2007991..8394acd 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
@@ -20,6 +20,15 @@
 
   /**
    * Parameters:
+   * 0: the key with which the value is associated
+   * 1: the allowed values as a comma-separated list
+   */
+  static const TransformSetErrorCode invalidValueOneOf = TransformSetErrorCode(
+      'invalid_value_one_of',
+      "The value of '{0}' must be one of the following: '{1}'.");
+
+  /**
+   * Parameters:
    * 0: the missing key
    */
   static const TransformSetErrorCode missingKey =
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
index 543bbeb..d283e88 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
@@ -219,6 +219,15 @@
     return null;
   }
 
+  /// Report that the value represented by the [node] does not have the
+  /// [expectedType], using the [context] to get the key to use in the message.
+  Null _reportInvalidValueOneOf(
+      YamlNode node, ErrorContext context, List<String> allowedValues) {
+    _reportError(TransformSetErrorCode.invalidValueOneOf, node,
+        [context.key, allowedValues.join(', ')]);
+    return null;
+  }
+
   /// Report that a required key is missing, using the [context] to locate the
   /// node associated with the diagnostic and the key to use in the message.
   Null _reportMissingKey(ErrorContext context) {
@@ -374,19 +383,25 @@
     if (node is YamlMap) {
       var kind = _translateString(node.valueAt(_kindKey),
           ErrorContext(key: _kindKey, parentNode: node));
-      if (kind == _addTypeParameterKind) {
-        return _translateAddTypeParameterChange(node);
-      } else if (kind == _renameKind) {
-        return _translateRenameChange(node);
+      if (kind == null) {
+        return null;
       } else if (kind == _addParameterKind) {
         _translateAddParameterChange(node);
         return null;
+      } else if (kind == _addTypeParameterKind) {
+        return _translateAddTypeParameterChange(node);
       } else if (kind == _removeParameterKind) {
         _translateRemoveParameterChange(node);
         return null;
+      } else if (kind == _renameKind) {
+        return _translateRenameChange(node);
       }
-      // TODO(brianwilkerson) Report the invalid change kind.
-      return null;
+      return _reportInvalidValueOneOf(node, context, [
+        _addParameterKind,
+        _addTypeParameterKind,
+        _removeParameterKind,
+        _renameKind,
+      ]);
     } else {
       return _reportInvalidValue(node, context, 'Map');
     }
@@ -427,10 +442,11 @@
           return null;
         }
       }
-      var extractors = _translateTemplateVariables(node.valueAt(_variablesKey),
+      // TODO(brianwilkerson) We should report unreferenced variables.
+      var generators = _translateTemplateVariables(node.valueAt(_variablesKey),
           ErrorContext(key: _variablesKey, parentNode: node));
       var components =
-          _extractTemplateComponents(template, extractors, templateOffset);
+          _extractTemplateComponents(template, generators, templateOffset);
       return CodeTemplate(kind, components);
     } else if (node == null) {
       if (required) {
@@ -670,7 +686,7 @@
       for (var entry in node.nodes.entries) {
         var name = _translateKey(entry.key);
         if (name != null) {
-          var value = _translateValueExtractor(
+          var value = _translateValueGenerator(
               entry.value, ErrorContext(key: name, parentNode: node));
           if (value != null) {
             generators[name] = value;
@@ -784,17 +800,21 @@
   /// extractor, or `null` if the [node] does not represent a valid value
   /// extractor. If the [node] is not valid, use the [context] to report the
   /// error.
-  ValueGenerator _translateValueExtractor(YamlNode node, ErrorContext context) {
+  ValueGenerator _translateValueGenerator(YamlNode node, ErrorContext context) {
     if (node is YamlMap) {
       var kind = _translateString(node.valueAt(_kindKey),
           ErrorContext(key: _kindKey, parentNode: node));
-      if (kind == _argumentKind) {
+      if (kind == null) {
+        return null;
+      } else if (kind == _argumentKind) {
         return _translateArgumentExtractor(node);
       } else if (kind == _importKind) {
         return _translateImportValue(node);
       }
-      // TODO(brianwilkerson) Report the invalid extractor kind.
-      return null;
+      return _reportInvalidValueOneOf(node, context, [
+        _argumentKind,
+        _importKind,
+      ]);
     } else if (node == null) {
       return _reportMissingKey(context);
     } else {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_one_of_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_one_of_test.dart
new file mode 100644
index 0000000..2e606bb
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_one_of_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../transform_set_parser_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidValueOneOfTest);
+  });
+}
+
+@reflectiveTest
+class InvalidValueOneOfTest extends AbstractTransformSetParserTest {
+  void test_changeKind() {
+    assertErrors('''
+version: 1
+transforms:
+- title: 'Rename A'
+  date: 2020-09-08
+  element:
+    uris: ['test.dart']
+    class: 'A'
+  changes:
+    - kind: 'invalid'
+''', [
+      error(TransformSetErrorCode.invalidValueOneOf, 129, 16),
+    ]);
+  }
+
+  void test_valueKind() {
+    assertErrors('''
+version: 1
+transforms:
+- title: 'Rename A'
+  date: 2020-09-08
+  element:
+    uris: ['test.dart']
+    class: 'A'
+  changes:
+    - kind: 'addTypeParameter'
+      index: 0
+      name: 'T'
+      argumentValue: 
+        expression: ''
+        variables:
+          x:
+            kind: 'invalid'
+''', [
+      error(TransformSetErrorCode.invalidValueOneOf, 274, 16),
+    ]);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
index 76bb9b4..e8bbf94 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
@@ -4,6 +4,7 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'invalid_value_one_of_test.dart' as invalid_value_one_of;
 import 'invalid_value_test.dart' as invalid_value;
 import 'missing_key_test.dart' as missing_key;
 import 'missing_template_end_test.dart' as missing_template_end;
@@ -13,6 +14,7 @@
 
 void main() {
   defineReflectiveSuite(() {
+    invalid_value_one_of.main();
     invalid_value.main();
     missing_key.main();
     missing_template_end.main();