From 16687346977656e362bd607dc4b94053b11e12d9 Mon Sep 17 00:00:00 2001 From: Keerti Parthasarathy Date: Tue, 6 Apr 2021 21:27:43 +0000 Subject: [PATCH] Add a method to resolve a library Change-Id: I0eba5b60bb46fa7dfbceb2b26e0d1d5ec3ae3ebf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/194015 Reviewed-by: Konstantin Shcheglov Commit-Queue: Keerti Parthasarathy --- .../lib/src/dart/micro/analysis_context.dart | 9 +- .../lib/src/dart/micro/resolve_file.dart | 83 +++++++++++++++---- .../dart/micro/simple_file_resolver_test.dart | 24 ++++++ 3 files changed, 90 insertions(+), 26 deletions(-) diff --git a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart index 97a397f5059..5e45d1e7e12 100644 --- a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart +++ b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart @@ -204,14 +204,7 @@ class _MicroAnalysisSessionImpl extends AnalysisSessionImpl { @override Future getResolvedLibrary(String path) async { - var resolvedUnit = await getResolvedUnit(path); - return ResolvedLibraryResultImpl( - this, - path, - resolvedUnit.uri, - resolvedUnit.libraryElement, - [resolvedUnit], - ); + return analysisContext.fileResolver.resolveLibrary(path: path); } @override diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart index 219aadc1b9b..03b5275cb43 100644 --- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart +++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart @@ -86,7 +86,7 @@ class FileResolver { /// It is used to allow assists and fixes without resolving the same file /// multiple times, as we compute more than one assist, or fixes when there /// are more than one error on a line. - final Map _cachedResults = {}; + final Map _cachedResults = {}; FileResolver( PerformanceLog logger, @@ -373,6 +373,48 @@ class FileResolver { performance ??= OperationPerformanceImpl(''); + return logger.run('Resolve $path', () { + var fileContext = getFileContext( + path: path, + performance: performance!, + ); + var file = fileContext.file; + + // If we have a `part of` directive, we want to analyze this library. + // But the library must include the file, so have its element. + var libraryFile = file; + var partOfLibrary = file.partOfLibrary; + if (partOfLibrary != null) { + if (partOfLibrary.libraryFiles.contains(file)) { + libraryFile = partOfLibrary; + } + } + + var libraryUnit = resolveLibrary( + completionLine: completionLine, + completionColumn: completionColumn, + path: libraryFile.path, + completionPath: path, + performance: performance, + ); + var result = + libraryUnit.units!.firstWhere((element) => element.path == path); + return result; + }); + } + + /// The [completionLine] and [completionColumn] are zero based. + ResolvedLibraryResult resolveLibrary({ + int? completionLine, + int? completionColumn, + String? completionPath, + required String path, + OperationPerformanceImpl? performance, + }) { + _throwIfNotAbsoluteNormalizedPath(path); + + performance ??= OperationPerformanceImpl(''); + var cachedResult = _cachedResults[path]; if (cachedResult != null) { return cachedResult; @@ -410,10 +452,6 @@ class FileResolver { testView?.addResolvedFile(path); - var content = _getFileContent(path); - var errorListener = RecordingErrorListener(); - var unit = file.parse(errorListener, content); - late Map results; logger.run('Compute analysis results', () { @@ -432,7 +470,7 @@ class FileResolver { try { results = performance!.run('analyze', (performance) { return libraryAnalyzer.analyzeSync( - completionPath: completionOffset != null ? path : null, + completionPath: completionOffset != null ? completionPath : null, completionOffset: completionOffset, performance: performance, ); @@ -450,19 +488,28 @@ class FileResolver { ); } }); - UnitAnalysisResult fileResult = results[file]!; - var result = ResolvedUnitResultImpl( - contextObjects!.analysisSession, - path, - file.uri, - file.exists, - content, - unit.lineInfo!, - false, // isPart - fileResult.unit, - fileResult.errors, - ); + results.forEach((key, value) { + print('$key: $value'); + }); + var resolvedUnits = results.values.map((fileResult) { + var file = fileResult.file; + return ResolvedUnitResultImpl( + contextObjects!.analysisSession, + file.path, + file.uri, + file.exists, + file.getContent(), + file.lineInfo, + file.unlinked2.hasPartOfDirective, + fileResult.unit, + fileResult.errors, + ); + }).toList(); + + var libraryUnit = resolvedUnits.first; + var result = ResolvedLibraryResultImpl(contextObjects!.analysisSession, + path, libraryUnit.uri, libraryUnit.libraryElement, resolvedUnits); _cachedResults[path] = result; return result; }); diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart index 15b8ebd60be..aa6dfb3358b 100644 --- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart +++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart @@ -679,6 +679,30 @@ void func() { expect(result, isNot(same(result1))); } + test_resolveLibrary() async { + var aPath = convertPath('/workspace/dart/test/lib/a.dart'); + newFile(aPath, content: r''' +part 'test.dart'; + +class A { + int m; +} +'''); + + newFile('/workspace/dart/test/lib/test.dart', content: r''' +part of 'a.dart'; + +void func() { + var a = A(); + print(a.m); +} +'''); + + var result = fileResolver.resolveLibrary(path: aPath); + expect(result.path, aPath); + expect(result.units?.length, 2); + } + test_reuse_compatibleOptions() async { newFile('/workspace/dart/aaa/BUILD', content: ''); newFile('/workspace/dart/bbb/BUILD', content: '');