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