DAS plugins: Do not report the "dependency_overrides" section as illegal

Change-Id: Ib7c3f88569172821c04bce96c1fcae4aa13e05c7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/508372
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/analysis_options/analysis_options_file.dart b/pkg/analyzer/lib/src/analysis_options/analysis_options_file.dart
index a58ca14..eb59c96 100644
--- a/pkg/analyzer/lib/src/analysis_options/analysis_options_file.dart
+++ b/pkg/analyzer/lib/src/analysis_options/analysis_options_file.dart
@@ -67,6 +67,7 @@
   static const String url = 'url';
   static const String version = 'version';
   static const String hosted = 'hosted';
+  static const String dependencyOverrides = 'dependency_overrides';
 
   /// Supported 'plugins' options.
   static const Set<String> pluginsOptions = {
diff --git a/pkg/analyzer/lib/src/analysis_options/options_file_validator.dart b/pkg/analyzer/lib/src/analysis_options/options_file_validator.dart
index 30698ac..68554af 100644
--- a/pkg/analyzer/lib/src/analysis_options/options_file_validator.dart
+++ b/pkg/analyzer/lib/src/analysis_options/options_file_validator.dart
@@ -1079,22 +1079,44 @@
           if (pluginName is! String) {
             return;
           }
-          switch (pluginValue) {
-            case YamlScalar(value: String()):
-              // Valid enough. We could validate that it is a legal VersionConstraint
-              // from the pub_semver package.
-              break;
-            case YamlMap():
-              _validatePluginMap(reporter, pluginName, pluginValue);
-            default:
-              reporter.report(
-                diag.invalidSectionFormat
-                    .withArguments(
-                      sectionName:
-                          '${AnalysisOptionsFileKeys.plugins}/$pluginName',
-                    )
-                    .atSourceSpan(pluginValue.span),
-              );
+          if (pluginName == AnalysisOptionsFileKeys.dependencyOverrides) {
+            switch (pluginValue) {
+              case YamlMap():
+                pluginValue.nodes.forEach((
+                  overriddenPluginNameNode,
+                  overriddenPluginValue,
+                ) {
+                  if (overriddenPluginNameNode is! YamlScalar) {
+                    return;
+                  }
+                  var overriddenPluginName = overriddenPluginNameNode.value;
+                  if (overriddenPluginName is! String) {
+                    return;
+                  }
+                  _validatePlugin(
+                    reporter,
+                    '${AnalysisOptionsFileKeys.plugins}/${AnalysisOptionsFileKeys.dependencyOverrides}',
+                    overriddenPluginName,
+                    overriddenPluginValue,
+                  );
+                });
+              default:
+                reporter.report(
+                  diag.invalidSectionFormat
+                      .withArguments(
+                        sectionName:
+                            '${AnalysisOptionsFileKeys.plugins}/${AnalysisOptionsFileKeys.dependencyOverrides}',
+                      )
+                      .atSourceSpan(pluginValue.span),
+                );
+            }
+          } else {
+            _validatePlugin(
+              reporter,
+              AnalysisOptionsFileKeys.plugins,
+              pluginName,
+              pluginValue,
+            );
           }
         });
       case YamlList():
@@ -1116,12 +1138,11 @@
 
   void _validateDiagnostics(
     DiagnosticReporter reporter,
-    String pluginName,
+    String pluginPath,
     YamlNode diagnosticsValue,
   ) {
     var sectionName = [
-      AnalysisOptionsFileKeys.plugins,
-      pluginName,
+      pluginPath,
       AnalysisOptionsFileKeys.diagnostics,
     ].join('/');
     if (diagnosticsValue is! YamlMap) {
@@ -1161,14 +1182,10 @@
 
   void _validateGit(
     DiagnosticReporter reporter,
-    String pluginName,
+    String pluginPath,
     YamlNode gitValue,
   ) {
-    var sectionName = [
-      AnalysisOptionsFileKeys.plugins,
-      pluginName,
-      AnalysisOptionsFileKeys.git,
-    ].join('/');
+    var sectionName = [pluginPath, AnalysisOptionsFileKeys.git].join('/');
 
     if (gitValue is YamlScalar) {
       if (gitValue.value is! String) {
@@ -1205,25 +1222,44 @@
     });
   }
 
+  void _validatePlugin(
+    DiagnosticReporter reporter,
+    String parentPath,
+    String pluginName,
+    YamlNode pluginValue,
+  ) {
+    var pluginPath = '$parentPath/$pluginName';
+    switch (pluginValue) {
+      case YamlScalar(value: String()):
+        // Valid enough. We could validate that it is a legal VersionConstraint
+        // from the pub_semver package.
+        break;
+      case YamlMap():
+        _validatePluginMap(reporter, pluginPath, pluginValue);
+      default:
+        reporter.report(
+          diag.invalidSectionFormat
+              .withArguments(sectionName: pluginPath)
+              .atSourceSpan(pluginValue.span),
+        );
+    }
+  }
+
   void _validatePluginMap(
     DiagnosticReporter reporter,
-    String pluginName,
+    String pluginPath,
     YamlMap pluginValue,
   ) {
     pluginValue.nodes.forEach((pluginMapKeyNode, pluginMapValueNode) {
       if (pluginMapKeyNode case YamlScalar(value: String pluginMapKey)) {
         if (pluginMapKey == AnalysisOptionsFileKeys.diagnostics) {
-          _validateDiagnostics(reporter, pluginName, pluginMapValueNode);
+          _validateDiagnostics(reporter, pluginPath, pluginMapValueNode);
         } else if (pluginMapKey == AnalysisOptionsFileKeys.git) {
-          _validateGit(reporter, pluginName, pluginMapValueNode);
+          _validateGit(reporter, pluginPath, pluginMapValueNode);
         } else if (!AnalysisOptionsFileKeys.pluginsOptions.contains(
           pluginMapKey,
         )) {
-          _builder.reportError(
-            reporter,
-            '${AnalysisOptionsFileKeys.plugins}/$pluginName',
-            pluginMapKeyNode,
-          );
+          _builder.reportError(reporter, pluginPath, pluginMapKeyNode);
         }
       }
       // TODO(srawlins): Validate 'path' is a YamlScalar.
diff --git a/pkg/analyzer/test/src/options/options_file_validator_test.dart b/pkg/analyzer/test/src/options/options_file_validator_test.dart
index 3b2e2a6..f35c352 100644
--- a/pkg/analyzer/test/src/options/options_file_validator_test.dart
+++ b/pkg/analyzer/test/src/options/options_file_validator_test.dart
@@ -616,6 +616,27 @@
     );
   }
 
+  test_plugins_dependencyOverrides() {
+    validate('''
+plugins:
+  dependency_overrides:
+    one:
+      git: https://github.com/dart-lang/linter.git
+''', []);
+  }
+
+  test_plugins_dependencyOverrides_invalid_mapKey() {
+    validate(
+      '''
+plugins:
+  dependency_overrides:
+    one:
+      ppath: foo/bar
+''',
+      [diag.unsupportedOptionWithLegalValues],
+    );
+  }
+
   test_plugins_diagnostics_invalid() {
     validate(
       '''