Version 2.18.0-164.0.dev
Merge commit 'aa0d0c56cb36ee1b3df7dcfef819d7e37256fbb1' into 'dev'
diff --git a/DEPS b/DEPS
index 797f60b..7ed2184 100644
--- a/DEPS
+++ b/DEPS
@@ -107,7 +107,7 @@
"dart_style_rev": "d7b73536a8079331c888b7da539b80e6825270ea",
"dartdoc_rev": "8549817bb1b59808108e83ef0e513157cb572d2a",
- "devtools_rev": "3c16b8d73120e46958982d94215d499793b972eb",
+ "devtools_rev": "51ac983d2db7eb19b3ce5956cb70b769d74fe784",
"ffi_rev": "0c8364a728cfe4e4ba859c53b99d56b3dbe3add4",
"file_rev": "0132eeedea2933513bf230513a766a8baeab0c4f",
"fixnum_rev": "3bfc2ed1eea7e7acb79ad4f17392f92c816fc5ce",
@@ -116,7 +116,7 @@
"http_io_rev": "405fc79233b4a3d4bb079ebf438bb2caf2f49355",
"http_multi_server_rev": "35a3b947256768426090e3b1f5132e4fc23c175d",
"http_parser_rev": "9126ee04e77fd8e4e2e6435b503ee4dd708d7ddc",
- "http_rev": "2c9b418f5086f999c150d18172d2eec1f963de7b",
+ "http_rev": "2993ea5dff5ffb066b4a35c707e7a2b8dcfa17c2",
"icu_rev": "81d656878ec611cb0b42d52c82e9dae93920d9ba",
"intl_rev": "9145f308f1458f37630a1ffce3b7d3b471ebbc56",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
diff --git a/pkg/analyzer/lib/src/dart/analysis/byte_store.dart b/pkg/analyzer/lib/src/dart/analysis/byte_store.dart
index 7fa38f7..0c096b3 100644
--- a/pkg/analyzer/lib/src/dart/analysis/byte_store.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/byte_store.dart
@@ -50,7 +50,18 @@
@override
Uint8List? get(String key) {
- return _cache.get(key, () => _store.get(key));
+ final cached = _cache.get(key);
+ if (cached != null) {
+ return cached;
+ }
+
+ final fromStore = _store.get(key);
+ if (fromStore != null) {
+ _cache.put(key, fromStore);
+ return fromStore;
+ }
+
+ return null;
}
@override
diff --git a/pkg/analyzer/lib/src/dart/analysis/cache.dart b/pkg/analyzer/lib/src/dart/analysis/cache.dart
index ca97db6..bddb6fa 100644
--- a/pkg/analyzer/lib/src/dart/analysis/cache.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/cache.dart
@@ -2,37 +2,33 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:meta/meta.dart';
+
/// LRU cache of objects.
class Cache<K, V> {
final int _maxSizeBytes;
final int Function(V) _meter;
- final _map = <K, V>{};
+ @visibleForTesting
+ final map = <K, V>{};
int _currentSizeBytes = 0;
Cache(this._maxSizeBytes, this._meter);
- V? get(K key, V? Function() getNotCached) {
- V? value = _map.remove(key);
- if (value == null) {
- value = getNotCached();
- if (value != null) {
- _map[key] = value;
- _currentSizeBytes += _meter(value);
- _evict();
- }
- } else {
- _map[key] = value;
+ V? get(K key) {
+ final value = map.remove(key);
+ if (value != null) {
+ map[key] = value;
}
return value;
}
void put(K key, V value) {
- V? oldValue = _map[key];
+ V? oldValue = map[key];
if (oldValue != null) {
_currentSizeBytes -= _meter(oldValue);
}
- _map[key] = value;
+ map[key] = value;
_currentSizeBytes += _meter(value);
_evict();
}
@@ -40,7 +36,7 @@
void _evict() {
if (_currentSizeBytes > _maxSizeBytes) {
var keysToRemove = <K>[];
- for (var entry in _map.entries) {
+ for (var entry in map.entries) {
keysToRemove.add(entry.key);
_currentSizeBytes -= _meter(entry.value);
if (_currentSizeBytes <= _maxSizeBytes) {
@@ -48,7 +44,7 @@
}
}
for (var key in keysToRemove) {
- _map.remove(key);
+ map.remove(key);
}
}
}
diff --git a/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart b/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
index dc78189..0ffa205 100644
--- a/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
+++ b/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
@@ -54,7 +54,7 @@
@override
CacheData? get(String key, Uint8List signature) {
- var entry = _cache.get(key, () => null);
+ final entry = _cache.get(key);
if (entry != null &&
const ListEquality<int>().equals(entry.signature, signature)) {
diff --git a/pkg/analyzer/test/src/dart/analysis/cache_test.dart b/pkg/analyzer/test/src/dart/analysis/cache_test.dart
index 9a6cac3..0531aa6 100644
--- a/pkg/analyzer/test/src/dart/analysis/cache_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/cache_test.dart
@@ -2,7 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:typed_data';
+
import 'package:analyzer/src/dart/analysis/cache.dart';
+import 'package:analyzer_utilities/testing/map_entry_matcher.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -12,52 +15,47 @@
});
}
-List<int> _b(int length) {
- return List<int>.filled(length, 0);
+Uint8List _b(int length) {
+ return Uint8List(length);
}
@reflectiveTest
class CacheTest {
- test_get_notFound_evict() {
- var cache = _newBytesCache(100);
+ test_get() {
+ final cache = _newBytesCache(100);
- // Request '1'. Nothing found.
- expect(cache.get('1', _noBytes), isNull);
+ expect(cache.get('1'), isNull);
+ expect(cache.map.entries, isEmpty);
- // Add enough data to the store to force an eviction.
- cache.put('2', _b(40));
- cache.put('3', _b(40));
- cache.put('4', _b(40));
+ cache.put('1', _b(10));
+ expect(cache.map.entries, [
+ isMapEntry('1', hasLength(10)),
+ ]);
+
+ expect(cache.get('1'), hasLength(10));
}
- test_get_notFound_retry() {
- var cache = _newBytesCache(100);
+ test_get_reorders() {
+ final cache = _newBytesCache(100);
- // Request '1'. Nothing found.
- expect(cache.get('1', _noBytes), isNull);
+ cache.put('1', _b(1));
+ cache.put('2', _b(2));
+ cache.put('3', _b(3));
+ cache.put('4', _b(4));
+ expect(cache.map.entries, [
+ isMapEntry('1', hasLength(1)),
+ isMapEntry('2', hasLength(2)),
+ isMapEntry('3', hasLength(3)),
+ isMapEntry('4', hasLength(4)),
+ ]);
- // Request '1' again.
- // The previous `null` result should not have been cached.
- expect(cache.get('1', () => _b(40)), isNotNull);
- }
-
- test_get_put_evict() {
- var cache = _newBytesCache(100);
-
- // Keys: [1, 2].
- cache.put('1', _b(40));
- cache.put('2', _b(50));
-
- // Request '1', so now it is the most recently used.
- // Keys: [2, 1].
- cache.get('1', _noBytes);
-
- // 40 + 50 + 30 > 100
- // So, '2' is evicted.
- cache.put('3', _b(30));
- expect(cache.get('1', _noBytes), hasLength(40));
- expect(cache.get('2', _noBytes), isNull);
- expect(cache.get('3', _noBytes), hasLength(30));
+ expect(cache.get('2'), hasLength(2));
+ expect(cache.map.entries, [
+ isMapEntry('1', hasLength(1)),
+ isMapEntry('3', hasLength(3)),
+ isMapEntry('4', hasLength(4)),
+ isMapEntry('2', hasLength(2)),
+ ]);
}
test_put_evict_first() {
@@ -66,36 +64,39 @@
// 40 + 50 < 100
cache.put('1', _b(40));
cache.put('2', _b(50));
- expect(cache.get('1', _noBytes), hasLength(40));
- expect(cache.get('2', _noBytes), hasLength(50));
+ expect(cache.map.entries, [
+ isMapEntry('1', hasLength(40)),
+ isMapEntry('2', hasLength(50)),
+ ]);
// 40 + 50 + 30 > 100
// So, '1' is evicted.
cache.put('3', _b(30));
- expect(cache.get('1', _noBytes), isNull);
- expect(cache.get('2', _noBytes), hasLength(50));
- expect(cache.get('3', _noBytes), hasLength(30));
+ expect(cache.map.entries, [
+ isMapEntry('2', hasLength(50)),
+ isMapEntry('3', hasLength(30)),
+ ]);
}
- test_put_evict_firstAndSecond() {
+ test_put_evict_firstSecond() {
var cache = _newBytesCache(100);
// 10 + 80 < 100
cache.put('1', _b(10));
cache.put('2', _b(80));
- expect(cache.get('1', _noBytes), hasLength(10));
- expect(cache.get('2', _noBytes), hasLength(80));
+ expect(cache.map.entries, [
+ isMapEntry('1', hasLength(10)),
+ isMapEntry('2', hasLength(80)),
+ ]);
// 10 + 80 + 30 > 100
// So, '1' and '2' are evicted.
cache.put('3', _b(30));
- expect(cache.get('1', _noBytes), isNull);
- expect(cache.get('2', _noBytes), isNull);
- expect(cache.get('3', _noBytes), hasLength(30));
+ expect(cache.map.entries, [
+ isMapEntry('3', hasLength(30)),
+ ]);
}
- Cache<String, List<int>> _newBytesCache(int maxSizeBytes) =>
- Cache<String, List<int>>(maxSizeBytes, (bytes) => bytes.length);
-
- static List<int>? _noBytes() => null;
+ Cache<String, Uint8List> _newBytesCache(int maxSizeBytes) =>
+ Cache<String, Uint8List>(maxSizeBytes, (bytes) => bytes.length);
}
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index 2be300b..4291c64 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -642,8 +642,7 @@
],
);
- final bundleFile =
- resourceProvider.getFile('/home/summaries/packages.sum');
+ final bundleFile = getFile('/home/summaries/packages.sum');
bundleFile.writeAsBytesSync(bundleBytes);
librarySummaryFiles.add(bundleFile);
@@ -716,8 +715,7 @@
],
);
- final bundleFile =
- resourceProvider.getFile('/home/summaries/packages.sum');
+ final bundleFile = getFile('/home/summaries/packages.sum');
bundleFile.writeAsBytesSync(bundleBytes);
librarySummaryFiles.add(bundleFile);
@@ -895,8 +893,7 @@
],
);
- final bundleFile =
- resourceProvider.getFile('/home/summaries/packages.sum');
+ final bundleFile = getFile('/home/summaries/packages.sum');
bundleFile.writeAsBytesSync(bundleBytes);
librarySummaryFiles.add(bundleFile);
@@ -975,8 +972,7 @@
],
);
- final bundleFile =
- resourceProvider.getFile('/home/summaries/packages.sum');
+ final bundleFile = getFile('/home/summaries/packages.sum');
bundleFile.writeAsBytesSync(bundleBytes);
librarySummaryFiles.add(bundleFile);
@@ -2156,7 +2152,7 @@
}
Future<File> _writeSdkSummary() async {
- final file = resourceProvider.getFile('/home/summaries/sdk.sum');
+ final file = getFile('/home/summaries/sdk.sum');
final bytes = await buildSdkSummary2(
resourceProvider: resourceProvider,
sdkPath: sdkRoot.path,
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index 3a7a851..3c9ebab 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -428,7 +428,7 @@
''');
final session = contextFor(testFilePath).currentSession;
- final result = session.getParsedLibrary(testFilePath);
+ final result = session.getParsedLibrary(testFile.path);
expect(result, isA<NotLibraryButAugmentationResult>());
}
@@ -697,7 +697,7 @@
''');
final session = contextFor(testFilePath).currentSession;
- final result = await session.getResolvedLibrary(testFilePath);
+ final result = await session.getResolvedLibrary(testFile.path);
expect(result, isA<NotLibraryButAugmentationResult>());
}
diff --git a/pkg/analyzer/test/src/workspace/package_build_test.dart b/pkg/analyzer/test/src/workspace/package_build_test.dart
index 9f659a6..80e9f53 100644
--- a/pkg/analyzer/test/src/workspace/package_build_test.dart
+++ b/pkg/analyzer/test/src/workspace/package_build_test.dart
@@ -268,7 +268,8 @@
convertPath(myPackageRootPath),
)!;
- myPackage = myWorkspace.findPackageFor('$myPackageLibPath/fake.dart')!;
+ final fakeFile = getFile('$myPackageLibPath/fake.dart');
+ myPackage = myWorkspace.findPackageFor(fakeFile.path)!;
}
test_contains_fileUri() {
diff --git a/pkg/analyzer_utilities/lib/testing/map_entry_matcher.dart b/pkg/analyzer_utilities/lib/testing/map_entry_matcher.dart
new file mode 100644
index 0000000..9556ee1
--- /dev/null
+++ b/pkg/analyzer_utilities/lib/testing/map_entry_matcher.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+/// Matches a [MapEntry] with matching [MapEntry.key] and [MapEntry.value].
+MapEntryMatcher isMapEntry(key, value) => MapEntryMatcher(key, value);
+
+class MapEntryMatcher extends Matcher {
+ final Matcher keyMatcher;
+ final Matcher valueMatcher;
+
+ MapEntryMatcher(key, value)
+ : keyMatcher = wrapMatcher(key),
+ valueMatcher = wrapMatcher(value);
+
+ @override
+ Description describe(Description description) => description
+ .add('MapEntry(key: ')
+ .addDescriptionOf(keyMatcher)
+ .add(', value: ')
+ .addDescriptionOf(valueMatcher)
+ .add(')');
+
+ @override
+ bool matches(item, Map matchState) =>
+ item is MapEntry &&
+ keyMatcher.matches(item.key, {}) &&
+ valueMatcher.matches(item.value, {});
+}
diff --git a/pkg/dartdev/lib/src/commands/language_server.dart b/pkg/dartdev/lib/src/commands/language_server.dart
index 20d2722..65eca06 100644
--- a/pkg/dartdev/lib/src/commands/language_server.dart
+++ b/pkg/dartdev/lib/src/commands/language_server.dart
@@ -8,9 +8,7 @@
import 'package:args/args.dart';
import '../core.dart';
-import '../sdk.dart';
import '../utils.dart';
-import '../vm_interop_handler.dart';
class LanguageServerCommand extends DartdevCommand {
static const String commandName = 'language-server';
@@ -40,14 +38,11 @@
@override
Future<int> run() async {
- if (!Sdk.checkArtifactExists(sdk.analysisServerSnapshot)) return 255;
-
- VmInteropHandler.run(
- sdk.analysisServerSnapshot,
- [
- ...argResults!.arguments,
- ],
- packageConfigOverride: null);
+ final driver = server_driver.Driver();
+ driver.start(
+ argResults!.arguments,
+ defaultToLsp: true,
+ );
// The server will continue to run past the return from this method.
//
diff --git a/pkg/dds/lib/dds.dart b/pkg/dds/lib/dds.dart
index 7d833ab..177a926 100644
--- a/pkg/dds/lib/dds.dart
+++ b/pkg/dds/lib/dds.dart
@@ -11,6 +11,8 @@
import 'src/dds_impl.dart';
+typedef UriConverter = String? Function(String uri);
+
/// An intermediary between a Dart VM service and its clients that offers
/// additional functionality on top of the standard VM service protocol.
///
@@ -49,6 +51,7 @@
List<String> cachedUserTags = const [],
DevToolsConfiguration? devToolsConfiguration,
bool logRequests = false,
+ UriConverter? uriConverter,
}) async {
if (!remoteVmServiceUri.isScheme('http')) {
throw ArgumentError(
@@ -89,6 +92,7 @@
devToolsConfiguration,
logRequests,
enableServicePortFallback,
+ uriConverter,
);
await service.startService();
return service;
diff --git a/pkg/dds/lib/src/client.dart b/pkg/dds/lib/src/client.dart
index 5b3abdc..a5e47bc 100644
--- a/pkg/dds/lib/src/client.dart
+++ b/pkg/dds/lib/src/client.dart
@@ -248,6 +248,11 @@
dds.expressionEvaluator.execute,
);
+ _clientPeer.registerMethod(
+ 'lookupResolvedPackageUris',
+ dds.packageUriConverter.convert,
+ );
+
// When invoked within a fallback, the next fallback will start executing.
// The final fallback forwards the request to the VM service directly.
@alwaysThrows
diff --git a/pkg/dds/lib/src/dds_impl.dart b/pkg/dds/lib/src/dds_impl.dart
index a52fd13..33be98f 100644
--- a/pkg/dds/lib/src/dds_impl.dart
+++ b/pkg/dds/lib/src/dds_impl.dart
@@ -26,6 +26,7 @@
import 'devtools/handler.dart';
import 'expression_evaluator.dart';
import 'isolate_manager.dart';
+import 'package_uri_converter.dart';
import 'stream_manager.dart';
@visibleForTesting
@@ -59,11 +60,13 @@
this._devToolsConfiguration,
this.shouldLogRequests,
this._enableServicePortFallback,
+ this.uriConverter,
) {
_clientManager = ClientManager(this);
_expressionEvaluator = ExpressionEvaluator(this);
_isolateManager = IsolateManager(this);
_streamManager = StreamManager(this);
+ _packageUriConverter = PackageUriConverter(this);
_authCode = _authCodesEnabled ? _makeAuthToken() : '';
}
@@ -433,6 +436,10 @@
bool _initializationComplete = false;
bool _shuttingDown = false;
+ UriConverter? uriConverter;
+ PackageUriConverter get packageUriConverter => _packageUriConverter;
+ late PackageUriConverter _packageUriConverter;
+
ClientManager get clientManager => _clientManager;
late ClientManager _clientManager;
diff --git a/pkg/dds/lib/src/package_uri_converter.dart b/pkg/dds/lib/src/package_uri_converter.dart
new file mode 100644
index 0000000..0f9b64a
--- /dev/null
+++ b/pkg/dds/lib/src/package_uri_converter.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
+
+import 'dds_impl.dart';
+
+/// Converts from `package:` URIs to resolved file paths.
+class PackageUriConverter {
+ PackageUriConverter(this.dds);
+
+ Future<Map<String, dynamic>> convert(json_rpc.Parameters parameters) async {
+ final isolateId = parameters['isolateId'].asString;
+ final uris = parameters['uris'].asList;
+ final useLocalResolver = parameters['local'].asBoolOr(false);
+
+ final params = <String, dynamic>{
+ 'isolateId': isolateId,
+ 'uris': uris,
+ };
+ final result = await dds.vmServiceClient.sendRequest(
+ 'lookupResolvedPackageUris',
+ params,
+ );
+
+ final converter = dds.uriConverter;
+ if (converter != null && useLocalResolver) {
+ final vmUris = result['uris'];
+
+ final localUris = uris.map((x) => converter(x as String)).toList();
+
+ final resultUris = <String?>[
+ for (var i = 0; i < vmUris.length; i++) localUris[i] ?? vmUris[i],
+ ];
+
+ return <String, dynamic>{
+ 'type': 'UriList',
+ 'uris': resultUris,
+ };
+ }
+ return result;
+ }
+
+ final DartDevelopmentServiceImpl dds;
+}
diff --git a/pkg/dds/test/uri_converter_test.dart b/pkg/dds/test/uri_converter_test.dart
new file mode 100644
index 0000000..2d82ea6
--- /dev/null
+++ b/pkg/dds/test/uri_converter_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:dds/dds.dart';
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart';
+import 'package:vm_service/vm_service_io.dart';
+import 'common/test_helper.dart';
+
+void main() {
+ late Process process;
+ DartDevelopmentService? dds;
+
+ setUp(() async {
+ process = await spawnDartProcess(
+ 'get_cached_cpu_samples_script.dart',
+ disableServiceAuthCodes: true,
+ );
+ });
+
+ tearDown(() async {
+ await dds?.shutdown();
+ process.kill();
+ });
+
+ test(
+ 'DDS returns local paths with a converter',
+ () async {
+ Uri serviceUri = remoteVmServiceUri;
+ dds = await DartDevelopmentService.startDartDevelopmentService(
+ remoteVmServiceUri,
+ uriConverter: (uri) => uri == 'package:test/has_local.dart'
+ ? 'file:///has_local.dart'
+ : null,
+ );
+ serviceUri = dds!.wsUri!;
+ expect(dds!.isRunning, true);
+ final service = await vmServiceConnectUri(serviceUri.toString());
+
+ IsolateRef isolate;
+ while (true) {
+ final vm = await service.getVM();
+ if (vm.isolates!.isNotEmpty) {
+ isolate = vm.isolates!.first;
+ try {
+ isolate = await service.getIsolate(isolate.id!);
+ if ((isolate as Isolate).runnable!) {
+ break;
+ }
+ } on SentinelException {
+ // ignore
+ }
+ }
+ await Future.delayed(const Duration(seconds: 1));
+ }
+ expect(isolate, isNotNull);
+
+ final unresolvedUris = <String>[
+ 'dart:io', // dart:io -> org-dartlang-sdk:///sdk/lib/io/io.dart
+ 'package:test/has_local.dart', // package:test/test.dart -> file:///has_local.dart
+ 'package:does_not_exist/does_not_exist.dart', // invalid URI -> null
+ ];
+ var result = await service
+ .lookupResolvedPackageUris(isolate.id!, unresolvedUris, local: true);
+
+ expect(result.uris?[0], 'org-dartlang-sdk:///sdk/lib/io/io.dart');
+ expect(result.uris?[1], 'file:///has_local.dart');
+ expect(result.uris?[2], null);
+ },
+ timeout: Timeout.none,
+ );
+}
diff --git a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
index fe77f2d..1e2c3e9 100644
--- a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
@@ -55,7 +55,7 @@
/// A builder for a formal parameter, i.e. a parameter on a method or
/// constructor.
class FormalParameterBuilder extends ModifierBuilderImpl
- implements VariableBuilder, ParameterBuilder {
+ implements VariableBuilder, ParameterBuilder, InferredTypeListener {
static const String noNameSentinel = 'no name sentinel';
/// List of metadata builders for the metadata declared on this parameter.
@@ -98,7 +98,9 @@
this.name, LibraryBuilder? compilationUnit, int charOffset,
{Uri? fileUri, this.isExtensionThis: false})
: this.fileUri = fileUri ?? compilationUnit?.fileUri,
- super(compilationUnit, charOffset);
+ super(compilationUnit, charOffset) {
+ type.registerInferredTypeListener(this);
+ }
@override
String get debugName => "FormalParameterBuilder";
@@ -166,6 +168,13 @@
}
@override
+ void onInferredType(DartType type) {
+ if (variable != null) {
+ variable!.type = type;
+ }
+ }
+
+ @override
ParameterBuilder clone(
List<NamedTypeBuilder> newTypes,
SourceLibraryBuilder contextLibrary,
@@ -213,9 +222,9 @@
void finalizeInitializingFormal(ClassBuilder classBuilder) {
Builder? fieldBuilder = classBuilder.lookupLocalMember(name);
if (fieldBuilder is SourceFieldBuilder) {
- variable!.type = fieldBuilder.inferType();
+ type.registerInferredType(fieldBuilder.inferType());
} else {
- variable!.type = const DynamicType();
+ type.registerInferredType(const DynamicType());
}
}
diff --git a/pkg/front_end/lib/src/fasta/builder/omitted_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/omitted_type_builder.dart
index 3cfc546..5ffdf21 100644
--- a/pkg/front_end/lib/src/fasta/builder/omitted_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/omitted_type_builder.dart
@@ -11,8 +11,6 @@
import 'type_builder.dart';
class OmittedTypeBuilder extends TypeBuilder {
- const OmittedTypeBuilder();
-
@override
DartType build(LibraryBuilder library, TypeUse typeUse) {
throw new UnsupportedError('$runtimeType.build');
@@ -67,4 +65,46 @@
TypeBuilder withNullabilityBuilder(NullabilityBuilder nullabilityBuilder) {
return this;
}
+
+ bool get hasType => _type != null;
+
+ DartType? _type;
+
+ DartType get type => _type!;
+
+ List<InferredTypeListener>? _listeners;
+
+ @override
+ void registerInferredTypeListener(InferredTypeListener onType) {
+ if (hasType) {
+ onType.onInferredType(type);
+ } else {
+ (_listeners ??= []).add(onType);
+ }
+ }
+
+ void _registerType(DartType type) {
+ // TODO(johnniwinther): Avoid multiple registration from enums and
+ // duplicated fields.
+ if (_type == null) {
+ _type = type;
+ List<InferredTypeListener>? listeners = _listeners;
+ if (listeners != null) {
+ _listeners = null;
+ for (InferredTypeListener listener in listeners) {
+ listener.onInferredType(type);
+ }
+ }
+ }
+ }
+
+ @override
+ void registerInferredType(DartType type) {
+ _registerType(type);
+ }
+}
+
+/// Listener for the late computation of an inferred type.
+abstract class InferredTypeListener {
+ void onInferredType(DartType type);
}
diff --git a/pkg/front_end/lib/src/fasta/builder/type_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
index 4582b5c..b694a5f 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
@@ -10,6 +10,7 @@
import 'library_builder.dart';
import 'named_type_builder.dart';
import 'nullability_builder.dart';
+import 'omitted_type_builder.dart';
import 'type_declaration_builder.dart';
import 'type_variable_builder.dart';
@@ -325,4 +326,10 @@
TypeBuilder withNullabilityBuilder(NullabilityBuilder nullabilityBuilder);
bool get isVoidType;
+
+ void registerInferredType(DartType type) {
+ throw new UnsupportedError("${runtimeType}.registerInferredType");
+ }
+
+ void registerInferredTypeListener(InferredTypeListener listener) {}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 586fae6..dfc641f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1197,9 +1197,42 @@
}
}
+ List<Object>? createSuperParametersAsArguments(
+ List<FormalParameterBuilder> formals) {
+ List<Object>? superParametersAsArguments;
+ for (FormalParameterBuilder formal in formals) {
+ if (formal.isSuperInitializingFormal) {
+ if (formal.isNamed) {
+ (superParametersAsArguments ??= <Object>[]).add(new NamedExpression(
+ formal.name,
+ createVariableGet(formal.variable!, formal.charOffset,
+ forNullGuardedAccess: false))
+ ..fileOffset = formal.charOffset);
+ } else {
+ (superParametersAsArguments ??= <Object>[]).add(createVariableGet(
+ formal.variable!, formal.charOffset,
+ forNullGuardedAccess: false));
+ }
+ }
+ }
+ return superParametersAsArguments;
+ }
+
void finishFunction(
FormalParameters? formals, AsyncMarker asyncModifier, Statement? body) {
debugEvent("finishFunction");
+
+ // Create variable get expressions for super parameters before finishing
+ // the analysis of the assigned variables. Creating the expressions later
+ // that point results in a flow analysis error.
+ List<Object>? superParametersAsArguments;
+ if (formals != null) {
+ List<FormalParameterBuilder>? formalParameters = formals.parameters;
+ if (formalParameters != null) {
+ superParametersAsArguments =
+ createSuperParametersAsArguments(formalParameters);
+ }
+ }
typeInferrer.assignedVariables.finish();
final SourceFunctionBuilder builder = member as SourceFunctionBuilder;
@@ -1255,7 +1288,8 @@
}
}
if (builder is DeclaredSourceConstructorBuilder) {
- finishConstructor(builder, asyncModifier, body);
+ finishConstructor(builder, asyncModifier, body,
+ superParametersAsArguments: superParametersAsArguments);
} else if (builder is SourceProcedureBuilder) {
builder.asyncModifier = asyncModifier;
} else if (builder is SourceFactoryBuilder) {
@@ -1720,7 +1754,7 @@
/* metadata = */ null,
FormalParameterKind.requiredPositional,
/* modifiers = */ 0,
- const OmittedTypeBuilder(),
+ libraryBuilder.addInferableType(),
formal.name!,
libraryBuilder,
formal.fileOffset,
@@ -1782,8 +1816,13 @@
handleNoInitializers();
}
if (doFinishConstructor) {
- finishConstructor(
- member as DeclaredSourceConstructorBuilder, AsyncMarker.Sync, null);
+ DeclaredSourceConstructorBuilder constructorBuilder =
+ member as DeclaredSourceConstructorBuilder;
+ List<FormalParameterBuilder>? formals = constructorBuilder.formals;
+ finishConstructor(constructorBuilder, AsyncMarker.Sync, null,
+ superParametersAsArguments: formals != null
+ ? createSuperParametersAsArguments(formals)
+ : null);
}
return _initializers;
}
@@ -1825,11 +1864,51 @@
}
void finishConstructor(DeclaredSourceConstructorBuilder builder,
- AsyncMarker asyncModifier, Statement? body) {
+ AsyncMarker asyncModifier, Statement? body,
+ {required List<Object /* Expression | NamedExpression */ >?
+ superParametersAsArguments}) {
/// Quotes below are from [Dart Programming Language Specification, 4th
/// Edition](
/// https://ecma-international.org/publications/files/ECMA-ST/ECMA-408.pdf).
assert(builder == member);
+ assert(() {
+ if (superParametersAsArguments == null) {
+ return true;
+ }
+ for (Object superParameterAsArgument in superParametersAsArguments) {
+ if (superParameterAsArgument is! Expression &&
+ superParameterAsArgument is! NamedExpression) {
+ return false;
+ }
+ }
+ return true;
+ }(),
+ "Expected 'superParametersAsArguments' "
+ "to contain nothing but Expressions and NamedExpressions.");
+ assert(() {
+ if (superParametersAsArguments == null) {
+ return true;
+ }
+ int previousOffset = -1;
+ for (Object superParameterAsArgument in superParametersAsArguments) {
+ int offset;
+ if (superParameterAsArgument is Expression) {
+ offset = superParameterAsArgument.fileOffset;
+ } else if (superParameterAsArgument is NamedExpression) {
+ offset = superParameterAsArgument.value.fileOffset;
+ } else {
+ return false;
+ }
+ if (previousOffset > offset) {
+ return false;
+ }
+ previousOffset = offset;
+ }
+ return true;
+ }(),
+ "Expected 'superParametersAsArguments' "
+ "to be sorted by occurrence in file.");
+
Constructor constructor = builder.actualConstructor;
List<FormalParameterBuilder>? formals = builder.formals;
if (formals != null) {
@@ -1839,26 +1918,45 @@
}
}
+ Set<String>? namedSuperParameterNames;
List<Expression>? positionalSuperParametersAsArguments;
List<NamedExpression>? namedSuperParametersAsArguments;
- Set<String>? namedSuperParameterNames;
- if (formals != null) {
+ if (superParametersAsArguments != null) {
+ for (Object superParameterAsArgument in superParametersAsArguments) {
+ if (superParameterAsArgument is Expression) {
+ (positionalSuperParametersAsArguments ??= <Expression>[])
+ .add(superParameterAsArgument);
+ } else {
+ NamedExpression namedSuperParameterAsArgument =
+ superParameterAsArgument as NamedExpression;
+ (namedSuperParametersAsArguments ??= <NamedExpression>[])
+ .add(namedSuperParameterAsArgument);
+ (namedSuperParameterNames ??= <String>{})
+ .add(namedSuperParameterAsArgument.name);
+ }
+ }
+ } else if (formals != null) {
for (FormalParameterBuilder formal in formals) {
if (formal.isSuperInitializingFormal) {
if (formal.isNamed) {
- (namedSuperParametersAsArguments ??= <NamedExpression>[]).add(
- new NamedExpression(
- formal.name,
- new VariableGetImpl(formal.variable!,
- forNullGuardedAccess: false)
- ..fileOffset = formal.charOffset)
- ..fileOffset = formal.charOffset);
+ NamedExpression superParameterAsArgument = new NamedExpression(
+ formal.name,
+ createVariableGet(formal.variable!, formal.charOffset,
+ forNullGuardedAccess: false))
+ ..fileOffset = formal.charOffset;
+ (namedSuperParametersAsArguments ??= <NamedExpression>[])
+ .add(superParameterAsArgument);
(namedSuperParameterNames ??= <String>{}).add(formal.name);
+ (superParametersAsArguments ??= <Object>[])
+ .add(superParameterAsArgument);
} else {
- (positionalSuperParametersAsArguments ??= <Expression>[]).add(
- new VariableGetImpl(formal.variable!,
- forNullGuardedAccess: false)
- ..fileOffset = formal.charOffset);
+ Expression superParameterAsArgument = createVariableGet(
+ formal.variable!, formal.charOffset,
+ forNullGuardedAccess: false);
+ (positionalSuperParametersAsArguments ??= <Expression>[])
+ .add(superParameterAsArgument);
+ (superParametersAsArguments ??= <Object>[])
+ .add(superParameterAsArgument);
}
}
}
@@ -1902,6 +2000,10 @@
setParents(namedSuperParametersAsArguments, arguments);
arguments.namedSuperParameterNames = namedSuperParameterNames;
}
+ if (superParametersAsArguments != null) {
+ arguments.argumentsOriginalOrder
+ ?.insertAll(0, superParametersAsArguments);
+ }
}
} else if (initializers.last is RedirectingInitializer) {
RedirectingInitializer redirectingInitializer =
@@ -4177,7 +4279,7 @@
}
}
TypeBuilder type = formals.toFunctionType(
- returnType ?? const OmittedTypeBuilder(),
+ returnType ?? libraryBuilder.addInferableType(),
libraryBuilder.nullableBuilderIfTrue(questionMark != null),
typeVariables);
exitLocalScope();
@@ -4384,7 +4486,7 @@
null,
kind,
modifiers,
- type ?? const OmittedTypeBuilder(),
+ type ?? libraryBuilder.addInferableType(),
name?.name ?? '',
libraryBuilder,
offsetForToken(nameToken),
@@ -4461,7 +4563,7 @@
reportErrorIfNullableType(question);
}
TypeBuilder type = formals.toFunctionType(
- returnType ?? const OmittedTypeBuilder(),
+ returnType ?? libraryBuilder.addInferableType(),
libraryBuilder.nullableBuilderIfTrue(question != null),
typeVariables);
exitLocalScope();
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart
index 3b0f111..1c689cc 100644
--- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart
@@ -191,7 +191,7 @@
if (declaredMember.returnType is OmittedTypeBuilder) {
inferredReturnType ??= const DynamicType();
- declaredFunction.returnType = inferredReturnType;
+ declaredMember.returnType.registerInferredType(inferredReturnType);
}
if (declaredMember.formals != null) {
for (FormalParameterBuilder declaredParameter
@@ -200,7 +200,7 @@
DartType inferredParameterType =
inferredParameterTypes[declaredParameter] ??
const DynamicType();
- declaredParameter.variable!.type = inferredParameterType;
+ declaredParameter.type.registerInferredType(inferredParameterType);
}
}
}
@@ -299,8 +299,8 @@
inferFrom(overriddenSetters, forSetter: true);
}
- declaredMember.procedure.function.returnType =
- inferredType ?? const DynamicType();
+ declaredMember.returnType
+ .registerInferredType(inferredType ?? const DynamicType());
}
}
@@ -364,7 +364,7 @@
inferFrom(overriddenGetters, forSetter: false);
}
- parameter.variable!.type = inferredType ?? const DynamicType();
+ parameter.type.registerInferredType(inferredType ?? const DynamicType());
}
}
@@ -483,7 +483,7 @@
inferredType = combinedMemberSignatureType;
}
- fieldBuilder.fieldType = inferredType;
+ fieldBuilder.type.registerInferredType(inferredType);
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
index 8294c53..7fc4b44c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
@@ -113,7 +113,9 @@
fieldBuilder.charOffset,
fieldBuilder.name.length,
fieldBuilder.fileUri);
- return fieldBuilder.fieldType = const InvalidType();
+ DartType type = const InvalidType();
+ fieldBuilder.type.registerInferredType(type);
+ return type;
}
isStarted = true;
DartType? inferredType;
diff --git a/pkg/front_end/lib/src/fasta/kernel/utils.dart b/pkg/front_end/lib/src/fasta/kernel/utils.dart
index c1a644f..393198a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/utils.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/utils.dart
@@ -234,7 +234,7 @@
new FixedTypeBuilder(dummyDartType, dummyUri, -1);
final FormalParameterBuilder dummyFormalParameterBuilder =
new FormalParameterBuilder(null, FormalParameterKind.requiredPositional, 0,
- const OmittedTypeBuilder(), '', null, -1,
+ new OmittedTypeBuilder(), '', null, -1,
fileUri: dummyUri);
final TypeVariableBuilder dummyTypeVariableBuilder = new TypeVariableBuilder(
TypeVariableBuilder.noNameSentinel, null, -1, null,
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index 05e5c4f..16e8716 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -974,7 +974,8 @@
BodyBuilder bodyBuilder =
createFunctionListener(defaultConstructorBuilder);
bodyBuilder.finishConstructor(
- defaultConstructorBuilder, AsyncMarker.Sync, new EmptyStatement());
+ defaultConstructorBuilder, AsyncMarker.Sync, new EmptyStatement(),
+ superParametersAsArguments: null);
}
}
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 81871e0..3e826a0 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -32,7 +32,6 @@
import '../builder/mixin_application_builder.dart';
import '../builder/named_type_builder.dart';
import '../builder/nullability_builder.dart';
-import '../builder/omitted_type_builder.dart';
import '../builder/type_builder.dart';
import '../builder/type_variable_builder.dart';
import '../combinator.dart' show CombinatorBuilder;
@@ -1926,7 +1925,6 @@
libraryBuilder.addConstructor(
metadata,
modifiers,
- returnType,
name,
constructorName,
typeVariables,
@@ -2261,7 +2259,7 @@
metadata,
kind,
modifiers,
- type ?? const OmittedTypeBuilder(),
+ type ?? libraryBuilder.addInferableType(),
name == null ? FormalParameterBuilder.noNameSentinel : name as String,
thisKeyword != null,
superKeyword != null,
@@ -2584,7 +2582,7 @@
List<TypeVariableBuilder>? typeVariables =
pop() as List<TypeVariableBuilder>?;
push(libraryBuilder.addFunctionType(
- returnType ?? const OmittedTypeBuilder(),
+ returnType ?? libraryBuilder.addInferableType(),
typeVariables,
formals,
libraryBuilder.nullableBuilderIfTrue(questionMark != null),
@@ -2605,7 +2603,7 @@
reportErrorIfNullableType(question);
}
push(libraryBuilder.addFunctionType(
- returnType ?? const OmittedTypeBuilder(),
+ returnType ?? libraryBuilder.addInferableType(),
typeVariables,
formals,
libraryBuilder.nullableBuilderIfTrue(question != null),
@@ -2644,7 +2642,7 @@
hasMembers: false);
// TODO(cstefantsova): Make sure that RHS of typedefs can't have '?'.
aliasedType = libraryBuilder.addFunctionType(
- returnType ?? const OmittedTypeBuilder(),
+ returnType ?? libraryBuilder.addInferableType(),
null,
formals,
const NullabilityBuilder.omitted(),
diff --git a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
index 4b94f07..aaca7a6 100644
--- a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
@@ -67,6 +67,9 @@
class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
implements SourceConstructorBuilder {
+ @override
+ final OmittedTypeBuilder returnType;
+
final Constructor _constructor;
final Procedure? _constructorTearOff;
@@ -107,7 +110,7 @@
DeclaredSourceConstructorBuilder(
List<MetadataBuilder>? metadata,
int modifiers,
- TypeBuilder returnType,
+ this.returnType,
String name,
List<TypeVariableBuilder>? typeVariables,
this.formals,
@@ -137,7 +140,7 @@
forAbstractClassOrEnum: forAbstractClassOrEnum),
_hasSuperInitializingFormals =
formals?.any((formal) => formal.isSuperInitializingFormal) ?? false,
- super(metadata, modifiers, returnType, name, typeVariables, formals,
+ super(metadata, modifiers, name, typeVariables, formals,
compilationUnit, charOffset, nativeMethodName);
@override
@@ -427,7 +430,7 @@
if (substitution.isNotEmpty && type != null) {
type = substitute(type, substitution);
}
- formal.variable!.type = type ?? const DynamicType();
+ formal.type.registerInferredType(type ?? const DynamicType());
}
formal.variable!.hasDeclaredInitializer = formal.hasDeclaredInitializer;
}
@@ -521,8 +524,9 @@
new TypeParameterType.withDefaultNullabilityForLibrary(
typeParameter, libraryBuilder.library));
}
- function.returnType = new InterfaceType(
+ DartType type = new InterfaceType(
enclosingClass, libraryBuilder.nonNullable, typeParameterTypes);
+ returnType.registerInferredType(type);
}
@override
diff --git a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
index 4da1575..b92e7c8 100644
--- a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
@@ -21,7 +21,6 @@
import '../builder/metadata_builder.dart';
import '../builder/named_type_builder.dart';
import '../builder/nullability_builder.dart';
-import '../builder/omitted_type_builder.dart';
import '../builder/procedure_builder.dart';
import '../builder/type_builder.dart';
import '../builder/type_declaration_builder.dart';
@@ -46,7 +45,6 @@
import '../kernel/constructor_tearoff_lowering.dart';
import '../kernel/expression_generator_helper.dart';
import '../kernel/kernel_helper.dart';
-import '../kernel/implicit_field_type.dart';
import '../kernel/internal_ast.dart';
import '../modifier.dart' show constMask, hasInitializerMask, staticMask;
@@ -310,7 +308,7 @@
new DeclaredSourceConstructorBuilder(
/* metadata = */ null,
constMask,
- /* returnType = */ const OmittedTypeBuilder(),
+ /* returnType = */ libraryBuilder.addInferableType(),
"",
/* typeParameters = */ null,
<FormalParameterBuilder>[
@@ -467,7 +465,7 @@
}
SourceFieldBuilder fieldBuilder = new SourceFieldBuilder(
metadata,
- const OmittedTypeBuilder(),
+ libraryBuilder.addInferableType(),
name,
constMask | staticMask | hasInitializerMask,
/* isTopLevel = */ false,
@@ -477,10 +475,8 @@
staticFieldNameScheme,
fieldReference: fieldReference,
fieldGetterReference: getterReference,
- fieldSetterReference: setterReference);
- fieldBuilder.fieldType = new ImplicitFieldType(
- fieldBuilder, enumConstantInfo.argumentsBeginToken);
- libraryBuilder.registerImplicitlyTypedField(fieldBuilder);
+ fieldSetterReference: setterReference,
+ initializerToken: enumConstantInfo.argumentsBeginToken);
members[name] = fieldBuilder..next = existing;
elementBuilders.add(fieldBuilder);
}
@@ -795,8 +791,8 @@
typeArgument: rawType(libraryBuilder.nonNullable), isConst: true));
for (SourceFieldBuilder elementBuilder in elementBuilders) {
- elementBuilder.fieldType =
- buildElement(elementBuilder, classHierarchy.coreTypes);
+ elementBuilder.type.registerInferredType(
+ buildElement(elementBuilder, classHierarchy.coreTypes));
}
delayedActionPerformers.addAll(_delayedActionPerformers);
_delayedActionPerformers.clear();
diff --git a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
index 7ba09c8..0b88f34 100644
--- a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
@@ -43,6 +43,9 @@
@override
final bool isExtensionInstanceMember = false;
+ @override
+ final TypeBuilder returnType;
+
final Procedure _procedureInternal;
final Procedure? _factoryTearOff;
@@ -53,7 +56,7 @@
SourceFactoryBuilder(
List<MetadataBuilder>? metadata,
int modifiers,
- TypeBuilder returnType,
+ this.returnType,
String name,
List<TypeVariableBuilder> typeVariables,
List<FormalParameterBuilder>? formals,
@@ -79,8 +82,8 @@
..isNonNullableByDefault = libraryBuilder.isNonNullableByDefault,
_factoryTearOff = createFactoryTearOffProcedure(name, libraryBuilder,
libraryBuilder.fileUri, charOffset, tearOffReference),
- super(metadata, modifiers, returnType, name, typeVariables, formals,
- libraryBuilder, charOffset, nativeMethodName) {
+ super(metadata, modifiers, name, typeVariables, formals, libraryBuilder,
+ charOffset, nativeMethodName) {
this.asyncModifier = asyncModifier;
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_field_builder.dart b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
index f9ca277..3b6f323 100644
--- a/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
@@ -41,7 +41,7 @@
import 'source_member_builder.dart';
class SourceFieldBuilder extends SourceMemberBuilderImpl
- implements FieldBuilder {
+ implements FieldBuilder, InferredTypeListener {
@override
final String name;
@@ -91,10 +91,13 @@
Reference? lateIsSetSetterReference,
Reference? lateGetterReference,
Reference? lateSetterReference,
+ Token? initializerToken,
Token? constInitializerToken,
this.isSynthesized = false})
: _constInitializerToken = constInitializerToken,
super(libraryBuilder, charOffset) {
+ type.registerInferredTypeListener(this);
+
bool isInstanceMember = fieldNameScheme.isInstanceMember;
Uri fileUri = libraryBuilder.fileUri;
@@ -259,6 +262,19 @@
getterReference: fieldGetterReference,
setterReference: fieldSetterReference);
}
+
+ if (type is OmittedTypeBuilder) {
+ if (!hasInitializer && isStatic) {
+ // A static field without type and initializer will always be inferred
+ // to have type `dynamic`.
+ type.registerInferredType(const DynamicType());
+ } else {
+ // A field with no type and initializer or an instance field without
+ // type and initializer need to have the type inferred.
+ fieldType = new ImplicitFieldType(this, initializerToken);
+ libraryBuilder.registerImplicitlyTypedField(this);
+ }
+ }
}
bool get isLateLowered => _fieldEncoding.isLateLowering;
@@ -326,11 +342,6 @@
isSynthetic: isSynthetic);
}
- bool get isEligibleForInference {
- return type is OmittedTypeBuilder &&
- (hasInitializer || isClassInstanceMember);
- }
-
@override
bool get isAssignable {
if (isConst) return false;
@@ -462,7 +473,7 @@
if (!libraryBuilder.isNonNullableByDefault) {
inferredType = legacyErasure(inferredType);
}
- fieldType = implicitFieldType.checkInferred(inferredType);
+ type.registerInferredType(implicitFieldType.checkInferred(inferredType));
IncludesTypeParametersNonCovariantly? needsCheckVisitor;
if (parent is ClassBuilder) {
@@ -485,6 +496,11 @@
return fieldType;
}
+ @override
+ void onInferredType(DartType type) {
+ fieldType = type;
+ }
+
DartType get builtType => fieldType;
List<ClassMember>? _localMembers;
diff --git a/pkg/front_end/lib/src/fasta/source/source_function_builder.dart b/pkg/front_end/lib/src/fasta/source/source_function_builder.dart
index 3b199e8..b91c160 100644
--- a/pkg/front_end/lib/src/fasta/source/source_function_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_function_builder.dart
@@ -127,7 +127,7 @@
/// Common base class for constructor and procedure builders.
abstract class SourceFunctionBuilderImpl extends SourceMemberBuilderImpl
- implements SourceFunctionBuilder {
+ implements SourceFunctionBuilder, InferredTypeListener {
@override
final List<MetadataBuilder>? metadata;
@@ -135,9 +135,6 @@
final int modifiers;
@override
- final TypeBuilder returnType;
-
- @override
final String name;
@override
@@ -158,7 +155,6 @@
SourceFunctionBuilderImpl(
this.metadata,
this.modifiers,
- this.returnType,
this.name,
this.typeVariables,
this.formals,
@@ -166,6 +162,7 @@
int charOffset,
this.nativeMethodName)
: super(compilationUnit, charOffset) {
+ returnType.registerInferredTypeListener(this);
if (formals != null) {
for (int i = 0; i < formals!.length; i++) {
formals![i].parent = this;
@@ -430,6 +427,11 @@
return _extensionTypeParameters;
}
+ @override
+ void onInferredType(DartType type) {
+ function.returnType = type;
+ }
+
bool _hasBuiltOutlineExpressions = false;
@override
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 760a0cc..8dff630 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -65,7 +65,6 @@
import '../import.dart' show Import;
import '../kernel/constructor_tearoff_lowering.dart';
import '../kernel/hierarchy/members_builder.dart';
-import '../kernel/implicit_field_type.dart';
import '../kernel/internal_ast.dart';
import '../kernel/kernel_helper.dart';
import '../kernel/load_library_builder.dart';
@@ -791,7 +790,7 @@
metadata,
modifiers,
isTopLevel,
- type ?? const OmittedTypeBuilder(),
+ type ?? addInferableType(),
info.name,
info.charOffset,
info.charEndOffset,
@@ -1585,6 +1584,11 @@
//addBuilder("Null", new NullTypeBuilder(const NullType(), this, -1), -1);
}
+ OmittedTypeBuilder addInferableType() {
+ // TODO(johnniwinther): Register inferable types in a backlog.
+ return new OmittedTypeBuilder();
+ }
+
NamedTypeBuilder addNamedType(
Object name,
NullabilityBuilder nullabilityBuilder,
@@ -2501,31 +2505,16 @@
lateIsSetSetterReference: lateIsSetSetterReference,
lateGetterReference: lateGetterReference,
lateSetterReference: lateSetterReference,
+ initializerToken: initializerToken,
constInitializerToken: constInitializerToken);
addBuilder(name, fieldBuilder, charOffset,
getterReference: fieldGetterReference,
setterReference: fieldSetterReference);
- if (type is OmittedTypeBuilder && fieldBuilder.next == null) {
- // Only the first one (the last one in the linked list of next pointers)
- // are added to the tree, had parent pointers and can infer correctly.
- if (initializerToken == null && fieldBuilder.isStatic) {
- // A static field without type and initializer will always be inferred
- // to have type `dynamic`.
- fieldBuilder.fieldType = const DynamicType();
- } else {
- // A field with no type and initializer or an instance field without
- // type and initializer need to have the type inferred.
- fieldBuilder.fieldType =
- new ImplicitFieldType(fieldBuilder, initializerToken);
- registerImplicitlyTypedField(fieldBuilder);
- }
- }
}
void addConstructor(
List<MetadataBuilder>? metadata,
int modifiers,
- TypeBuilder? returnType,
final Object? name,
String constructorName,
List<TypeVariableBuilder>? typeVariables,
@@ -2551,7 +2540,7 @@
new DeclaredSourceConstructorBuilder(
metadata,
modifiers & ~abstractMask,
- returnType ?? const OmittedTypeBuilder(),
+ addInferableType(),
constructorName,
typeVariables,
formals,
@@ -2658,7 +2647,7 @@
SourceProcedureBuilder procedureBuilder = new SourceProcedureBuilder(
metadata,
modifiers,
- returnType ?? const OmittedTypeBuilder(),
+ returnType ?? addInferableType(),
name,
typeVariables,
formals,
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 3748d5e3..3787878 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -52,7 +52,6 @@
import '../builder/member_builder.dart';
import '../builder/modifier_builder.dart';
import '../builder/named_type_builder.dart';
-import '../builder/omitted_type_builder.dart';
import '../builder/prefix_builder.dart';
import '../builder/procedure_builder.dart';
import '../builder/type_alias_builder.dart';
@@ -1208,7 +1207,7 @@
ProcedureBuilder builder = new SourceProcedureBuilder(
/* metadata = */ null,
/* modifier flags = */ 0,
- const OmittedTypeBuilder(),
+ libraryBuilder.addInferableType(),
"debugExpr",
/* type variables = */ null,
/* formals = */ null,
diff --git a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
index e24939d..e513652 100644
--- a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
@@ -11,7 +11,6 @@
import '../builder/formal_parameter_builder.dart';
import '../builder/member_builder.dart';
import '../builder/metadata_builder.dart';
-import '../builder/omitted_type_builder.dart';
import '../builder/procedure_builder.dart';
import '../builder/type_builder.dart';
import '../builder/type_variable_builder.dart';
@@ -35,6 +34,9 @@
@override
final bool isExtensionInstanceMember;
+ @override
+ final TypeBuilder returnType;
+
late Procedure _procedure;
final Reference? _tearOffReference;
@@ -61,7 +63,7 @@
SourceProcedureBuilder(
List<MetadataBuilder>? metadata,
int modifiers,
- TypeBuilder returnType,
+ this.returnType,
String name,
List<TypeVariableBuilder>? typeVariables,
List<FormalParameterBuilder>? formals,
@@ -85,8 +87,8 @@
assert(isInstanceMember != null),
assert(kind != ProcedureKind.Factory),
this.isExtensionInstanceMember = isInstanceMember && isExtensionMember,
- super(metadata, modifiers, returnType, name, typeVariables, formals,
- libraryBuilder, charOffset, nativeMethodName) {
+ super(metadata, modifiers, name, typeVariables, formals, libraryBuilder,
+ charOffset, nativeMethodName) {
_procedure = new Procedure(
nameScheme.getProcedureName(kind, name),
isExtensionInstanceMember ? ProcedureKind.Method : kind,
@@ -131,18 +133,6 @@
function.dartAsyncMarker = actualAsyncModifier;
}
- bool get isEligibleForTopLevelInference {
- if (isDeclarationInstanceMember) {
- if (returnType is OmittedTypeBuilder) return true;
- if (formals != null) {
- for (FormalParameterBuilder formal in formals!) {
- if (formal.type is OmittedTypeBuilder) return true;
- }
- }
- }
- return false;
- }
-
bool get isExtensionMethod {
return parent is ExtensionBuilder;
}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 4ab6e5a..7381b60 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -3127,14 +3127,16 @@
implicitInvocationPropertyName: implicitInvocationPropertyName,
extensionAccessCandidates:
target.isAmbiguous ? target.candidates : null);
- inferInvocation(typeContext, fileOffset, unknownFunction, arguments,
+ InvocationInferenceResult inferenceResult = inferInvocation(
+ typeContext, fileOffset, unknownFunction, arguments,
hoistedExpressions: hoistedExpressions,
receiverType: receiverType,
isImplicitCall: isExpressionInvocation || isImplicitCall);
+ Expression replacementError = inferenceResult.applyResult(error);
assert(name != equalsName);
// TODO(johnniwinther): Use InvalidType instead.
return createNullAwareExpressionInferenceResult(
- const DynamicType(), error, nullAwareGuards);
+ const DynamicType(), replacementError, nullAwareGuards);
}
ExpressionInferenceResult _inferExtensionInvocation(
@@ -5325,7 +5327,8 @@
if (hoistedArguments == null || hoistedArguments.isEmpty) {
return expression;
} else {
- assert(expression is InvocationExpression);
+ assert(expression is InvocationExpression ||
+ expression is InvalidExpression);
if (expression is FactoryConstructorInvocation) {
return InvocationInferenceResult._insertHoistedExpressions(
expression, hoistedArguments);
@@ -5364,6 +5367,9 @@
} else if (expression is SuperMethodInvocation) {
return InvocationInferenceResult._insertHoistedExpressions(
expression, hoistedArguments);
+ } else if (expression is InvalidExpression) {
+ return InvocationInferenceResult._insertHoistedExpressions(
+ expression, hoistedArguments);
} else {
throw new StateError(
"Unhandled invocation kind '${expression.runtimeType}'.");
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index e3d8120..37bfea3 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -634,6 +634,7 @@
inequivalence
inequivalences
inequivalent
+inferable
influence
informative
infos
diff --git a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.expect b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.expect
index 95402af..1aab9b0 100644
--- a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.expect
+++ b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.expect
@@ -29,7 +29,7 @@
import "org-dartlang-testcase:///weekly_bot_91_failure.dart";
static method bar(core::int i) → dynamic {
- invalid-expression "pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_lib.dart:4:5: Error: The method '_foo' isn't defined for the class 'int'.
+ let final core::int #t1 = 0 in invalid-expression "pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_lib.dart:4:5: Error: The method '_foo' isn't defined for the class 'int'.
Try correcting the name to the name of an existing method, or defining a method named '_foo'.
i._foo(a: 0, (x) {
^^^^" in i{<unresolved>}._foo((dynamic x) → Null {
diff --git a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.modular.expect b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.modular.expect
index 95402af..1aab9b0 100644
--- a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.modular.expect
@@ -29,7 +29,7 @@
import "org-dartlang-testcase:///weekly_bot_91_failure.dart";
static method bar(core::int i) → dynamic {
- invalid-expression "pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_lib.dart:4:5: Error: The method '_foo' isn't defined for the class 'int'.
+ let final core::int #t1 = 0 in invalid-expression "pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_lib.dart:4:5: Error: The method '_foo' isn't defined for the class 'int'.
Try correcting the name to the name of an existing method, or defining a method named '_foo'.
i._foo(a: 0, (x) {
^^^^" in i{<unresolved>}._foo((dynamic x) → Null {
diff --git a/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.transformed.expect b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.transformed.expect
new file mode 100644
index 0000000..1aab9b0
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure.dart.weak.transformed.expect
@@ -0,0 +1,42 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///weekly_bot_91_failure_lib.dart";
+
+extension _extension#0 on core::int {
+ method _foo = self::_extension#0|_foo;
+ tearoff _foo = self::_extension#0|get#_foo;
+}
+static method _extension#0|_foo<T extends core::Object? = dynamic>(lowered final core::int #this, (self::_extension#0|_foo::T%) → void x, {required self::_extension#0|_foo::T% a = #C1}) → void
+ return throw "";
+static method _extension#0|get#_foo(lowered final core::int #this) → <T extends core::Object? = dynamic>((T%) → void, {a: T%}) → void
+ return <T extends core::Object? = dynamic>((T%) → void x, {T% a = #C1}) → void => self::_extension#0|_foo<T%>(#this, x, a: a);
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_lib.dart:4:5: Error: The method '_foo' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing method, or defining a method named '_foo'.
+// i._foo(a: 0, (x) {
+// ^^^^
+//
+import self as self2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///weekly_bot_91_failure.dart";
+
+static method bar(core::int i) → dynamic {
+ let final core::int #t1 = 0 in invalid-expression "pkg/front_end/testcases/general/error_recovery/weekly_bot_91_failure_lib.dart:4:5: Error: The method '_foo' isn't defined for the class 'int'.
+Try correcting the name to the name of an existing method, or defining a method named '_foo'.
+ i._foo(a: 0, (x) {
+ ^^^^" in i{<unresolved>}._foo((dynamic x) → Null {
+ x;
+ }, a: #t1);
+}
+
+constants {
+ #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/issue38961.dart.weak.expect b/pkg/front_end/testcases/general/issue38961.dart.weak.expect
index 0b9c61a..5a863b3 100644
--- a/pkg/front_end/testcases/general/issue38961.dart.weak.expect
+++ b/pkg/front_end/testcases/general/issue38961.dart.weak.expect
@@ -9,14 +9,14 @@
// dynamic x = this;
// ^
//
-// pkg/front_end/testcases/general/issue38961.dart:6:15: Error: Can't access 'this' in a field initializer.
-// dynamic x = this;
-// ^^^^
-//
// pkg/front_end/testcases/general/issue38961.dart:7:11: Error: Can't access 'this' in a field initializer.
// var x = this;
// ^^^^
//
+// pkg/front_end/testcases/general/issue38961.dart:6:15: Error: Can't access 'this' in a field initializer.
+// dynamic x = this;
+// ^^^^
+//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/general/issue38961.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue38961.dart.weak.modular.expect
index 0b9c61a..5a863b3 100644
--- a/pkg/front_end/testcases/general/issue38961.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/issue38961.dart.weak.modular.expect
@@ -9,14 +9,14 @@
// dynamic x = this;
// ^
//
-// pkg/front_end/testcases/general/issue38961.dart:6:15: Error: Can't access 'this' in a field initializer.
-// dynamic x = this;
-// ^^^^
-//
// pkg/front_end/testcases/general/issue38961.dart:7:11: Error: Can't access 'this' in a field initializer.
// var x = this;
// ^^^^
//
+// pkg/front_end/testcases/general/issue38961.dart:6:15: Error: Can't access 'this' in a field initializer.
+// dynamic x = this;
+// ^^^^
+//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/general/issue38961.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue38961.dart.weak.outline.expect
index 6b1474b..4ce64d9 100644
--- a/pkg/front_end/testcases/general/issue38961.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/issue38961.dart.weak.outline.expect
@@ -9,6 +9,10 @@
// dynamic x = this;
// ^
//
+// pkg/front_end/testcases/general/issue38961.dart:7:11: Error: Can't access 'this' in a field initializer.
+// var x = this;
+// ^^^^
+//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/general/issue38961.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue38961.dart.weak.transformed.expect
index 0b9c61a..5a863b3 100644
--- a/pkg/front_end/testcases/general/issue38961.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/issue38961.dart.weak.transformed.expect
@@ -9,14 +9,14 @@
// dynamic x = this;
// ^
//
-// pkg/front_end/testcases/general/issue38961.dart:6:15: Error: Can't access 'this' in a field initializer.
-// dynamic x = this;
-// ^^^^
-//
// pkg/front_end/testcases/general/issue38961.dart:7:11: Error: Can't access 'this' in a field initializer.
// var x = this;
// ^^^^
//
+// pkg/front_end/testcases/general/issue38961.dart:6:15: Error: Can't access 'this' in a field initializer.
+// dynamic x = this;
+// ^^^^
+//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/general/issue49040.dart b/pkg/front_end/testcases/general/issue49040.dart
new file mode 100644
index 0000000..430f1d7
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49040.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+bar(int i) {
+ i.foo(a: 0, 1);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49040.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue49040.dart.textual_outline.expect
new file mode 100644
index 0000000..c476edd
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49040.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bar(int i) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49040.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue49040.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c476edd
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49040.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bar(int i) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49040.dart.weak.expect b/pkg/front_end/testcases/general/issue49040.dart.weak.expect
new file mode 100644
index 0000000..11626ce
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49040.dart.weak.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49040.dart:6:5: Error: The method 'foo' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// i.foo(a: 0, 1);
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method bar(core::int i) → dynamic {
+ let final core::int #t1 = 0 in invalid-expression "pkg/front_end/testcases/general/issue49040.dart:6:5: Error: The method 'foo' isn't defined for the class 'int'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ i.foo(a: 0, 1);
+ ^^^" in i{<unresolved>}.foo(1, a: #t1);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue49040.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue49040.dart.weak.modular.expect
new file mode 100644
index 0000000..11626ce
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49040.dart.weak.modular.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49040.dart:6:5: Error: The method 'foo' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// i.foo(a: 0, 1);
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method bar(core::int i) → dynamic {
+ let final core::int #t1 = 0 in invalid-expression "pkg/front_end/testcases/general/issue49040.dart:6:5: Error: The method 'foo' isn't defined for the class 'int'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ i.foo(a: 0, 1);
+ ^^^" in i{<unresolved>}.foo(1, a: #t1);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue49040.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue49040.dart.weak.outline.expect
new file mode 100644
index 0000000..72c40bf
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49040.dart.weak.outline.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method bar(core::int i) → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/issue49040.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue49040.dart.weak.transformed.expect
new file mode 100644
index 0000000..11626ce
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49040.dart.weak.transformed.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49040.dart:6:5: Error: The method 'foo' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// i.foo(a: 0, 1);
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method bar(core::int i) → dynamic {
+ let final core::int #t1 = 0 in invalid-expression "pkg/front_end/testcases/general/issue49040.dart:6:5: Error: The method 'foo' isn't defined for the class 'int'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ i.foo(a: 0, 1);
+ ^^^" in i{<unresolved>}.foo(1, a: #t1);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/named_parameters_super_and_not.dart b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart
new file mode 100644
index 0000000..a8990e0
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Super {
+ Super.named(num x, {bool y = false, String? z});
+}
+
+class SubNamed extends Super {
+ SubNamed.namedAnywhere(double x, String z, {super.y}) : super.named(z: z, x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.textual_outline.expect b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.textual_outline.expect
new file mode 100644
index 0000000..80ecae2
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Super {
+ Super.named(num x, {bool y = false, String? z});
+}
+
+class SubNamed extends Super {
+ SubNamed.namedAnywhere(double x, String z, {super.y}) : super.named(z: z, x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2b49772
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class SubNamed extends Super {
+ SubNamed.namedAnywhere(double x, String z, {super.y}) : super.named(z: z, x);
+}
+
+class Super {
+ Super.named(num x, {bool y = false, String? z});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.weak.expect b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.weak.expect
new file mode 100644
index 0000000..6604bdd
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.weak.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Super extends core::Object {
+ constructor named(core::num x, {core::bool y = #C1, core::String? z = #C2}) → self::Super
+ : super core::Object::•()
+ ;
+}
+class SubNamed extends self::Super {
+ constructor namedAnywhere(core::double x, core::String z, {core::bool y = #C1}) → self::SubNamed
+ : final core::String #t1 = z, final core::bool #t2 = y, super self::Super::named(x, z: #t1, y: #t2)
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = false
+ #C2 = null
+}
diff --git a/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.weak.modular.expect b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.weak.modular.expect
new file mode 100644
index 0000000..6604bdd
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.weak.modular.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Super extends core::Object {
+ constructor named(core::num x, {core::bool y = #C1, core::String? z = #C2}) → self::Super
+ : super core::Object::•()
+ ;
+}
+class SubNamed extends self::Super {
+ constructor namedAnywhere(core::double x, core::String z, {core::bool y = #C1}) → self::SubNamed
+ : final core::String #t1 = z, final core::bool #t2 = y, super self::Super::named(x, z: #t1, y: #t2)
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = false
+ #C2 = null
+}
diff --git a/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.weak.outline.expect b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.weak.outline.expect
new file mode 100644
index 0000000..d32b57d
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.weak.outline.expect
@@ -0,0 +1,14 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Super extends core::Object {
+ constructor named(core::num x, {core::bool y = false, core::String? z = null}) → self::Super
+ ;
+}
+class SubNamed extends self::Super {
+ constructor namedAnywhere(core::double x, core::String z, {core::bool y = false}) → self::SubNamed
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.weak.transformed.expect b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.weak.transformed.expect
new file mode 100644
index 0000000..6604bdd
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_parameters_super_and_not.dart.weak.transformed.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Super extends core::Object {
+ constructor named(core::num x, {core::bool y = #C1, core::String? z = #C2}) → self::Super
+ : super core::Object::•()
+ ;
+}
+class SubNamed extends self::Super {
+ constructor namedAnywhere(core::double x, core::String z, {core::bool y = #C1}) → self::SubNamed
+ : final core::String #t1 = z, final core::bool #t2 = y, super self::Super::named(x, z: #t1, y: #t2)
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = false
+ #C2 = null
+}
diff --git a/pkg/front_end/testcases/modular.status b/pkg/front_end/testcases/modular.status
index ab59caa..8fc1080 100644
--- a/pkg/front_end/testcases/modular.status
+++ b/pkg/front_end/testcases/modular.status
@@ -29,7 +29,6 @@
general/crashes/crash_02/main: Crash
general/crashes/crash_06/main: Crash
general/duplicated_declarations: TypeCheckError
-general/error_recovery/weekly_bot_91_failure: Crash
general/getter_vs_setter_type: TypeCheckError
general/implement_semi_stub: TypeCheckError
general/implicit_super_call: TypeCheckError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 93f5cae..b38220f 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -50,7 +50,6 @@
general/error_locations/error_location_03: RuntimeError
general/error_recovery/empty_await_for: RuntimeError
general/error_recovery/empty_for: RuntimeError
-general/error_recovery/weekly_bot_91_failure: Crash
general/expressions: RuntimeError
general/getter_vs_setter_type: TypeCheckError
general/implement_semi_stub: TypeCheckError
@@ -71,6 +70,7 @@
general/mixin_application_override: TypeCheckError
general/mixin_constructors_with_default_values: RuntimeError
general/mixin_covariant2: RuntimeError
+general/named_parameters_super_and_not: TextSerializationFailure # Issue 47524.
general/operator_method_not_found: RuntimeError
general/optional: RuntimeError
general/override_check_accessor_after_inference: TypeCheckError # Issue #31620
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 5a91ed6..e309c17 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -140,7 +140,6 @@
general/error_locations/error_location_03: RuntimeError
general/error_recovery/empty_await_for: RuntimeError
general/error_recovery/empty_for: RuntimeError
-general/error_recovery/weekly_bot_91_failure: Crash
general/expressions: RuntimeError
general/getter_vs_setter_type: TypeCheckError
general/implement_semi_stub: TypeCheckError
diff --git a/pkg/vm_service/java/version.properties b/pkg/vm_service/java/version.properties
index 3e17349..8aee343 100644
--- a/pkg/vm_service/java/version.properties
+++ b/pkg/vm_service/java/version.properties
@@ -1 +1 @@
-version=3.57
+version=3.58
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index b859add..de2a2ea 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -26,7 +26,7 @@
HeapSnapshotObjectNoData,
HeapSnapshotObjectNullData;
-const String vmServiceVersion = '3.57.0';
+const String vmServiceVersion = '3.58.0';
/// @optional
const String optional = 'optional';
@@ -945,9 +945,12 @@
/// If a URI is not known, the corresponding entry in the [UriList] response
/// will be `null`.
///
+ /// If `local` is true, the VM will attempt to return local file paths instead
+ /// of relative paths, but this is not guaranteed.
+ ///
/// See [UriList].
- Future<UriList> lookupResolvedPackageUris(
- String isolateId, List<String> uris);
+ Future<UriList> lookupResolvedPackageUris(String isolateId, List<String> uris,
+ {bool? local});
/// The `lookupPackageUris` RPC is used to convert a list of URIs to their
/// unresolved paths. For example, URIs passed to this RPC are mapped in the
@@ -1552,6 +1555,7 @@
response = await _serviceImplementation.lookupResolvedPackageUris(
params!['isolateId'],
List<String>.from(params['uris'] ?? []),
+ local: params['local'],
);
break;
case 'lookupPackageUris':
@@ -2086,10 +2090,13 @@
_call('kill', {'isolateId': isolateId});
@override
- Future<UriList> lookupResolvedPackageUris(
- String isolateId, List<String> uris) =>
- _call(
- 'lookupResolvedPackageUris', {'isolateId': isolateId, 'uris': uris});
+ Future<UriList> lookupResolvedPackageUris(String isolateId, List<String> uris,
+ {bool? local}) =>
+ _call('lookupResolvedPackageUris', {
+ 'isolateId': isolateId,
+ 'uris': uris,
+ if (local != null) 'local': local,
+ });
@override
Future<UriList> lookupPackageUris(String isolateId, List<String> uris) =>
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index fc2f766..8c07540 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.57
+# Dart VM Service Protocol 3.58
> Please post feedback to the [observatory-discuss group][discuss-list]
-This document describes of _version 3.57_ of the Dart VM Service Protocol. This
+This document describes of _version 3.58_ of the Dart VM Service Protocol. This
protocol is used to communicate with a running Dart Virtual Machine.
To use the Service Protocol, start the VM with the *--observe* flag.
@@ -1220,7 +1220,7 @@
### lookupResolvedPackageUris
```
-UriList lookupResolvedPackageUris(string isolateId, string[] uris)
+UriList lookupResolvedPackageUris(string isolateId, string[] uris, bool local [optional])
```
The _lookupResolvedPackageUris_ RPC is used to convert a list of URIs to their
@@ -1234,6 +1234,8 @@
If a URI is not known, the corresponding entry in the [UriList] response will be
`null`.
+If `local` is true, the VM will attempt to return local file paths instead of relative paths, but this is not guaranteed.
+
See [UriList](#urilist).
### lookupPackageUris
@@ -4369,5 +4371,6 @@
3.55 | Added `streamCpuSamplesWithUserTag` RPC.
3.56 | Added optional `line` and `column` properties to `SourceLocation`. Added a new `SourceReportKind`, `BranchCoverage`, which reports branch level coverage information.
3.57 | Added optional `libraryFilters` parameter to `getSourceReport` RPC.
+3.58 | Added optional `local` parameter to `lookupResolvedPackageUris` RPC.
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/sdk/lib/core/num.dart b/sdk/lib/core/num.dart
index 4da3b29..3da1875 100644
--- a/sdk/lib/core/num.dart
+++ b/sdk/lib/core/num.dart
@@ -150,7 +150,7 @@
/// print(5 % -3); // 2
/// print(-5 % -3); // 1
/// ```
- num operator %(num other);
+ num operator %(num other);
/// Divides this number by [other].
double operator /(num other);
diff --git a/tools/VERSION b/tools/VERSION
index 1dd679d..01fed72 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 163
+PRERELEASE 164
PRERELEASE_PATCH 0
\ No newline at end of file