Add AnalysisContext.sdkRoot

Change-Id: I5895b4bb9ba797c93b22f20ee1f2185066de9365
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/180622
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index fe2afbf..a8e8b53 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -4,6 +4,7 @@
 * Widened the dependency on package:crypto to include version 3.0.0.
 * Deprecated `CompilationUnitElement.functionTypeAliases`.
   Use `CompilationUnitElement.typeAliases` instead.
+* Added `AnalysisContext.sdkRoot`.
 
 ## 0.41.1
 * Updated `PackageBuildWorkspace` that supports `package:build` to stop
diff --git a/pkg/analyzer/lib/dart/analysis/analysis_context.dart b/pkg/analyzer/lib/dart/analysis/analysis_context.dart
index 37035e4..97ff59c 100644
--- a/pkg/analyzer/lib/dart/analysis/analysis_context.dart
+++ b/pkg/analyzer/lib/dart/analysis/analysis_context.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/analysis/context_root.dart';
 import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 
@@ -27,6 +28,10 @@
   /// Return the currently active analysis session.
   AnalysisSession get currentSession;
 
+  /// The root directory of the SDK against which files of this context are
+  /// analyzed, or `null` if the SDK is not directory based.
+  Folder get sdkRoot;
+
   /// Return the workspace for containing the context root.
   Workspace get workspace;
 }
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
index 1d90610..13ebb84 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart' show AnalysisDriver;
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisOptions;
 import 'package:analyzer/src/workspace/workspace.dart';
 
@@ -42,6 +43,15 @@
   AnalysisSession get currentSession => driver.currentSession;
 
   @override
+  Folder get sdkRoot {
+    var sdk = driver.sourceFactory.dartSdk;
+    if (sdk is FolderBasedDartSdk) {
+      return sdk.directory;
+    }
+    return null;
+  }
+
+  @override
   Workspace get workspace {
     return _workspace ??= _buildWorkspace();
   }
diff --git a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
index a54fa1a..8df9d1c 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
@@ -88,4 +88,14 @@
     expect(context.driver.sourceFactory.dartSdk.mapDartUri('dart:core'),
         sdk.mapDartUri('dart:core'));
   }
+
+  test_createContext_sdkRoot() {
+    MockSdk(resourceProvider: resourceProvider);
+    DriverBasedAnalysisContext context = contextBuilder.createContext(
+        contextRoot: contextRoot,
+        sdkPath: resourceProvider.convertPath(sdkRoot));
+    expect(context.analysisOptions, isNotNull);
+    expect(context.contextRoot, contextRoot);
+    expect(context.sdkRoot.path, sdkRoot);
+  }
 }