Version 2.14.0-277.0.dev
Merge commit 'e75d26b76c13349847e93b5883f4d941119996e2' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart b/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart
index b577fba..e033fca 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart
@@ -22,11 +22,15 @@
/// open parenthesis. If [insertIdentifier] is true, then a synthetic
/// identifier is included between the open and close parenthesis.
Token insertParens(Token token, bool includeIdentifier) {
- // Assert that the token is not eof, though allow an eof-token if the offset
+ // Throw if the token is eof, though allow an eof-token if the offset
// is negative. The last part is because [syntheticPreviousToken] sometimes
// creates eof tokens that aren't the real eof-token that has a negative
// offset (which wouldn't be valid for the real eof).
- assert(!token.isEof || token.offset < 0);
+ if (!(!token.isEof || token.offset < 0)) {
+ // Inserting here could cause a infinite loop. We prefer to crash.
+ throw 'Internal Error: Rewriting at eof.';
+ }
+
Token next = token.next!;
int offset = next.charOffset;
BeginToken leftParen =
@@ -49,11 +53,15 @@
/// Insert [newToken] after [token] and return [newToken].
Token insertToken(Token token, Token newToken) {
- // Assert that the token is not eof, though allow an eof-token if the offset
+ // Throw if the token is eof, though allow an eof-token if the offset
// is negative. The last part is because [syntheticPreviousToken] sometimes
// creates eof tokens that aren't the real eof-token that has a negative
// offset (which wouldn't be valid for the real eof).
- assert(!token.isEof || token.offset < 0);
+ if (!(!token.isEof || token.offset < 0)) {
+ // Inserting here could cause a infinite loop. We prefer to crash.
+ throw 'Internal Error: Rewriting at eof.';
+ }
+
_setNext(newToken, token.next!);
// A no-op rewriter could skip this step.
@@ -65,11 +73,15 @@
/// Move [endGroup] (a synthetic `)`, `]`, or `}` token) and associated
/// error token after [token] in the token stream and return [endGroup].
Token moveSynthetic(Token token, Token endGroup) {
- // Assert that the token is not eof, though allow an eof-token if the offset
+ // Throw if the token is eof, though allow an eof-token if the offset
// is negative. The last part is because [syntheticPreviousToken] sometimes
// creates eof tokens that aren't the real eof-token that has a negative
// offset (which wouldn't be valid for the real eof).
- assert(!token.isEof || token.offset < 0);
+ if (!(!token.isEof || token.offset < 0)) {
+ // Inserting here could cause a infinite loop. We prefer to crash.
+ throw 'Internal Error: Rewriting at eof.';
+ }
+
// ignore:unnecessary_null_comparison
assert(endGroup.beforeSynthetic != null);
if (token == endGroup) return endGroup;
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 832c3ee..79bc69f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -239,6 +239,9 @@
/// TODO(scheglov) We probably should tie it into the session.
LibraryContext? _libraryContext;
+ /// Whether `dart:core` has been transitively discovered.
+ bool _hasDartCoreDiscovered = false;
+
/// This function is invoked when the current session is about to be discarded.
/// The argument represents the path of the resource causing the session
/// to be discarded or `null` if there are multiple or this is unknown.
@@ -972,6 +975,11 @@
return;
}
+ if (!_hasDartCoreDiscovered) {
+ _hasDartCoreDiscovered = true;
+ _discoverDartCore();
+ }
+
// Analyze a requested file.
if (_requestedFiles.isNotEmpty) {
String path = _requestedFiles.keys.first;
@@ -1585,6 +1593,29 @@
_discoverAvailableFilesTask ??= _DiscoverAvailableFilesTask(this);
}
+ /// When we look at a part that has a `part of name;` directive, we
+ /// usually don't know the library (in contrast to `part of uri;`).
+ /// So, we have no choice than to resolve this part as its own library.
+ /// TODO(scheglov) Maybe just return an error result instead?
+ ///
+ /// But parts of `dart:xyz` libraries are special. The reason is that
+ /// `dart:core` is always implicitly imported. So, when we start building
+ /// the library cycle of such "part as a library", we discover `dart:core`,
+ /// and see that it contains our part. So, we don't add it as a library on
+ /// its own. But have already committed that it is a library. This causes
+ /// an exception in `LinkedElementFactory`.
+ ///
+ /// The current workaround for this is to discover `dart:core` before any
+ /// analysis.
+ void _discoverDartCore() {
+ _fsState.getFileForUri(Uri.parse('dart:core')).map(
+ (file) {
+ file?.transitiveFiles;
+ },
+ (externalLibrary) {},
+ );
+ }
+
void _fillSalt() {
_fillSaltForUnlinked();
_fillSaltForElements();
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index a970cf4..dee0e8e 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -1545,6 +1545,13 @@
expect(result.errors, isEmpty);
}
+ test_getResult_dartAsyncPart() async {
+ var path = convertPath('/sdk/lib/async/stream.dart');
+ var result = await driver.getResultValid(path);
+ expect(result.path, path);
+ expect(result.unit, isNotNull);
+ }
+
test_getResult_doesNotExist() async {
var a = convertPath('/test/lib/a.dart');
diff --git a/tools/VERSION b/tools/VERSION
index a619ee9..e6616ec 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 276
+PRERELEASE 277
PRERELEASE_PATCH 0
\ No newline at end of file