Add FileResult and AnalysisDriver.getFileSync().

I thought that getSourceKind() might be not the best API. We are moving
away from Source, and it seems that we should stop using SourceKind as well.

R=brianwilkerson@google.com

Change-Id: I0fcff8dc8cefcd6d8fb899badab8037bf8d67775
Reviewed-on: https://dart-review.googlesource.com/58442
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
index 2b8b4ac..4798194 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
@@ -150,8 +150,8 @@
 
   Future<Null> computeResult(String uri) {
     FileState file = fsState.getFileForUri(Uri.parse(uri));
-    AnalysisResult result = new AnalysisResult(
-        this, null, file.path, null, true, null, null, null, null, null, null);
+    AnalysisResult result = new AnalysisResult(this, null, file.path, null,
+        true, null, null, false, null, null, null, null);
     _resultController.add(result);
     return new Future.delayed(new Duration(milliseconds: 1));
   }
diff --git a/pkg/analyzer/lib/dart/analysis/results.dart b/pkg/analyzer/lib/dart/analysis/results.dart
index 91fd27c..635fe97 100644
--- a/pkg/analyzer/lib/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/dart/analysis/results.dart
@@ -42,16 +42,11 @@
  *
  * Clients may not extend, implement or mix-in this class.
  */
-abstract class AnalysisResultWithErrors implements AnalysisResult {
+abstract class AnalysisResultWithErrors implements FileResult {
   /**
    * The analysis errors that were computed during analysis.
    */
   List<AnalysisError> get errors;
-
-  /**
-   * Information about lines in the content.
-   */
-  LineInfo get lineInfo;
 }
 
 /**
@@ -63,6 +58,24 @@
 abstract class ErrorsResult implements AnalysisResultWithErrors {}
 
 /**
+ * The result of computing some cheap information for a single file, when full
+ * parsed file is not required, so [ParseResult] is not necessary.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FileResult implements AnalysisResult {
+  /**
+   * Whether the file is a part.
+   */
+  bool get isPart;
+
+  /**
+   * Information about lines in the content.
+   */
+  LineInfo get lineInfo;
+}
+
+/**
  * The result of parsing of a single file. The errors returned include only
  * those discovered during scanning and parsing.
  *
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 822e3d3..26b49f5 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -663,7 +663,7 @@
     }
 
     return new ErrorsResult(currentSession, path, analysisResult.uri,
-        analysisResult.lineInfo, analysisResult.errors);
+        analysisResult.lineInfo, analysisResult.isPart, analysisResult.errors);
   }
 
   /**
@@ -691,6 +691,18 @@
   }
 
   /**
+   * Return the [FileResult] for the Dart file with the given [path].
+   *
+   * The [path] must be absolute and normalized.
+   */
+  FileResult getFileSync(String path) {
+    _throwIfNotAbsolutePath(path);
+    FileState file = _fileTracker.verifyApiSignature(path);
+    return new FileResult(
+        _currentSession, path, file.uri, file.lineInfo, file.isPart);
+  }
+
+  /**
    * Return a [Future] that completes with the [AnalysisDriverUnitIndex] for
    * the file with the given [path], or with `null` if the file cannot be
    * analyzed.
@@ -904,7 +916,7 @@
     RecordingErrorListener listener = new RecordingErrorListener();
     CompilationUnit unit = file.parse(listener);
     return new ParseResult(currentSession, file.path, file.uri, file.content,
-        unit.lineInfo, unit, listener.errors);
+        file.lineInfo, file.isPart, unit, listener.errors);
   }
 
   @override
@@ -1495,6 +1507,7 @@
         file.exists,
         content,
         file.lineInfo,
+        file.isPart,
         signature,
         resolvedUnit,
         errors,
@@ -1584,6 +1597,7 @@
         file.exists,
         null,
         file.lineInfo,
+        file.isPart,
         null,
         null,
         [
@@ -2044,10 +2058,9 @@
  * Every result is independent, and is not guaranteed to be consistent with
  * any previously returned result, even inside of the same library.
  */
-class AnalysisResult extends BaseAnalysisResult
-    implements results.ResolveResult {
+class AnalysisResult extends FileResult implements results.ResolveResult {
   static final _UNCHANGED = new AnalysisResult(
-      null, null, null, null, null, null, null, null, null, null, null);
+      null, null, null, null, null, null, null, null, null, null, null, null);
 
   /**
    * The [AnalysisDriver] that produced this result.
@@ -2067,9 +2080,6 @@
   @override
   final String content;
 
-  @override
-  final LineInfo lineInfo;
-
   /**
    * The signature of the result based on the content of the file, and the
    * transitive closure of files imported and exported by the library of
@@ -2095,12 +2105,13 @@
       Uri uri,
       this.exists,
       this.content,
-      this.lineInfo,
+      LineInfo lineInfo,
+      bool isPart,
       this._signature,
       this.unit,
       this.errors,
       this._index)
-      : super(driver?.currentSession, path, uri);
+      : super(driver?.currentSession, path, uri, lineInfo, isPart);
 
   @override
   LibraryElement get libraryElement => unit.element.library;
@@ -2158,16 +2169,13 @@
  * to each other. But none of the results is guaranteed to be consistent with
  * the state of the files.
  */
-class ErrorsResult extends BaseAnalysisResult implements results.ErrorsResult {
-  @override
-  final LineInfo lineInfo;
-
+class ErrorsResult extends FileResult implements results.ErrorsResult {
   @override
   final List<AnalysisError> errors;
 
-  ErrorsResult(
-      AnalysisSession session, String path, Uri uri, this.lineInfo, this.errors)
-      : super(session, path, uri);
+  ErrorsResult(AnalysisSession session, String path, Uri uri, LineInfo lineInfo,
+      bool isPart, this.errors)
+      : super(session, path, uri, lineInfo, isPart);
 
   @override
   results.ResultState get state => results.ResultState.VALID;
@@ -2201,28 +2209,44 @@
 }
 
 /**
+ * The result of computing some cheap information for a single file, when full
+ * parsed file is not required, so [ParseResult] is not necessary.
+ */
+class FileResult extends BaseAnalysisResult implements results.FileResult {
+  @override
+  final LineInfo lineInfo;
+
+  @override
+  final bool isPart;
+
+  FileResult(
+      AnalysisSession session, String path, Uri uri, this.lineInfo, this.isPart)
+      : super(session, path, uri);
+
+  @override
+  results.ResultState get state => results.ResultState.VALID;
+}
+
+/**
  * The result of parsing of a single file.
  *
  * These results are self-consistent, i.e. [content], [lineInfo], the
  * parsed [unit] correspond to each other. But none of the results is
  * guaranteed to be consistent with the state of the files.
  */
-class ParseResult extends BaseAnalysisResult implements results.ParseResult {
+class ParseResult extends FileResult implements results.ParseResult {
   @override
   final String content;
 
   @override
-  final LineInfo lineInfo;
-
-  @override
   final CompilationUnit unit;
 
   @override
   final List<AnalysisError> errors;
 
   ParseResult(AnalysisSession session, String path, Uri uri, this.content,
-      this.lineInfo, this.unit, this.errors)
-      : super(session, path, uri);
+      LineInfo lineInfo, bool isPart, this.unit, this.errors)
+      : super(session, path, uri, lineInfo, isPart);
 
   @override
   results.ResultState get state => results.ResultState.VALID;
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 3804ff6..30d31dd 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -1442,6 +1442,31 @@
     expect(files, isNot(contains(c)));
   }
 
+  test_getFileSync_library() async {
+    var path = _p('/test/lib/a.dart');
+    provider.newFile(path, '');
+    var file = driver.getFileSync(path);
+    expect(file.path, path);
+    expect(file.uri.toString(), 'package:test/a.dart');
+    expect(file.isPart, isFalse);
+  }
+
+  test_getFileSync_notAbsolutePath() async {
+    try {
+      driver.getFileSync('not_absolute.dart');
+      fail('ArgumentError expected.');
+    } on ArgumentError {}
+  }
+
+  test_getFileSync_part() async {
+    var path = _p('/test/lib/a.dart');
+    provider.newFile(path, 'part of lib;');
+    var file = driver.getFileSync(path);
+    expect(file.path, path);
+    expect(file.uri.toString(), 'package:test/a.dart');
+    expect(file.isPart, isTrue);
+  }
+
   test_getIndex() async {
     String content = r'''
 foo(int p) {}
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index e518b96..0eab813 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -37,7 +37,7 @@
   }
 
   test_getErrors() async {
-    ErrorsResult result = new ErrorsResult(null, null, null, null, null);
+    ErrorsResult result = new ErrorsResult(null, null, null, null, null, null);
     driver.errorsResult = result;
     expect(await session.getErrors('path'), result);
   }
@@ -58,14 +58,14 @@
 
   test_getParsedAst() async {
     ParseResult result =
-        new ParseResult(null, null, null, null, null, null, null);
+        new ParseResult(null, null, null, null, null, null, null, null);
     driver.parseResult = result;
     expect(await session.getParsedAst('path'), result);
   }
 
   test_getResolvedAst() async {
-    AnalysisResult result = new AnalysisResult(
-        driver, null, null, null, null, null, null, null, null, null, null);
+    AnalysisResult result = new AnalysisResult(driver, null, null, null, null,
+        null, null, null, null, null, null, null);
     driver.result = result;
     expect(await session.getResolvedAst('path'), result);
   }
diff --git a/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
index 906a974..b982527 100644
--- a/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
@@ -91,7 +91,7 @@
   Future<AssistRequest> getAssistRequest(
       EditGetAssistsParams parameters) async {
     AnalysisResult result = new AnalysisResult(
-        null, null, null, null, null, null, null, null, null, null, null);
+        null, null, null, null, null, null, null, null, null, null, null, null);
     return new DartAssistRequestImpl(
         resourceProvider, parameters.offset, parameters.length, result);
   }
diff --git a/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart
index e4fa3e8..2132a89 100644
--- a/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart
@@ -99,7 +99,7 @@
   Future<CompletionRequest> getCompletionRequest(
       CompletionGetSuggestionsParams parameters) async {
     AnalysisResult result = new AnalysisResult(
-        null, null, null, null, null, null, null, null, null, null, null);
+        null, null, null, null, null, null, null, null, null, null, null, null);
     return new DartCompletionRequestImpl(
         resourceProvider, parameters.offset, result);
   }
diff --git a/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
index 08a0e76..8b7182e 100644
--- a/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
@@ -99,7 +99,7 @@
     AnalysisError error = new AnalysisError(
         new MockSource(), 0, 0, CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT);
     AnalysisResult result = new AnalysisResult(null, null, null, null, null,
-        null, new LineInfo([0, 20]), null, null, [error], null);
+        null, new LineInfo([0, 20]), false, null, null, [error], null);
     return new DartFixesRequestImpl(resourceProvider, offset, [error], result);
   }
 }
diff --git a/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
index e8e2d46..ce80ba8 100644
--- a/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
@@ -94,7 +94,7 @@
   @override
   Future<FoldingRequest> getFoldingRequest(String path) async {
     AnalysisResult result = new AnalysisResult(
-        null, null, path, null, null, null, null, null, null, null, null);
+        null, null, path, null, null, null, null, null, null, null, null, null);
     return new DartFoldingRequestImpl(resourceProvider, result);
   }
 }
diff --git a/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart
index f9ee17e..32f855a 100644
--- a/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart
@@ -94,7 +94,7 @@
   @override
   Future<HighlightsRequest> getHighlightsRequest(String path) async {
     AnalysisResult result = new AnalysisResult(
-        null, null, path, null, null, null, null, null, null, null, null);
+        null, null, path, null, null, null, null, null, null, null, null, null);
     return new DartHighlightsRequestImpl(resourceProvider, result);
   }
 }
diff --git a/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart
index a3af883..579a974 100644
--- a/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart
@@ -95,7 +95,7 @@
   Future<EntryRequest> getEntryRequest(
       KytheGetKytheEntriesParams parameters) async {
     AnalysisResult result = new AnalysisResult(
-        null, null, null, null, null, null, null, null, null, null, null);
+        null, null, null, null, null, null, null, null, null, null, null, null);
     return new DartEntryRequestImpl(resourceProvider, result);
   }
 }
diff --git a/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
index 22603d2..a334843 100644
--- a/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
@@ -110,7 +110,7 @@
   Future<NavigationRequest> getNavigationRequest(
       AnalysisGetNavigationParams parameters) async {
     AnalysisResult result = new AnalysisResult(null, null, parameters.file,
-        null, null, null, null, null, null, null, null);
+        null, null, null, null, null, null, null, null, null);
     return new DartNavigationRequestImpl(
         resourceProvider, parameters.offset, parameters.length, result);
   }
diff --git a/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart
index ea8a305..f0b56b2 100644
--- a/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart
@@ -121,7 +121,7 @@
   @override
   Future<OccurrencesRequest> getOccurrencesRequest(String path) async {
     AnalysisResult result = new AnalysisResult(
-        null, null, path, null, null, null, null, null, null, null, null);
+        null, null, path, null, null, null, null, null, null, null, null, null);
     return new DartOccurrencesRequestImpl(resourceProvider, result);
   }
 }
diff --git a/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart
index 3291163..1e94ef2 100644
--- a/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart
@@ -95,7 +95,7 @@
   @override
   Future<OutlineRequest> getOutlineRequest(String path) async {
     AnalysisResult result = new AnalysisResult(
-        null, null, path, null, null, null, null, null, null, null, null);
+        null, null, path, null, null, null, null, null, null, null, null, null);
     return new DartOutlineRequestImpl(resourceProvider, result);
   }
 }
diff --git a/pkg/analyzer_plugin/test/utilities/navigation_test.dart b/pkg/analyzer_plugin/test/utilities/navigation_test.dart
index dc4a9cc..351cff2 100644
--- a/pkg/analyzer_plugin/test/utilities/navigation_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/navigation_test.dart
@@ -20,7 +20,7 @@
   MemoryResourceProvider provider = new MemoryResourceProvider();
 
   ResolveResult resolveResult = new driver.AnalysisResult(
-      null, null, 'a.dart', null, true, '', null, '', null, null, null);
+      null, null, 'a.dart', null, true, '', null, false, '', null, null, null);
 
   test_none() {
     NavigationGenerator generator = new NavigationGenerator([]);