Skip to content

Commit e8aeb4a

Browse files
scheglovCommit Queue
authored andcommitted
Add MissingSdkLibraryResult and centralize SDK checks
Introduce a dedicated result type, `MissingSdkLibraryResult`, returned when required SDK libraries (e.g., `dart:core`, `dart:async`) are not available. The analysis driver now detects missing SDK libraries early and completes all pending requests for the affected library with this typed result. What changes - New public API: - `abstract class MissingSdkLibraryResult` (exposes `missingUri`) - `MissingSdkLibraryResultImpl` implementation - Driver behavior: - New helper `_completeRequestsIfMissingSdkLibrary(...)` short-circuits analysis when `dart:core` or `dart:async` is missing, completing: - `getErrors`, `getResolvedUnit`, `getResolvedLibrary`, `getUnitElement`, `getLibraryByUri` with `MissingSdkLibraryResult` - `getIndex` with `null` for index data - Removes duplicated per-call checks and ad-hoc error creation - Result printing updated to render `MissingSdkLibraryResult` - Old path that produced an `ErrorsResult` with a synthetic `missingDartLibrary` diagnostic is removed Why - Provide a clear, explicit signal to callers that the SDK is incomplete - Unify behavior across APIs and reduce duplicated logic - Avoid relying on temporary diagnostics for a systemic environment issue Behavioral / API notes - Calls that previously could yield an `ErrorsResult` containing a synthetic “missing SDK library” diagnostic will now return `MissingSdkLibraryResult`. Clients should handle this result type and surface the `missingUri` to users as appropriate. Change-Id: Ib71ceb05269d5b9fe4276a03155278aef64daf56 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/447005 Reviewed-by: Brian Wilkerson <[email protected]> Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent 0623511 commit e8aeb4a

File tree

6 files changed

+415
-107
lines changed

6 files changed

+415
-107
lines changed

pkg/analyzer/api.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,9 @@ package:analyzer/dart/analysis/results.dart:
487487
new (constructor: LibraryElementResult Function())
488488
element (getter: LibraryElement, experimental)
489489
element2 (getter: LibraryElement, deprecated, experimental)
490+
MissingSdkLibraryResult (class extends Object implements InvalidResult, SomeErrorsResult, SomeResolvedLibraryResult, SomeResolvedUnitResult, SomeLibraryElementResult, SomeUnitElementResult):
491+
new (constructor: MissingSdkLibraryResult Function())
492+
missingUri (getter: Uri)
490493
NotElementOfThisSessionResult (class extends Object implements InvalidResult, SomeParsedLibraryResult, SomeResolvedLibraryResult):
491494
new (constructor: NotElementOfThisSessionResult Function())
492495
NotLibraryButPartResult (class extends Object implements InvalidResult, SomeLibraryElementResult, SomeParsedLibraryResult, SomeResolvedLibraryResult):

pkg/analyzer/lib/dart/analysis/results.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,22 @@ abstract class LibraryElementResult implements SomeLibraryElementResult {
178178
LibraryElement get element2;
179179
}
180180

181+
/// The type of [InvalidResult] returned when Dart SDK does not have a
182+
/// required library, e.g. `dart:core` or `dart:async`.
183+
///
184+
/// Clients may not extend, implement or mix-in this class.
185+
abstract class MissingSdkLibraryResult
186+
implements
187+
InvalidResult,
188+
SomeErrorsResult,
189+
SomeResolvedLibraryResult,
190+
SomeResolvedUnitResult,
191+
SomeLibraryElementResult,
192+
SomeUnitElementResult {
193+
/// The URI of the missing SDK library.
194+
Uri get missingUri;
195+
}
196+
181197
/// The type of [InvalidResult] returned when the given element was not
182198
/// created by the requested session.
183199
///

pkg/analyzer/lib/src/dart/analysis/driver.dart

Lines changed: 58 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import 'package:analyzer/src/dart/element/element.dart';
3939
import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
4040
import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
4141
import 'package:analyzer/src/diagnostic/diagnostic.dart';
42-
import 'package:analyzer/src/error/codes.dart';
4342
import 'package:analyzer/src/exception/exception.dart';
4443
import 'package:analyzer/src/fine/requirements.dart';
4544
import 'package:analyzer/src/generated/engine.dart'
@@ -1315,19 +1314,7 @@ class AnalysisDriver {
13151314
events.AnalyzeFile(file: file, library: library),
13161315
);
13171316

1318-
if (!_hasLibraryByUri('dart:core')) {
1319-
_errorsRequestedFiles.completeAll(
1320-
path,
1321-
_newMissingDartLibraryResult(file, 'dart:core'),
1322-
);
1323-
return;
1324-
}
1325-
1326-
if (!_hasLibraryByUri('dart:async')) {
1327-
_errorsRequestedFiles.completeAll(
1328-
path,
1329-
_newMissingDartLibraryResult(file, 'dart:async'),
1330-
);
1317+
if (_completeRequestsIfMissingSdkLibrary(library)) {
13311318
return;
13321319
}
13331320

@@ -1572,6 +1559,50 @@ class AnalysisDriver {
15721559
_resolvedLibraryCache.clear();
15731560
}
15741561

1562+
/// Completes pending requests if a required SDK library is missing.
1563+
///
1564+
/// If a required SDK library is missing, this completes all pending requests
1565+
/// for the [library] and returns `true`.
1566+
bool _completeRequestsIfMissingSdkLibrary(LibraryFileKind library) {
1567+
bool hasLibraryByUri(Uri uri) {
1568+
var fileOr = _fsState.getFileForUri(uri);
1569+
return switch (fileOr) {
1570+
null => false,
1571+
UriResolutionFile(:var file) => file.exists,
1572+
UriResolutionExternalLibrary() => true,
1573+
};
1574+
}
1575+
1576+
void emitMissingSdkLibraryResult(Uri missingUri) {
1577+
var result = MissingSdkLibraryResultImpl(missingUri: missingUri);
1578+
1579+
_requestedLibraries.completeAll(library.file.path, result);
1580+
1581+
for (var file in library.files) {
1582+
_fileTracker.fileWasAnalyzed(file.path);
1583+
_errorsRequestedFiles.completeAll(file.path, result);
1584+
_requestedFiles.completeAll(file.path, result);
1585+
_requestedFilesNonInteractive.completeAll(file.path, result);
1586+
_unitElementRequestedFiles.completeAll(file.path, result);
1587+
_indexRequestedFiles.completeAll(file.path, null);
1588+
}
1589+
}
1590+
1591+
var dartCore = uriCache.parse('dart:core');
1592+
if (!hasLibraryByUri(dartCore)) {
1593+
emitMissingSdkLibraryResult(dartCore);
1594+
return true;
1595+
}
1596+
1597+
var dartAsync = uriCache.parse('dart:async');
1598+
if (!hasLibraryByUri(dartAsync)) {
1599+
emitMissingSdkLibraryResult(dartAsync);
1600+
return true;
1601+
}
1602+
1603+
return false;
1604+
}
1605+
15751606
ErrorsResultImpl _createErrorsResultFromBytes(
15761607
FileState file,
15771608
LibraryFileKind library,
@@ -1709,21 +1740,7 @@ class AnalysisDriver {
17091740
var kind = file.kind;
17101741
var library = kind.library ?? kind.asLibrary;
17111742

1712-
// TODO(scheglov): this is duplicate
1713-
if (!_hasLibraryByUri('dart:core')) {
1714-
_errorsRequestedFiles.completeAll(
1715-
path,
1716-
_newMissingDartLibraryResult(file, 'dart:core'),
1717-
);
1718-
return;
1719-
}
1720-
1721-
// TODO(scheglov): this is duplicate
1722-
if (!_hasLibraryByUri('dart:async')) {
1723-
_errorsRequestedFiles.completeAll(
1724-
path,
1725-
_newMissingDartLibraryResult(file, 'dart:async'),
1726-
);
1743+
if (_completeRequestsIfMissingSdkLibrary(library)) {
17271744
return;
17281745
}
17291746

@@ -1841,6 +1858,10 @@ class AnalysisDriver {
18411858
var kind = file.kind;
18421859
var library = kind.library ?? kind.asLibrary;
18431860

1861+
if (_completeRequestsIfMissingSdkLibrary(library)) {
1862+
return;
1863+
}
1864+
18441865
// Prepare the signature and key.
18451866
var signature = _getResolvedUnitSignature(library, file);
18461867
var key = _getResolvedUnitKey(signature);
@@ -1932,6 +1953,10 @@ class AnalysisDriver {
19321953
var kind = file.kind;
19331954
var library = kind.library ?? kind.asLibrary;
19341955

1956+
if (_completeRequestsIfMissingSdkLibrary(library)) {
1957+
return;
1958+
}
1959+
19351960
performance.run('libraryContext', (performance) {
19361961
libraryContext.load(targetLibrary: library, performance: performance);
19371962
});
@@ -1947,16 +1972,6 @@ class AnalysisDriver {
19471972
});
19481973
}
19491974

1950-
bool _hasLibraryByUri(String uriStr) {
1951-
var uri = uriCache.parse(uriStr);
1952-
var fileOr = _fsState.getFileForUri(uri);
1953-
return switch (fileOr) {
1954-
null => false,
1955-
UriResolutionFile(:var file) => file.exists,
1956-
UriResolutionExternalLibrary() => true,
1957-
};
1958-
}
1959-
19601975
bool _isAbsolutePath(String path) {
19611976
return _resourceProvider.pathContext.isAbsolute(path);
19621977
}
@@ -1981,34 +1996,6 @@ class AnalysisDriver {
19811996
}
19821997
}
19831998

1984-
/// We detected that one of the required `dart` libraries is missing.
1985-
/// Return the empty analysis result with the error.
1986-
ErrorsResultImpl _newMissingDartLibraryResult(
1987-
FileState file,
1988-
String missingUri,
1989-
) {
1990-
// TODO(scheglov): Find a better way to report this.
1991-
return ErrorsResultImpl(
1992-
session: currentSession,
1993-
file: file.resource,
1994-
content: file.content,
1995-
lineInfo: file.lineInfo,
1996-
uri: file.uri,
1997-
isLibrary: file.kind is LibraryFileKind,
1998-
isPart: file.kind is PartFileKind,
1999-
diagnostics: [
2000-
Diagnostic.tmp(
2001-
source: file.source,
2002-
offset: 0,
2003-
length: 0,
2004-
diagnosticCode: CompileTimeErrorCode.missingDartLibrary,
2005-
arguments: [missingUri],
2006-
),
2007-
],
2008-
analysisOptions: file.analysisOptions,
2009-
);
2010-
}
2011-
20121999
void _onNewFile(FileState file) {
20132000
var ownedFiles = this.ownedFiles;
20142001
if (ownedFiles != null) {
@@ -2028,6 +2015,10 @@ class AnalysisDriver {
20282015
var kind = file.kind;
20292016
var library = kind.library ?? kind.asLibrary;
20302017

2018+
if (_completeRequestsIfMissingSdkLibrary(library)) {
2019+
return;
2020+
}
2021+
20312022
// Errors are based on elements, so load them.
20322023
performance.run('libraryContext', (performance) {
20332024
libraryContext.load(targetLibrary: library, performance: performance);

pkg/analyzer/lib/src/dart/analysis/results.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,13 @@ class LibraryElementResultImpl implements LibraryElementResult {
287287
LibraryElement get element2 => element;
288288
}
289289

290+
class MissingSdkLibraryResultImpl implements MissingSdkLibraryResult {
291+
@override
292+
final Uri missingUri;
293+
294+
MissingSdkLibraryResultImpl({required this.missingUri});
295+
}
296+
290297
class ParsedLibraryResultImpl extends AnalysisResultImpl
291298
implements ParsedLibraryResult {
292299
@override

0 commit comments

Comments
 (0)