Version 2.16.0-154.0.dev
Merge commit '2f222990dcda6081059e1d31870f24ebd3409066' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 284ed91..8839a05 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
"constraint, update this by running tools/generate_package_config.dart."
],
"configVersion": 2,
- "generated": "2021-12-10T17:31:54.553345",
+ "generated": "2021-12-22T16:24:00.538300",
"generator": "tools/generate_package_config.dart",
"packages": [
{
@@ -629,7 +629,7 @@
"name": "source_span",
"rootUri": "../third_party/pkg/source_span",
"packageUri": "lib/",
- "languageVersion": "2.12"
+ "languageVersion": "2.14"
},
{
"name": "sourcemap_testing",
@@ -817,4 +817,4 @@
"languageVersion": "2.12"
}
]
-}
\ No newline at end of file
+}
diff --git a/DEPS b/DEPS
index b98102b..e0dda5f 100644
--- a/DEPS
+++ b/DEPS
@@ -118,7 +118,7 @@
"http_io_rev": "2fa188caf7937e313026557713f7feffedd4978b",
"http_multi_server_rev": "de1b312164c24a1690b46c6e97bd47eff40c4649",
"http_parser_rev": "202391286ddc13c4c3c284ac5b511f04697250ed",
- "http_rev": "f35d1e1467092f6a5edb2abf7071c4a99e8c737a",
+ "http_rev": "1e42ffa181b263f7790f276a5465832bff7ce615",
"icu_rev" : "81d656878ec611cb0b42d52c82e9dae93920d9ba",
"intl_tag": "0.17.0-nullsafety",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
@@ -152,7 +152,7 @@
"source_map_stack_trace_rev": "1c3026f69d9771acf2f8c176a1ab750463309cce",
"source_maps-0.9.4_rev": "38524",
"source_maps_rev": "6499ee3adac8d469e2953e2e8ba4bdb4c2fbef90",
- "source_span_rev": "1be3c44045a06dff840d2ed3a13e6082d7a03a23",
+ "source_span_rev": "dc189b455d823e2919667f6c5dcb41ab7483bce0",
"sse_rev": "9084339389eb441d0c0518cddac211a097e78657",
"stack_trace_rev": "5220580872625ddee41e9ca9a5f3364789b2f0f6",
"stream_channel_rev": "3fa3e40c75c210d617b8b943b9b8f580e9866a89",
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart
index 0d4e878..d4d248d 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart
@@ -4,6 +4,13 @@
import 'api.dart';
+/// Exposes a platform specific [MacroExecutor], through a top level
+/// `Future<MacroExecutor> start()` function.
+///
+/// TODO: conditionally load isolate_mirrors_executor.dart once conditional
+/// imports of mirrors are supported in AOT (issue #48057).
+import 'fake_executor/fake_executor.dart' as executor_impl show start;
+
/// The interface used by Dart language implementations, in order to load
/// and execute macros, as well as produce library augmentations from those
/// macro applications.
@@ -12,6 +19,11 @@
/// during macro discovery and expansion, and unifies how augmentation libraries
/// are produced.
abstract class MacroExecutor {
+ /// Returns a platform specific [MacroExecutor]. On unsupported platforms this
+ /// will be a fake executor object, which will throw an [UnsupportedError] if
+ /// used.
+ static Future<MacroExecutor> start() => executor_impl.start();
+
/// Invoked when an implementation discovers a new macro definition in a
/// [library] with [name], and prepares this executor to run the macro.
///
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/fake_executor/fake_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/fake_executor/fake_executor.dart
new file mode 100644
index 0000000..9bfd0a7
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/fake_executor/fake_executor.dart
@@ -0,0 +1,18 @@
+// 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 '../executor.dart';
+
+/// The only public api exposed by this library, returns a [_FakeMacroExecutor].
+Future<MacroExecutor> start() async => new _FakeMacroExecutor();
+
+/// A [MacroExecutor] implementation which throws an [UnsupportedError] in all
+/// methods.
+class _FakeMacroExecutor implements MacroExecutor {
+ @override
+ dynamic noSuchMethod(Invocation invocation) {
+ throw new UnsupportedError(
+ 'Macro expansion is not supported on this platform.');
+ }
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart
index d6476af..48b0229 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart
@@ -11,12 +11,17 @@
import '../executor.dart';
import '../api.dart';
+/// Returns an instance of [_IsolateMirrorMacroExecutor].
+///
+/// This is the only public api exposed by this library.
+Future<MacroExecutor> start() => _IsolateMirrorMacroExecutor.start();
+
/// A [MacroExecutor] implementation which relies on [IsolateMirror.loadUri]
/// in order to load macros libraries.
///
/// All actual work happens in a separate [Isolate], and this class serves as
/// a bridge between that isolate and the language frontends.
-class IsolateMirrorMacroExecutor implements MacroExecutor {
+class _IsolateMirrorMacroExecutor implements MacroExecutor {
/// The actual isolate doing macro loading and execution.
final Isolate _macroIsolate;
@@ -33,7 +38,7 @@
/// to perform any necessary cleanup.
final void Function() _onClose;
- IsolateMirrorMacroExecutor._(
+ _IsolateMirrorMacroExecutor._(
this._macroIsolate, this._sendPort, this._responseStream, this._onClose) {
_responseStream.listen((event) {
Completer<GenericResponse>? completer =
@@ -63,7 +68,7 @@
}).onDone(responseStreamController.close);
Isolate macroIsolate = await Isolate.spawn(spawn, receivePort.sendPort);
- return new IsolateMirrorMacroExecutor._(
+ return new _IsolateMirrorMacroExecutor._(
macroIsolate,
await sendPortCompleter.future,
responseStreamController.stream,
diff --git a/pkg/_fe_analyzer_shared/lib/src/util/libraries_specification.dart b/pkg/_fe_analyzer_shared/lib/src/util/libraries_specification.dart
index bbc64f4..bcbe485 100644
--- a/pkg/_fe_analyzer_shared/lib/src/util/libraries_specification.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/util/libraries_specification.dart
@@ -96,9 +96,10 @@
/// Contains information about all libraries on all target platforms defined in
/// that file.
class LibrariesSpecification {
+ final Uri specUri;
final Map<String, TargetLibrariesSpecification> _targets;
- const LibrariesSpecification(
+ const LibrariesSpecification(this.specUri,
[this._targets = const <String, TargetLibrariesSpecification>{}]);
/// The library specification for a given [target], or throws if none is
@@ -107,23 +108,53 @@
TargetLibrariesSpecification? targetSpec = _targets[target];
if (targetSpec == null) {
throw new LibrariesSpecificationException(
- 'No library specification for target "$target"');
+ messageMissingTarget(target, specUri));
}
return targetSpec;
}
+ static Future<LibrariesSpecification> load(
+ Uri uri, Future<String> Function(Uri uri) read) {
+ Map<Uri, LibrariesSpecification?> cache = {};
+ Future<LibrariesSpecification> loadSpecification(Uri uri) async {
+ if (cache.containsKey(uri)) {
+ LibrariesSpecification? specification = cache[uri];
+ if (specification == null) {
+ throw new LibrariesSpecificationException(messageCyclicSpec(uri));
+ }
+ return specification;
+ }
+ cache[uri] = null;
+ String json;
+ try {
+ json = await read(uri);
+ } catch (e) {
+ throw new LibrariesSpecificationException(
+ messageIncludePathCouldNotBeRead(uri, e));
+ }
+ return cache[uri] =
+ await LibrariesSpecification.parse(uri, json, loadSpecification);
+ }
+
+ return loadSpecification(uri);
+ }
+
/// Parse the given [json] as a library specification, resolving any relative
- /// paths from [baseUri].
+ /// paths from [specUri].
///
/// May throw an exception if [json] is not properly formatted or contains
/// invalid values.
- static LibrariesSpecification parse(Uri baseUri, String? json) {
- if (json == null) return const LibrariesSpecification();
+ static Future<LibrariesSpecification> parse(
+ Uri specUri,
+ String? json,
+ Future<LibrariesSpecification> Function(Uri uri)
+ loadSpecification) async {
+ if (json == null) return new LibrariesSpecification(specUri);
Map<String, dynamic> jsonData;
try {
dynamic data = jsonDecode(json);
if (data is! Map<String, dynamic>) {
- return _reportError('top-level specification is not a map');
+ return _reportError(messageTopLevelIsNotAMap(specUri));
}
jsonData = data;
} on FormatException catch (e) {
@@ -131,62 +162,129 @@
}
Map<String, TargetLibrariesSpecification> targets =
<String, TargetLibrariesSpecification>{};
- jsonData.forEach((String targetName, targetData) {
- if (targetName.startsWith("comment:")) return null;
+
+ Set<String> currentTargets = {};
+
+ Future<TargetLibrariesSpecification> resolveTargetData(
+ String targetName) async {
+ TargetLibrariesSpecification? spec = targets[targetName];
+ if (spec != null) {
+ return spec;
+ }
+ if (currentTargets.contains(targetName)) {
+ _reportError(messageCyclicInternalInclude(targetName, specUri));
+ }
+
+ currentTargets.add(targetName);
Map<String, LibraryInfo> libraries = <String, LibraryInfo>{};
+ Object? targetData = jsonData[targetName];
if (targetData is! Map) {
- _reportError("target specification for '$targetName' is not a map");
+ _reportError(messageTargetIsNotAMap(targetName, specUri));
+ }
+
+ Object? include = targetData["include"];
+ if (include != null) {
+ if (include is! List) {
+ _reportError(messageIncludeIsNotAList(targetName, specUri));
+ }
+ for (Object? map in include) {
+ if (map is! Map<String, dynamic>) {
+ _reportError(messageIncludeEntryIsNotAMap(targetName, specUri));
+ }
+ if (!map.containsKey("target")) {
+ _reportError(messageIncludeTargetMissing(targetName, specUri));
+ }
+ Object? target = map["target"];
+ if (target is! String) {
+ _reportError(messageIncludeTargetIsNotAString(targetName, specUri));
+ }
+ if (!map.containsKey("path")) {
+ if (!jsonData.containsKey(target)) {
+ _reportError(messageMissingTarget(target, specUri));
+ }
+ TargetLibrariesSpecification targetLibrariesSpecification =
+ await resolveTargetData(target);
+ libraries.addAll(targetLibrariesSpecification._libraries);
+ } else {
+ Object? path = map["path"];
+ if (path is! String) {
+ _reportError(messageIncludePathIsNotAString(targetName, specUri));
+ }
+ Uri uri = Uri.parse(path);
+ if (uri.scheme != '' && uri.scheme != 'file') {
+ return _reportError(messageUnsupportedUriScheme(path, specUri));
+ }
+ LibrariesSpecification specification =
+ await loadSpecification(specUri.resolveUri(uri));
+ TargetLibrariesSpecification targetSpecification =
+ specification.specificationFor(target);
+ for (LibraryInfo libraryInfo in targetSpecification.allLibraries) {
+ libraries[libraryInfo.name] = libraryInfo;
+ }
+ }
+ }
}
if (!targetData.containsKey("libraries")) {
- _reportError("target specification "
- "for '$targetName' doesn't have a libraries entry");
+ _reportError(messageTargetLibrariesMissing(targetName, specUri));
}
- dynamic librariesData = targetData["libraries"];
+ Object? librariesData = targetData["libraries"];
if (librariesData is! Map<String, dynamic>) {
- _reportError("libraries entry for '$targetName' is not a map");
+ _reportError(messageLibrariesEntryIsNotAMap(targetName, specUri));
}
- librariesData.forEach((String name, data) {
+ librariesData.forEach((String libraryName, Object? data) {
if (data is! Map<String, dynamic>) {
_reportError(
- "library data for '$name' in target '$targetName' is not a map");
+ messageLibraryDataIsNotAMap(libraryName, targetName, specUri));
}
- Uri checkAndResolve(uriString) {
+ Uri checkAndResolve(Object? uriString) {
if (uriString is! String) {
- return _reportError("uri value '$uriString' is not a string"
- "(from library '$name' in target '$targetName')");
+ return _reportError(messageLibraryUriIsNotAString(
+ uriString, libraryName, targetName, specUri));
}
Uri uri = Uri.parse(uriString);
if (uri.scheme != '' && uri.scheme != 'file') {
- return _reportError("uri scheme in '$uriString' is not supported.");
+ return _reportError(
+ messageUnsupportedUriScheme(uriString, specUri));
}
- return baseUri.resolveUri(uri);
+ return specUri.resolveUri(uri);
}
+ if (!data.containsKey('uri')) {
+ _reportError(
+ messageLibraryUriMissing(libraryName, targetName, specUri));
+ }
Uri uri = checkAndResolve(data['uri']);
List<Uri> patches;
if (data['patches'] is List) {
patches =
- data['patches'].map<Uri>((s) => baseUri.resolve(s)).toList();
+ data['patches'].map<Uri>((s) => specUri.resolve(s)).toList();
} else if (data['patches'] is String) {
patches = [checkAndResolve(data['patches'])];
} else if (data['patches'] == null) {
patches = const [];
} else {
- _reportError("patches entry for '$name' is not a list or a string");
+ _reportError(messagePatchesMustBeListOrString(libraryName));
}
dynamic supported = data['supported'] ?? true;
if (supported is! bool) {
- _reportError("\"supported\" entry: expected a 'bool' but "
- "got a '${supported.runtimeType}' ('$supported')");
+ _reportError(messageSupportedIsNotABool(supported));
}
- libraries[name] =
- new LibraryInfo(name, uri, patches, isSupported: supported);
+ libraries[libraryName] =
+ new LibraryInfo(libraryName, uri, patches, isSupported: supported);
});
- targets[targetName] =
+ currentTargets.remove(targetName);
+ return targets[targetName] =
new TargetLibrariesSpecification(targetName, libraries);
- });
- return new LibrariesSpecification(targets);
+ }
+
+ for (String targetName in jsonData.keys) {
+ if (targetName.startsWith("comment:")) {
+ continue;
+ }
+ await resolveTargetData(targetName);
+ }
+ return new LibrariesSpecification(specUri, targets);
}
static Never _reportError(String error) =>
@@ -264,3 +362,67 @@
@override
String toString() => '$error';
}
+
+String messageMissingTarget(String targetName, Uri specUri) =>
+ 'No library specification for target "$targetName" in ${specUri}.';
+
+String messageCyclicSpec(Uri specUri) => 'Cyclic dependency in ${specUri}.';
+
+String messageCyclicInternalInclude(String targetName, Uri specUri) =>
+ 'Cyclic dependency of target "$targetName" in ${specUri}.';
+
+String messageTopLevelIsNotAMap(Uri specUri) =>
+ 'Top-level specification is not a map in ${specUri}.';
+
+String messageTargetIsNotAMap(String targetName, Uri specUri) =>
+ 'Target specification for "$targetName" is not a map in $specUri.';
+
+String messageIncludeIsNotAList(String targetName, Uri specUri) =>
+ '"include" specification for "$targetName" is not a list in $specUri.';
+
+String messageIncludeEntryIsNotAMap(String targetName, Uri specUri) =>
+ '"include" entry in "$targetName" is not a map in $specUri.';
+
+String messageIncludePathIsNotAString(String targetName, Uri specUri) =>
+ '"include" path in "$targetName" is not a string in $specUri.';
+
+String messageIncludePathCouldNotBeRead(Uri includeUri, Object error) =>
+ '"include" path \'$includeUri\' could not be read: $error';
+
+String messageIncludeTargetMissing(String targetName, Uri specUri) =>
+ '"include" target in "$targetName" is missing in $specUri.';
+
+String messageIncludeTargetIsNotAString(String targetName, Uri specUri) =>
+ '"include" target in "$targetName" is not a string in $specUri.';
+
+String messageTargetLibrariesMissing(String targetName, Uri specUri) =>
+ 'Target specification '
+ 'for "$targetName" doesn\'t have a libraries entry in $specUri.';
+
+String messageLibrariesEntryIsNotAMap(String targetName, Uri specUri) =>
+ '"libraries" entry for "$targetName" is not a map in $specUri.';
+
+String messageLibraryDataIsNotAMap(
+ String libraryName, String targetName, Uri specUri) =>
+ 'Library data for \'$libraryName\' in target "$targetName" is not a map '
+ 'in $specUri.';
+
+String messageLibraryUriMissing(
+ String libraryName, String targetName, Uri specUri) =>
+ '"uri" is missing '
+ 'from library \'$libraryName\' in target "$targetName" in $specUri.';
+
+String messageLibraryUriIsNotAString(
+ Object? uriValue, String libraryName, String targetName, Uri specUri) =>
+ 'Uri value `$uriValue` is not a string '
+ '(from library \'$libraryName\' in target "$targetName" in $specUri).';
+
+String messageUnsupportedUriScheme(String uriValue, Uri specUri) =>
+ "Uri scheme in '$uriValue' is not supported in $specUri.";
+
+String messagePatchesMustBeListOrString(String libraryName) =>
+ '"patches" entry for "$libraryName" is not a list or a string.';
+
+String messageSupportedIsNotABool(Object supportedValue) =>
+ '"supported" entry: expected a `bool` but '
+ 'got a `${supportedValue.runtimeType}` ("$supportedValue").';
diff --git a/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/isolate_mirror_executor_test.dart b/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/isolate_mirror_executor_test.dart
index 48ca97b..ab7b057 100644
--- a/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/isolate_mirror_executor_test.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/isolate_mirror_executor_test.dart
@@ -6,7 +6,8 @@
import 'package:_fe_analyzer_shared/src/macros/api.dart';
import 'package:_fe_analyzer_shared/src/macros/executor.dart';
-import 'package:_fe_analyzer_shared/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart';
+import 'package:_fe_analyzer_shared/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart'
+ as mirrorExecutor;
import 'package:test/fake.dart';
import 'package:test/test.dart';
@@ -15,7 +16,7 @@
late MacroExecutor executor;
setUp(() async {
- executor = await IsolateMirrorMacroExecutor.start();
+ executor = await mirrorExecutor.start();
});
tearDown(() {
diff --git a/pkg/_fe_analyzer_shared/test/util/libraries_specification_test.dart b/pkg/_fe_analyzer_shared/test/util/libraries_specification_test.dart
index 10f9717..990f989c 100644
--- a/pkg/_fe_analyzer_shared/test/util/libraries_specification_test.dart
+++ b/pkg/_fe_analyzer_shared/test/util/libraries_specification_test.dart
@@ -5,56 +5,102 @@
import 'package:_fe_analyzer_shared/src/util/libraries_specification.dart';
import 'package:test/test.dart';
+bool Function(dynamic) checkException(String expectedMessage) {
+ return (exception) {
+ print(exception);
+ if (exception is LibrariesSpecificationException) {
+ expect(exception.error, expectedMessage);
+ return true;
+ }
+ return false;
+ };
+}
+
void main() {
+ String notFoundMessage = 'File not found';
+
+ Uri specUri = Uri.parse('org-dartlang-test:///f.json');
+
+ Future<String> Function(Uri) read(Map<Uri, String> map) {
+ return (Uri uri) async {
+ String? jsonString = map[uri];
+ if (jsonString == null) {
+ throw notFoundMessage;
+ }
+ return jsonString;
+ };
+ }
+
group('parse', () {
test('top-level must be a map', () async {
var jsonString = '[]';
expect(
- () => LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///f.json'), jsonString),
- throwsA((e) => e is LibrariesSpecificationException));
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(messageTopLevelIsNotAMap(specUri))));
jsonString = '""';
expect(
- () => LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///f.json'), jsonString),
- throwsA((e) => e is LibrariesSpecificationException));
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(messageTopLevelIsNotAMap(specUri))));
});
test('target entry must be a map', () async {
var jsonString = '{"vm" : []}';
expect(
- () => LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///f.json'), jsonString),
- throwsA((e) => e is LibrariesSpecificationException));
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(messageTargetIsNotAMap('vm', specUri))));
jsonString = '{"vm" : ""}';
expect(
- () => LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///f.json'), jsonString),
- throwsA((e) => e is LibrariesSpecificationException));
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(messageTargetIsNotAMap('vm', specUri))));
});
test('library entry must exist', () async {
var jsonString = '{"vm" : {}}';
expect(
- () => LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///f.json'), jsonString),
- throwsA((e) => e is LibrariesSpecificationException));
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(
+ checkException(messageTargetLibrariesMissing('vm', specUri))));
});
test('library entry must be a map', () async {
var jsonString = '{"vm" : {"libraries": []}}';
expect(
- () => LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///f.json'), jsonString),
- throwsA((e) => e is LibrariesSpecificationException));
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(
+ checkException(messageLibrariesEntryIsNotAMap('vm', specUri))));
+ });
+
+ test('library data must be a map', () async {
+ var jsonString = '{"vm" : {"libraries": { "foo": [] }}}';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(
+ messageLibraryDataIsNotAMap('foo', 'vm', specUri))));
+ });
+
+ test('library uri must be supplied', () async {
+ var jsonString = '{"vm" : {"libraries": {"core": {}}}}';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(
+ checkException(messageLibraryUriMissing('core', 'vm', specUri))));
});
test('uri must be a string', () async {
- var jsonString = '{"vm" : {"libraries": {"core": {"uri": 3}}}';
+ var jsonString = '{"vm" : {"libraries": {"core": {"uri": 3}}}}';
expect(
- () => LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///f.json'), jsonString),
- throwsA((e) => e is LibrariesSpecificationException));
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(
+ messageLibraryUriIsNotAString(3, 'core', 'vm', specUri))));
});
test('patches must be a string or list of string', () async {
@@ -71,9 +117,9 @@
}
''';
expect(
- () => LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///f.json'), jsonString),
- throwsA((e) => e is LibrariesSpecificationException));
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(messagePatchesMustBeListOrString('c'))));
jsonString = '''
{
@@ -87,8 +133,8 @@
}
}
''';
- var spec = LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///f.json'), jsonString);
+ var spec = await LibrariesSpecification.load(
+ specUri, read({specUri: jsonString}));
expect(spec.specificationFor("none").libraryInfoFor("c")!.patches.first,
Uri.parse('org-dartlang-test:///a.dart'));
@@ -104,8 +150,8 @@
}
}
''';
- spec = LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///f.json'), jsonString);
+ spec = await LibrariesSpecification.load(
+ specUri, read({specUri: jsonString}));
expect(spec.specificationFor("none").libraryInfoFor("c")!.patches.first,
Uri.parse('org-dartlang-test:///a.dart'));
});
@@ -114,8 +160,9 @@
var jsonString = '''
{ "none": { "libraries": {"c" : { "uri": "c/main.dart" }}}}
''';
- var spec = LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///one/two/f.json'), jsonString);
+ var uri = Uri.parse('org-dartlang-test:///one/two/f.json');
+ var spec =
+ await LibrariesSpecification.load(uri, read({uri: jsonString}));
expect(spec, isNotNull);
expect(
spec.specificationFor('none').libraryInfoFor('c')!.patches, isEmpty);
@@ -125,9 +172,9 @@
var jsonString = '''
{ "none": { "libraries": {"c" : { "uri": "c/main.dart" }}}}
''';
-
- var spec = LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///one/two/f.json'), jsonString);
+ var uri = Uri.parse('org-dartlang-test:///one/two/f.json');
+ var spec =
+ await LibrariesSpecification.load(uri, read({uri: jsonString}));
expect(spec.specificationFor('none').libraryInfoFor('c')!.uri,
Uri.parse('org-dartlang-test:///one/two/c/main.dart'));
});
@@ -148,9 +195,9 @@
}
}
''';
-
- var spec = LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///one/two/f.json'), jsonString);
+ var uri = Uri.parse('org-dartlang-test:///one/two/f.json');
+ var spec =
+ await LibrariesSpecification.load(uri, read({uri: jsonString}));
expect(spec.specificationFor('none').libraryInfoFor('c')!.patches[0],
Uri.parse('org-dartlang-test:///one/a/p1.dart'));
expect(spec.specificationFor('none').libraryInfoFor('c')!.patches[1],
@@ -186,9 +233,9 @@
}
}
''';
-
- var spec = LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///one/two/f.json'), jsonString);
+ var uri = Uri.parse('org-dartlang-test:///one/two/f.json');
+ var spec =
+ await LibrariesSpecification.load(uri, read({uri: jsonString}));
expect(spec.specificationFor('vm').libraryInfoFor('foo')!.uri,
Uri.parse('org-dartlang-test:///one/two/a/main.dart'));
@@ -199,12 +246,23 @@
});
test('supported entry must be bool', () async {
- var jsonString = '{"vm" : {"libraries": {"core": '
- '{"uri": "main.dart", "supported": 3}},';
+ var jsonString = '''
+ {
+ "vm":
+ {
+ "libraries":
+ {
+ "core": {
+ "uri": "main.dart",
+ "supported": 3
+ }
+ }
+ }
+ }''';
expect(
- () => LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///f.json'), jsonString),
- throwsA((e) => e is LibrariesSpecificationException));
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(messageSupportedIsNotABool(3))));
});
test('supported entry is copied correctly when parsing', () async {
@@ -238,8 +296,9 @@
}
}
''';
- var spec = LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///one/two/f.json'), jsonString);
+ var uri = Uri.parse('org-dartlang-test:///one/two/f.json');
+ var spec =
+ await LibrariesSpecification.load(uri, read({uri: jsonString}));
expect(spec.specificationFor('vm').libraryInfoFor('foo')!.isSupported,
false);
expect(
@@ -249,6 +308,399 @@
});
});
+ group('nested', () {
+ test('include must be a list', () async {
+ var jsonString = '''
+ {
+ "target": {
+ "include": "",
+ "libraries": {}
+ }
+ }
+ ''';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(messageIncludeIsNotAList('target', specUri))));
+ });
+
+ test('include entry must be a map', () async {
+ var jsonString = '''
+ {
+ "target": {
+ "include": [""],
+ "libraries": {}
+ }
+ }
+ ''';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(
+ checkException(messageIncludeEntryIsNotAMap('target', specUri))));
+ });
+
+ test('include entry must have a target string', () async {
+ var jsonString = '''
+ {
+ "target": {
+ "include": [{}],
+ "libraries": {}
+ }
+ }
+ ''';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(
+ checkException(messageIncludeTargetMissing('target', specUri))));
+
+ jsonString = '''
+ {
+ "target": {
+ "include": [{"path": "dummy"}],
+ "libraries": {}
+ }
+ }
+ ''';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(
+ checkException(messageIncludeTargetMissing('target', specUri))));
+
+ jsonString = '''
+ {
+ "target": {
+ "include": [{"path": 0, "target": 0}],
+ "libraries": {}
+ }
+ }
+ ''';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(
+ messageIncludeTargetIsNotAString('target', specUri))));
+ });
+
+ test('include entry path must be a string', () async {
+ var jsonString = '''
+ {
+ "target": {
+ "include": [{"path": 0, "target": "dummy"}],
+ "libraries": {}
+ }
+ }
+ ''';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(
+ messageIncludePathIsNotAString('target', specUri))));
+
+ jsonString = '''
+ {
+ "target": {
+ "include": [{"path": "dummy", "target": 0}],
+ "libraries": {}
+ }
+ }
+ ''';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(
+ messageIncludeTargetIsNotAString('target', specUri))));
+ });
+
+ test('include entry path scheme can only be file', () async {
+ var jsonString = '''
+ {
+ "target": {
+ "include": [{"path": "http://foo.dart", "target": "none"}],
+ "libraries": {}
+ }
+ }
+ ''';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(
+ messageUnsupportedUriScheme("http://foo.dart", specUri))));
+ });
+
+ test('include entry must be a existing path and target', () async {
+ var otherFile = 'g.json';
+ var otherUri = specUri.resolve(otherFile);
+ var jsonString = '''
+ {
+ "target": {
+ "include": [{"path": "$otherFile", "target": "none"}],
+ "libraries": {}
+ }
+ }
+ ''';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(
+ messageIncludePathCouldNotBeRead(otherUri, notFoundMessage))));
+
+ var otherJsonString = '''
+ {
+ "target": {
+ "libraries": {}
+ }
+ }''';
+ expect(
+ () => LibrariesSpecification.load(
+ specUri, read({specUri: jsonString, otherUri: otherJsonString})),
+ throwsA(checkException(messageMissingTarget('none', otherUri))));
+ });
+
+ test('internal include target must exist', () async {
+ var jsonString = '''
+ {
+ "target": {
+ "include": [{"target": "none"}],
+ "libraries": {}
+ }
+ }
+ ''';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(messageMissingTarget('none', specUri))));
+ });
+
+ test('include entry cannot be cyclic', () async {
+ var thisFile = 'f.json';
+ var thisUri = specUri.resolve(thisFile);
+ var otherFile = 'g.json';
+ var otherUri = thisUri.resolve(otherFile);
+ var thisJsonString = '''
+ {
+ "target": {
+ "include": [{"path": "$thisFile", "target": "target"}],
+ "libraries": {}
+ }
+ }
+ ''';
+ expect(
+ () => LibrariesSpecification.load(
+ thisUri, read({thisUri: thisJsonString})),
+ throwsA(checkException(messageCyclicSpec(thisUri))));
+
+ thisJsonString = '''
+ {
+ "target": {
+ "include": [{"path": "$otherFile", "target": "none"}],
+ "libraries": {}
+ }
+ }
+ ''';
+ var otherJsonString = '''
+ {
+ "none": {
+ "include": [{"path": "$thisFile", "target": "target"}],
+ "libraries": {}
+ }
+ }''';
+ expect(
+ () => LibrariesSpecification.load(thisUri,
+ read({thisUri: thisJsonString, otherUri: otherJsonString})),
+ throwsA(checkException(messageCyclicSpec(thisUri))));
+ });
+
+ test('include entry cannot be cyclic internally', () async {
+ var jsonString = '''
+ {
+ "target": {
+ "include": [{"target": "target"}],
+ "libraries": {}
+ }
+ }
+ ''';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(
+ checkException(messageCyclicInternalInclude('target', specUri))));
+
+ jsonString = '''
+ {
+ "a": {
+ "include": [{"target": "b"}],
+ "libraries": {}
+ },
+ "b": {
+ "include": [{"target": "a"}],
+ "libraries": {}
+ }
+ }
+ ''';
+ expect(
+ () =>
+ LibrariesSpecification.load(specUri, read({specUri: jsonString})),
+ throwsA(checkException(messageCyclicInternalInclude('a', specUri))));
+ });
+
+ test('include works transitively', () async {
+ var thisFile = 'f.json';
+ var thisUri = specUri.resolve(thisFile);
+ var otherFile1 = 'g.json';
+ var otherUri1 = thisUri.resolve(otherFile1);
+ var otherFile2 = 'subfolder/h.json';
+ var otherUri2 = thisUri.resolve(otherFile2);
+ var otherFile3 = '../i.json';
+ var otherUri3 = otherUri2.resolve(otherFile3);
+ var thisJsonString = '''
+ {
+ "foo": {
+ "include": [
+ {
+ "path": "$otherFile1",
+ "target": "foo"
+ },
+ {
+ "path": "$otherFile2",
+ "target": "foo"
+ }
+ ],
+ "libraries": {}
+ },
+ "bar": {
+ "include": [{"path": "$otherFile2", "target": "bar"}],
+ "libraries": {}
+ }
+ }
+ ''';
+ var otherJsonString1 = '''
+ {
+ "foo": {
+ "libraries": {
+ "foo": {
+ "uri": "foo.dart"
+ }
+ }
+ }
+ }''';
+ var otherJsonString2 = '''
+ {
+ "foo": {
+ "libraries": {
+ "foo_extra": {
+ "uri": "foo_extra.dart"
+ }
+ }
+ },
+ "bar": {
+ "include": [{"path": "$otherFile3", "target": "baz"}],
+ "libraries": {
+ "bar": {
+ "uri": "bar/baz.dart"
+ }
+ }
+ }
+ }''';
+ var otherJsonString3 = '''
+ {
+ "baz": {
+ "libraries": {
+ "baz": {
+ "uri": "bar/baz.dart"
+ }
+ }
+ }
+ }''';
+ var spec = await LibrariesSpecification.load(
+ thisUri,
+ read({
+ thisUri: thisJsonString,
+ otherUri1: otherJsonString1,
+ otherUri2: otherJsonString2,
+ otherUri3: otherJsonString3,
+ }));
+
+ expect(spec.specificationFor('foo').libraryInfoFor('foo')!.uri,
+ otherUri1.resolve('foo.dart'));
+ expect(spec.specificationFor('foo').libraryInfoFor('foo_extra')!.uri,
+ otherUri2.resolve('foo_extra.dart'));
+ expect(spec.specificationFor('bar').libraryInfoFor('bar')!.uri,
+ otherUri2.resolve('bar/baz.dart'));
+ expect(spec.specificationFor('bar').libraryInfoFor('baz')!.uri,
+ otherUri3.resolve('bar/baz.dart'));
+ });
+
+ test('internal include works transitively', () async {
+ var jsonString = '''
+ {
+ "foo": {
+ "include": [{"target": "common"}],
+ "libraries": {
+ "foo": {
+ "uri": "foo.dart"
+ }
+ }
+ },
+ "bar": {
+ "include": [
+ {
+ "target": "common"
+ },
+ {
+ "target": "baz"
+ }
+ ],
+ "libraries": {
+ "bar": {
+ "uri": "bar.dart"
+ }
+ }
+ },
+ "common": {
+ "libraries": {
+ "common": {
+ "uri": "common.dart"
+ }
+ }
+ },
+ "baz": {
+ "include": [{"target": "boz"}],
+ "libraries": {
+ "baz": {
+ "uri": "bar/baz.dart"
+ }
+ }
+ },
+ "boz": {
+ "libraries": {
+ "boz": {
+ "uri": "bar/boz.dart"
+ }
+ }
+ }
+ }
+ ''';
+ var spec = await LibrariesSpecification.load(
+ specUri, read({specUri: jsonString}));
+
+ expect(spec.specificationFor('foo').libraryInfoFor('foo')!.uri,
+ specUri.resolve('foo.dart'));
+ expect(spec.specificationFor('foo').libraryInfoFor('common')!.uri,
+ specUri.resolve('common.dart'));
+ expect(spec.specificationFor('bar').libraryInfoFor('bar')!.uri,
+ specUri.resolve('bar.dart'));
+ expect(spec.specificationFor('bar').libraryInfoFor('common')!.uri,
+ specUri.resolve('common.dart'));
+ expect(spec.specificationFor('bar').libraryInfoFor('baz')!.uri,
+ specUri.resolve('bar/baz.dart'));
+ expect(spec.specificationFor('bar').libraryInfoFor('boz')!.uri,
+ specUri.resolve('bar/boz.dart'));
+ });
+ });
+
group('toJson', () {
test('serialization produces same data that was parsed', () async {
var jsonString = '''
@@ -282,11 +734,12 @@
}
''';
- var spec = LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///one/two/f.json'), jsonString);
+ var uri = Uri.parse('org-dartlang-test:///one/two/f.json');
+ var spec =
+ await LibrariesSpecification.load(uri, read({uri: jsonString}));
var newJson =
spec.toJsonString(Uri.parse('org-dartlang-test:///one/two/g.json'));
- expect(jsonString.replaceAll(new RegExp('\\s'), ''), newJson);
+ expect(newJson, jsonString.replaceAll(new RegExp('\\s'), ''));
});
test('serialization can adapt to new file location', () async {
@@ -319,8 +772,9 @@
}
''';
- var spec = LibrariesSpecification.parse(
- Uri.parse('org-dartlang-test:///one/two/f.json'), jsonString);
+ var uri = Uri.parse('org-dartlang-test:///one/two/f.json');
+ var spec =
+ await LibrariesSpecification.load(uri, read({uri: jsonString}));
var newJson =
spec.toJsonString(Uri.parse('org-dartlang-test:///one/g.json'));
@@ -354,7 +808,71 @@
}
''';
- expect(expected.replaceAll(new RegExp('\\s'), ''), newJson);
+ expect(newJson, expected.replaceAll(new RegExp('\\s'), ''));
+ });
+
+ test('serialization of nested specs inlines data', () async {
+ var jsonString = '''
+ {
+ "vm": {
+ "include": [
+ {
+ "path": "g.json",
+ "target": "vm"
+ }
+ ],
+ "libraries": {
+ "foo" : {
+ "uri": "a/main.dart"
+ }
+ }
+ }
+ }
+ ''';
+ var otherJsonString = '''
+ {
+ "vm": {
+ "libraries": {
+ "bar" : {
+ "uri": "b/main.dart"
+ }
+ }
+ },
+ "unused": {
+ "libraries": {
+ "foo" : {
+ "uri": "c/main.dart"
+ }
+ }
+ }
+ }
+ ''';
+
+ var uri = Uri.parse('org-dartlang-test:///one/two/f.json');
+ var otherUri = Uri.parse('org-dartlang-test:///one/two/g.json');
+ var spec = await LibrariesSpecification.load(
+ uri, read({uri: jsonString, otherUri: otherJsonString}));
+ var newJson =
+ spec.toJsonString(Uri.parse('org-dartlang-test:///one/two/h.json'));
+ expect(
+ newJson,
+ '''
+ {
+ "vm": {
+ "libraries": {
+ "bar" : {
+ "uri": "b/main.dart",
+ "patches": []
+ },
+ "foo" : {
+ "uri": "a/main.dart",
+ "patches": []
+ }
+ }
+ }
+ }
+ '''
+ .replaceAll(new RegExp('\\s'), ''));
});
});
}
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 1bb0ba8..ea924c5 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -3117,6 +3117,7 @@
+
<dl><dt class="typeDefinition"><a name="type_AddContentOverlay">AddContentOverlay: object</a></dt><dd>
<p>
A directive to begin overlaying the contents of a file. The supplied
@@ -3484,7 +3485,23 @@
An identifier used to associate completion results with a
completion request.
</p>
- </dd><dt class="typeDefinition"><a name="type_CompletionService">CompletionService: String</a></dt><dd>
+ </dd><dt class="typeDefinition"><a name="type_CompletionMode">CompletionMode: String</a></dt><dd>
+ <p>
+ An enumeration of the kinds of code completion that users can invoke.
+ </p>
+
+ <dl><dt class="value">BASIC</dt><dd>
+
+ <p>
+ Basic code completion invocation type, and the default for this
+ enumeration.
+ </p>
+ </dd><dt class="value">SMART</dt><dd>
+
+ <p>
+ Smart code completion, currently not implemented.
+ </p>
+ </dd></dl></dd><dt class="typeDefinition"><a name="type_CompletionService">CompletionService: String</a></dt><dd>
<p>
An enumeration of the completion services to which a client can subscribe.
</p>
@@ -6098,7 +6115,7 @@
TODO: TBD
</p>
<h2 class="domain"><a name="index">Index</a></h2>
-<h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li><li><a href="#request_server.cancelRequest">cancelRequest</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.log">log</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.closingLabels">closingLabels</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li><li><a href="#request_completion.setSubscriptions">setSubscriptions</a></li><li><a href="#request_completion.registerLibraryPaths">registerLibraryPaths</a></li><li><a href="#request_completion.getSuggestionDetails">getSuggestionDetails</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li><li><a href="#notification_completion.availableSuggestions">availableSuggestions</a></li><li><a href="#notification_completion.existingImports">existingImports</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getPostfixCompletion">getPostfixCompletion</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.getSuggestions">getSuggestions</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h4>diagnostic (<a href="#domain_diagnostic">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_diagnostic.getDiagnostics">getDiagnostics</a></li><li><a href="#request_diagnostic.getServerPort">getServerPort</a></li></ul></div><h4>flutter (<a href="#domain_flutter">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_flutter.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_flutter.outline">outline</a></li></ul></div></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_AvailableSuggestion">AvailableSuggestion</a></li><li><a href="#type_AvailableSuggestionRelevanceTag">AvailableSuggestionRelevanceTag</a></li><li><a href="#type_AvailableSuggestionSet">AvailableSuggestionSet</a></li><li><a href="#type_BulkFix">BulkFix</a></li><li><a href="#type_BulkFixDetail">BulkFixDetail</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_ClosingLabel">ClosingLabel</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionService">CompletionService</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextData">ContextData</a></li><li><a href="#type_DiagnosticMessage">DiagnosticMessage</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementDeclaration">ElementDeclaration</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_ExistingImport">ExistingImport</a></li><li><a href="#type_ExistingImports">ExistingImports</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FlutterOutline">FlutterOutline</a></li><li><a href="#type_FlutterOutlineAttribute">FlutterOutlineAttribute</a></li><li><a href="#type_FlutterOutlineKind">FlutterOutlineKind</a></li><li><a href="#type_FlutterService">FlutterService</a></li><li><a href="#type_FlutterWidgetProperty">FlutterWidgetProperty</a></li><li><a href="#type_FlutterWidgetPropertyEditor">FlutterWidgetPropertyEditor</a></li><li><a href="#type_FlutterWidgetPropertyEditorKind">FlutterWidgetPropertyEditorKind</a></li><li><a href="#type_FlutterWidgetPropertyValue">FlutterWidgetPropertyValue</a></li><li><a href="#type_FlutterWidgetPropertyValueEnumItem">FlutterWidgetPropertyValueEnumItem</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_ImportedElementSet">ImportedElementSet</a></li><li><a href="#type_ImportedElements">ImportedElements</a></li><li><a href="#type_IncludedSuggestionRelevanceTag">IncludedSuggestionRelevanceTag</a></li><li><a href="#type_IncludedSuggestionSet">IncludedSuggestionSet</a></li><li><a href="#type_KytheEntry">KytheEntry</a></li><li><a href="#type_KytheVName">KytheVName</a></li><li><a href="#type_LibraryPathSet">LibraryPathSet</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PostfixTemplateDescriptor">PostfixTemplateDescriptor</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a></li><li><a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a></li><li><a href="#type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind</a></li><li><a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_EXTRACT_WIDGET">EXTRACT_WIDGET</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
+<h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li><li><a href="#request_server.cancelRequest">cancelRequest</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.log">log</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.closingLabels">closingLabels</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li><li><a href="#request_completion.setSubscriptions">setSubscriptions</a></li><li><a href="#request_completion.registerLibraryPaths">registerLibraryPaths</a></li><li><a href="#request_completion.getSuggestionDetails">getSuggestionDetails</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li><li><a href="#notification_completion.availableSuggestions">availableSuggestions</a></li><li><a href="#notification_completion.existingImports">existingImports</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getPostfixCompletion">getPostfixCompletion</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.getSuggestions">getSuggestions</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h4>diagnostic (<a href="#domain_diagnostic">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_diagnostic.getDiagnostics">getDiagnostics</a></li><li><a href="#request_diagnostic.getServerPort">getServerPort</a></li></ul></div><h4>flutter (<a href="#domain_flutter">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_flutter.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_flutter.outline">outline</a></li></ul></div></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_AvailableSuggestion">AvailableSuggestion</a></li><li><a href="#type_AvailableSuggestionRelevanceTag">AvailableSuggestionRelevanceTag</a></li><li><a href="#type_AvailableSuggestionSet">AvailableSuggestionSet</a></li><li><a href="#type_BulkFix">BulkFix</a></li><li><a href="#type_BulkFixDetail">BulkFixDetail</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_ClosingLabel">ClosingLabel</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionMode">CompletionMode</a></li><li><a href="#type_CompletionService">CompletionService</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextData">ContextData</a></li><li><a href="#type_DiagnosticMessage">DiagnosticMessage</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementDeclaration">ElementDeclaration</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_ExistingImport">ExistingImport</a></li><li><a href="#type_ExistingImports">ExistingImports</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FlutterOutline">FlutterOutline</a></li><li><a href="#type_FlutterOutlineAttribute">FlutterOutlineAttribute</a></li><li><a href="#type_FlutterOutlineKind">FlutterOutlineKind</a></li><li><a href="#type_FlutterService">FlutterService</a></li><li><a href="#type_FlutterWidgetProperty">FlutterWidgetProperty</a></li><li><a href="#type_FlutterWidgetPropertyEditor">FlutterWidgetPropertyEditor</a></li><li><a href="#type_FlutterWidgetPropertyEditorKind">FlutterWidgetPropertyEditorKind</a></li><li><a href="#type_FlutterWidgetPropertyValue">FlutterWidgetPropertyValue</a></li><li><a href="#type_FlutterWidgetPropertyValueEnumItem">FlutterWidgetPropertyValueEnumItem</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_ImportedElementSet">ImportedElementSet</a></li><li><a href="#type_ImportedElements">ImportedElements</a></li><li><a href="#type_IncludedSuggestionRelevanceTag">IncludedSuggestionRelevanceTag</a></li><li><a href="#type_IncludedSuggestionSet">IncludedSuggestionSet</a></li><li><a href="#type_KytheEntry">KytheEntry</a></li><li><a href="#type_KytheVName">KytheVName</a></li><li><a href="#type_LibraryPathSet">LibraryPathSet</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PostfixTemplateDescriptor">PostfixTemplateDescriptor</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a></li><li><a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a></li><li><a href="#type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind</a></li><li><a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_EXTRACT_WIDGET">EXTRACT_WIDGET</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
</body></html>
\ No newline at end of file
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 00b690a..ad20782 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -138,7 +138,11 @@
const String COMPLETION_NOTIFICATION_RESULTS_RESULTS = 'results';
const String COMPLETION_REQUEST_GET_SUGGESTIONS = 'completion.getSuggestions';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2 = 'completion.getSuggestions2';
+const String COMPLETION_REQUEST_GET_SUGGESTIONS2_COMPLETION_MODE =
+ 'completionMode';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2_FILE = 'file';
+const String COMPLETION_REQUEST_GET_SUGGESTIONS2_INVOCATION_COUNT =
+ 'invocationCount';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2_MAX_RESULTS = 'maxResults';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2_OFFSET = 'offset';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2_TIMEOUT = 'timeout';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 8d9f921..19f187f 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -4698,6 +4698,15 @@
/// to true.
int maxResults;
+ /// The mode of code completion being invoked. If no value is provided, BASIC
+ /// will be assumed. BASIC is also the only currently supported.
+ CompletionMode? completionMode;
+
+ /// The number of times that the user has invoked code completion at the same
+ /// code location, counting from 1. If no value is provided, 1 will be
+ /// assumed.
+ int? invocationCount;
+
/// The approximate time in milliseconds that the server should spend. The
/// server will perform some steps anyway, even if it takes longer than the
/// specified timeout. This field is intended to be used for benchmarking,
@@ -4705,7 +4714,7 @@
int? timeout;
CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults,
- {this.timeout});
+ {this.completionMode, this.invocationCount, this.timeout});
factory CompletionGetSuggestions2Params.fromJson(
JsonDecoder jsonDecoder, String jsonPath, Object? json) {
@@ -4730,11 +4739,23 @@
} else {
throw jsonDecoder.mismatch(jsonPath, 'maxResults');
}
+ CompletionMode? completionMode;
+ if (json.containsKey('completionMode')) {
+ completionMode = CompletionMode.fromJson(
+ jsonDecoder, jsonPath + '.completionMode', json['completionMode']);
+ }
+ int? invocationCount;
+ if (json.containsKey('invocationCount')) {
+ invocationCount = jsonDecoder.decodeInt(
+ jsonPath + '.invocationCount', json['invocationCount']);
+ }
int? timeout;
if (json.containsKey('timeout')) {
timeout = jsonDecoder.decodeInt(jsonPath + '.timeout', json['timeout']);
}
return CompletionGetSuggestions2Params(file, offset, maxResults,
+ completionMode: completionMode,
+ invocationCount: invocationCount,
timeout: timeout);
} else {
throw jsonDecoder.mismatch(
@@ -4753,6 +4774,14 @@
result['file'] = file;
result['offset'] = offset;
result['maxResults'] = maxResults;
+ var completionMode = this.completionMode;
+ if (completionMode != null) {
+ result['completionMode'] = completionMode.toJson();
+ }
+ var invocationCount = this.invocationCount;
+ if (invocationCount != null) {
+ result['invocationCount'] = invocationCount;
+ }
var timeout = this.timeout;
if (timeout != null) {
result['timeout'] = timeout;
@@ -4774,6 +4803,8 @@
return file == other.file &&
offset == other.offset &&
maxResults == other.maxResults &&
+ completionMode == other.completionMode &&
+ invocationCount == other.invocationCount &&
timeout == other.timeout;
}
return false;
@@ -4784,6 +4815,8 @@
file,
offset,
maxResults,
+ completionMode,
+ invocationCount,
timeout,
);
}
@@ -5090,6 +5123,58 @@
int get hashCode => id.hashCode;
}
+/// CompletionMode
+///
+/// enum {
+/// BASIC
+/// SMART
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class CompletionMode implements Enum {
+ /// Basic code completion invocation type, and the default for this
+ /// enumeration.
+ static const CompletionMode BASIC = CompletionMode._('BASIC');
+
+ /// Smart code completion, currently not implemented.
+ static const CompletionMode SMART = CompletionMode._('SMART');
+
+ /// A list containing all of the enum values that are defined.
+ static const List<CompletionMode> VALUES = <CompletionMode>[BASIC, SMART];
+
+ @override
+ final String name;
+
+ const CompletionMode._(this.name);
+
+ factory CompletionMode(String name) {
+ switch (name) {
+ case 'BASIC':
+ return BASIC;
+ case 'SMART':
+ return SMART;
+ }
+ throw Exception('Illegal enum value: $name');
+ }
+
+ factory CompletionMode.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object? json) {
+ if (json is String) {
+ try {
+ return CompletionMode(json);
+ } catch (_) {
+ // Fall through
+ }
+ }
+ throw jsonDecoder.mismatch(jsonPath, 'CompletionMode', json);
+ }
+
+ @override
+ String toString() => 'CompletionMode.$name';
+
+ String toJson() => name;
+}
+
/// completion.registerLibraryPaths params
///
/// {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
index 3b4f5f2..185cc30 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
@@ -114,7 +114,7 @@
}
void _addExtensionMembers(List<ExtensionElement> extensions,
- CompletionSuggestionKind? kind, DartType type) {
+ CompletionSuggestionKind kind, DartType type) {
var applicableExtensions = extensions.applicableTo(
targetLibrary: request.libraryElement,
targetType: type,
@@ -134,7 +134,7 @@
}
void _addInstanceMembers(ExtensionElement extension,
- CompletionSuggestionKind? kind, double inheritanceDistance) {
+ CompletionSuggestionKind kind, double inheritanceDistance) {
for (var method in extension.methods) {
if (!method.isStatic) {
memberBuilder.addSuggestionForMethod(
@@ -151,7 +151,7 @@
}
}
- void _addTypeMembers(InterfaceType type, CompletionSuggestionKind? kind,
+ void _addTypeMembers(InterfaceType type, CompletionSuggestionKind kind,
double inheritanceDistance) {
for (var method in type.methods) {
memberBuilder.addSuggestionForMethod(
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
index 1e16887..b3a1499 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
@@ -25,7 +25,7 @@
late MemberSuggestionBuilder memberBuilder;
/// The kind of suggestion to make.
- CompletionSuggestionKind? classMemberSuggestionKind;
+ late CompletionSuggestionKind classMemberSuggestionKind;
/// The [_VisibilityTracker] tracks the set of elements already added in the
/// completion list, this object helps prevents suggesting elements that have
@@ -314,8 +314,7 @@
if (declaredElement is FunctionElement) {
builder.suggestTopLevelFunction(declaredElement, kind: _defaultKind);
} else if (declaredElement is PropertyAccessorElement) {
- builder.suggestTopLevelPropertyAccessor(declaredElement,
- kind: _defaultKind);
+ builder.suggestTopLevelPropertyAccessor(declaredElement);
}
}
}
@@ -324,7 +323,7 @@
void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
var declaredElement = declaration.declaredElement;
if (declaredElement != null && opType.includeTypeNameSuggestions) {
- builder.suggestTypeAlias(declaredElement, kind: _defaultKind);
+ builder.suggestTypeAlias(declaredElement);
}
}
@@ -333,7 +332,7 @@
var declaredElement = declaration.declaredElement;
if (declaredElement is TypeAliasElement &&
opType.includeTypeNameSuggestions) {
- builder.suggestTypeAlias(declaredElement, kind: _defaultKind);
+ builder.suggestTypeAlias(declaredElement);
}
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
index 62adabb..d0f8af8 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
@@ -2,6 +2,7 @@
// 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:analysis_server/src/protocol_server.dart' as protocol;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
@@ -56,7 +57,11 @@
}
for (var method in element.methods) {
if (method.isStatic && isVisible(method)) {
- builder.suggestMethod(method, inheritanceDistance: 0.0);
+ builder.suggestMethod(
+ method,
+ kind: protocol.CompletionSuggestionKind.INVOCATION,
+ inheritanceDistance: 0.0,
+ );
}
}
} else if (element is ExtensionElement) {
@@ -74,7 +79,11 @@
}
for (var method in element.methods) {
if (method.isStatic && isVisible(method)) {
- builder.suggestMethod(method, inheritanceDistance: 0.0);
+ builder.suggestMethod(
+ method,
+ kind: protocol.CompletionSuggestionKind.INVOCATION,
+ inheritanceDistance: 0.0,
+ );
}
}
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index a606391..a441aa0 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -87,7 +87,7 @@
/// Add a suggestion for the given [method].
void addSuggestionForMethod(
{required MethodElement method,
- CompletionSuggestionKind? kind,
+ required CompletionSuggestionKind kind,
required double inheritanceDistance}) {
if (method.isAccessibleIn(request.libraryElement) &&
_shouldAddSuggestion(method)) {
@@ -273,7 +273,13 @@
superMatches: superMatches,
inheritanceDistance: inheritanceDistance,
);
- _add(_createSuggestion(accessor, relevance: relevance));
+ _add(
+ _createSuggestion(
+ accessor,
+ kind: CompletionSuggestionKind.IDENTIFIER,
+ relevance: relevance,
+ ),
+ );
}
}
@@ -291,8 +297,14 @@
elementKind: elementKind,
isConstant: isConstant,
);
- _add(_createSuggestion(parameter,
- elementKind: protocol.ElementKind.PARAMETER, relevance: relevance));
+ _add(
+ _createSuggestion(
+ parameter,
+ elementKind: protocol.ElementKind.PARAMETER,
+ kind: CompletionSuggestionKind.IDENTIFIER,
+ relevance: relevance,
+ ),
+ );
}
/// Add a suggestion for a [classElement]. If the class can only be
@@ -425,9 +437,9 @@
suggestTopLevelFunction(element, kind: kind);
} else if (element is PropertyAccessorElement &&
element.enclosingElement is CompilationUnitElement) {
- suggestTopLevelPropertyAccessor(element, kind: kind);
+ suggestTopLevelPropertyAccessor(element);
} else if (element is TypeAliasElement) {
- suggestTypeAlias(element, kind: kind);
+ suggestTypeAlias(element);
} else {
throw ArgumentError('Cannot suggest a ${element.runtimeType}');
}
@@ -442,8 +454,15 @@
var completion = '$enumName.$constantName';
var relevance =
_computeTopLevelRelevance(constant, elementType: constant.type);
- _add(_createSuggestion(constant,
- completion: completion, prefix: prefix, relevance: relevance));
+ _add(
+ _createSuggestion(
+ constant,
+ completion: completion,
+ kind: CompletionSuggestionKind.IDENTIFIER,
+ prefix: prefix,
+ relevance: relevance,
+ ),
+ );
}
/// Add a suggestion for an [extension]. If a [kind] is provided it will be
@@ -484,14 +503,26 @@
superMatches: superMatches,
inheritanceDistance: inheritanceDistance,
);
- _add(_createSuggestion(field, relevance: relevance));
+ _add(
+ _createSuggestion(
+ field,
+ kind: CompletionSuggestionKind.IDENTIFIER,
+ relevance: relevance,
+ ),
+ );
}
/// Add a suggestion to reference a [field] in a field formal parameter.
void suggestFieldFormalParameter(FieldElement field) {
// TODO(brianwilkerson) Add a parameter (`bool includePrefix`) indicating
// whether to include the `this.` prefix in the completion.
- _add(_createSuggestion(field, relevance: Relevance.fieldFormalParameter));
+ _add(
+ _createSuggestion(
+ field,
+ kind: CompletionSuggestionKind.IDENTIFIER,
+ relevance: Relevance.fieldFormalParameter,
+ ),
+ );
}
/// Add a suggestion for the `call` method defined on functions.
@@ -561,7 +592,13 @@
// TODO(brianwilkerson) This might want to use the context type rather than
// a fixed value.
var relevance = Relevance.loadLibrary;
- _add(_createSuggestion(function, relevance: relevance));
+ _add(
+ _createSuggestion(
+ function,
+ kind: CompletionSuggestionKind.INVOCATION,
+ relevance: relevance,
+ ),
+ );
}
/// Add a suggestion for a local [variable].
@@ -585,7 +622,13 @@
isConstant: isConstant,
localVariableDistance: localVariableDistance,
);
- _add(_createSuggestion(variable, relevance: relevance));
+ _add(
+ _createSuggestion(
+ variable,
+ kind: CompletionSuggestionKind.IDENTIFIER,
+ relevance: relevance,
+ ),
+ );
}
/// Add a suggestion for a [method]. If the method is being invoked with a
@@ -594,7 +637,8 @@
/// used as the kind for the suggestion. The [inheritanceDistance] is the
/// value of the inheritance distance feature computed for the method.
void suggestMethod(MethodElement method,
- {CompletionSuggestionKind? kind, required double inheritanceDistance}) {
+ {required CompletionSuggestionKind kind,
+ required double inheritanceDistance}) {
// TODO(brianwilkerson) Refactor callers so that we're passing in the type
// of the target (assuming we don't already have that type available via
// the [request]) and compute the [inheritanceDistance] in this method.
@@ -809,7 +853,13 @@
elementKind: elementKind,
isConstant: isConstant,
);
- _add(_createSuggestion(parameter, relevance: relevance));
+ _add(
+ _createSuggestion(
+ parameter,
+ kind: CompletionSuggestionKind.IDENTIFIER,
+ relevance: relevance,
+ ),
+ );
}
/// Add a suggestion for a [prefix] associated with a [library].
@@ -844,8 +894,7 @@
/// can only be referenced using a prefix, then the [prefix] should be
/// provided.
void suggestTopLevelPropertyAccessor(PropertyAccessorElement accessor,
- {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
- String? prefix}) {
+ {String? prefix}) {
assert(
accessor.enclosingElement is CompilationUnitElement,
'Enclosing element of ${accessor.runtimeType} is '
@@ -857,7 +906,7 @@
if (accessor.isGetter) {
var variable = accessor.variable;
if (variable is TopLevelVariableElement) {
- suggestTopLevelVariable(variable, kind: kind);
+ suggestTopLevelVariable(variable);
}
}
} else {
@@ -881,7 +930,14 @@
startsWithDollar: startsWithDollar,
superMatches: superMatches,
);
- _add(_createSuggestion(accessor, prefix: prefix, relevance: relevance));
+ _add(
+ _createSuggestion(
+ accessor,
+ kind: CompletionSuggestionKind.IDENTIFIER,
+ prefix: prefix,
+ relevance: relevance,
+ ),
+ );
}
}
@@ -889,25 +945,34 @@
/// will be used as the kind for the suggestion. If the variable can only be
/// referenced using a prefix, then the [prefix] should be provided.
void suggestTopLevelVariable(TopLevelVariableElement variable,
- {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
- String? prefix}) {
+ {String? prefix}) {
assert(variable.enclosingElement is CompilationUnitElement);
var relevance =
_computeTopLevelRelevance(variable, elementType: variable.type);
- _add(_createSuggestion(variable,
- kind: kind, prefix: prefix, relevance: relevance));
+ _add(
+ _createSuggestion(
+ variable,
+ kind: CompletionSuggestionKind.IDENTIFIER,
+ prefix: prefix,
+ relevance: relevance,
+ ),
+ );
}
/// Add a suggestion for a [typeAlias]. If a [kind] is provided it
/// will be used as the kind for the suggestion. If the alias can only be
/// referenced using a prefix, then the [prefix] should be provided.
- void suggestTypeAlias(TypeAliasElement typeAlias,
- {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
- String? prefix}) {
+ void suggestTypeAlias(TypeAliasElement typeAlias, {String? prefix}) {
var relevance = _computeTopLevelRelevance(typeAlias,
elementType: _instantiateTypeAlias(typeAlias));
- _add(_createSuggestion(typeAlias,
- kind: kind, prefix: prefix, relevance: relevance));
+ _add(
+ _createSuggestion(
+ typeAlias,
+ kind: CompletionSuggestionKind.IDENTIFIER,
+ prefix: prefix,
+ relevance: relevance,
+ ),
+ );
}
/// Add a suggestion for a type [parameter].
@@ -1038,7 +1103,7 @@
CompletionSuggestion? _createSuggestion(Element element,
{String? completion,
protocol.ElementKind? elementKind,
- CompletionSuggestionKind? kind,
+ required CompletionSuggestionKind kind,
String? prefix,
required int relevance}) {
var inputs = _CompletionSuggestionInputs(
@@ -1081,7 +1146,7 @@
Element element, {
required String? completion,
required protocol.ElementKind? elementKind,
- required CompletionSuggestionKind? kind,
+ required CompletionSuggestionKind kind,
required String? prefix,
required int relevance,
}) {
@@ -1096,7 +1161,6 @@
if (prefix != null && prefix.isNotEmpty) {
completion = '$prefix.$completion';
}
- kind ??= CompletionSuggestionKind.INVOCATION;
var suggestion = CompletionSuggestion(kind, relevance, completion,
completion.length, 0, element.hasOrInheritsDeprecated, false);
@@ -1256,7 +1320,7 @@
class _CompletionSuggestionInputs {
final String? completion;
final protocol.ElementKind? elementKind;
- final CompletionSuggestionKind? kind;
+ final CompletionSuggestionKind kind;
final String? prefix;
_CompletionSuggestionInputs({
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index 589c793..3717b9c 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -4,6 +4,7 @@
import 'dart:collection';
+import 'package:analysis_server/src/protocol_server.dart' as protocol;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
@@ -253,7 +254,10 @@
// Exclude static methods when completion on an instance.
if (!method.isStatic) {
addSuggestionForMethod(
- method: method, inheritanceDistance: inheritanceDistance);
+ method: method,
+ kind: protocol.CompletionSuggestionKind.INVOCATION,
+ inheritanceDistance: inheritanceDistance,
+ );
}
}
for (var accessor in targetType.accessors) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart
index 4a1c1e4..c392597 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart
@@ -4,6 +4,7 @@
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/error_verifier.dart';
@@ -35,16 +36,23 @@
// Compute uninitialized final fields.
var fields = ErrorVerifier.computeNotInitializedFields(constructor);
fields.retainWhere((FieldElement field) => field.isFinal);
-
- // Prepare new parameters code.
fields.sort((a, b) => a.nameOffset - b.nameOffset);
- var fieldParametersCode =
- fields.map((field) => 'this.${field.name}').join(', ');
// Specialize for Flutter widgets.
if (flutter.isExactlyStatelessWidgetType(superType) ||
flutter.isExactlyStatefulWidgetType(superType)) {
if (parameters.isNotEmpty && parameters.last.isNamed) {
+ var isNullSafe =
+ libraryElement.featureSet.isEnabled(Feature.non_nullable);
+ String parameterForField(FieldElement field) {
+ var prefix = '';
+ if (isNullSafe && typeSystem.isPotentiallyNonNullable(field.type)) {
+ prefix = 'required ';
+ }
+ return '${prefix}this.${field.name}';
+ }
+
+ var fieldParametersCode = fields.map(parameterForField).join(', ');
await builder.addDartFileEdit(file, (builder) {
builder.addSimpleInsertion(
parameters.last.end,
@@ -63,6 +71,8 @@
}
}
+ var fieldParametersCode =
+ fields.map((field) => 'this.${field.name}').join(', ');
await builder.addDartFileEdit(file, (builder) {
if (lastRequiredParameter != null) {
builder.addSimpleInsertion(
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
index 2a5b705..a9b1c89 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
@@ -43,22 +43,30 @@
return;
}
- if (node is SimpleFormalParameter) {
+ final AstNode normalParameter;
+ if (node is DefaultFormalParameter) {
+ normalParameter = node.parameter;
+ } else {
+ normalParameter = node;
+ }
+
+ if (normalParameter is SimpleFormalParameter) {
+ final simpleNode = normalParameter;
await builder.addDartFileEdit(file, (builder) {
- final keyword = node.keyword;
+ final keyword = simpleNode.keyword;
if (keyword != null && keyword.keyword == Keyword.VAR) {
builder.addSimpleReplacement(range.token(keyword), 'final');
} else {
- final type = node.type;
+ final type = simpleNode.type;
if (type != null) {
builder.addSimpleInsertion(type.offset, 'final ');
return;
}
- final identifier = node.identifier;
+ final identifier = simpleNode.identifier;
if (identifier != null) {
builder.addSimpleInsertion(identifier.offset, 'final ');
} else {
- builder.addSimpleInsertion(node.offset, 'final ');
+ builder.addSimpleInsertion(simpleNode.offset, 'final ');
}
}
});
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 0186ba9..1b58a84 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -889,6 +889,9 @@
AddRequiredKeyword.newInstance,
MakeVariableNullable.newInstance,
],
+ CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION: [
+ AddRequiredKeyword.newInstance,
+ ],
CompileTimeErrorCode.MISSING_REQUIRED_ARGUMENT: [
AddMissingRequiredArgument.newInstance,
],
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index b73ad91..c7b86d9 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -1779,42 +1779,42 @@
addTestFile('class A {bool foo; A() : ^;}');
await getSuggestions();
assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
}
Future<void> test_constructor2() async {
addTestFile('class A {bool foo; A() : s^;}');
await getSuggestions();
assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
}
Future<void> test_constructor3() async {
addTestFile('class A {bool foo; A() : a=7,^;}');
await getSuggestions();
assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
}
Future<void> test_constructor4() async {
addTestFile('class A {bool foo; A() : a=7,s^;}');
await getSuggestions();
assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
}
Future<void> test_constructor5() async {
addTestFile('class A {bool foo; A() : a=7,s^}');
await getSuggestions();
assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
}
Future<void> test_constructor6() async {
addTestFile('class A {bool foo; A() : a=7,^ void bar() {}}');
await getSuggestions();
assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
}
Future<void> test_extension() async {
@@ -2228,7 +2228,7 @@
class A { var isVisible;}
void f(A p) { var v1 = p.is^; }''');
await getSuggestions();
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'isVisible');
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'isVisible');
}
Future<void> test_keyword() {
@@ -2311,7 +2311,7 @@
expect(replacementLength, equals(0));
// The class is suggested.
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'A');
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'A');
// Class and all its constructors are shadowed by the local variable.
assertNoResult('A', elementKind: ElementKind.CLASS);
@@ -2326,8 +2326,8 @@
expect(replacementLength, equals(0));
assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'A',
elementKind: ElementKind.CLASS);
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'a');
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'a');
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'b');
assertHasResult(CompletionSuggestionKind.INVOCATION, 'x');
assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'DateTime',
elementKind: ElementKind.CLASS);
@@ -2459,7 +2459,7 @@
expect(replacementLength, equals(4));
// Suggestions based upon imported elements are partially filtered
//assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'test');
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'test');
assertNoResult('HtmlElement');
});
}
@@ -2663,7 +2663,7 @@
}
void assertGetter() {
- expect(suggestion.kind, CompletionSuggestionKind.INVOCATION);
+ expect(suggestion.kind, CompletionSuggestionKind.IDENTIFIER);
expect(suggestion.element?.kind, ElementKind.GETTER);
}
@@ -2682,12 +2682,12 @@
}
void assertSetter() {
- expect(suggestion.kind, CompletionSuggestionKind.INVOCATION);
+ expect(suggestion.kind, CompletionSuggestionKind.IDENTIFIER);
expect(suggestion.element?.kind, ElementKind.SETTER);
}
void assertTopLevelVariable() {
- expect(suggestion.kind, CompletionSuggestionKind.INVOCATION);
+ expect(suggestion.kind, CompletionSuggestionKind.IDENTIFIER);
expect(suggestion.element?.kind, ElementKind.TOP_LEVEL_VARIABLE);
}
}
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index b8704aa..23a7a61 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1041,8 +1041,12 @@
/// requested maxResults.
Future<CompletionGetSuggestions2Result> sendCompletionGetSuggestions2(
String file, int offset, int maxResults,
- {int? timeout}) async {
+ {CompletionMode? completionMode,
+ int? invocationCount,
+ int? timeout}) async {
var params = CompletionGetSuggestions2Params(file, offset, maxResults,
+ completionMode: completionMode,
+ invocationCount: invocationCount,
timeout: timeout)
.toJson();
var result = await server.send('completion.getSuggestions2', params);
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index a7e358db..4f35ccd 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -235,6 +235,15 @@
/// String
final Matcher isCompletionId = isString;
+/// CompletionMode
+///
+/// enum {
+/// BASIC
+/// SMART
+/// }
+final Matcher isCompletionMode =
+ MatchesEnum('CompletionMode', ['BASIC', 'SMART']);
+
/// CompletionService
///
/// enum {
@@ -2138,9 +2147,15 @@
/// "maxResults": int
/// }
final Matcher isCompletionGetSuggestions2Params = LazyMatcher(() =>
- MatchesJsonObject('completion.getSuggestions2 params',
- {'file': isFilePath, 'offset': isInt, 'maxResults': isInt},
- optionalFields: {'timeout': isInt}));
+ MatchesJsonObject('completion.getSuggestions2 params', {
+ 'file': isFilePath,
+ 'offset': isInt,
+ 'maxResults': isInt
+ }, optionalFields: {
+ 'completionMode': isCompletionMode,
+ 'invocationCount': isInt,
+ 'timeout': isInt
+ }));
/// completion.getSuggestions2 result
///
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index 6c4801c..8128659 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -2,14 +2,11 @@
// 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:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/arglist_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_utilities/check/check.dart';
-import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'completion_check.dart';
@@ -49,21 +46,22 @@
}
''';
addTestSource(content);
- await computeSuggestions();
- expect(suggestions, hasLength(1));
- var suggestion = suggestions[0];
- expect(suggestion.docSummary, 'aaa');
- expect(suggestion.docComplete, 'aaa\n\nbbb\nccc');
-
- var element = suggestion.element!;
- expect(element.kind, ElementKind.PARAMETER);
- expect(element.name, 'fff');
- expect(element.location!.offset, content.indexOf('fff})'));
+ var response = await computeSuggestions2();
+ _checkNamedArguments(response).matchesInAnyOrder([
+ (suggestion) => suggestion
+ ..completion.isEqualTo('fff: ')
+ ..docComplete.isEqualTo('aaa\n\nbbb\nccc')
+ ..docSummary.isEqualTo('aaa')
+ ..hasSelection(offset: 5)
+ ..element.isNotNull.which((e) => e
+ ..isParameter
+ ..name.isEqualTo('fff'))
+ ]);
}
Future<void> test_fieldFormal_noDocumentation() async {
- var content = '''
+ addTestSource('''
class A {
int fff;
A({this.fff});
@@ -71,19 +69,19 @@
main() {
new A(^);
}
-''';
- addTestSource(content);
- await computeSuggestions();
- expect(suggestions, hasLength(1));
+''');
- var suggestion = suggestions[0];
- expect(suggestion.docSummary, isNull);
- expect(suggestion.docComplete, isNull);
-
- var element = suggestion.element!;
- expect(element.kind, ElementKind.PARAMETER);
- expect(element.name, 'fff');
- expect(element.location!.offset, content.indexOf('fff})'));
+ var response = await computeSuggestions2();
+ _checkNamedArguments(response).matchesInAnyOrder([
+ (suggestion) => suggestion
+ ..completion.isEqualTo('fff: ')
+ ..docComplete.isNull
+ ..docSummary.isNull
+ ..hasSelection(offset: 5)
+ ..element.isNotNull.which((e) => e
+ ..isParameter
+ ..name.isEqualTo('fff'))
+ ]);
}
Future<void> test_flutter_InstanceCreationExpression_0() async {
@@ -97,13 +95,13 @@
);
''');
- await computeSuggestions();
-
- assertSuggest('children: [],',
- csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
- defaultArgListString: null,
- selectionOffset: 11,
- defaultArgumentListTextRanges: null);
+ var response = await computeSuggestions2();
+ _checkNamedArguments(response).containsMatch((suggestion) {
+ suggestion
+ ..completion.isEqualTo('children: [],')
+ ..defaultArgumentListString.isNull
+ ..hasSelection(offset: 11);
+ });
}
Future<void> test_flutter_InstanceCreationExpression_01() async {
@@ -119,12 +117,13 @@
);
''');
- await computeSuggestions();
-
- assertSuggest('backgroundColor: ,',
- csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
- defaultArgListString: null, // No default values.
- selectionOffset: 17);
+ var response = await computeSuggestions2();
+ _checkNamedArguments(response).containsMatch((suggestion) {
+ suggestion
+ ..completion.isEqualTo('backgroundColor: ,')
+ ..defaultArgumentListString.isNull
+ ..hasSelection(offset: 17);
+ });
}
Future<void> test_flutter_InstanceCreationExpression_1() async {
@@ -139,13 +138,13 @@
);
''');
- await computeSuggestions();
-
- assertSuggest('children: [],',
- csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
- defaultArgListString: null,
- selectionOffset: 11,
- defaultArgumentListTextRanges: null);
+ var response = await computeSuggestions2();
+ _checkNamedArguments(response).containsMatch((suggestion) {
+ suggestion
+ ..completion.isEqualTo('children: [],')
+ ..defaultArgumentListString.isNull
+ ..hasSelection(offset: 11);
+ });
}
Future<void> test_flutter_InstanceCreationExpression_2() async {
@@ -160,13 +159,13 @@
);
''');
- await computeSuggestions();
-
- assertSuggest('children: [],',
- csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
- defaultArgListString: null,
- selectionOffset: 11,
- defaultArgumentListTextRanges: null);
+ var response = await computeSuggestions2();
+ _checkNamedArguments(response).containsMatch((suggestion) {
+ suggestion
+ ..completion.isEqualTo('children: [],')
+ ..defaultArgumentListString.isNull
+ ..hasSelection(offset: 11);
+ });
}
Future<void>
@@ -187,13 +186,13 @@
}
''');
- await computeSuggestions();
-
- assertSuggest('children: [],',
- csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
- defaultArgListString: null,
- selectionOffset: 11,
- defaultArgumentListTextRanges: null);
+ var response = await computeSuggestions2();
+ _checkNamedArguments(response).matchesInAnyOrder([
+ (suggestion) => suggestion
+ ..completion.isEqualTo('children: [],')
+ ..defaultArgumentListString.isNull
+ ..hasSelection(offset: 11),
+ ]);
}
Future<void> test_flutter_InstanceCreationExpression_children_Map() async {
@@ -212,12 +211,13 @@
}
''');
- await computeSuggestions();
-
- assertSuggest('children: ,',
- csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
- selectionOffset: 10,
- defaultArgListString: null);
+ var response = await computeSuggestions2();
+ _checkNamedArguments(response).matchesInAnyOrder([
+ (suggestion) => suggestion
+ ..completion.isEqualTo('children: ,')
+ ..defaultArgumentListString.isNull
+ ..hasSelection(offset: 10),
+ ]);
}
Future<void> test_flutter_InstanceCreationExpression_slivers() async {
@@ -235,13 +235,13 @@
}
''');
- await computeSuggestions();
-
- assertSuggest('slivers: [],',
- csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
- defaultArgListString: null,
- selectionOffset: 10,
- defaultArgumentListTextRanges: null);
+ var response = await computeSuggestions2();
+ _checkNamedArguments(response).matchesInAnyOrder([
+ (suggestion) => suggestion
+ ..completion.isEqualTo('slivers: [],')
+ ..defaultArgumentListString.isNull
+ ..hasSelection(offset: 10),
+ ]);
}
Future<void> test_flutter_MethodExpression_children() async {
@@ -261,11 +261,13 @@
foo({String children}) {}
''');
- await computeSuggestions();
-
- assertSuggest('children: ',
- csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
- defaultArgListString: null);
+ var response = await computeSuggestions2();
+ _checkNamedArguments(response).matchesInAnyOrder([
+ (suggestion) => suggestion
+ ..completion.isEqualTo('children: ')
+ ..defaultArgumentListString.isNull
+ ..defaultArgumentListTextRanges.isNull,
+ ]);
}
Future<void> test_named_01() async {
@@ -273,7 +275,7 @@
parameters: '({bool one, int two})',
arguments: '(^)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one: ')
..parameterType.isEqualTo('bool')
@@ -294,7 +296,7 @@
parameters: '({bool one, int two})',
arguments: '(o^)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one: ')
..parameterType.isEqualTo('bool')
@@ -315,7 +317,7 @@
parameters: '({bool one, int two})',
arguments: '(o^ two: 2)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one: ,')
..parameterType.isEqualTo('bool')
@@ -331,7 +333,7 @@
parameters: '({bool one, int two})',
arguments: '(o^, two: 2)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one: ')
..parameterType.isEqualTo('bool')
@@ -347,7 +349,7 @@
parameters: '({bool one, int two})',
arguments: '(o^ , two: 2)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one: ')
..parameterType.isEqualTo('bool')
@@ -363,7 +365,7 @@
parameters: '({bool one, int two})',
arguments: '(^o,)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one: ')
..parameterType.isEqualTo('bool')
@@ -384,7 +386,7 @@
parameters: '({bool one, int two})',
arguments: '(^ two: 2)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one: ,')
..parameterType.isEqualTo('bool')
@@ -400,7 +402,7 @@
parameters: '({bool one, int two})',
arguments: '(^two: 2)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one: ,')
..parameterType.isEqualTo('bool')
@@ -416,7 +418,7 @@
parameters: '({bool one, int two})',
arguments: '(^, two: 2)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one: ')
..parameterType.isEqualTo('bool')
@@ -432,7 +434,7 @@
parameters: '({bool one, int two})',
arguments: '(^ , two: 2)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one: ')
..parameterType.isEqualTo('bool')
@@ -448,7 +450,7 @@
parameters: '(int one, {bool two, int three})',
arguments: '(1, ^, three: 3)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('two: ')
..parameterType.isEqualTo('bool')
@@ -464,7 +466,7 @@
parameters: '(int one, {bool two, int three})',
arguments: '(1, ^ three: 3)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('two: ,')
..parameterType.isEqualTo('bool')
@@ -480,7 +482,7 @@
parameters: '(int one, {bool two, int three})',
arguments: '(1, ^three: 3)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('two: ,')
..parameterType.isEqualTo('bool')
@@ -497,7 +499,7 @@
parameters: '({bool one, int two})',
arguments: '(two: 2^)',
check: (response) {
- check(response).suggestions.namedArguments.isEmpty;
+ _checkNamedArguments(response).isEmpty;
},
);
}
@@ -508,7 +510,7 @@
parameters: '({bool one, int two})',
arguments: '(two: 2 ^)',
check: (response) {
- check(response).suggestions.namedArguments.isEmpty;
+ _checkNamedArguments(response).isEmpty;
},
);
}
@@ -518,7 +520,7 @@
parameters: '({bool one, int two})',
arguments: '(two: 2, ^)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one: ')
..parameterType.isEqualTo('bool')
@@ -534,7 +536,7 @@
parameters: '({bool one, int two})',
arguments: '(two: 2, o^)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one: ')
..parameterType.isEqualTo('bool')
@@ -550,7 +552,7 @@
parameters: '({bool one, int two})',
arguments: '(two: 2, o^,)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one: ')
..parameterType.isEqualTo('bool')
@@ -566,7 +568,7 @@
parameters: '(int one, int two, int three, {int four, int five})',
arguments: '(1, ^, 3)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('four: ')
..parameterType.isEqualTo('int')
@@ -588,7 +590,7 @@
parameters: '(int one, int two, int three, {int four, int five})',
arguments: '(1, ^, 3)',
check: (response) {
- check(response).suggestions.namedArguments.isEmpty;
+ _checkNamedArguments(response).isEmpty;
},
);
}
@@ -598,7 +600,7 @@
parameters: '({bool one, int two})',
arguments: '(o^: false)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('one')
..parameterType.isEqualTo('bool')
@@ -619,7 +621,7 @@
parameters: '(bool one, {int two, double three})',
arguments: '(false, ^t: 2)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('two: ,')
..parameterType.isEqualTo('int')
@@ -640,7 +642,7 @@
parameters: '(bool one, {int two})',
arguments: '(false, foo^ba: 2)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
..completion.isEqualTo('two')
..parameterType.isEqualTo('int')
@@ -656,7 +658,7 @@
parameters: '(bool one, {int two, double three})',
arguments: '(false, ^: 2)',
check: (response) {
- check(response).suggestions.namedArguments.matchesInAnyOrder([
+ _checkNamedArguments(response).matchesInAnyOrder([
(suggestion) => suggestion
// TODO(scheglov) This does not seem right.
..completion.isEqualTo('two: ')
@@ -679,7 +681,7 @@
parameters: '({bool one, int two})',
arguments: '(one: ^)',
check: (response) {
- check(response).suggestions.namedArguments.isEmpty;
+ _checkNamedArguments(response).isEmpty;
},
);
}
@@ -695,15 +697,8 @@
: '// no language version override';
Future<void> computeAndCheck() async {
- await computeSuggestions();
- check(
- CompletionResponseForTesting(
- requestOffset: completionOffset,
- replacementOffset: replacementOffset,
- replacementLength: replacementLength,
- suggestions: suggestions,
- ),
- );
+ var response = await computeSuggestions2();
+ check(response);
}
// Annotation, local class.
@@ -851,4 +846,9 @@
await computeSuggestions();
assertNoSuggestions();
}
+
+ static CheckTarget<Iterable<CompletionSuggestionForTesting>>
+ _checkNamedArguments(CompletionResponseForTesting response) {
+ return check(response).suggestions.namedArguments;
+ }
}
diff --git a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
index a04f0be..3b1df62 100644
--- a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
@@ -63,8 +63,7 @@
assertSuggestClass('A', kind: CompletionSuggestionKind.IDENTIFIER);
assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
assertSuggestClass('PB', kind: CompletionSuggestionKind.IDENTIFIER);
- assertSuggestTopLevelVar('T1', null,
- kind: CompletionSuggestionKind.IDENTIFIER);
+ assertSuggestTopLevelVar('T1', null);
assertSuggestFunction('F1', 'PB',
kind: CompletionSuggestionKind.IDENTIFIER);
assertNotSuggested('C');
@@ -107,8 +106,7 @@
assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
assertNotSuggested('_AB');
assertSuggestClass('PB', kind: CompletionSuggestionKind.IDENTIFIER);
- assertSuggestTopLevelVar('T1', null,
- kind: CompletionSuggestionKind.IDENTIFIER);
+ assertSuggestTopLevelVar('T1', null);
assertSuggestFunction('F1', 'PB',
kind: CompletionSuggestionKind.IDENTIFIER);
assertSuggestClass('Clz', kind: CompletionSuggestionKind.IDENTIFIER);
@@ -147,8 +145,7 @@
Future<void> test_Combinator_show_pi() async {
addTestSource('import "dart:math" show ^;');
await computeSuggestions();
- assertSuggestTopLevelVar('pi', 'double',
- kind: CompletionSuggestionKind.IDENTIFIER);
+ assertSuggestTopLevelVar('pi', 'double');
}
Future<void> test_Combinator_show_recursive() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_check.dart b/pkg/analysis_server/test/services/completion/dart/completion_check.dart
index 669cf76..f9cdaf1 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_check.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_check.dart
@@ -56,10 +56,12 @@
extension CompletionResponseExtension
on CheckTarget<CompletionResponseForTesting> {
CheckTarget<List<CompletionSuggestionForTesting>> get suggestions {
- var suggestions = value.suggestions
- .map((e) =>
- CompletionSuggestionForTesting(response: value, suggestion: e))
- .toList();
+ var suggestions = value.suggestions.map((e) {
+ return CompletionSuggestionForTesting(
+ response: value,
+ suggestion: e,
+ );
+ }).toList();
return nest(
suggestions,
(selected) => 'suggestions ${valueStr(selected)}',
@@ -76,6 +78,41 @@
);
}
+ CheckTarget<String?> get defaultArgumentListString {
+ return nest(
+ value.suggestion.defaultArgumentListString,
+ (selected) => 'has defaultArgumentListString ${valueStr(selected)}',
+ );
+ }
+
+ CheckTarget<List<int>?> get defaultArgumentListTextRanges {
+ return nest(
+ value.suggestion.defaultArgumentListTextRanges,
+ (selected) => 'has defaultArgumentListTextRanges ${valueStr(selected)}',
+ );
+ }
+
+ CheckTarget<String?> get docComplete {
+ return nest(
+ value.suggestion.docComplete,
+ (selected) => 'has docComplete ${valueStr(selected)}',
+ );
+ }
+
+ CheckTarget<String?> get docSummary {
+ return nest(
+ value.suggestion.docSummary,
+ (selected) => 'has docSummary ${valueStr(selected)}',
+ );
+ }
+
+ CheckTarget<Element?> get element {
+ return nest(
+ value.suggestion.element,
+ (selected) => 'has element ${valueStr(selected)}',
+ );
+ }
+
CheckTarget<String?> get parameterType {
return nest(
value.suggestion.parameterType,
@@ -146,3 +183,23 @@
);
}
}
+
+extension ElementExtension on CheckTarget<Element> {
+ void get isParameter {
+ kind.isEqualTo(ElementKind.PARAMETER);
+ }
+
+ CheckTarget<ElementKind> get kind {
+ return nest(
+ value.kind,
+ (selected) => 'has kind ${valueStr(selected)}',
+ );
+ }
+
+ CheckTarget<String> get name {
+ return nest(
+ value.name,
+ (selected) => 'has name ${valueStr(selected)}',
+ );
+ }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index 7b202bf..a750956 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -17,6 +17,7 @@
import 'package:test/test.dart';
import '../../../abstract_context.dart';
+import 'completion_check.dart';
SuggestionMatcher suggestionHas(
{required String completion,
@@ -267,7 +268,7 @@
}
CompletionSuggestion assertSuggestClassTypeAlias(String name,
- {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
+ {CompletionSuggestionKind kind = CompletionSuggestionKind.IDENTIFIER}) {
var cs = assertSuggest(name, csKind: kind);
var element = cs.element!;
expect(element.kind, equals(ElementKind.CLASS_TYPE_ALIAS));
@@ -309,7 +310,11 @@
CompletionSuggestion assertSuggestEnumConst(String completion,
{bool isDeprecated = false}) {
- var suggestion = assertSuggest(completion, isDeprecated: isDeprecated);
+ var suggestion = assertSuggest(
+ completion,
+ csKind: CompletionSuggestionKind.IDENTIFIER,
+ isDeprecated: isDeprecated,
+ );
expect(suggestion.completion, completion);
expect(suggestion.isDeprecated, isDeprecated);
expect(suggestion.element!.kind, ElementKind.ENUM_CONSTANT);
@@ -317,10 +322,11 @@
}
CompletionSuggestion assertSuggestField(String name, String? type,
- {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
- bool isDeprecated = false}) {
+ {bool isDeprecated = false}) {
var cs = assertSuggest(name,
- csKind: kind, elemKind: ElementKind.FIELD, isDeprecated: isDeprecated);
+ csKind: CompletionSuggestionKind.IDENTIFIER,
+ elemKind: ElementKind.FIELD,
+ isDeprecated: isDeprecated);
// The returnType represents the type of a field
expect(cs.returnType, type ?? 'dynamic');
var element = cs.element!;
@@ -365,10 +371,13 @@
}
CompletionSuggestion assertSuggestGetter(String name, String? returnType,
- {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
- bool isDeprecated = false}) {
- var cs = assertSuggest(name,
- csKind: kind, elemKind: ElementKind.GETTER, isDeprecated: isDeprecated);
+ {bool isDeprecated = false}) {
+ var cs = assertSuggest(
+ name,
+ csKind: CompletionSuggestionKind.IDENTIFIER,
+ elemKind: ElementKind.GETTER,
+ isDeprecated: isDeprecated,
+ );
expect(cs.returnType, returnType ?? 'dynamic');
var element = cs.element!;
expect(element.kind, equals(ElementKind.GETTER));
@@ -382,7 +391,7 @@
CompletionSuggestion assertSuggestLocalVariable(
String name, String? returnType) {
// Local variables should only be suggested by LocalReferenceContributor
- var cs = assertSuggest(name, csKind: CompletionSuggestionKind.INVOCATION);
+ var cs = assertSuggest(name, csKind: CompletionSuggestionKind.IDENTIFIER);
expect(cs.returnType, returnType ?? 'dynamic');
var element = cs.element!;
expect(element.kind, equals(ElementKind.LOCAL_VARIABLE));
@@ -451,7 +460,7 @@
}
CompletionSuggestion assertSuggestParameter(String name, String? returnType) {
- var cs = assertSuggest(name, csKind: CompletionSuggestionKind.INVOCATION);
+ var cs = assertSuggest(name, csKind: CompletionSuggestionKind.IDENTIFIER);
expect(cs.returnType, returnType ?? 'dynamic');
var element = cs.element!;
expect(element.kind, equals(ElementKind.PARAMETER));
@@ -461,9 +470,12 @@
return cs;
}
- CompletionSuggestion assertSuggestSetter(String name,
- {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
- var cs = assertSuggest(name, csKind: kind, elemKind: ElementKind.SETTER);
+ CompletionSuggestion assertSuggestSetter(String name) {
+ var cs = assertSuggest(
+ name,
+ csKind: CompletionSuggestionKind.IDENTIFIER,
+ elemKind: ElementKind.SETTER,
+ );
var element = cs.element!;
expect(element.kind, equals(ElementKind.SETTER));
expect(element.name, equals(name));
@@ -478,11 +490,8 @@
}
CompletionSuggestion assertSuggestTopLevelVar(
- String name,
- String? returnType, {
- CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
- }) {
- var cs = assertSuggest(name, csKind: kind);
+ String name, String? returnType) {
+ var cs = assertSuggest(name, csKind: CompletionSuggestionKind.IDENTIFIER);
if (returnType != null) {
expect(cs.returnType, returnType);
} else if (isNullExpectedReturnTypeConsideredDynamic) {
@@ -506,7 +515,7 @@
String? aliasedType,
String? returnType,
bool isDeprecated = false,
- CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
+ CompletionSuggestionKind kind = CompletionSuggestionKind.IDENTIFIER,
}) {
var cs = assertSuggest(name, csKind: kind, isDeprecated: isDeprecated);
if (returnType != null) {
@@ -567,6 +576,16 @@
expect(suggestions, isNotNull, reason: 'expected suggestions');
}
+ Future<CompletionResponseForTesting> computeSuggestions2() async {
+ await computeSuggestions();
+ return CompletionResponseForTesting(
+ requestOffset: completionOffset,
+ replacementOffset: replacementOffset,
+ replacementLength: replacementLength,
+ suggestions: suggestions,
+ );
+ }
+
Never failedCompletion(String message,
[Iterable<CompletionSuggestion>? completions]) {
var sb = StringBuffer(message);
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index 1378b11..1e716a2 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -1307,12 +1307,12 @@
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertSuggest('e1', elemKind: ElementKind.FIELD);
- assertSuggest('f1', elemKind: ElementKind.FIELD);
- assertSuggest('i1', elemKind: ElementKind.FIELD);
- assertSuggest('m1', elemKind: ElementKind.FIELD);
- assertSuggest('f3', elemKind: ElementKind.GETTER);
- assertSuggest('f4', elemKind: ElementKind.SETTER);
+ assertSuggestField('e1', null);
+ assertSuggestField('f1', null);
+ assertSuggestField('i1', 'int');
+ assertSuggestField('m1', null);
+ assertSuggestGetter('f3', null);
+ assertSuggestSetter('f4');
assertSuggest('e2', elemKind: ElementKind.METHOD);
assertSuggest('f2', elemKind: ElementKind.METHOD);
assertSuggest('i2', elemKind: ElementKind.METHOD);
@@ -1386,12 +1386,12 @@
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertSuggest('e1', elemKind: ElementKind.FIELD);
- assertSuggest('f1', elemKind: ElementKind.FIELD);
- assertSuggest('i1', elemKind: ElementKind.FIELD);
- assertSuggest('m1', elemKind: ElementKind.FIELD);
- assertSuggest('f3', elemKind: ElementKind.GETTER);
- assertSuggest('f4', elemKind: ElementKind.SETTER);
+ assertSuggestField('e1', null);
+ assertSuggestField('f1', null);
+ assertSuggestField('i1', 'int');
+ assertSuggestField('m1', null);
+ assertSuggestGetter('f3', null);
+ assertSuggestSetter('f4');
assertSuggest('e2', elemKind: ElementKind.METHOD);
assertSuggest('f2', elemKind: ElementKind.METHOD);
assertSuggest('i2', elemKind: ElementKind.METHOD);
@@ -2446,7 +2446,7 @@
''');
await computeSuggestions();
- assertSuggest('E', elemKind: ElementKind.LOCAL_VARIABLE);
+ assertSuggestLocalVariable('E', 'int');
// Enum and all its constants are shadowed by the local variable.
assertNotSuggested('E', elemKind: ElementKind.ENUM);
@@ -2706,7 +2706,7 @@
await computeSuggestions();
assertNotSuggested('E', elemKind: ElementKind.EXTENSION);
- assertSuggest('E', elemKind: ElementKind.LOCAL_VARIABLE);
+ assertSuggestLocalVariable('E', 'int');
}
Future<void> test_ExtensionDeclaration_unnamed() async {
@@ -2758,7 +2758,7 @@
await computeSuggestions();
assertNotSuggested('foo', elemKind: ElementKind.FIELD);
- assertSuggest('foo', elemKind: ElementKind.LOCAL_VARIABLE);
+ assertSuggestLocalVariable('foo', 'int');
}
Future<void> test_FieldFormalParameter_in_non_constructor() async {
@@ -3335,7 +3335,7 @@
await computeSuggestions();
assertNotSuggested('bar', elemKind: ElementKind.FUNCTION);
- assertSuggest('bar', elemKind: ElementKind.LOCAL_VARIABLE);
+ assertSuggestLocalVariable('bar', 'int');
}
Future<void> test_functionDeclaration_typeParameterBounds() async {
@@ -4196,7 +4196,7 @@
''');
await computeSuggestions();
- assertSuggest('A');
+ assertSuggestLocalVariable('A', 'int');
// Class and all its constructors are shadowed by the local variable.
assertNotSuggested('A', elemKind: ElementKind.CLASS);
@@ -4919,7 +4919,7 @@
await computeSuggestions();
assertNotSuggested('foo', elemKind: ElementKind.METHOD);
- assertSuggest('foo', elemKind: ElementKind.LOCAL_VARIABLE);
+ assertSuggestLocalVariable('foo', 'dynamic');
}
Future<void> test_MethodDeclaration_shadowed2() async {
@@ -4940,7 +4940,7 @@
await computeSuggestions();
assertNotSuggested('foo', elemKind: ElementKind.METHOD);
- assertSuggest('foo', elemKind: ElementKind.LOCAL_VARIABLE);
+ assertSuggestLocalVariable('foo', 'dynamic');
}
Future<void> test_methodDeclaration_typeParameterBounds() async {
@@ -5099,7 +5099,7 @@
await computeSuggestions();
assertNotSuggested('foo', elemKind: ElementKind.MIXIN);
- assertSuggest('foo', elemKind: ElementKind.LOCAL_VARIABLE);
+ assertSuggestLocalVariable('foo', 'int');
}
Future<void> test_new_instance() async {
@@ -5248,7 +5248,7 @@
await computeSuggestions();
assertNotSuggested('bar', elemKind: ElementKind.PARAMETER);
- assertSuggest('bar', elemKind: ElementKind.LOCAL_VARIABLE);
+ assertSuggestLocalVariable('bar', 'int');
}
Future<void> test_PrefixedIdentifier_class_const() async {
@@ -6049,7 +6049,7 @@
await computeSuggestions();
assertNotSuggested('foo', elemKind: ElementKind.TOP_LEVEL_VARIABLE);
- assertSuggest('foo', elemKind: ElementKind.LOCAL_VARIABLE);
+ assertSuggestLocalVariable('foo', 'dynamic');
}
Future<void> test_TopLevelVariableDeclaration_typed_name() async {
@@ -6192,7 +6192,7 @@
''');
await computeSuggestions();
assertNotSuggested('T', elemKind: ElementKind.TYPE_PARAMETER);
- assertSuggest('T', elemKind: ElementKind.LOCAL_VARIABLE);
+ assertSuggestLocalVariable('T', 'int');
}
Future<void> test_VariableDeclaration_name() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
index 039c915..13a02b0 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
@@ -54,7 +54,7 @@
var bLocalVar = suggestionWith(
completion: 'b',
element: ElementKind.LOCAL_VARIABLE,
- kind: CompletionSuggestionKind.INVOCATION);
+ kind: CompletionSuggestionKind.IDENTIFIER);
assertOrder([bLocalVar, trueSuggestion, falseSuggestion]);
}
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart
index c1481fb..8fe61ae 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart
@@ -29,15 +29,15 @@
suggestionWith(
completion: 'c',
element: ElementKind.LOCAL_VARIABLE,
- kind: CompletionSuggestionKind.INVOCATION),
+ kind: CompletionSuggestionKind.IDENTIFIER),
suggestionWith(
completion: 'b',
element: ElementKind.LOCAL_VARIABLE,
- kind: CompletionSuggestionKind.INVOCATION),
+ kind: CompletionSuggestionKind.IDENTIFIER),
suggestionWith(
completion: 'a',
element: ElementKind.LOCAL_VARIABLE,
- kind: CompletionSuggestionKind.INVOCATION),
+ kind: CompletionSuggestionKind.IDENTIFIER),
]);
}
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_field_formal_parameters_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_field_formal_parameters_test.dart
index e9c868c..e4c955c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_field_formal_parameters_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_field_formal_parameters_test.dart
@@ -19,7 +19,7 @@
@override
FixKind get kind => DartFixKind.ADD_FIELD_FORMAL_PARAMETERS;
- Future<void> test_flutter() async {
+ Future<void> test_flutter_nullable() async {
writeTestPackageConfig(
flutter: true,
);
@@ -30,22 +30,53 @@
class MyWidget extends StatelessWidget {
final int a;
final int b;
- final int c;
+ final int? c;
+ final int d;
MyWidget({required Key key, required this.a}) : super(key: key);
}
''');
- // TODO(brianwilkerson) The result should include `required` for the new
- // parameters, but I'm omitting them to match the current behavior.
await assertHasFix('''
import 'package:flutter/widgets.dart';
class MyWidget extends StatelessWidget {
final int a;
final int b;
- final int c;
+ final int? c;
+ final int d;
- MyWidget({required Key key, required this.a, this.b, this.c}) : super(key: key);
+ MyWidget({required Key key, required this.a, required this.b, this.c, required this.d}) : super(key: key);
+}
+''');
+ }
+
+ Future<void> test_flutter_potentiallyNullable() async {
+ writeTestPackageConfig(
+ flutter: true,
+ );
+
+ await resolveTestCode('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget<T> extends StatelessWidget {
+ final int a;
+ final int b;
+ final T c;
+ final int d;
+
+ MyWidget({required Key key, required this.a}) : super(key: key);
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget<T> extends StatelessWidget {
+ final int a;
+ final int b;
+ final T c;
+ final int d;
+
+ MyWidget({required Key key, required this.a, required this.b, required this.c, required this.d}) : super(key: key);
}
''');
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_enum_like_case_clauses_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_enum_like_case_clauses_test.dart
index 87b75db..67f4e6c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_missing_enum_like_case_clauses_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_enum_like_case_clauses_test.dart
@@ -51,7 +51,8 @@
static const E a = E._(0);
static const E b = E._(1);
static const E c = E._(2);
- const E._(int x);
+ final int x;
+ const E._(this.x);
}
''');
await assertHasFixWithFilter('''
@@ -72,7 +73,8 @@
static const E a = E._(0);
static const E b = E._(1);
static const E c = E._(2);
- const E._(int x);
+ final int x;
+ const E._(this.x);
}
''');
}
@@ -86,7 +88,8 @@
static const E a = E._(0);
static const E b = E._(1);
static const E c = E._(2);
- const E._(int x);
+ final int x;
+ const E._(this.x);
}
''');
await assertHasFixWithFilter('''
@@ -107,7 +110,8 @@
static const E a = E._(0);
static const E b = E._(1);
static const E c = E._(2);
- const E._(int x);
+ final int x;
+ const E._(this.x);
}
''');
}
@@ -126,7 +130,8 @@
static const E a = E._(0);
static const E b = E._(1);
static const E c = E._(2);
- const E._(int x);
+ final int x;
+ const E._(this.x);
}
''');
await assertHasFix('''
@@ -145,7 +150,8 @@
static const E a = E._(0);
static const E b = E._(1);
static const E c = E._(2);
- const E._(int x);
+ final int x;
+ const E._(this.x);
}
''');
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart b/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart
index d7771af..16718c3 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart
@@ -304,6 +304,19 @@
''');
}
+ Future<void> test_named_optional_withDefault() async {
+ await resolveTestCode('''
+void fn({String test = 'value'}) {
+ print(test);
+}
+''');
+ await assertHasFix('''
+void fn({final String test = 'value'}) {
+ print(test);
+}
+''');
+ }
+
Future<void> test_named_required() async {
await resolveTestCode('''
void fn({required String test}) {
@@ -330,6 +343,19 @@
''');
}
+ Future<void> test_positional_optional_withDefault() async {
+ await resolveTestCode('''
+void fn([String? test = 'value']) {
+ print(test);
+}
+''');
+ await assertHasFix('''
+void fn([final String? test = 'value']) {
+ print(test);
+}
+''');
+ }
+
Future<void> test_simple_hasType() async {
await resolveTestCode('''
void fn(String test) {
@@ -356,6 +382,19 @@
''');
}
+ Future<void> test_simple_nullable() async {
+ await resolveTestCode('''
+void fn(String? test) {
+ print(test);
+}
+''');
+ await assertHasFix('''
+void fn(final String? test) {
+ print(test);
+}
+''');
+ }
+
Future<void> test_simple_second() async {
await resolveTestCode('''
void fn(final String test, String other) {
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index c5022ea..c5a5ed2 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -441,12 +441,16 @@
* @param offset The offset within the file at which suggestions are to be made.
* @param maxResults The maximum number of suggestions to return. If the number of suggestions
* after filtering is greater than the maxResults, then isIncomplete is set to true.
+ * @param completionMode The mode of code completion being invoked. If no value is provided, BASIC
+ * will be assumed. BASIC is also the only currently supported.
+ * @param invocationCount The number of times that the user has invoked code completion at the same
+ * code location, counting from 1. If no value is provided, 1 will be assumed.
* @param timeout The approximate time in milliseconds that the server should spend. The server
* will perform some steps anyway, even if it takes longer than the specified timeout. This
* field is intended to be used for benchmarking, and usually should not be provided, so
* that the default timeout is used.
*/
- public void completion_getSuggestions2(String file, int offset, int maxResults, int timeout, GetSuggestions2Consumer consumer);
+ public void completion_getSuggestions2(String file, int offset, int maxResults, String completionMode, int invocationCount, int timeout, GetSuggestions2Consumer consumer);
/**
* {@code completion.registerLibraryPaths}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionMode.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionMode.java
new file mode 100644
index 0000000..89f11dd
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionMode.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019, 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.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+/**
+ * An enumeration of the kinds of code completion that users can invoke.
+ *
+ * @coverage dart.server.generated.types
+ */
+public class CompletionMode {
+
+ /**
+ * Basic code completion invocation type, and the default for this enumeration.
+ */
+ public static final String BASIC = "BASIC";
+
+ /**
+ * Smart code completion, currently not implemented.
+ */
+ public static final String SMART = "SMART";
+
+}
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index c634b46..76d97d58 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -1507,6 +1507,22 @@
then <tt>isIncomplete</tt> is set to <tt>true</tt>.
</p>
</field>
+ <field name="completionMode" experimental="true" optional="true">
+ <ref>CompletionMode</ref>
+ <p>
+ The mode of code completion being invoked. If no value is provided,
+ <tt>BASIC</tt> will be assumed. <tt>BASIC</tt> is also the only
+ currently supported.
+ </p>
+ </field>
+ <field name="invocationCount" experimental="true" optional="true">
+ <ref>int</ref>
+ <p>
+ The number of times that the user has invoked code completion at
+ the same code location, counting from 1. If no value is provided,
+ 1 will be assumed.
+ </p>
+ </field>
<field name="timeout" experimental="true" optional="true">
<ref>int</ref>
<p>
@@ -4128,6 +4144,26 @@
</field>
</object>
</type>
+ <type name="CompletionMode">
+ <p>
+ An enumeration of the kinds of code completion that users can invoke.
+ </p>
+ <enum>
+ <value>
+ <code>BASIC</code>
+ <p>
+ Basic code completion invocation type, and the default for this
+ enumeration.
+ </p>
+ </value>
+ <value>
+ <code>SMART</code>
+ <p>
+ Smart code completion, currently not implemented.
+ </p>
+ </value>
+ </enum>
+ </type>
<type name="RuntimeCompletionExpression">
<p>
An expression for which we want to know its runtime type.
diff --git a/pkg/analysis_server_client/lib/server.dart b/pkg/analysis_server_client/lib/server.dart
index 3d9dbb4..169d25b 100644
--- a/pkg/analysis_server_client/lib/server.dart
+++ b/pkg/analysis_server_client/lib/server.dart
@@ -99,11 +99,12 @@
bool suppressAnalytics = true,
bool useAnalysisHighlight2 = false,
bool enableAsserts = false,
+ String? dartBinary,
}) async {
if (_process != null) {
throw Exception('Process already started');
}
- var dartBinary = Platform.executable;
+ dartBinary ??= Platform.executable;
// The integration tests run 3x faster when run from snapshots
// (you need to run test.py with --use-sdk).
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
index 00b690a..ad20782 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -138,7 +138,11 @@
const String COMPLETION_NOTIFICATION_RESULTS_RESULTS = 'results';
const String COMPLETION_REQUEST_GET_SUGGESTIONS = 'completion.getSuggestions';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2 = 'completion.getSuggestions2';
+const String COMPLETION_REQUEST_GET_SUGGESTIONS2_COMPLETION_MODE =
+ 'completionMode';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2_FILE = 'file';
+const String COMPLETION_REQUEST_GET_SUGGESTIONS2_INVOCATION_COUNT =
+ 'invocationCount';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2_MAX_RESULTS = 'maxResults';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2_OFFSET = 'offset';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2_TIMEOUT = 'timeout';
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
index c375b0c..d24faa1 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -4698,6 +4698,15 @@
/// to true.
int maxResults;
+ /// The mode of code completion being invoked. If no value is provided, BASIC
+ /// will be assumed. BASIC is also the only currently supported.
+ CompletionMode? completionMode;
+
+ /// The number of times that the user has invoked code completion at the same
+ /// code location, counting from 1. If no value is provided, 1 will be
+ /// assumed.
+ int? invocationCount;
+
/// The approximate time in milliseconds that the server should spend. The
/// server will perform some steps anyway, even if it takes longer than the
/// specified timeout. This field is intended to be used for benchmarking,
@@ -4705,7 +4714,7 @@
int? timeout;
CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults,
- {this.timeout});
+ {this.completionMode, this.invocationCount, this.timeout});
factory CompletionGetSuggestions2Params.fromJson(
JsonDecoder jsonDecoder, String jsonPath, Object? json) {
@@ -4730,11 +4739,23 @@
} else {
throw jsonDecoder.mismatch(jsonPath, 'maxResults');
}
+ CompletionMode? completionMode;
+ if (json.containsKey('completionMode')) {
+ completionMode = CompletionMode.fromJson(
+ jsonDecoder, jsonPath + '.completionMode', json['completionMode']);
+ }
+ int? invocationCount;
+ if (json.containsKey('invocationCount')) {
+ invocationCount = jsonDecoder.decodeInt(
+ jsonPath + '.invocationCount', json['invocationCount']);
+ }
int? timeout;
if (json.containsKey('timeout')) {
timeout = jsonDecoder.decodeInt(jsonPath + '.timeout', json['timeout']);
}
return CompletionGetSuggestions2Params(file, offset, maxResults,
+ completionMode: completionMode,
+ invocationCount: invocationCount,
timeout: timeout);
} else {
throw jsonDecoder.mismatch(
@@ -4753,6 +4774,14 @@
result['file'] = file;
result['offset'] = offset;
result['maxResults'] = maxResults;
+ var completionMode = this.completionMode;
+ if (completionMode != null) {
+ result['completionMode'] = completionMode.toJson();
+ }
+ var invocationCount = this.invocationCount;
+ if (invocationCount != null) {
+ result['invocationCount'] = invocationCount;
+ }
var timeout = this.timeout;
if (timeout != null) {
result['timeout'] = timeout;
@@ -4774,6 +4803,8 @@
return file == other.file &&
offset == other.offset &&
maxResults == other.maxResults &&
+ completionMode == other.completionMode &&
+ invocationCount == other.invocationCount &&
timeout == other.timeout;
}
return false;
@@ -4784,6 +4815,8 @@
file,
offset,
maxResults,
+ completionMode,
+ invocationCount,
timeout,
);
}
@@ -5090,6 +5123,58 @@
int get hashCode => id.hashCode;
}
+/// CompletionMode
+///
+/// enum {
+/// BASIC
+/// SMART
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class CompletionMode implements Enum {
+ /// Basic code completion invocation type, and the default for this
+ /// enumeration.
+ static const CompletionMode BASIC = CompletionMode._('BASIC');
+
+ /// Smart code completion, currently not implemented.
+ static const CompletionMode SMART = CompletionMode._('SMART');
+
+ /// A list containing all of the enum values that are defined.
+ static const List<CompletionMode> VALUES = <CompletionMode>[BASIC, SMART];
+
+ @override
+ final String name;
+
+ const CompletionMode._(this.name);
+
+ factory CompletionMode(String name) {
+ switch (name) {
+ case 'BASIC':
+ return BASIC;
+ case 'SMART':
+ return SMART;
+ }
+ throw Exception('Illegal enum value: $name');
+ }
+
+ factory CompletionMode.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object? json) {
+ if (json is String) {
+ try {
+ return CompletionMode(json);
+ } catch (_) {
+ // Fall through
+ }
+ }
+ throw jsonDecoder.mismatch(jsonPath, 'CompletionMode', json);
+ }
+
+ @override
+ String toString() => 'CompletionMode.$name';
+
+ String toJson() => name;
+}
+
/// completion.registerLibraryPaths params
///
/// {
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 61dc1e9..441903a 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -216,6 +216,10 @@
CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
CompileTimeErrorCode.IMPLEMENTS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
+ CompileTimeErrorCode
+ .IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_MISSING_REQUIRED_ARGUMENT,
+ CompileTimeErrorCode
+ .IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_NOT_ENOUGH_POSITIONAL_ARGUMENTS,
CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY,
CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY,
CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES,
@@ -282,12 +286,12 @@
CompileTimeErrorCode.MISSING_CONST_IN_SET_LITERAL,
CompileTimeErrorCode.MISSING_DART_LIBRARY,
CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER,
+ CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION,
CompileTimeErrorCode.MISSING_REQUIRED_ARGUMENT,
CompileTimeErrorCode.MIXIN_APPLICATION_CONCRETE_SUPER_INVOKED_MEMBER_TYPE,
CompileTimeErrorCode.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR,
- CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR,
CompileTimeErrorCode.MIXIN_DEFERRED_CLASS,
CompileTimeErrorCode.MIXIN_INFERENCE_INCONSISTENT_MATCHING_CLASSES,
CompileTimeErrorCode.MIXIN_INFERENCE_NO_MATCHING_CLASS,
@@ -404,6 +408,7 @@
CompileTimeErrorCode.SHARED_DEFERRED_PREFIX,
CompileTimeErrorCode.SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
CompileTimeErrorCode.STATIC_ACCESS_TO_INSTANCE_MEMBER,
+ CompileTimeErrorCode.SUPER_FORMAL_PARAMETER_TYPE_IS_NOT_SUBTYPE_OF_ASSOCIATED,
CompileTimeErrorCode.SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_NAMED,
CompileTimeErrorCode.SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_POSITIONAL,
CompileTimeErrorCode.SUPER_IN_EXTENSION,
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 598631f..ebc5b48 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -1328,17 +1328,15 @@
var unitElement = libraryContext.computeUnitElement(library, file)
as CompilationUnitElementImpl;
- var analyzer = LibraryAnalyzer(
- analysisOptions as AnalysisOptionsImpl,
- declaredVariables,
- sourceFactory,
- libraryContext.analysisContext,
- libraryContext.elementFactory.libraryOfUri2(library.uriStr),
- libraryContext.analysisSession.inheritanceManager,
- library,
- testingData: testingData);
-
- var analysisResult = analyzer.analyzeForCompletion(
+ var analysisResult = LibraryAnalyzer(
+ analysisOptions as AnalysisOptionsImpl,
+ declaredVariables,
+ sourceFactory,
+ libraryContext.elementFactory.libraryOfUri2(library.uriStr),
+ libraryContext.analysisSession.inheritanceManager,
+ library,
+ testingData: testingData,
+ ).analyzeForCompletion(
file: file,
offset: offset,
unitElement: unitElement,
@@ -1443,27 +1441,26 @@
libraryContext.load2(library!);
- LibraryAnalyzer analyzer = LibraryAnalyzer(
- analysisOptions as AnalysisOptionsImpl,
- declaredVariables,
- sourceFactory,
- libraryContext.analysisContext,
- libraryContext.elementFactory.libraryOfUri2(library.uriStr),
- libraryContext.analysisSession.inheritanceManager,
- library,
- testingData: testingData);
- Map<FileState, UnitAnalysisResult> results = analyzer.analyze();
+ var results = LibraryAnalyzer(
+ analysisOptions as AnalysisOptionsImpl,
+ declaredVariables,
+ sourceFactory,
+ libraryContext.elementFactory.libraryOfUri2(library.uriStr),
+ libraryContext.analysisSession.inheritanceManager,
+ library,
+ testingData: testingData,
+ ).analyze();
late Uint8List bytes;
late CompilationUnit resolvedUnit;
- for (FileState unitFile in results.keys) {
- UnitAnalysisResult unitResult = results[unitFile]!;
+ for (var unitResult in results) {
var unitBytes =
_serializeResolvedUnit(unitResult.unit, unitResult.errors);
- String unitSignature = _getResolvedUnitSignature(library, unitFile);
+ String unitSignature =
+ _getResolvedUnitSignature(library, unitResult.file);
String unitKey = _getResolvedUnitKey(unitSignature);
_byteStore.put(unitKey, unitBytes);
- if (unitFile == file) {
+ if (unitResult.file == file) {
bytes = unitBytes;
resolvedUnit = unitResult.unit;
}
@@ -1515,21 +1512,19 @@
_testView.numOfAnalyzedLibraries++;
libraryContext.load2(library);
- LibraryAnalyzer analyzer = LibraryAnalyzer(
- analysisOptions as AnalysisOptionsImpl,
- declaredVariables,
- sourceFactory,
- libraryContext.analysisContext,
- libraryContext.elementFactory.libraryOfUri2(library.uriStr),
- libraryContext.analysisSession.inheritanceManager,
- library,
- testingData: testingData);
- Map<FileState, UnitAnalysisResult> unitResults = analyzer.analyze();
+ var unitResults = LibraryAnalyzer(
+ analysisOptions as AnalysisOptionsImpl,
+ declaredVariables,
+ sourceFactory,
+ libraryContext.elementFactory.libraryOfUri2(library.uriStr),
+ libraryContext.analysisSession.inheritanceManager,
+ library,
+ testingData: testingData)
+ .analyze();
var resolvedUnits = <ResolvedUnitResult>[];
- for (var entry in unitResults.entries) {
- var unitFile = entry.key;
- var unitResult = entry.value;
+ for (var unitResult in unitResults) {
+ var unitFile = unitResult.file;
resolvedUnits.add(
ResolvedUnitResultImpl(
currentSession,
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 6d7e98d..347e551 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -51,7 +51,6 @@
import 'package:analyzer/src/task/strong/checker.dart';
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/util/uri.dart';
-import 'package:pub_semver/pub_semver.dart';
var timerLibraryAnalyzer = Stopwatch();
var timerLibraryAnalyzerConst = Stopwatch();
@@ -72,17 +71,11 @@
/// Analyzer of a single library.
class LibraryAnalyzer {
- /// A marker object used to prevent the initialization of
- /// [_versionConstraintFromPubspec] when the previous initialization attempt
- /// failed.
- static final VersionRange noSpecifiedRange = VersionRange();
final AnalysisOptionsImpl _analysisOptions;
final DeclaredVariables _declaredVariables;
final SourceFactory _sourceFactory;
final FileState _library;
-
final InheritanceManager3 _inheritance;
- final AnalysisContext _context;
final LibraryElementImpl _libraryElement;
@@ -92,16 +85,11 @@
final Map<FileState, RecordingErrorListener> _errorListeners = {};
final Map<FileState, ErrorReporter> _errorReporters = {};
final TestingData? _testingData;
- final List<UsedImportedElements> _usedImportedElementsList = [];
- final List<UsedLocalElements> _usedLocalElementsList = [];
-
- final Set<ConstantEvaluationTarget> _constants = {};
LibraryAnalyzer(
this._analysisOptions,
this._declaredVariables,
this._sourceFactory,
- this._context,
this._libraryElement,
this._inheritance,
this._library,
@@ -113,98 +101,25 @@
TypeSystemImpl get _typeSystem => _libraryElement.typeSystem;
/// Compute analysis results for all units of the library.
- Map<FileState, UnitAnalysisResult> analyze() {
- timerLibraryAnalyzer.start();
- Map<FileState, CompilationUnitImpl> units = {};
-
- // Parse all files.
- timerLibraryAnalyzerFreshUnit.start();
- for (FileState file in _library.libraryFiles) {
- units[file] = _parse(file);
- }
- timerLibraryAnalyzerFreshUnit.stop();
-
- // Resolve URIs in directives to corresponding sources.
- FeatureSet featureSet = units[_library]!.featureSet;
- units.forEach((file, unit) {
- _validateFeatureSet(unit, featureSet);
- _resolveUriBasedDirectives(file, unit);
- });
-
- timerLibraryAnalyzerResolve.start();
- _resolveDirectives(units);
-
- units.forEach((file, unit) {
- _resolveFile(file, unit);
- });
- timerLibraryAnalyzerResolve.stop();
-
- timerLibraryAnalyzerConst.start();
- units.values.forEach(_findConstants);
- _computeConstants();
- timerLibraryAnalyzerConst.stop();
-
- timerLibraryAnalyzerVerify.start();
- units.forEach((file, unit) {
- _computeVerifyErrors(file, unit);
- });
-
- if (_analysisOptions.hint) {
- units.forEach((file, unit) {
- {
- var visitor = GatherUsedLocalElementsVisitor(_libraryElement);
- unit.accept(visitor);
- _usedLocalElementsList.add(visitor.usedElements);
- }
- {
- var visitor = GatherUsedImportedElementsVisitor(_libraryElement);
- unit.accept(visitor);
- _usedImportedElementsList.add(visitor.usedElements);
- }
- });
- units.forEach((file, unit) {
- _computeHints(file, unit);
- });
- }
-
- if (_analysisOptions.lint) {
- var allUnits = _library.libraryFiles
- .map((file) => LinterContextUnit(file.content, units[file]!))
- .toList();
- for (int i = 0; i < allUnits.length; i++) {
- _computeLints(_library.libraryFiles[i], allUnits[i], allUnits);
- }
- }
-
- assert(units.values.every(LegacyTypeAsserter.assertLegacyTypes));
-
- _checkForInconsistentLanguageVersionOverride(units);
-
- // This must happen after all other diagnostics have been computed but
- // before the list of diagnostics has been filtered.
- for (var file in _library.libraryFiles) {
- IgnoreValidator(
- _getErrorReporter(file),
- _getErrorListener(file).errors,
- _fileToIgnoreInfo[file]!,
- _fileToLineInfo[file]!,
- _analysisOptions.unignorableNames,
- ).reportErrors();
- }
-
- timerLibraryAnalyzerVerify.stop();
+ List<UnitAnalysisResult> analyze() {
+ var units = _parseAndResolve();
+ _computeDiagnostics(units);
// Return full results.
- Map<FileState, UnitAnalysisResult> results = {};
+ var results = <UnitAnalysisResult>[];
units.forEach((file, unit) {
List<AnalysisError> errors = _getErrorListener(file).errors;
errors = _filterIgnoredErrors(file, errors);
- results[file] = UnitAnalysisResult(file, unit, errors);
+ results.add(UnitAnalysisResult(file, unit, errors));
});
timerLibraryAnalyzer.stop();
return results;
}
+ /// Analyze [file] for a completion result.
+ ///
+ /// This method aims to avoid work that [analyze] does which would be
+ /// unnecessary for a completion request.
AnalysisForCompletionResult analyzeForCompletion({
required FileState file,
required int offset,
@@ -264,8 +179,8 @@
e.parent is MixinDeclaration;
});
if (nodeToResolve != null) {
- var can = resolverVisitor.prepareForResolving(nodeToResolve);
- if (can) {
+ var canResolveNode = resolverVisitor.prepareForResolving(nodeToResolve);
+ if (canResolveNode) {
nodeToResolve.accept(resolverVisitor);
return AnalysisForCompletionResult(
parsedUnit: parsedUnit,
@@ -274,11 +189,11 @@
}
}
- var resolvedUnits = analyze();
- var resolvedUnit = resolvedUnits[file]!;
+ var units = _parseAndResolve();
+ var unit = units[file]!;
return AnalysisForCompletionResult(
- parsedUnit: resolvedUnit.unit,
- resolvedNodes: [resolvedUnit.unit],
+ parsedUnit: unit,
+ resolvedNodes: [unit],
);
});
}
@@ -333,12 +248,80 @@
}
/// Compute [_constants] in all units.
- void _computeConstants() {
- computeConstants(
- _declaredVariables, _constants.toList(), _libraryElement.featureSet);
+ void _computeConstants(Iterable<CompilationUnitImpl> units) {
+ var constants = [
+ for (var unit in units) ..._findConstants(unit),
+ ];
+ computeConstants(_declaredVariables, constants, _libraryElement.featureSet);
}
- void _computeHints(FileState file, CompilationUnit unit) {
+ /// Compute diagnostics in [units], including errors and warnings, hints,
+ /// lints, and a few other cases.
+ void _computeDiagnostics(Map<FileState, CompilationUnitImpl> units) {
+ timerLibraryAnalyzerVerify.start();
+ units.forEach((file, unit) {
+ _computeVerifyErrors(file, unit);
+ });
+
+ if (_analysisOptions.hint) {
+ var usedImportedElements = <UsedImportedElements>[];
+ var usedLocalElements = <UsedLocalElements>[];
+ for (var unit in units.values) {
+ {
+ var visitor = GatherUsedLocalElementsVisitor(_libraryElement);
+ unit.accept(visitor);
+ usedLocalElements.add(visitor.usedElements);
+ }
+ {
+ var visitor = GatherUsedImportedElementsVisitor(_libraryElement);
+ unit.accept(visitor);
+ usedImportedElements.add(visitor.usedElements);
+ }
+ }
+ units.forEach((file, unit) {
+ _computeHints(
+ file,
+ unit,
+ usedImportedElements: usedImportedElements,
+ usedLocalElements: usedLocalElements,
+ );
+ });
+ }
+
+ if (_analysisOptions.lint) {
+ var allUnits = _library.libraryFiles
+ .map((file) => LinterContextUnit(file.content, units[file]!))
+ .toList();
+ for (int i = 0; i < allUnits.length; i++) {
+ _computeLints(_library.libraryFiles[i], allUnits[i], allUnits,
+ analysisOptions: _analysisOptions);
+ }
+ }
+
+ assert(units.values.every(LegacyTypeAsserter.assertLegacyTypes));
+
+ _checkForInconsistentLanguageVersionOverride(units);
+
+ // This must happen after all other diagnostics have been computed but
+ // before the list of diagnostics has been filtered.
+ for (var file in _library.libraryFiles) {
+ IgnoreValidator(
+ _getErrorReporter(file),
+ _getErrorListener(file).errors,
+ _fileToIgnoreInfo[file]!,
+ _fileToLineInfo[file]!,
+ _analysisOptions.unignorableNames,
+ ).reportErrors();
+ }
+ timerLibraryAnalyzerVerify.stop();
+ }
+
+ void _computeHints(
+ FileState file,
+ CompilationUnit unit, {
+ required List<UsedImportedElements> usedImportedElements,
+ required List<UsedLocalElements> usedLocalElements,
+ }) {
AnalysisErrorListener errorListener = _getErrorListener(file);
ErrorReporter errorReporter = _getErrorReporter(file);
@@ -365,7 +348,7 @@
declaredVariables: _declaredVariables,
typeSystem: _typeSystem,
inheritanceManager: _inheritance,
- analysisOptions: _context.analysisOptions,
+ analysisOptions: _analysisOptions,
workspacePackage: _library.workspacePackage,
),
);
@@ -383,19 +366,19 @@
{
ImportsVerifier verifier = ImportsVerifier();
verifier.addImports(unit);
- _usedImportedElementsList.forEach(verifier.removeUsedElements);
+ usedImportedElements.forEach(verifier.removeUsedElements);
verifier.generateDuplicateImportHints(errorReporter);
verifier.generateDuplicateShownHiddenNameHints(errorReporter);
verifier.generateUnusedImportHints(errorReporter);
verifier.generateUnusedShownNameHints(errorReporter);
verifier.generateUnnecessaryImportHints(
- errorReporter, _usedImportedElementsList);
+ errorReporter, usedImportedElements);
}
// Unused local elements.
{
UsedLocalElements usedElements =
- UsedLocalElements.merge(_usedLocalElementsList);
+ UsedLocalElements.merge(usedLocalElements);
UnusedLocalElementsVerifier visitor = UnusedLocalElementsVerifier(
errorListener, usedElements, _inheritance, _libraryElement);
unit.accept(visitor);
@@ -413,12 +396,16 @@
}
}
- void _computeLints(FileState file, LinterContextUnit currentUnit,
- List<LinterContextUnit> allUnits) {
+ void _computeLints(
+ FileState file,
+ LinterContextUnit currentUnit,
+ List<LinterContextUnit> allUnits, {
+ required AnalysisOptionsImpl analysisOptions,
+ }) {
var unit = currentUnit.unit;
var errorReporter = _getErrorReporter(file);
- var enableTiming = _analysisOptions.enableTiming;
+ var enableTiming = analysisOptions.enableTiming;
var nodeRegistry = NodeLintRegistry(enableTiming);
var context = LinterContextImpl(
@@ -428,10 +415,10 @@
_typeProvider,
_typeSystem,
_inheritance,
- _analysisOptions,
+ analysisOptions,
file.workspacePackage,
);
- for (var linter in _analysisOptions.lintRules) {
+ for (var linter in analysisOptions.lintRules) {
linter.reporter = errorReporter;
var timer = enableTiming ? lintRegistry.getTimer(linter) : null;
timer?.start();
@@ -444,7 +431,7 @@
LinterVisitor(
nodeRegistry,
LinterExceptionHandler(
- propagateExceptions: _analysisOptions.propagateLinterExceptions,
+ propagateExceptions: analysisOptions.propagateLinterExceptions,
).logException,
),
);
@@ -522,17 +509,6 @@
return errors.where((AnalysisError e) => !isIgnored(e)).toList();
}
- /// Find constants to compute.
- void _findConstants(CompilationUnit unit) {
- ConstantFinder constantFinder = ConstantFinder();
- unit.accept(constantFinder);
- _constants.addAll(constantFinder.constantsToCompute);
-
- var dependenciesFinder = ConstantExpressionsDependenciesFinder();
- unit.accept(dependenciesFinder);
- _constants.addAll(dependenciesFinder.dependencies);
- }
-
RecordingErrorListener _getErrorListener(FileState file) =>
_errorListeners.putIfAbsent(file, () => RecordingErrorListener());
@@ -589,13 +565,47 @@
String content = file.content;
var unit = file.parse(errorListener);
- LineInfo lineInfo = unit.lineInfo!;
- _fileToLineInfo[file] = lineInfo;
+ _fileToLineInfo[file] = unit.lineInfo!;
_fileToIgnoreInfo[file] = IgnoreInfo.forDart(unit, content);
return unit;
}
+ /// Parse and resolve all files in [_library].
+ Map<FileState, CompilationUnitImpl> _parseAndResolve() {
+ timerLibraryAnalyzer.start();
+ var units = <FileState, CompilationUnitImpl>{};
+
+ // Parse all files.
+ timerLibraryAnalyzerFreshUnit.start();
+ for (FileState file in _library.libraryFiles) {
+ units[file] = _parse(file);
+ }
+ timerLibraryAnalyzerFreshUnit.stop();
+
+ // Resolve URIs in directives to corresponding sources.
+ FeatureSet featureSet = units[_library]!.featureSet;
+ units.forEach((file, unit) {
+ _validateFeatureSet(unit, featureSet);
+ _resolveUriBasedDirectives(file, unit);
+ });
+
+ timerLibraryAnalyzerResolve.start();
+ _resolveDirectives(units);
+
+ units.forEach((file, unit) {
+ _resolveFile(file, unit);
+ });
+ timerLibraryAnalyzerResolve.stop();
+
+ timerLibraryAnalyzerConst.start();
+
+ _computeConstants(units.values);
+ timerLibraryAnalyzerConst.stop();
+
+ return units;
+ }
+
void _resolveDirectives(Map<FileState, CompilationUnitImpl> units) {
var definingCompilationUnit = units[_library]!;
definingCompilationUnit.element = _libraryElement.definingCompilationUnit;
@@ -917,6 +927,19 @@
}
}
+ /// Find constants in [unit] to compute.
+ static List<ConstantEvaluationTarget> _findConstants(CompilationUnit unit) {
+ ConstantFinder constantFinder = ConstantFinder();
+ unit.accept(constantFinder);
+
+ var dependenciesFinder = ConstantExpressionsDependenciesFinder();
+ unit.accept(dependenciesFinder);
+ return [
+ ...constantFinder.constantsToCompute,
+ ...dependenciesFinder.dependencies,
+ ];
+ }
+
static bool _hasEmptyCompletionContext(AstNode? node) {
if (node is DoubleLiteral || node is IntegerLiteral) {
return true;
diff --git a/pkg/analyzer/lib/src/dart/element/subtype.dart b/pkg/analyzer/lib/src/dart/element/subtype.dart
index 85a9387..4c8850c 100644
--- a/pkg/analyzer/lib/src/dart/element/subtype.dart
+++ b/pkg/analyzer/lib/src/dart/element/subtype.dart
@@ -31,21 +31,21 @@
_objectNone = typeSystem.objectNone,
_objectQuestion = typeSystem.objectQuestion;
- /// Return `true` if [_T0] is a subtype of [_T1].
- bool isSubtypeOf(DartType _T0, DartType _T1) {
+ /// Return `true` if [T0_] is a subtype of [T1_].
+ bool isSubtypeOf(DartType T0_, DartType T1_) {
// Reflexivity: if `T0` and `T1` are the same type then `T0 <: T1`.
- if (identical(_T0, _T1)) {
+ if (identical(T0_, T1_)) {
return true;
}
// `_` is treated as a top and a bottom type during inference.
- if (identical(_T0, UnknownInferredType.instance) ||
- identical(_T1, UnknownInferredType.instance)) {
+ if (identical(T0_, UnknownInferredType.instance) ||
+ identical(T1_, UnknownInferredType.instance)) {
return true;
}
- var T0 = _T0 as TypeImpl;
- var T1 = _T1 as TypeImpl;
+ var T0 = T0_ as TypeImpl;
+ var T1 = T1_ as TypeImpl;
var T1_nullability = T1.nullabilitySuffix;
var T0_nullability = T0.nullabilitySuffix;
diff --git a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
index 2caa7a1..f6a8e6a 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
@@ -47,14 +47,9 @@
import 'package:analyzer/src/task/strong/checker.dart';
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/workspace/workspace.dart';
-import 'package:pub_semver/pub_semver.dart';
/// Analyzer of a single library.
class LibraryAnalyzer {
- /// A marker object used to prevent the initialization of
- /// [_versionConstraintFromPubspec] when the previous initialization attempt
- /// failed.
- static final VersionRange noSpecifiedRange = VersionRange();
final AnalysisOptionsImpl _analysisOptions;
final DeclaredVariables _declaredVariables;
final SourceFactory _sourceFactory;
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index 0c25625..6033cde 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -4521,27 +4521,30 @@
static const CompileTimeErrorCode EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER =
CompileTimeErrorCode(
- 'EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER',
- "External fields cannot have initializers.",
+ 'EXTERNAL_WITH_INITIALIZER',
+ "External fields can't have initializers.",
correctionMessage:
"Try removing the field initializer or the 'external' keyword from the "
"field declaration.",
+ uniqueName: 'EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER',
);
static const CompileTimeErrorCode EXTERNAL_FIELD_INITIALIZER =
CompileTimeErrorCode(
- 'EXTERNAL_FIELD_INITIALIZER',
- "External fields cannot have initializers.",
+ 'EXTERNAL_WITH_INITIALIZER',
+ "External fields can't have initializers.",
correctionMessage:
"Try removing the initializer or the 'external' keyword.",
+ uniqueName: 'EXTERNAL_FIELD_INITIALIZER',
);
static const CompileTimeErrorCode EXTERNAL_VARIABLE_INITIALIZER =
CompileTimeErrorCode(
- 'EXTERNAL_VARIABLE_INITIALIZER',
- "External variables cannot have initializers.",
+ 'EXTERNAL_WITH_INITIALIZER',
+ "External variables can't have initializers.",
correctionMessage:
"Try removing the initializer or the 'external' keyword.",
+ uniqueName: 'EXTERNAL_VARIABLE_INITIALIZER',
);
/**
@@ -5952,6 +5955,28 @@
hasPublishedDocs: true,
);
+ static const CompileTimeErrorCode
+ IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_MISSING_REQUIRED_ARGUMENT =
+ CompileTimeErrorCode(
+ 'IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_MISSING_REQUIRED_ARGUMENT',
+ "The named parameter '{0}' is required in the implicitly invoked unnamed "
+ "constructor of '{1}'.",
+ correctionMessage:
+ "Try declaring corresponding named super-parameter, or explicitly "
+ "invoking a different constructor.",
+ );
+
+ static const CompileTimeErrorCode
+ IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_NOT_ENOUGH_POSITIONAL_ARGUMENTS =
+ CompileTimeErrorCode(
+ 'IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_NOT_ENOUGH_POSITIONAL_ARGUMENTS',
+ "The implicitly invoked unnamed constructor of '{0}' expects {1} "
+ "positional arguments, but {2} found.",
+ correctionMessage:
+ "Try declaring positional super-parameters, or explicitly invoking a "
+ "different constructor.",
+ );
+
/**
* Parameters:
* 0: the uri pointing to a library
@@ -8514,6 +8539,20 @@
);
/**
+ * No parameters.
+ */
+ static const CompileTimeErrorCode
+ MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION =
+ CompileTimeErrorCode(
+ 'MISSING_DEFAULT_VALUE_FOR_PARAMETER',
+ "With null safety, use the 'required' keyword, not the '@required' "
+ "annotation.",
+ correctionMessage: "Try removing the '@'.",
+ hasPublishedDocs: true,
+ uniqueName: 'MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION',
+ );
+
+ /**
* Parameters:
* 0: the name of the parameter
*/
@@ -8863,16 +8902,6 @@
);
/**
- * The <i>mixinMember</i> production allows the same instance or static
- * members that a class would allow, but no constructors (for now).
- */
- static const CompileTimeErrorCode MIXIN_DECLARES_CONSTRUCTOR =
- CompileTimeErrorCode(
- 'MIXIN_DECLARES_CONSTRUCTOR',
- "Mixins can't declare constructors.",
- );
-
- /**
* No parameters.
*/
static const CompileTimeErrorCode MIXIN_DEFERRED_CLASS = CompileTimeErrorCode(
@@ -13082,6 +13111,21 @@
);
/**
+ * Parameters:
+ * 0: the type of super-parameter
+ * 1: the type of associated super-constructor parameter
+ */
+ static const CompileTimeErrorCode
+ SUPER_FORMAL_PARAMETER_TYPE_IS_NOT_SUBTYPE_OF_ASSOCIATED =
+ CompileTimeErrorCode(
+ 'SUPER_FORMAL_PARAMETER_TYPE_IS_NOT_SUBTYPE_OF_ASSOCIATED',
+ "The type '{0}' of this parameter is not a subtype of the type '{1}' of "
+ "the associated super-constructor parameter.",
+ correctionMessage:
+ "Try removing the explicit type annotation from the parameter.",
+ );
+
+ /**
* No parameters.
*/
static const CompileTimeErrorCode
diff --git a/pkg/analyzer/lib/src/error/super_formal_parameters_verifier.dart b/pkg/analyzer/lib/src/error/super_formal_parameters_verifier.dart
new file mode 100644
index 0000000..309ead0
--- /dev/null
+++ b/pkg/analyzer/lib/src/error/super_formal_parameters_verifier.dart
@@ -0,0 +1,45 @@
+// 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/error/codes.dart';
+
+VerifySuperFormalParametersResult verifySuperFormalParameters({
+ required ConstructorDeclaration constructor,
+ ErrorReporter? errorReporter,
+ bool hasExplicitPositionalArguments = false,
+}) {
+ var result = VerifySuperFormalParametersResult();
+ for (var parameter in constructor.parameters.parameters) {
+ parameter = parameter.notDefault;
+ if (parameter is SuperFormalParameter) {
+ var parameterElement =
+ parameter.declaredElement as SuperFormalParameterElementImpl;
+ if (parameter.isNamed) {
+ result.namedArgumentNames.add(parameterElement.name);
+ } else {
+ result.positionalArgumentCount++;
+ if (hasExplicitPositionalArguments) {
+ errorReporter?.reportErrorForNode(
+ CompileTimeErrorCode
+ .POSITIONAL_SUPER_FORMAL_PARAMETER_WITH_POSITIONAL_ARGUMENT,
+ parameter.identifier,
+ );
+ }
+ }
+ }
+ }
+ return result;
+}
+
+class VerifySuperFormalParametersResult {
+ /// The count of positional arguments provided by the super-parameters.
+ int positionalArgumentCount = 0;
+
+ /// The names of named arguments provided by the super-parameters.
+ List<String> namedArgumentNames = [];
+}
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 7d363ca..78bd179 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -37,6 +37,7 @@
import 'package:analyzer/src/error/literal_element_verifier.dart';
import 'package:analyzer/src/error/required_parameters_verifier.dart';
import 'package:analyzer/src/error/return_type_verifier.dart';
+import 'package:analyzer/src/error/super_formal_parameters_verifier.dart';
import 'package:analyzer/src/error/type_arguments_verifier.dart';
import 'package:analyzer/src/error/use_result_verifier.dart';
import 'package:analyzer/src/generated/element_resolver.dart';
@@ -1141,6 +1142,8 @@
@override
void visitSuperFormalParameter(SuperFormalParameter node) {
+ super.visitSuperFormalParameter(node);
+
var constructor = node.parentFormalParameterList.parent;
if (!(constructor is ConstructorDeclaration &&
constructor.isNonRedirectingGenerative)) {
@@ -1148,9 +1151,33 @@
CompileTimeErrorCode.INVALID_SUPER_FORMAL_PARAMETER_LOCATION,
node.superKeyword,
);
+ return;
}
- super.visitSuperFormalParameter(node);
+ var element = node.declaredElement as SuperFormalParameterElementImpl;
+ var superParameter = element.superConstructorParameter;
+
+ if (superParameter == null) {
+ errorReporter.reportErrorForNode(
+ node.isNamed
+ ? CompileTimeErrorCode
+ .SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_NAMED
+ : CompileTimeErrorCode
+ .SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_POSITIONAL,
+ node.identifier,
+ );
+ return;
+ }
+
+ if (!_currentLibrary.typeSystem
+ .isSubtypeOf(element.type, superParameter.type)) {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode
+ .SUPER_FORMAL_PARAMETER_TYPE_IS_NOT_SUBTYPE_OF_ASSOCIATED,
+ node.identifier,
+ [element.type, superParameter.type],
+ );
+ }
}
@override
@@ -1779,23 +1806,23 @@
}
/// Verify all conflicts between type variable and enclosing class.
- /// TODO(scheglov)
void _checkForConflictingClassTypeVariableErrorCodes() {
- for (TypeParameterElement typeParameter
- in _enclosingClass!.typeParameters) {
+ var enclosingClass = _enclosingClass!;
+ for (TypeParameterElement typeParameter in enclosingClass.typeParameters) {
String name = typeParameter.name;
// name is same as the name of the enclosing class
- if (_enclosingClass!.name == name) {
- var code = _enclosingClass!.isMixin
+ if (enclosingClass.name == name) {
+ var code = enclosingClass.isMixin
? CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MIXIN
: CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS;
errorReporter.reportErrorForElement(code, typeParameter, [name]);
}
// check members
- if (_enclosingClass!.getMethod(name) != null ||
- _enclosingClass!.getGetter(name) != null ||
- _enclosingClass!.getSetter(name) != null) {
- var code = _enclosingClass!.isMixin
+ if (enclosingClass.getNamedConstructor(name) != null ||
+ enclosingClass.getMethod(name) != null ||
+ enclosingClass.getGetter(name) != null ||
+ enclosingClass.getSetter(name) != null) {
+ var code = enclosingClass.isMixin
? CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN
: CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS;
errorReporter.reportErrorForElement(code, typeParameter, [name]);
@@ -4173,15 +4200,6 @@
return;
}
- // TODO(scheglov) Restore when working on errors.
- if (_currentLibrary.featureSet.isEnabled(Feature.super_parameters)) {
- if (constructor.parameters.parameters.any((parameter) {
- return parameter.notDefault is SuperFormalParameter;
- })) {
- return;
- }
- }
-
// Ignore if the constructor has either an implicit super constructor
// invocation or a redirecting constructor invocation.
for (ConstructorInitializer constructorInitializer
@@ -4199,37 +4217,88 @@
return;
}
ClassElement superElement = superType.element;
+
if (superElement.constructors
.every((constructor) => constructor.isFactory)) {
// Already reported [NO_GENERATIVE_CONSTRUCTORS_IN_SUPERCLASS].
return;
}
+
var superUnnamedConstructor = superElement.unnamedConstructor;
superUnnamedConstructor = superUnnamedConstructor != null
? _currentLibrary.toLegacyElementIfOptOut(superUnnamedConstructor)
: superUnnamedConstructor;
- if (superUnnamedConstructor != null) {
- if (superUnnamedConstructor.isFactory) {
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
- constructor.returnType,
- [superUnnamedConstructor]);
- } else if (!superUnnamedConstructor.isDefaultConstructor) {
- Identifier returnType = constructor.returnType;
- var name = constructor.name;
- int offset = returnType.offset;
- int length = (name != null ? name.end : returnType.end) - offset;
- errorReporter.reportErrorForOffset(
- CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT,
- offset,
- length,
- [superType]);
- }
- } else {
+ if (superUnnamedConstructor == null) {
errorReporter.reportErrorForNode(
- CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT,
- constructor.returnType,
- [superElement.name]);
+ CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT,
+ constructor.returnType,
+ [superElement.name],
+ );
+ return;
+ }
+
+ if (superUnnamedConstructor.isFactory) {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
+ constructor.returnType,
+ [superUnnamedConstructor],
+ );
+ return;
+ }
+
+ var requiredPositionalParameterCount = superUnnamedConstructor.parameters
+ .where((parameter) => parameter.isRequiredPositional)
+ .length;
+ var requiredNamedParameters = superUnnamedConstructor.parameters
+ .where((parameter) => parameter.isRequiredNamed)
+ .map((parameter) => parameter.name)
+ .toSet();
+
+ void reportError(ErrorCode errorCode, List<Object> arguments) {
+ Identifier returnType = constructor.returnType;
+ var name = constructor.name;
+ int offset = returnType.offset;
+ int length = (name != null ? name.end : returnType.end) - offset;
+ errorReporter.reportErrorForOffset(errorCode, offset, length, arguments);
+ }
+
+ if (!_currentLibrary.featureSet.isEnabled(Feature.super_parameters)) {
+ if (requiredPositionalParameterCount != 0 ||
+ requiredNamedParameters.isNotEmpty) {
+ reportError(
+ CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT,
+ [superType],
+ );
+ }
+ return;
+ }
+
+ var superParametersResult = verifySuperFormalParameters(
+ constructor: constructor,
+ errorReporter: errorReporter,
+ );
+ requiredNamedParameters.removeAll(
+ superParametersResult.namedArgumentNames,
+ );
+
+ if (requiredPositionalParameterCount >
+ superParametersResult.positionalArgumentCount) {
+ reportError(
+ CompileTimeErrorCode
+ .IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_NOT_ENOUGH_POSITIONAL_ARGUMENTS,
+ [
+ superType,
+ requiredPositionalParameterCount,
+ superParametersResult.positionalArgumentCount,
+ ],
+ );
+ }
+ for (var requiredNamedParameterName in requiredNamedParameters) {
+ reportError(
+ CompileTimeErrorCode
+ .IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_MISSING_REQUIRED_ARGUMENT,
+ [requiredNamedParameterName, superType],
+ );
}
}
@@ -4871,14 +4940,23 @@
);
}
} else if (defaultValuesAreExpected && parameter.defaultValue == null) {
- var type = parameter.declaredElement!.type;
+ var parameterElement = parameter.declaredElement!;
+ var type = parameterElement.type;
if (typeSystem.isPotentiallyNonNullable(type)) {
var parameterName = _parameterName(parameter);
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER,
- parameterName ?? parameter,
- [parameterName?.name ?? '?'],
- );
+ if (parameterElement.hasRequired) {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode
+ .MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION,
+ parameterName ?? parameter,
+ );
+ } else {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER,
+ parameterName ?? parameter,
+ [parameterName?.name ?? '?'],
+ );
+ }
}
}
}
diff --git a/pkg/analyzer/lib/src/generated/java_core.dart b/pkg/analyzer/lib/src/generated/java_core.dart
index 75fa4d3..9891065 100644
--- a/pkg/analyzer/lib/src/generated/java_core.dart
+++ b/pkg/analyzer/lib/src/generated/java_core.dart
@@ -39,137 +39,3 @@
return arguments[index].toString();
});
}
-
-/// Very limited printf implementation, supports only %s and %d.
-String _printf(String fmt, List args) {
- StringBuffer sb = StringBuffer();
- bool markFound = false;
- int argIndex = 0;
- for (int i = 0; i < fmt.length; i++) {
- int c = fmt.codeUnitAt(i);
- if (c == 0x25) {
- if (markFound) {
- sb.writeCharCode(c);
- markFound = false;
- } else {
- markFound = true;
- }
- continue;
- }
- if (markFound) {
- markFound = false;
- // %d
- if (c == 0x64) {
- sb.write(args[argIndex++]);
- continue;
- }
- // %s
- if (c == 0x73) {
- sb.write(args[argIndex++]);
- continue;
- }
- // unknown
- throw ArgumentError('[$fmt][$i] = 0x${c.toRadixString(16)}');
- } else {
- sb.writeCharCode(c);
- }
- }
- return sb.toString();
-}
-
-class Character {
- static const int MAX_VALUE = 0xffff;
- static const int MAX_CODE_POINT = 0x10ffff;
- static const int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
- static const int MIN_LOW_SURROGATE = 0xDC00;
- static const int MIN_HIGH_SURROGATE = 0xD800;
-
- static int digit(int codePoint, int radix) {
- if (radix != 16) {
- throw ArgumentError("only radix == 16 is supported");
- }
- if (0x30 <= codePoint && codePoint <= 0x39) {
- return codePoint - 0x30;
- }
- if (0x41 <= codePoint && codePoint <= 0x46) {
- return 0xA + (codePoint - 0x41);
- }
- if (0x61 <= codePoint && codePoint <= 0x66) {
- return 0xA + (codePoint - 0x61);
- }
- return -1;
- }
-
- static bool isDigit(int c) => c >= 0x30 && c <= 0x39;
-
- static bool isLetter(int c) =>
- c >= 0x41 && c <= 0x5A || c >= 0x61 && c <= 0x7A;
-
- static bool isLetterOrDigit(int c) => isLetter(c) || isDigit(c);
-
- static bool isWhitespace(int c) =>
- c == 0x09 || c == 0x20 || c == 0x0A || c == 0x0D;
-
- static String toChars(int codePoint) {
- if (codePoint < 0 || codePoint > MAX_CODE_POINT) {
- throw ArgumentError();
- }
- if (codePoint < MIN_SUPPLEMENTARY_CODE_POINT) {
- return String.fromCharCode(codePoint);
- }
- int offset = codePoint - MIN_SUPPLEMENTARY_CODE_POINT;
- int c0 = ((offset & 0x7FFFFFFF) >> 10) + MIN_HIGH_SURROGATE;
- int c1 = (offset & 0x3ff) + MIN_LOW_SURROGATE;
- return String.fromCharCodes([c0, c1]);
- }
-}
-
-@deprecated
-abstract class Enum<E extends Enum<E>> implements Comparable<E> {
- /// The name of this enum constant, as declared in the enum declaration.
- final String name;
-
- /// The position in the enum declaration.
- final int ordinal;
-
- const Enum(this.name, this.ordinal);
-
- @override
- int get hashCode => ordinal;
-
- @override
- int compareTo(E other) => ordinal - other.ordinal;
-
- @override
- String toString() => name;
-}
-
-@deprecated
-class PrintStringWriter extends PrintWriter {
- final StringBuffer _sb = StringBuffer();
-
- @override
- void print(Object x) {
- _sb.write(x);
- }
-
- @override
- String toString() => _sb.toString();
-}
-
-abstract class PrintWriter {
- void newLine() {
- print('\n');
- }
-
- void print(Object x);
-
- void printf(String fmt, List args) {
- print(_printf(fmt, args));
- }
-
- void println(String s) {
- print(s);
- newLine();
- }
-}
diff --git a/pkg/analyzer/lib/src/generated/java_io.dart b/pkg/analyzer/lib/src/generated/java_io.dart
deleted file mode 100644
index 4751bc4..0000000
--- a/pkg/analyzer/lib/src/generated/java_io.dart
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2014, 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:io";
-
-import 'package:path/path.dart' as path;
-
-@Deprecated('Use ResourceProvider and path context instead.')
-class JavaFile {
- @deprecated
- static path.Context pathContext = path.context;
- static final String separator = Platform.pathSeparator;
- static final int separatorChar = Platform.pathSeparator.codeUnitAt(0);
- late final String _path;
- JavaFile(String path) {
- _path = path;
- }
- JavaFile.fromUri(Uri uri) : this(path.context.fromUri(uri));
- JavaFile.relative(JavaFile base, String child) {
- if (child.isEmpty) {
- _path = base._path;
- } else {
- _path = path.context.join(base._path, child);
- }
- }
- @override
- int get hashCode => _path.hashCode;
- @override
- bool operator ==(Object other) {
- return other is JavaFile && other._path == _path;
- }
-
- bool exists() {
- if (_newFile().existsSync()) {
- return true;
- }
- if (_newDirectory().existsSync()) {
- return true;
- }
- return false;
- }
-
- JavaFile getAbsoluteFile() => JavaFile(getAbsolutePath());
- String getAbsolutePath() {
- String abolutePath = path.context.absolute(_path);
- abolutePath = path.context.normalize(abolutePath);
- return abolutePath;
- }
-
- JavaFile getCanonicalFile() => JavaFile(getCanonicalPath());
- String getCanonicalPath() {
- return _newFile().resolveSymbolicLinksSync();
- }
-
- String getName() => path.context.basename(_path);
- String? getParent() {
- var result = path.context.dirname(_path);
- // "." or "/" or "C:\"
- if (result.length < 4) return null;
- return result;
- }
-
- JavaFile? getParentFile() {
- var parent = getParent();
- if (parent == null) return null;
- return JavaFile(parent);
- }
-
- String getPath() => _path;
- bool isDirectory() {
- return _newDirectory().existsSync();
- }
-
- bool isExecutable() {
- return _newFile().statSync().mode & 0x111 != 0;
- }
-
- bool isFile() {
- return _newFile().existsSync();
- }
-
- int lastModified() {
- try {
- return _newFile().lastModifiedSync().millisecondsSinceEpoch;
- } catch (exception) {
- return -1;
- }
- }
-
- List<JavaFile> listFiles() {
- var files = <JavaFile>[];
- var entities = _newDirectory().listSync();
- for (FileSystemEntity entity in entities) {
- files.add(JavaFile(entity.path));
- }
- return files;
- }
-
- String readAsStringSync() => _newFile().readAsStringSync();
- @override
- String toString() => _path.toString();
- Uri toURI() {
- String absolutePath = getAbsolutePath();
- return path.context.toUri(absolutePath);
- }
-
- Directory _newDirectory() => Directory(_path);
- File _newFile() => File(_path);
-}
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index aef17ef..dfeb521 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -60,6 +60,7 @@
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/error/dead_code_verifier.dart';
import 'package:analyzer/src/error/nullable_dereference_verifier.dart';
+import 'package:analyzer/src/error/super_formal_parameters_verifier.dart';
import 'package:analyzer/src/generated/element_resolver.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error_detection_helpers.dart';
@@ -2332,9 +2333,6 @@
ErrorReporter? errorReporter,
ConstructorDeclaration? enclosingConstructor,
}) {
- if (parameters.isEmpty && argumentList.arguments.isEmpty) {
- return const <ParameterElement>[];
- }
int requiredParameterCount = 0;
int unnamedParameterCount = 0;
List<ParameterElement> unnamedParameters = <ParameterElement>[];
@@ -2360,11 +2358,38 @@
List<ParameterElement?> resolvedParameters =
List<ParameterElement?>.filled(argumentCount, null);
int positionalArgumentCount = 0;
- HashSet<String>? usedNames;
bool noBlankArguments = true;
Expression? firstUnresolvedArgument;
for (int i = 0; i < argumentCount; i++) {
Expression argument = arguments[i];
+ if (argument is! NamedExpressionImpl) {
+ if (argument is SimpleIdentifier && argument.name.isEmpty) {
+ noBlankArguments = false;
+ }
+ positionalArgumentCount++;
+ if (unnamedIndex < unnamedParameterCount) {
+ resolvedParameters[i] = unnamedParameters[unnamedIndex++];
+ } else {
+ firstUnresolvedArgument ??= argument;
+ }
+ }
+ }
+
+ Set<String>? usedNames;
+ if (enclosingConstructor != null) {
+ var result = verifySuperFormalParameters(
+ constructor: enclosingConstructor,
+ hasExplicitPositionalArguments: positionalArgumentCount != 0,
+ errorReporter: errorReporter,
+ );
+ positionalArgumentCount += result.positionalArgumentCount;
+ if (result.namedArgumentNames.isNotEmpty) {
+ usedNames = result.namedArgumentNames.toSet();
+ }
+ }
+
+ for (int i = 0; i < argumentCount; i++) {
+ Expression argument = arguments[i];
if (argument is NamedExpressionImpl) {
var nameNode = argument.name.label;
String name = nameNode.name;
@@ -2376,57 +2401,11 @@
resolvedParameters[i] = element;
nameNode.staticElement = element;
}
- usedNames ??= HashSet<String>();
+ usedNames ??= <String>{};
if (!usedNames.add(name)) {
errorReporter?.reportErrorForNode(
CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, [name]);
}
- } else {
- if (argument is SimpleIdentifier && argument.name.isEmpty) {
- noBlankArguments = false;
- }
- positionalArgumentCount++;
- if (unnamedIndex < unnamedParameterCount) {
- resolvedParameters[i] = unnamedParameters[unnamedIndex++];
- } else {
- firstUnresolvedArgument ??= argument;
- }
- }
- }
-
- if (enclosingConstructor != null) {
- var hasExplicitPositionalArguments = positionalArgumentCount != 0;
- for (var formalParameter in enclosingConstructor.parameters.parameters) {
- formalParameter = formalParameter.notDefault;
- if (formalParameter is SuperFormalParameter) {
- var element = formalParameter.declaredElement
- as SuperFormalParameterElementImpl;
- if (formalParameter.isNamed) {
- if (element.superConstructorParameter == null) {
- errorReporter?.reportErrorForNode(
- CompileTimeErrorCode
- .SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_NAMED,
- formalParameter.identifier,
- );
- }
- } else {
- positionalArgumentCount++;
- if (hasExplicitPositionalArguments) {
- errorReporter?.reportErrorForNode(
- CompileTimeErrorCode
- .POSITIONAL_SUPER_FORMAL_PARAMETER_WITH_POSITIONAL_ARGUMENT,
- formalParameter.identifier,
- );
- }
- if (element.superConstructorParameter == null) {
- errorReporter?.reportErrorForNode(
- CompileTimeErrorCode
- .SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_POSITIONAL,
- formalParameter.identifier,
- );
- }
- }
- }
}
}
diff --git a/pkg/analyzer/lib/src/generated/utilities_collection.dart b/pkg/analyzer/lib/src/generated/utilities_collection.dart
index 59758e4..c3c0036 100644
--- a/pkg/analyzer/lib/src/generated/utilities_collection.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_collection.dart
@@ -2,8 +2,6 @@
// 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:analyzer/src/generated/java_core.dart';
-
/// Returns `true` if a and b contain equal elements in the same order.
bool listsEqual(List a, List b) {
// TODO(rnystrom): package:collection also implements this, and analyzer
@@ -34,11 +32,6 @@
return (array & (1 << index)) > 0;
}
- /// Return the value of the element at the given index.
- @deprecated
- static bool getEnum<E extends Enum<E>>(int array, Enum<E> index) =>
- get(array, index.ordinal);
-
/// Set the value of the element of the given [array] at the given [index] to
/// the given [value].
static int set(int array, int index, bool value) {
@@ -50,11 +43,6 @@
}
}
- /// Set the value of the element at the given index to the given value.
- @deprecated
- static int setEnum<E extends Enum<E>>(int array, Enum<E> index, bool value) =>
- set(array, index.ordinal, value);
-
/// Throw an exception if the index is not within the bounds allowed for an
/// integer-encoded array of boolean values.
static void _checkIndex(int index) {
diff --git a/pkg/analyzer/lib/src/summary/flat_buffers.dart b/pkg/analyzer/lib/src/summary/flat_buffers.dart
index 49a7400..80ba07c 100644
--- a/pkg/analyzer/lib/src/summary/flat_buffers.dart
+++ b/pkg/analyzer/lib/src/summary/flat_buffers.dart
@@ -467,20 +467,20 @@
_currentVTable!.addField(field, _tail);
}
- static void _setFloat64AtTail(ByteData _buf, int tail, double x) {
- _buf.setFloat64(_buf.lengthInBytes - tail, x, Endian.little);
+ static void _setFloat64AtTail(ByteData buf, int tail, double x) {
+ buf.setFloat64(buf.lengthInBytes - tail, x, Endian.little);
}
- static void _setInt32AtTail(ByteData _buf, int tail, int x) {
- _buf.setInt32(_buf.lengthInBytes - tail, x, Endian.little);
+ static void _setInt32AtTail(ByteData buf, int tail, int x) {
+ buf.setInt32(buf.lengthInBytes - tail, x, Endian.little);
}
- static void _setUint32AtTail(ByteData _buf, int tail, int x) {
- _buf.setUint32(_buf.lengthInBytes - tail, x, Endian.little);
+ static void _setUint32AtTail(ByteData buf, int tail, int x) {
+ buf.setUint32(buf.lengthInBytes - tail, x, Endian.little);
}
- static void _setUint8AtTail(ByteData _buf, int tail, int x) {
- _buf.setUint8(_buf.lengthInBytes - tail, x);
+ static void _setUint8AtTail(ByteData buf, int tail, int x) {
+ buf.setUint8(buf.lengthInBytes - tail, x);
}
}
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index e85a569..fcbf6a9 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -241,24 +241,24 @@
implements idl.AnalysisDriverExceptionContext {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_exception = exception;
if (local_exception != '') {
- _result["exception"] = local_exception;
+ result["exception"] = local_exception;
}
var local_files = files;
if (local_files.isNotEmpty) {
- _result["files"] = local_files.map((_value) => _value.toJson()).toList();
+ result["files"] = local_files.map((value) => value.toJson()).toList();
}
var local_path = path;
if (local_path != '') {
- _result["path"] = local_path;
+ result["path"] = local_path;
}
var local_stackTrace = stackTrace;
if (local_stackTrace != '') {
- _result["stackTrace"] = local_stackTrace;
+ result["stackTrace"] = local_stackTrace;
}
- return _result;
+ return result;
}
@override
@@ -367,16 +367,16 @@
implements idl.AnalysisDriverExceptionFile {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_content = content;
if (local_content != '') {
- _result["content"] = local_content;
+ result["content"] = local_content;
}
var local_path = path;
if (local_path != '') {
- _result["path"] = local_path;
+ result["path"] = local_path;
}
- return _result;
+ return result;
}
@override
@@ -512,17 +512,16 @@
implements idl.AnalysisDriverResolvedUnit {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_errors = errors;
if (local_errors.isNotEmpty) {
- _result["errors"] =
- local_errors.map((_value) => _value.toJson()).toList();
+ result["errors"] = local_errors.map((value) => value.toJson()).toList();
}
var local_index = index;
if (local_index != null) {
- _result["index"] = local_index.toJson();
+ result["index"] = local_index.toJson();
}
- return _result;
+ return result;
}
@override
@@ -634,16 +633,16 @@
implements idl.AnalysisDriverSubtype {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_members = members;
if (local_members.isNotEmpty) {
- _result["members"] = local_members;
+ result["members"] = local_members;
}
var local_name = name;
if (local_name != 0) {
- _result["name"] = local_name;
+ result["name"] = local_name;
}
- return _result;
+ return result;
}
@override
@@ -859,33 +858,33 @@
implements idl.AnalysisDriverUnitError {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_contextMessages = contextMessages;
if (local_contextMessages.isNotEmpty) {
- _result["contextMessages"] =
- local_contextMessages.map((_value) => _value.toJson()).toList();
+ result["contextMessages"] =
+ local_contextMessages.map((value) => value.toJson()).toList();
}
var local_correction = correction;
if (local_correction != '') {
- _result["correction"] = local_correction;
+ result["correction"] = local_correction;
}
var local_length = length;
if (local_length != 0) {
- _result["length"] = local_length;
+ result["length"] = local_length;
}
var local_message = message;
if (local_message != '') {
- _result["message"] = local_message;
+ result["message"] = local_message;
}
var local_offset = offset;
if (local_offset != 0) {
- _result["offset"] = local_offset;
+ result["offset"] = local_offset;
}
var local_uniqueName = uniqueName;
if (local_uniqueName != '') {
- _result["uniqueName"] = local_uniqueName;
+ result["uniqueName"] = local_uniqueName;
}
- return _result;
+ return result;
}
@override
@@ -1711,96 +1710,95 @@
implements idl.AnalysisDriverUnitIndex {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_elementKinds = elementKinds;
if (local_elementKinds.isNotEmpty) {
- _result["elementKinds"] = local_elementKinds
- .map((_value) => _value.toString().split('.')[1])
+ result["elementKinds"] = local_elementKinds
+ .map((value) => value.toString().split('.')[1])
.toList();
}
var local_elementNameClassMemberIds = elementNameClassMemberIds;
if (local_elementNameClassMemberIds.isNotEmpty) {
- _result["elementNameClassMemberIds"] = local_elementNameClassMemberIds;
+ result["elementNameClassMemberIds"] = local_elementNameClassMemberIds;
}
var local_elementNameParameterIds = elementNameParameterIds;
if (local_elementNameParameterIds.isNotEmpty) {
- _result["elementNameParameterIds"] = local_elementNameParameterIds;
+ result["elementNameParameterIds"] = local_elementNameParameterIds;
}
var local_elementNameUnitMemberIds = elementNameUnitMemberIds;
if (local_elementNameUnitMemberIds.isNotEmpty) {
- _result["elementNameUnitMemberIds"] = local_elementNameUnitMemberIds;
+ result["elementNameUnitMemberIds"] = local_elementNameUnitMemberIds;
}
var local_elementUnits = elementUnits;
if (local_elementUnits.isNotEmpty) {
- _result["elementUnits"] = local_elementUnits;
+ result["elementUnits"] = local_elementUnits;
}
var local_nullStringId = nullStringId;
if (local_nullStringId != 0) {
- _result["nullStringId"] = local_nullStringId;
+ result["nullStringId"] = local_nullStringId;
}
var local_strings = strings;
if (local_strings.isNotEmpty) {
- _result["strings"] = local_strings;
+ result["strings"] = local_strings;
}
var local_subtypes = subtypes;
if (local_subtypes.isNotEmpty) {
- _result["subtypes"] =
- local_subtypes.map((_value) => _value.toJson()).toList();
+ result["subtypes"] =
+ local_subtypes.map((value) => value.toJson()).toList();
}
var local_supertypes = supertypes;
if (local_supertypes.isNotEmpty) {
- _result["supertypes"] = local_supertypes;
+ result["supertypes"] = local_supertypes;
}
var local_unitLibraryUris = unitLibraryUris;
if (local_unitLibraryUris.isNotEmpty) {
- _result["unitLibraryUris"] = local_unitLibraryUris;
+ result["unitLibraryUris"] = local_unitLibraryUris;
}
var local_unitUnitUris = unitUnitUris;
if (local_unitUnitUris.isNotEmpty) {
- _result["unitUnitUris"] = local_unitUnitUris;
+ result["unitUnitUris"] = local_unitUnitUris;
}
var local_usedElementIsQualifiedFlags = usedElementIsQualifiedFlags;
if (local_usedElementIsQualifiedFlags.isNotEmpty) {
- _result["usedElementIsQualifiedFlags"] =
- local_usedElementIsQualifiedFlags;
+ result["usedElementIsQualifiedFlags"] = local_usedElementIsQualifiedFlags;
}
var local_usedElementKinds = usedElementKinds;
if (local_usedElementKinds.isNotEmpty) {
- _result["usedElementKinds"] = local_usedElementKinds
- .map((_value) => _value.toString().split('.')[1])
+ result["usedElementKinds"] = local_usedElementKinds
+ .map((value) => value.toString().split('.')[1])
.toList();
}
var local_usedElementLengths = usedElementLengths;
if (local_usedElementLengths.isNotEmpty) {
- _result["usedElementLengths"] = local_usedElementLengths;
+ result["usedElementLengths"] = local_usedElementLengths;
}
var local_usedElementOffsets = usedElementOffsets;
if (local_usedElementOffsets.isNotEmpty) {
- _result["usedElementOffsets"] = local_usedElementOffsets;
+ result["usedElementOffsets"] = local_usedElementOffsets;
}
var local_usedElements = usedElements;
if (local_usedElements.isNotEmpty) {
- _result["usedElements"] = local_usedElements;
+ result["usedElements"] = local_usedElements;
}
var local_usedNameIsQualifiedFlags = usedNameIsQualifiedFlags;
if (local_usedNameIsQualifiedFlags.isNotEmpty) {
- _result["usedNameIsQualifiedFlags"] = local_usedNameIsQualifiedFlags;
+ result["usedNameIsQualifiedFlags"] = local_usedNameIsQualifiedFlags;
}
var local_usedNameKinds = usedNameKinds;
if (local_usedNameKinds.isNotEmpty) {
- _result["usedNameKinds"] = local_usedNameKinds
- .map((_value) => _value.toString().split('.')[1])
+ result["usedNameKinds"] = local_usedNameKinds
+ .map((value) => value.toString().split('.')[1])
.toList();
}
var local_usedNameOffsets = usedNameOffsets;
if (local_usedNameOffsets.isNotEmpty) {
- _result["usedNameOffsets"] = local_usedNameOffsets;
+ result["usedNameOffsets"] = local_usedNameOffsets;
}
var local_usedNames = usedNames;
if (local_usedNames.isNotEmpty) {
- _result["usedNames"] = local_usedNames;
+ result["usedNames"] = local_usedNames;
}
- return _result;
+ return result;
}
@override
@@ -2499,110 +2497,110 @@
abstract class _AvailableDeclarationMixin implements idl.AvailableDeclaration {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_children = children;
if (local_children.isNotEmpty) {
- _result["children"] =
- local_children.map((_value) => _value.toJson()).toList();
+ result["children"] =
+ local_children.map((value) => value.toJson()).toList();
}
var local_codeLength = codeLength;
if (local_codeLength != 0) {
- _result["codeLength"] = local_codeLength;
+ result["codeLength"] = local_codeLength;
}
var local_codeOffset = codeOffset;
if (local_codeOffset != 0) {
- _result["codeOffset"] = local_codeOffset;
+ result["codeOffset"] = local_codeOffset;
}
var local_defaultArgumentListString = defaultArgumentListString;
if (local_defaultArgumentListString != '') {
- _result["defaultArgumentListString"] = local_defaultArgumentListString;
+ result["defaultArgumentListString"] = local_defaultArgumentListString;
}
var local_defaultArgumentListTextRanges = defaultArgumentListTextRanges;
if (local_defaultArgumentListTextRanges.isNotEmpty) {
- _result["defaultArgumentListTextRanges"] =
+ result["defaultArgumentListTextRanges"] =
local_defaultArgumentListTextRanges;
}
var local_docComplete = docComplete;
if (local_docComplete != '') {
- _result["docComplete"] = local_docComplete;
+ result["docComplete"] = local_docComplete;
}
var local_docSummary = docSummary;
if (local_docSummary != '') {
- _result["docSummary"] = local_docSummary;
+ result["docSummary"] = local_docSummary;
}
var local_fieldMask = fieldMask;
if (local_fieldMask != 0) {
- _result["fieldMask"] = local_fieldMask;
+ result["fieldMask"] = local_fieldMask;
}
var local_isAbstract = isAbstract;
if (local_isAbstract != false) {
- _result["isAbstract"] = local_isAbstract;
+ result["isAbstract"] = local_isAbstract;
}
var local_isConst = isConst;
if (local_isConst != false) {
- _result["isConst"] = local_isConst;
+ result["isConst"] = local_isConst;
}
var local_isDeprecated = isDeprecated;
if (local_isDeprecated != false) {
- _result["isDeprecated"] = local_isDeprecated;
+ result["isDeprecated"] = local_isDeprecated;
}
var local_isFinal = isFinal;
if (local_isFinal != false) {
- _result["isFinal"] = local_isFinal;
+ result["isFinal"] = local_isFinal;
}
var local_isStatic = isStatic;
if (local_isStatic != false) {
- _result["isStatic"] = local_isStatic;
+ result["isStatic"] = local_isStatic;
}
var local_kind = kind;
if (local_kind != idl.AvailableDeclarationKind.CLASS) {
- _result["kind"] = local_kind.toString().split('.')[1];
+ result["kind"] = local_kind.toString().split('.')[1];
}
var local_locationOffset = locationOffset;
if (local_locationOffset != 0) {
- _result["locationOffset"] = local_locationOffset;
+ result["locationOffset"] = local_locationOffset;
}
var local_locationStartColumn = locationStartColumn;
if (local_locationStartColumn != 0) {
- _result["locationStartColumn"] = local_locationStartColumn;
+ result["locationStartColumn"] = local_locationStartColumn;
}
var local_locationStartLine = locationStartLine;
if (local_locationStartLine != 0) {
- _result["locationStartLine"] = local_locationStartLine;
+ result["locationStartLine"] = local_locationStartLine;
}
var local_name = name;
if (local_name != '') {
- _result["name"] = local_name;
+ result["name"] = local_name;
}
var local_parameterNames = parameterNames;
if (local_parameterNames.isNotEmpty) {
- _result["parameterNames"] = local_parameterNames;
+ result["parameterNames"] = local_parameterNames;
}
var local_parameters = parameters;
if (local_parameters != '') {
- _result["parameters"] = local_parameters;
+ result["parameters"] = local_parameters;
}
var local_parameterTypes = parameterTypes;
if (local_parameterTypes.isNotEmpty) {
- _result["parameterTypes"] = local_parameterTypes;
+ result["parameterTypes"] = local_parameterTypes;
}
var local_relevanceTags = relevanceTags;
if (local_relevanceTags.isNotEmpty) {
- _result["relevanceTags"] = local_relevanceTags;
+ result["relevanceTags"] = local_relevanceTags;
}
var local_requiredParameterCount = requiredParameterCount;
if (local_requiredParameterCount != 0) {
- _result["requiredParameterCount"] = local_requiredParameterCount;
+ result["requiredParameterCount"] = local_requiredParameterCount;
}
var local_returnType = returnType;
if (local_returnType != '') {
- _result["returnType"] = local_returnType;
+ result["returnType"] = local_returnType;
}
var local_typeParameters = typeParameters;
if (local_typeParameters != '') {
- _result["typeParameters"] = local_typeParameters;
+ result["typeParameters"] = local_typeParameters;
}
- return _result;
+ return result;
}
@override
@@ -2900,38 +2898,37 @@
abstract class _AvailableFileMixin implements idl.AvailableFile {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_declarations = declarations;
if (local_declarations.isNotEmpty) {
- _result["declarations"] =
- local_declarations.map((_value) => _value.toJson()).toList();
+ result["declarations"] =
+ local_declarations.map((value) => value.toJson()).toList();
}
var local_directiveInfo = directiveInfo;
if (local_directiveInfo != null) {
- _result["directiveInfo"] = local_directiveInfo.toJson();
+ result["directiveInfo"] = local_directiveInfo.toJson();
}
var local_exports = exports;
if (local_exports.isNotEmpty) {
- _result["exports"] =
- local_exports.map((_value) => _value.toJson()).toList();
+ result["exports"] = local_exports.map((value) => value.toJson()).toList();
}
var local_isLibrary = isLibrary;
if (local_isLibrary != false) {
- _result["isLibrary"] = local_isLibrary;
+ result["isLibrary"] = local_isLibrary;
}
var local_isLibraryDeprecated = isLibraryDeprecated;
if (local_isLibraryDeprecated != false) {
- _result["isLibraryDeprecated"] = local_isLibraryDeprecated;
+ result["isLibraryDeprecated"] = local_isLibraryDeprecated;
}
var local_lineStarts = lineStarts;
if (local_lineStarts.isNotEmpty) {
- _result["lineStarts"] = local_lineStarts;
+ result["lineStarts"] = local_lineStarts;
}
var local_parts = parts;
if (local_parts.isNotEmpty) {
- _result["parts"] = local_parts;
+ result["parts"] = local_parts;
}
- return _result;
+ return result;
}
@override
@@ -3057,17 +3054,17 @@
abstract class _AvailableFileExportMixin implements idl.AvailableFileExport {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_combinators = combinators;
if (local_combinators.isNotEmpty) {
- _result["combinators"] =
- local_combinators.map((_value) => _value.toJson()).toList();
+ result["combinators"] =
+ local_combinators.map((value) => value.toJson()).toList();
}
var local_uri = uri;
if (local_uri != '') {
- _result["uri"] = local_uri;
+ result["uri"] = local_uri;
}
- return _result;
+ return result;
}
@override
@@ -3194,16 +3191,16 @@
implements idl.AvailableFileExportCombinator {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_hides = hides;
if (local_hides.isNotEmpty) {
- _result["hides"] = local_hides;
+ result["hides"] = local_hides;
}
var local_shows = shows;
if (local_shows.isNotEmpty) {
- _result["shows"] = local_shows;
+ result["shows"] = local_shows;
}
- return _result;
+ return result;
}
@override
@@ -3340,17 +3337,16 @@
abstract class _CiderUnitErrorsMixin implements idl.CiderUnitErrors {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_errors = errors;
if (local_errors.isNotEmpty) {
- _result["errors"] =
- local_errors.map((_value) => _value.toJson()).toList();
+ result["errors"] = local_errors.map((value) => value.toJson()).toList();
}
var local_signature = signature;
if (local_signature.isNotEmpty) {
- _result["signature"] = local_signature;
+ result["signature"] = local_signature;
}
- return _result;
+ return result;
}
@override
@@ -3524,28 +3520,28 @@
abstract class _DiagnosticMessageMixin implements idl.DiagnosticMessage {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_filePath = filePath;
if (local_filePath != '') {
- _result["filePath"] = local_filePath;
+ result["filePath"] = local_filePath;
}
var local_length = length;
if (local_length != 0) {
- _result["length"] = local_length;
+ result["length"] = local_length;
}
var local_message = message;
if (local_message != '') {
- _result["message"] = local_message;
+ result["message"] = local_message;
}
var local_offset = offset;
if (local_offset != 0) {
- _result["offset"] = local_offset;
+ result["offset"] = local_offset;
}
var local_url = url;
if (local_url != '') {
- _result["url"] = local_url;
+ result["url"] = local_url;
}
- return _result;
+ return result;
}
@override
@@ -3672,16 +3668,16 @@
abstract class _DirectiveInfoMixin implements idl.DirectiveInfo {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_templateNames = templateNames;
if (local_templateNames.isNotEmpty) {
- _result["templateNames"] = local_templateNames;
+ result["templateNames"] = local_templateNames;
}
var local_templateValues = templateValues;
if (local_templateValues.isNotEmpty) {
- _result["templateValues"] = local_templateValues;
+ result["templateValues"] = local_templateValues;
}
- return _result;
+ return result;
}
@override
@@ -3762,12 +3758,12 @@
abstract class _PackageBundleMixin implements idl.PackageBundle {
@override
Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
+ Map<String, Object> result = <String, Object>{};
var local_fake = fake;
if (local_fake != 0) {
- _result["fake"] = local_fake;
+ result["fake"] = local_fake;
}
- return _result;
+ return result;
}
@override
diff --git a/pkg/analyzer/lib/src/summary2/data_reader.dart b/pkg/analyzer/lib/src/summary2/data_reader.dart
index e72e947..9c1988d 100644
--- a/pkg/analyzer/lib/src/summary2/data_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/data_reader.dart
@@ -242,7 +242,7 @@
}
}
- static String _decodeWtf8(Uint8List _bytes, int start, int end) {
+ static String _decodeWtf8(Uint8List bytes, int start, int end) {
// WTF-8 decoder that trusts its input, meaning that the correctness of
// the code depends on the bytes from start to end being valid and
// complete WTF-8. Instead of masking off the control bits from every
@@ -252,28 +252,28 @@
int i = start;
int j = 0;
while (i < end) {
- int byte = _bytes[i++];
+ int byte = bytes[i++];
if (byte < 0x80) {
// ASCII.
charCodes[j++] = byte;
} else if (byte < 0xE0) {
// Two-byte sequence (11-bit unicode value).
- int byte2 = _bytes[i++];
+ int byte2 = bytes[i++];
int value = (byte << 6) ^ byte2 ^ 0x3080;
assert(value >= 0x80 && value < 0x800);
charCodes[j++] = value;
} else if (byte < 0xF0) {
// Three-byte sequence (16-bit unicode value).
- int byte2 = _bytes[i++];
- int byte3 = _bytes[i++];
+ int byte2 = bytes[i++];
+ int byte3 = bytes[i++];
int value = (byte << 12) ^ (byte2 << 6) ^ byte3 ^ 0xE2080;
assert(value >= 0x800 && value < 0x10000);
charCodes[j++] = value;
} else {
// Four-byte sequence (non-BMP unicode value).
- int byte2 = _bytes[i++];
- int byte3 = _bytes[i++];
- int byte4 = _bytes[i++];
+ int byte2 = bytes[i++];
+ int byte3 = bytes[i++];
+ int byte4 = bytes[i++];
int value =
(byte << 18) ^ (byte2 << 12) ^ (byte3 << 6) ^ byte4 ^ 0x3C82080;
assert(value >= 0x10000 && value < 0x110000);
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 8e60369..3b2abaf 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -3971,13 +3971,16 @@
If there are multiple cascaded accesses, you'll need to duplicate the
extension override for each one.
EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER:
- problemMessage: External fields cannot have initializers.
+ sharedName: EXTERNAL_WITH_INITIALIZER
+ problemMessage: External fields can't have initializers.
correctionMessage: "Try removing the field initializer or the 'external' keyword from the field declaration."
EXTERNAL_FIELD_INITIALIZER:
- problemMessage: External fields cannot have initializers.
+ sharedName: EXTERNAL_WITH_INITIALIZER
+ problemMessage: External fields can't have initializers.
correctionMessage: "Try removing the initializer or the 'external' keyword."
EXTERNAL_VARIABLE_INITIALIZER:
- problemMessage: External variables cannot have initializers.
+ sharedName: EXTERNAL_WITH_INITIALIZER
+ problemMessage: External variables can't have initializers.
correctionMessage: "Try removing the initializer or the 'external' keyword."
EXTRA_POSITIONAL_ARGUMENTS:
problemMessage: "Too many positional arguments: {0} expected, but {1} found."
@@ -5185,6 +5188,12 @@
int get defaultX => 0;
}
```
+ IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_MISSING_REQUIRED_ARGUMENT:
+ problemMessage: The named parameter '{0}' is required in the implicitly invoked unnamed constructor of '{1}'.
+ correctionMessage: Try declaring corresponding named super-parameter, or explicitly invoking a different constructor.
+ IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_NOT_ENOUGH_POSITIONAL_ARGUMENTS:
+ problemMessage: The implicitly invoked unnamed constructor of '{0}' expects {1} positional arguments, but {2} found.
+ correctionMessage: Try declaring positional super-parameters, or explicitly invoking a different constructor.
IMPORT_INTERNAL_LIBRARY:
problemMessage: "The library '{0}' is internal and can't be imported."
hasPublishedDocs: true
@@ -7370,6 +7379,12 @@
void f(int x) {}
void g({required int x}) {}
```
+ MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION:
+ sharedName: MISSING_DEFAULT_VALUE_FOR_PARAMETER
+ problemMessage: "With null safety, use the 'required' keyword, not the '@required' annotation."
+ correctionMessage: "Try removing the '@'."
+ hasPublishedDocs: true
+ comment: No parameters.
MISSING_REQUIRED_ARGUMENT:
problemMessage: "The named parameter '{0}' is required, but there's no corresponding argument."
correctionMessage: Try adding the required argument.
@@ -7690,11 +7705,6 @@
class B extends A {}
```
- MIXIN_DECLARES_CONSTRUCTOR:
- problemMessage: "Mixins can't declare constructors."
- comment: |-
- The <i>mixinMember</i> production allows the same instance or static
- members that a class would allow, but no constructors (for now).
MIXIN_INFERENCE_INCONSISTENT_MATCHING_CLASSES:
problemMessage: "Type parameters couldn't be inferred for the mixin '{0}' because the base class implements the mixin's supertype constraint '{1}' in multiple conflicting ways"
MIXIN_INFERENCE_NO_MATCHING_CLASS:
@@ -11097,6 +11107,13 @@
int f(C c) => c.b;
```
+ SUPER_FORMAL_PARAMETER_TYPE_IS_NOT_SUBTYPE_OF_ASSOCIATED:
+ problemMessage: The type '{0}' of this parameter is not a subtype of the type '{1}' of the associated super-constructor parameter.
+ comment: |-
+ Parameters:
+ 0: the type of super-parameter
+ 1: the type of associated super-constructor parameter
+ correctionMessage: Try removing the explicit type annotation from the parameter.
SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_NAMED:
problemMessage: No associated named super-constructor parameter.
comment: No parameters.
diff --git a/pkg/analyzer/test/generated/java_core_test.dart b/pkg/analyzer/test/generated/java_core_test.dart
index 9d8ccfe..1dd1ff2 100644
--- a/pkg/analyzer/test/generated/java_core_test.dart
+++ b/pkg/analyzer/test/generated/java_core_test.dart
@@ -6,53 +6,17 @@
import 'package:test/test.dart';
main() {
- group('Character', () {
- group('isLetter', () {
- test('digits', () {
- expect(Character.isLetter('0'.codeUnitAt(0)), isFalse);
- expect(Character.isLetter('1'.codeUnitAt(0)), isFalse);
- expect(Character.isLetter('9'.codeUnitAt(0)), isFalse);
- });
+ test('formatList', () {
+ expect(
+ format('Hello, {0} {1}!', 'John', 'Doe'),
+ 'Hello, John Doe!',
+ );
+ });
- test('letters', () {
- expect(Character.isLetter('a'.codeUnitAt(0)), isTrue);
- expect(Character.isLetter('b'.codeUnitAt(0)), isTrue);
- expect(Character.isLetter('z'.codeUnitAt(0)), isTrue);
- expect(Character.isLetter('C'.codeUnitAt(0)), isTrue);
- expect(Character.isLetter('D'.codeUnitAt(0)), isTrue);
- expect(Character.isLetter('Y'.codeUnitAt(0)), isTrue);
- });
-
- test('other', () {
- expect(Character.isLetter(' '.codeUnitAt(0)), isFalse);
- expect(Character.isLetter('.'.codeUnitAt(0)), isFalse);
- expect(Character.isLetter('-'.codeUnitAt(0)), isFalse);
- expect(Character.isLetter('+'.codeUnitAt(0)), isFalse);
- });
- });
-
- group('isLetterOrDigit', () {
- test('digits', () {
- expect(Character.isLetterOrDigit('0'.codeUnitAt(0)), isTrue);
- expect(Character.isLetterOrDigit('1'.codeUnitAt(0)), isTrue);
- expect(Character.isLetterOrDigit('9'.codeUnitAt(0)), isTrue);
- });
-
- test('letters', () {
- expect(Character.isLetterOrDigit('a'.codeUnitAt(0)), isTrue);
- expect(Character.isLetterOrDigit('b'.codeUnitAt(0)), isTrue);
- expect(Character.isLetterOrDigit('z'.codeUnitAt(0)), isTrue);
- expect(Character.isLetterOrDigit('C'.codeUnitAt(0)), isTrue);
- expect(Character.isLetterOrDigit('D'.codeUnitAt(0)), isTrue);
- expect(Character.isLetterOrDigit('Y'.codeUnitAt(0)), isTrue);
- });
-
- test('other', () {
- expect(Character.isLetterOrDigit(' '.codeUnitAt(0)), isFalse);
- expect(Character.isLetterOrDigit('.'.codeUnitAt(0)), isFalse);
- expect(Character.isLetterOrDigit('-'.codeUnitAt(0)), isFalse);
- expect(Character.isLetterOrDigit('+'.codeUnitAt(0)), isFalse);
- });
- });
+ test('formatList', () {
+ expect(
+ formatList('Hello, {0} {1}!', ['John', 'Doe']),
+ 'Hello, John Doe!',
+ );
});
}
diff --git a/pkg/analyzer/test/generated/java_io_test.dart b/pkg/analyzer/test/generated/java_io_test.dart
deleted file mode 100644
index 35bfdeb..0000000
--- a/pkg/analyzer/test/generated/java_io_test.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2014, 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:analyzer/src/generated/java_io.dart';
-import 'package:path/path.dart' as path;
-import 'package:test/test.dart';
-
-main() {
- group('JavaFile', () {
- group('toURI', () {
- test('forAbsolute', () {
- String tempPath = '/temp';
- String absolutePath = path.context.join(tempPath, 'foo.dart');
- // we use an absolute path
- expect(path.context.isAbsolute(absolutePath), isTrue,
- reason: '"$absolutePath" is not absolute');
- // test that toURI() returns an absolute URI
- // ignore: deprecated_member_use_from_same_package
- Uri uri = JavaFile(absolutePath).toURI();
- expect(uri.isAbsolute, isTrue);
- expect(uri.scheme, 'file');
- });
- test('forRelative', () {
- String tempPath = '/temp';
- String absolutePath = path.context.join(tempPath, 'foo.dart');
- expect(path.context.isAbsolute(absolutePath), isTrue,
- reason: '"$absolutePath" is not absolute');
- // prepare a relative path
- // We should not check that "relPath" is actually relative -
- // it may be not on Windows, if "temp" is on other disk.
- String relPath = path.context.relative(absolutePath);
- // test that toURI() returns an absolute URI
- // ignore: deprecated_member_use_from_same_package
- Uri uri = JavaFile(relPath).toURI();
- expect(uri.isAbsolute, isTrue);
- expect(uri.scheme, 'file');
- });
- });
- });
-}
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index 2d48f18..065d67a 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -21,7 +21,6 @@
import 'invalid_code_test.dart' as invalid_code;
import 'issues_test.dart' as issues;
import 'java_core_test.dart' as java_core_test;
-import 'java_io_test.dart' as java_io_test;
import 'new_as_identifier_parser_test.dart' as new_as_identifier_parser;
import 'nnbd_parser_test.dart' as nnbd_parser;
import 'non_error_parser_test.dart' as non_error_parser;
@@ -63,7 +62,6 @@
invalid_code.main();
issues.main();
java_core_test.main();
- java_io_test.main();
new_as_identifier_parser.main();
nnbd_parser.main();
non_error_parser.main();
diff --git a/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart b/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
index 31462c1..efbf9533f 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
@@ -1507,14 +1507,14 @@
_assertAnalyzedFiles(root, pathList);
}
- void _assertBasicWorkspace(Workspace _workspace, String posixRoot) {
- var workspace = _workspace as BasicWorkspace;
+ void _assertBasicWorkspace(Workspace workspace, String posixRoot) {
+ workspace as BasicWorkspace;
var root = convertPath(posixRoot);
expect(workspace.root, root);
}
- void _assertBazelWorkspace(Workspace _workspace, String posixRoot) {
- var workspace = _workspace as BazelWorkspace;
+ void _assertBazelWorkspace(Workspace workspace, String posixRoot) {
+ workspace as BazelWorkspace;
var root = convertPath(posixRoot);
expect(workspace.root, root);
}
@@ -1526,8 +1526,8 @@
}
}
- void _assertPubWorkspace(Workspace _workspace, String posixRoot) {
- var workspace = _workspace as PubWorkspace;
+ void _assertPubWorkspace(Workspace workspace, String posixRoot) {
+ workspace as PubWorkspace;
var root = convertPath(posixRoot);
expect(workspace.root, root);
}
diff --git a/pkg/analyzer/test/src/diagnostics/conflicting_type_variable_and_member_test.dart b/pkg/analyzer/test/src/diagnostics/conflicting_type_variable_and_member_test.dart
index ff439eb..efab14b 100644
--- a/pkg/analyzer/test/src/diagnostics/conflicting_type_variable_and_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/conflicting_type_variable_and_member_test.dart
@@ -18,6 +18,17 @@
@reflectiveTest
class ConflictingTypeVariableAndMemberClassTest
extends PubPackageResolutionTest {
+ test_constructor() async {
+ await assertErrorsInCode(r'''
+class A<T> {
+ A.T();
+}
+''', [
+ error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS, 8,
+ 1),
+ ]);
+ }
+
test_field() async {
await assertErrorsInCode(r'''
class A<T> {
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_named_argument_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_named_argument_test.dart
index cb69a3a..74bca78 100644
--- a/pkg/analyzer/test/src/diagnostics/duplicate_named_argument_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/duplicate_named_argument_test.dart
@@ -42,6 +42,18 @@
]);
}
+ test_constructor_superParameter() async {
+ await assertErrorsInCode(r'''
+class A {
+ A({required int a});
+}
+
+class B extends A {
+ B({required super.a}) : super(a: 0);
+}
+''', [error(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, 88, 1)]);
+ }
+
test_function() async {
await assertErrorsInCode(r'''
f({a, b}) {}
diff --git a/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
index e292d65..0656a4b 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
@@ -11,6 +11,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(MissingDefaultValueForParameterTest);
+ defineReflectiveTests(MissingDefaultValueForParameterWithAnnotationTest);
});
}
@@ -538,3 +539,24 @@
]);
}
}
+
+@reflectiveTest
+class MissingDefaultValueForParameterWithAnnotationTest
+ extends PubPackageResolutionTest {
+ test_method_withAnnotation() async {
+ writeTestPackageConfigWithMeta();
+ await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+
+class C {
+ void foo({@required int a}) {}
+}
+''', [
+ error(
+ CompileTimeErrorCode
+ .MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION,
+ 70,
+ 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/no_default_super_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/no_default_super_constructor_test.dart
index a0e3db6..a94e1c1 100644
--- a/pkg/analyzer/test/src/diagnostics/no_default_super_constructor_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/no_default_super_constructor_test.dart
@@ -16,44 +16,64 @@
@reflectiveTest
class NoDefaultSuperConstructorTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin, NoDefaultSuperConstructorTestCases {}
-
-mixin NoDefaultSuperConstructorTestCases on PubPackageResolutionTest {
- test_explicitDefaultSuperConstructor() async {
- await assertNoErrorsInCode(r'''
-class A {
- A();
-}
-class B extends A {
- B() {}
-}
-''');
- }
-
- test_implicitDefaultSuperConstructor() async {
- await assertNoErrorsInCode(r'''
-class A {
-}
-class B extends A {
- B() {}
-}
-''');
- }
-
- test_missingDefaultSuperConstructor_explicitConstructor() async {
+ with WithoutNullSafetyMixin, NoDefaultSuperConstructorTestCases {
+ test_super_requiredPositional_subclass_explicit() async {
await assertErrorsInCode(r'''
class A {
A(p);
}
class B extends A {
- B() {}
+ B();
}
''', [
error(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, 42, 1),
]);
}
+}
- test_missingDefaultSuperConstructor_externalConstructor() async {
+mixin NoDefaultSuperConstructorTestCases on PubPackageResolutionTest {
+ test_super_implicit_subclass_explicit() async {
+ await assertNoErrorsInCode(r'''
+class A {}
+class B extends A {
+ B();
+}
+''');
+ }
+
+ test_super_implicit_subclass_implicit() async {
+ await assertNoErrorsInCode(r'''
+class A {}
+class B extends A {}
+''');
+ }
+
+ test_super_noParameters() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A();
+}
+class B extends A {
+ B();
+}
+''');
+ }
+
+ test_super_requiredPositional_subclass_explicit_language214() async {
+ await assertErrorsInCode(r'''
+// @dart = 2.14
+class A {
+ A(p);
+}
+class B extends A {
+ B();
+}
+''', [
+ error(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, 58, 1),
+ ]);
+ }
+
+ test_super_requiredPositional_subclass_external() async {
await assertNoErrorsInCode(r'''
class A {
A(p);
@@ -64,24 +84,14 @@
''');
}
- test_missingDefaultSuperConstructor_implicitConstructor() async {
+ test_super_requiredPositional_subclass_implicit() async {
await assertErrorsInCode(r'''
class A {
A(p);
}
-class B extends A {
-}
-''', [
- error(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, 26, 1),
- ]);
- }
-
- test_missingDefaultSuperConstructor_onlyNamedSuperConstructor() async {
- await assertErrorsInCode(r'''
-class A { A.named() {} }
class B extends A {}
''', [
- error(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, 31, 1),
+ error(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, 26, 1),
]);
}
}
@@ -89,7 +99,69 @@
@reflectiveTest
class NoDefaultSuperConstructorWithNullSafetyTest
extends PubPackageResolutionTest with NoDefaultSuperConstructorTestCases {
- test_super_requiredParameter_legacySubclass_explicitConstructor() async {
+ test_super_optionalNamed_subclass_explicit() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A({int? a});
+}
+class B extends A {
+ B();
+}
+''');
+ }
+
+ test_super_optionalNamed_subclass_implicit() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A({int? a});
+}
+class B extends A {}
+''');
+ }
+
+ test_super_optionalNamed_subclass_superParameter() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A({int? a});
+}
+class B extends A {
+ B({super.a});
+}
+''');
+ }
+
+ test_super_optionalPositional_subclass_explicit() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A([int? a]);
+}
+class B extends A {
+ B();
+}
+''');
+ }
+
+ test_super_optionalPositional_subclass_implicit() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A([int? a]);
+}
+class B extends A {}
+''');
+ }
+
+ test_super_optionalPositional_subclass_superParameter() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A([int? a]);
+}
+class B extends A {
+ B(super.a);
+}
+''');
+ }
+
+ test_super_requiredNamed_legacySubclass_explicitConstructor() async {
newFile('$testPackageLibPath/a.dart', content: r'''
class A {
A({required String s});
@@ -105,11 +177,11 @@
''');
}
- test_super_requiredParameter_legacySubclass_implicitConstructor() async {
+ test_super_requiredNamed_legacySubclass_implicitConstructor() async {
newFile('$testPackageLibPath/a.dart', content: r'''
class A {
A({required String s});
-}
+}O
''');
await assertNoErrorsInCode(r'''
// @dart=2.8
@@ -118,4 +190,132 @@
class B extends A {}
''');
}
+
+ test_super_requiredNamed_subclass_explicit() async {
+ await assertErrorsInCode(r'''
+class A {
+ A({required int? a});
+}
+class B extends A {
+ B();
+}
+''', [
+ error(
+ CompileTimeErrorCode
+ .IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_MISSING_REQUIRED_ARGUMENT,
+ 58,
+ 1),
+ ]);
+ }
+
+ test_super_requiredNamed_subclass_implicit() async {
+ await assertErrorsInCode(r'''
+class A {
+ A({required int? a});
+}
+class B extends A {}
+''', [
+ error(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, 42, 1),
+ ]);
+ }
+
+ test_super_requiredNamed_subclass_superParameter() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A({required int? a});
+}
+class B extends A {
+ B({required super.a});
+}
+''');
+ }
+
+ test_super_requiredNamed_subclass_superParameter_oneLeft() async {
+ await assertErrorsInCode(r'''
+class A {
+ A({required int? a, required int? b});
+}
+class B extends A {
+ B({required super.a});
+}
+''', [
+ error(
+ CompileTimeErrorCode
+ .IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_MISSING_REQUIRED_ARGUMENT,
+ 75,
+ 1),
+ ]);
+ }
+
+ test_super_requiredNamed_subclass_superParameter_optionalNamed_hasDefault() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A({required int? a});
+}
+class B extends A {
+ B({super.a = 0});
+}
+''');
+ }
+
+ test_super_requiredNamed_subclass_superParameter_optionalNamed_noDefault() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A({required int? a});
+}
+class B extends A {
+ B({super.a});
+}
+''');
+ }
+
+ test_super_requiredPositional_subclass_explicit() async {
+ await assertErrorsInCode(r'''
+class A {
+ A(p);
+}
+class B extends A {
+ B();
+}
+''', [
+ error(
+ CompileTimeErrorCode
+ .IMPLICIT_UNNAMED_SUPER_CONSTRUCTOR_INVOCATION_NOT_ENOUGH_POSITIONAL_ARGUMENTS,
+ 42,
+ 1),
+ ]);
+ }
+
+ test_super_requiredPositional_subclass_superParameter_optionalPositional_withDefault() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A(int? a);
+}
+class B extends A {
+ B([super.a = 0]);
+}
+''');
+ }
+
+ test_super_requiredPositional_subclass_superParameter_optionalPositional_withoutDefault() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A(int? a);
+}
+class B extends A {
+ B([super.a]);
+}
+''');
+ }
+
+ test_super_requiredPositional_subclass_superParameter_requiredPositional() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A(int? a);
+}
+class B extends A {
+ B(super.a);
+}
+''');
+ }
}
diff --git a/pkg/analyzer/test/src/diagnostics/super_formal_parameter_type_is_not_subtype_of_associated_test.dart b/pkg/analyzer/test/src/diagnostics/super_formal_parameter_type_is_not_subtype_of_associated_test.dart
new file mode 100644
index 0000000..b7db53b
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/super_formal_parameter_type_is_not_subtype_of_associated_test.dart
@@ -0,0 +1,168 @@
+// 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:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SuperFormalParameterTypeIsNotSubtypeOfAssociatedTest);
+ });
+}
+
+@reflectiveTest
+class SuperFormalParameterTypeIsNotSubtypeOfAssociatedTest
+ extends PubPackageResolutionTest {
+ test_generic_requiredPositional_explicit_notSubtype() async {
+ await assertErrorsInCode(r'''
+class A<T> {
+ A(T a);
+}
+
+class B extends A<int> {
+ B(num super.a);
+}
+''', [
+ error(
+ CompileTimeErrorCode
+ .SUPER_FORMAL_PARAMETER_TYPE_IS_NOT_SUBTYPE_OF_ASSOCIATED,
+ 65,
+ 1),
+ ]);
+ }
+
+ test_generic_requiredPositional_explicit_same() async {
+ await assertNoErrorsInCode(r'''
+class A<T> {
+ A(T a);
+}
+
+class B extends A<num> {
+ B(num super.a);
+}
+''');
+ }
+
+ test_generic_requiredPositional_explicit_subtype() async {
+ await assertNoErrorsInCode(r'''
+class A<T> {
+ A(T a);
+}
+
+class B extends A<num> {
+ B(int super.a);
+}
+''');
+ }
+
+ test_requiredNamed_explicit_notSubtype() async {
+ await assertErrorsInCode(r'''
+class A {
+ A({required int a});
+}
+
+class B extends A {
+ B({required num super.a});
+}
+''', [
+ error(
+ CompileTimeErrorCode
+ .SUPER_FORMAL_PARAMETER_TYPE_IS_NOT_SUBTYPE_OF_ASSOCIATED,
+ 80,
+ 1),
+ ]);
+ }
+
+ test_requiredNamed_explicit_same() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A({required num a});
+}
+
+class B extends A {
+ B({required num super.a});
+}
+''');
+ }
+
+ test_requiredNamed_explicit_subtype() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A({required num a});
+}
+
+class B extends A {
+ B({required int super.a});
+}
+''');
+ }
+
+ test_requiredNamed_inherited() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A({required int a});
+}
+
+class B extends A {
+ B({required super.a});
+}
+''');
+ }
+
+ test_requiredPositional_explicit_notSubtype() async {
+ await assertErrorsInCode(r'''
+class A {
+ A(int a);
+}
+
+class B extends A {
+ B(num super.a);
+}
+''', [
+ error(
+ CompileTimeErrorCode
+ .SUPER_FORMAL_PARAMETER_TYPE_IS_NOT_SUBTYPE_OF_ASSOCIATED,
+ 59,
+ 1),
+ ]);
+ }
+
+ test_requiredPositional_explicit_same() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A(num a);
+}
+
+class B extends A {
+ B(num super.a);
+}
+''');
+ }
+
+ test_requiredPositional_explicit_subtype() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A(num a);
+}
+
+class B extends A {
+ B(int super.a);
+}
+''');
+ }
+
+ test_requiredPositional_inherited() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A(int a);
+}
+
+class B extends A {
+ B(super.a);
+}
+''');
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/super_formal_parameter_without_associated_named_test.dart b/pkg/analyzer/test/src/diagnostics/super_formal_parameter_without_associated_named_test.dart
index 049858a..80bb982 100644
--- a/pkg/analyzer/test/src/diagnostics/super_formal_parameter_without_associated_named_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/super_formal_parameter_without_associated_named_test.dart
@@ -16,11 +16,9 @@
@reflectiveTest
class SuperFormalParameterWithoutAssociatedNamedTest
extends PubPackageResolutionTest {
- test_optional() async {
+ test_explicit_optional() async {
await assertErrorsInCode(r'''
-class A {
- A([int? a]);
-}
+class A {}
class B extends A {
B({super.a}) : super();
@@ -28,16 +26,14 @@
''', [
error(
CompileTimeErrorCode.SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_NAMED,
- 59,
+ 43,
1)
]);
}
- test_required() async {
+ test_explicit_required() async {
await assertErrorsInCode(r'''
-class A {
- A([int? a]);
-}
+class A {}
class B extends A {
B({required super.a}) : super();
@@ -45,7 +41,37 @@
''', [
error(
CompileTimeErrorCode.SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_NAMED,
- 68,
+ 52,
+ 1)
+ ]);
+ }
+
+ test_implicit_optional() async {
+ await assertErrorsInCode(r'''
+class A {}
+
+class B extends A {
+ B({super.a});
+}
+''', [
+ error(
+ CompileTimeErrorCode.SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_NAMED,
+ 43,
+ 1)
+ ]);
+ }
+
+ test_implicit_required() async {
+ await assertErrorsInCode(r'''
+class A {}
+
+class B extends A {
+ B({required super.a});
+}
+''', [
+ error(
+ CompileTimeErrorCode.SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_NAMED,
+ 52,
1)
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/super_formal_parameter_without_associated_positional_test.dart b/pkg/analyzer/test/src/diagnostics/super_formal_parameter_without_associated_positional_test.dart
index 47d5cde..c88f091 100644
--- a/pkg/analyzer/test/src/diagnostics/super_formal_parameter_without_associated_positional_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/super_formal_parameter_without_associated_positional_test.dart
@@ -16,11 +16,9 @@
@reflectiveTest
class SuperFormalParameterWithoutAssociatedPositionalTest
extends PubPackageResolutionTest {
- test_optional() async {
+ test_explicit_optional() async {
await assertErrorsInCode(r'''
-class A {
- A({int? a});
-}
+class A {}
class B extends A {
B([super.a]) : super();
@@ -29,16 +27,14 @@
error(
CompileTimeErrorCode
.SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_POSITIONAL,
- 59,
+ 43,
1)
]);
}
- test_required() async {
+ test_explicit_required() async {
await assertErrorsInCode(r'''
-class A {
- A({int? a});
-}
+class A {}
class B extends A {
B(super.a) : super();
@@ -47,7 +43,39 @@
error(
CompileTimeErrorCode
.SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_POSITIONAL,
- 58,
+ 42,
+ 1)
+ ]);
+ }
+
+ test_implicit_optional() async {
+ await assertErrorsInCode(r'''
+class A {}
+
+class B extends A {
+ B([super.a]);
+}
+''', [
+ error(
+ CompileTimeErrorCode
+ .SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_POSITIONAL,
+ 43,
+ 1)
+ ]);
+ }
+
+ test_implicit_required() async {
+ await assertErrorsInCode(r'''
+class A {}
+
+class B extends A {
+ B(super.a);
+}
+''', [
+ error(
+ CompileTimeErrorCode
+ .SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_POSITIONAL,
+ 42,
1)
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 445a54b..2529d3a 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -628,6 +628,8 @@
import 'subtype_of_ffi_class_test.dart' as subtype_of_ffi_class;
import 'subtype_of_sealed_class_test.dart' as subtype_of_sealed_class;
import 'subtype_of_struct_class_test.dart' as subtype_of_struct_class;
+import 'super_formal_parameter_type_is_not_subtype_of_associated_test.dart'
+ as super_formal_parameter_type_is_not_subtype_of_associated;
import 'super_formal_parameter_without_associated_named_test.dart'
as super_formal_parameter_without_associated_named;
import 'super_formal_parameter_without_associated_positional_test.dart'
@@ -1146,6 +1148,7 @@
subtype_of_ffi_class.main();
subtype_of_sealed_class.main();
subtype_of_struct_class.main();
+ super_formal_parameter_type_is_not_subtype_of_associated.main();
super_formal_parameter_without_associated_named.main();
super_formal_parameter_without_associated_positional.main();
super_in_extension.main();
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 8f8c3aa..0b6ebfb 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -8042,6 +8042,8 @@
_The parameter '{0}' can't have a value of 'null' because of its type, but the
implicit default value is 'null'._
+_With null safety, use the 'required' keyword, not the '@required' annotation._
+
#### Description
The analyzer produces this diagnostic when an optional parameter, whether
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index b18c095..981e0cf 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -1069,12 +1069,12 @@
if (convertItem == null) {
convertField = localName;
} else if (type.isList) {
- convertField = '$localName.map((_value) =>'
- ' ${convertItem('_value')}).toList()';
+ convertField = '$localName.map((value) =>'
+ ' ${convertItem('value')}).toList()';
} else {
convertField = convertItem(localName);
}
- return '_result[${quoted(name)}] = $convertField';
+ return 'result[${quoted(name)}] = $convertField';
}
void writeConditionalStatement(String condition, String statement) {
@@ -1087,7 +1087,7 @@
out('@override');
out('Map<String, Object> toJson() {');
indent(() {
- out('Map<String, Object> _result = <String, Object>{};');
+ out('Map<String, Object> result = <String, Object>{};');
indent(() {
for (idl_model.FieldDeclaration field in cls.fields) {
@@ -1099,7 +1099,7 @@
}
});
- out('return _result;');
+ out('return result;');
});
out('}');
out();
diff --git a/pkg/analyzer_utilities/lib/check/iterable.dart b/pkg/analyzer_utilities/lib/check/iterable.dart
index e6415c3..5b43453 100644
--- a/pkg/analyzer_utilities/lib/check/iterable.dart
+++ b/pkg/analyzer_utilities/lib/check/iterable.dart
@@ -19,6 +19,28 @@
}
}
+ /// Succeeds if there is an element that matches the [matcher],
+ void containsMatch(void Function(CheckTarget<T> element) matcher) {
+ var elementList = value.toList();
+ for (var elementIndex = 0;
+ elementIndex < elementList.length;
+ elementIndex++) {
+ var element = elementList[elementIndex];
+ var elementTarget = nest(
+ element,
+ (element) =>
+ 'element ${valueStr(element)} at ${valueStr(elementIndex)}',
+ );
+ try {
+ matcher(elementTarget);
+ return;
+ } on test_package.TestFailure {
+ continue;
+ }
+ }
+ fail('Does not contain at least one element that matches');
+ }
+
@UseResult.unless(parameterDefined: 'expected')
CheckTarget<int> hasLength([int? expected]) {
var actual = value.length;
diff --git a/pkg/analyzer_utilities/test/check/check_test.dart b/pkg/analyzer_utilities/test/check/check_test.dart
index bab4572..20873c0 100644
--- a/pkg/analyzer_utilities/test/check/check_test.dart
+++ b/pkg/analyzer_utilities/test/check/check_test.dart
@@ -62,6 +62,12 @@
});
});
group('Iterable', () {
+ test('containsMatch', () {
+ check(<int>[0]).containsMatch((e) => e.isZero);
+ check(<int>[1, 0, 2]).containsMatch((e) => e.isZero);
+ _fails(() => check(<int>[]).containsMatch((e) => e.isZero));
+ _fails(() => check(<int>[1]).containsMatch((e) => e.isZero));
+ });
test('hasLength', () {
check(<int>[]).hasLength().isZero;
check(<int>[0]).hasLength().isEqualTo(1);
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index c8aba18..2b0ad7d 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -64,7 +64,9 @@
if (env.supportedLibraries == null) {
future = future.then((_) {
Uri specificationUri = options.librariesSpecificationUri;
- return provider.readFromUri(specificationUri).then((api.Input spec) {
+
+ Future<String> readJson(Uri uri) async {
+ api.Input spec = await provider.readFromUri(specificationUri);
String json = null;
// TODO(sigmund): simplify this, we have some API inconsistencies when
// our internal input adds a terminating zero.
@@ -73,12 +75,16 @@
} else if (spec is Binary) {
json = utf8.decode(spec.data);
}
+ return json;
+ }
- // TODO(sigmund): would be nice to front-load some of the CFE option
- // processing and parse this .json file only once.
- env.supportedLibraries = getSupportedLibraryNames(specificationUri,
- json, options.compileForServer ? "dart2js_server" : "dart2js")
- .toSet();
+ // TODO(sigmund): would be nice to front-load some of the CFE option
+ // processing and parse this .json file only once.
+ return getSupportedLibraryNames(specificationUri,
+ options.compileForServer ? "dart2js_server" : "dart2js",
+ readJson: readJson)
+ .then((libraries) {
+ env.supportedLibraries = libraries.toSet();
});
});
}
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index 8d2c4b9..b3195a7 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -1111,7 +1111,7 @@
@override
visitVariableInitialization(js.VariableInitialization node) {
- visit(node.leftHandSide);
+ visit(node.declaration);
visit(node.value);
}
diff --git a/pkg/compiler/lib/src/js/placeholder_safety.dart b/pkg/compiler/lib/src/js/placeholder_safety.dart
index 9f14b58..29fea71 100644
--- a/pkg/compiler/lib/src/js/placeholder_safety.dart
+++ b/pkg/compiler/lib/src/js/placeholder_safety.dart
@@ -192,6 +192,23 @@
}
@override
+ int visitVariableInitialization(js.VariableInitialization node) {
+ js.Expression left = node.declaration;
+ js.Expression right = node.value;
+
+ visit(left);
+ if (left is js.InterpolatedNode) {
+ // A bare interpolated expression should not be the LHS of an initialized
+ // variable declaration.
+ safe = false;
+ }
+ if (right != null) {
+ return visit(right);
+ }
+ return UNKNOWN_VALUE;
+ }
+
+ @override
int visitCall(js.Call node) {
// TODO(sra): Recognize JavaScript built-ins like
// 'Object.prototype.hasOwnProperty.call'.
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 803221c..0008046 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -2493,7 +2493,7 @@
@override
bool visitAssignment(js.Assignment node) {
bool leftHandSide = visit(node.leftHandSide);
- bool value = (node.value == null) ? false : visit(node.value);
+ bool value = visit(node.value);
return leftHandSide || value;
}
@@ -2877,7 +2877,9 @@
@override
bool visitVariableInitialization(js.VariableInitialization node) {
- return visitAssignment(node);
+ bool leftHandSide = visit(node.declaration);
+ bool value = (node.value == null) ? false : visit(node.value);
+ return leftHandSide || value;
}
@override
diff --git a/pkg/compiler/lib/src/js/size_estimator.dart b/pkg/compiler/lib/src/js/size_estimator.dart
index 33a45ed..d081f4c0 100644
--- a/pkg/compiler/lib/src/js/size_estimator.dart
+++ b/pkg/compiler/lib/src/js/size_estimator.dart
@@ -556,7 +556,13 @@
@override
visitVariableInitialization(VariableInitialization initialization) {
- visitAssignment(initialization);
+ visitNestedExpression(initialization.declaration, CALL,
+ newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
+ if (initialization.value != null) {
+ out('=');
+ visitNestedExpression(initialization.value, ASSIGNMENT,
+ newInForInit: inForInit, newAtStatementBegin: false);
+ }
}
@override
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index f354388..7aa5677 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -170,6 +170,7 @@
/// http://matt.might.net/articles/closure-conversion/.
class ClosureDataBuilder {
+ final DiagnosticReporter _reporter;
final JsToElementMap _elementMap;
final AnnotationsData _annotationsData;
@@ -185,7 +186,7 @@
final Map<MemberEntity, MemberEntity> _enclosingMembers = {};
- ClosureDataBuilder(this._elementMap, this._annotationsData);
+ ClosureDataBuilder(this._reporter, this._elementMap, this._annotationsData);
void _updateScopeBasedOnRtiNeed(KernelScopeInfo scope, ClosureRtiNeed rtiNeed,
MemberEntity outermostEntity) {
@@ -323,7 +324,7 @@
Map<MemberEntity, ClosureScopeModel> closureModels,
ClosureRtiNeed rtiNeed,
List<FunctionEntity> callMethods) {
- closureModels.forEach((MemberEntity member, ClosureScopeModel model) {
+ void processModel(MemberEntity member, ClosureScopeModel model) {
Map<ir.VariableDeclaration, JRecordField> allBoxedVariables =
_elementMap.makeRecordContainer(model.scopeInfo, member);
_scopeMap[member] = JsScopeInfo.from(
@@ -381,6 +382,12 @@
}
callMethods.add(closureClassInfo.callMethod);
}
+ }
+
+ closureModels.forEach((MemberEntity member, ClosureScopeModel model) {
+ _reporter.withCurrentElement(member, () {
+ processModel(member, model);
+ });
});
return ClosureDataImpl(
_elementMap,
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index c6f42f1..bfd0363 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -168,8 +168,8 @@
strategy.elementMap,
closedWorld.liveMemberUsage,
closedWorld.annotationsData);
- ClosureDataBuilder closureDataBuilder =
- ClosureDataBuilder(_elementMap, closedWorld.annotationsData);
+ ClosureDataBuilder closureDataBuilder = ClosureDataBuilder(
+ _compiler.reporter, _elementMap, closedWorld.annotationsData);
JsClosedWorldBuilder closedWorldBuilder = JsClosedWorldBuilder(_elementMap,
closureDataBuilder, _compiler.options, _compiler.abstractValueStrategy);
JClosedWorld jClosedWorld = closedWorldBuilder.convertClosedWorld(
diff --git a/pkg/compiler/lib/src/native/js.dart b/pkg/compiler/lib/src/native/js.dart
index 9c21348..295dd0b 100644
--- a/pkg/compiler/lib/src/native/js.dart
+++ b/pkg/compiler/lib/src/native/js.dart
@@ -213,6 +213,14 @@
}
@override
+ NativeThrowBehavior visitVariableInitialization(
+ js.VariableInitialization node) {
+ final value = node.value;
+ if (value == null) return NativeThrowBehavior.NEVER;
+ return visit(value);
+ }
+
+ @override
NativeThrowBehavior visitCall(js.Call node) {
js.Expression target = node.target;
if (target is js.PropertyAccess && _isFirstInterpolatedProperty(target)) {
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index a74fa84..457f673 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -20,6 +20,7 @@
import '../vm_interop_handler.dart';
class RunCommand extends DartdevCommand {
+ static const bool isProductMode = bool.fromEnvironment("dart.vm.product");
static const String cmdName = 'run';
// kErrorExitCode, as defined in runtime/bin/error_exit.h
@@ -47,97 +48,103 @@
// the list of flags in Options::ProcessVMDebuggingOptions in
// runtime/bin/main_options.cc. Failure to do so will result in those VM
// options being ignored.
- argParser
- ..addSeparator(
- 'Debugging options:',
- )
- ..addOption(
- 'observe',
- help: 'The observe flag is a convenience flag used to run a program '
- 'with a set of common options useful for debugging.',
- valueHelp: '[<port>[/<bind-address>]]',
- )
- ..addOption('launch-dds', hide: true, help: 'Launch DDS.')
- ..addSeparator(
- 'Options implied by --observe are currently:',
- )
- ..addOption(
- 'enable-vm-service',
- help: 'Enables the VM service and listens on the specified port for '
- 'connections (default port number is 8181, default bind address '
- 'is localhost).',
- valueHelp: '[<port>[/<bind-address>]]',
- )
- ..addFlag(
- 'serve-devtools',
- help: 'Serves an instance of the Dart DevTools debugger and profiler '
- 'via the VM service at <vm-service-uri>/devtools.',
- defaultsTo: true,
- )
- ..addFlag(
- 'pause-isolates-on-exit',
- help: 'Pause isolates on exit when '
- 'running with --enable-vm-service.',
- )
- ..addFlag(
- 'pause-isolates-on-unhandled-exceptions',
- help: 'Pause isolates when an unhandled exception is encountered '
- 'when running with --enable-vm-service.',
- )
- ..addFlag(
- 'warn-on-pause-with-no-debugger',
- help: 'Print a warning when an isolate pauses with no attached debugger'
- ' when running with --enable-vm-service.',
- )
- ..addSeparator(
- 'Other debugging options:',
- )
- ..addFlag(
- 'pause-isolates-on-start',
- help: 'Pause isolates on start when '
- 'running with --enable-vm-service.',
- )
- ..addFlag(
- 'enable-asserts',
- help: 'Enable assert statements.',
- )
- ..addOption(
- 'verbosity',
- help: 'Sets the verbosity level of the compilation.',
- defaultsTo: Verbosity.defaultValue,
- allowed: Verbosity.allowedValues,
- allowedHelp: Verbosity.allowedValuesHelp,
- );
+ argParser.addSeparator(
+ 'Debugging options:',
+ );
+ if (!isProductMode) {
+ argParser
+ ..addOption(
+ 'observe',
+ help: 'The observe flag is a convenience flag used to run a program '
+ 'with a set of common options useful for debugging.',
+ valueHelp: '[<port>[/<bind-address>]]',
+ )
+ ..addOption('launch-dds', hide: true, help: 'Launch DDS.')
+ ..addSeparator(
+ 'Options implied by --observe are currently:',
+ )
+ ..addOption(
+ 'enable-vm-service',
+ help: 'Enables the VM service and listens on the specified port for '
+ 'connections (default port number is 8181, default bind address '
+ 'is localhost).',
+ valueHelp: '[<port>[/<bind-address>]]',
+ )
+ ..addFlag(
+ 'serve-devtools',
+ help: 'Serves an instance of the Dart DevTools debugger and profiler '
+ 'via the VM service at <vm-service-uri>/devtools.',
+ defaultsTo: true,
+ )
+ ..addFlag(
+ 'pause-isolates-on-exit',
+ help: 'Pause isolates on exit when '
+ 'running with --enable-vm-service.',
+ )
+ ..addFlag(
+ 'pause-isolates-on-unhandled-exceptions',
+ help: 'Pause isolates when an unhandled exception is encountered '
+ 'when running with --enable-vm-service.',
+ )
+ ..addFlag(
+ 'warn-on-pause-with-no-debugger',
+ help:
+ 'Print a warning when an isolate pauses with no attached debugger'
+ ' when running with --enable-vm-service.',
+ )
+ ..addSeparator(
+ 'Other debugging options:',
+ )
+ ..addFlag(
+ 'pause-isolates-on-start',
+ help: 'Pause isolates on start when '
+ 'running with --enable-vm-service.',
+ )
+ ..addFlag(
+ 'enable-asserts',
+ help: 'Enable assert statements.',
+ );
+ }
+ argParser.addOption(
+ 'verbosity',
+ help: 'Sets the verbosity level of the compilation.',
+ defaultsTo: Verbosity.defaultValue,
+ allowed: Verbosity.allowedValues,
+ allowedHelp: Verbosity.allowedValuesHelp,
+ );
if (verbose) {
argParser.addSeparator(
'Advanced options:',
);
}
+ argParser.addMultiOption(
+ 'define',
+ abbr: 'D',
+ valueHelp: 'key=value',
+ help: 'Define an environment declaration.',
+ );
+ if (!isProductMode) {
+ argParser
+ ..addFlag(
+ 'disable-service-auth-codes',
+ hide: !verbose,
+ negatable: false,
+ help: 'Disables the requirement for an authentication code to '
+ 'communicate with the VM service. Authentication codes help '
+ 'protect against CSRF attacks, so it is not recommended to '
+ 'disable them unless behind a firewall on a secure device.',
+ )
+ ..addFlag(
+ 'enable-service-port-fallback',
+ hide: !verbose,
+ negatable: false,
+ help: 'When the VM service is told to bind to a particular port, '
+ 'fallback to 0 if it fails to bind instread of failing to '
+ 'start.',
+ );
+ }
argParser
- ..addMultiOption(
- 'define',
- abbr: 'D',
- valueHelp: 'key=value',
- help: 'Define an environment declaration.',
- )
- ..addFlag(
- 'disable-service-auth-codes',
- hide: !verbose,
- negatable: false,
- help: 'Disables the requirement for an authentication code to '
- 'communicate with the VM service. Authentication codes help '
- 'protect against CSRF attacks, so it is not recommended to '
- 'disable them unless behind a firewall on a secure device.',
- )
- ..addFlag(
- 'enable-service-port-fallback',
- hide: !verbose,
- negatable: false,
- help: 'When the VM service is told to bind to a particular port, '
- 'fallback to 0 if it fails to bind instread of failing to '
- 'start.',
- )
..addOption(
'namespace',
hide: !verbose,
@@ -164,17 +171,22 @@
hide: !verbose,
negatable: false,
help: 'Enables tracing of library and script loading.',
- )
- ..addFlag('dds',
- hide: !verbose,
- help: 'Use the Dart Development Service (DDS) for enhanced debugging '
- 'functionality. Note: Disabling DDS may break some functionality '
- 'in IDEs and other tooling.',
- defaultsTo: true)
- ..addFlag(
- 'debug-dds',
- hide: true,
);
+
+ if (!isProductMode) {
+ argParser
+ ..addFlag('dds',
+ hide: !verbose,
+ help:
+ 'Use the Dart Development Service (DDS) for enhanced debugging '
+ 'functionality. Note: Disabling DDS may break some functionality '
+ 'in IDEs and other tooling.',
+ defaultsTo: true)
+ ..addFlag(
+ 'debug-dds',
+ hide: true,
+ );
+ }
addExperimentalFlags(argParser, verbose);
}
@@ -191,40 +203,43 @@
// The command line arguments after the command name.
runArgs = argResults.rest.skip(1).toList();
}
- // --launch-dds is provided by the VM if the VM service is to be enabled. In
- // that case, we need to launch DDS as well.
- String launchDdsArg = argResults['launch-dds'];
- String ddsHost = '';
- String ddsPort = '';
- bool launchDevTools = argResults['serve-devtools'];
- bool launchDds = false;
- if (launchDdsArg != null) {
- launchDds = true;
- final ddsUrl = launchDdsArg.split('\\:');
- ddsHost = ddsUrl[0];
- ddsPort = ddsUrl[1];
- }
- final bool debugDds = argResults['debug-dds'];
+ if (!isProductMode) {
+ // --launch-dds is provided by the VM if the VM service is to be enabled. In
+ // that case, we need to launch DDS as well.
+ String launchDdsArg = argResults['launch-dds'];
+ String ddsHost = '';
+ String ddsPort = '';
- bool disableServiceAuthCodes = argResults['disable-service-auth-codes'];
+ bool launchDevTools = argResults['serve-devtools'];
+ bool launchDds = false;
+ if (launchDdsArg != null) {
+ launchDds = true;
+ final ddsUrl = launchDdsArg.split('\\:');
+ ddsHost = ddsUrl[0];
+ ddsPort = ddsUrl[1];
+ }
+ final bool debugDds = argResults['debug-dds'];
- // If the user wants to start a debugging session we need to do some extra
- // work and spawn a Dart Development Service (DDS) instance. DDS is a VM
- // service intermediary which implements the VM service protocol and
- // provides non-VM specific extensions (e.g., log caching, client
- // synchronization).
- _DebuggingSession debugSession;
- if (launchDds) {
- debugSession = _DebuggingSession();
- if (!await debugSession.start(
- ddsHost,
- ddsPort,
- disableServiceAuthCodes,
- launchDevTools,
- debugDds,
- )) {
- return errorExitCode;
+ bool disableServiceAuthCodes = argResults['disable-service-auth-codes'];
+
+ // If the user wants to start a debugging session we need to do some extra
+ // work and spawn a Dart Development Service (DDS) instance. DDS is a VM
+ // service intermediary which implements the VM service protocol and
+ // provides non-VM specific extensions (e.g., log caching, client
+ // synchronization).
+ _DebuggingSession debugSession;
+ if (launchDds) {
+ debugSession = _DebuggingSession();
+ if (!await debugSession.start(
+ ddsHost,
+ ddsPort,
+ disableServiceAuthCodes,
+ launchDevTools,
+ debugDds,
+ )) {
+ return errorExitCode;
+ }
}
}
diff --git a/pkg/dartdev/lib/src/templates/server_shelf.dart b/pkg/dartdev/lib/src/templates/server_shelf.dart
index 33dd442..ed6b730 100644
--- a/pkg/dartdev/lib/src/templates/server_shelf.dart
+++ b/pkg/dartdev/lib/src/templates/server_shelf.dart
@@ -125,7 +125,7 @@
}
Response _echoHandler(Request request) {
- final message = request.params['message'];
+ final message = params(request, 'message');
return Response.ok('$message\n');
}
diff --git a/pkg/dartdev/test/commands/create_integration_test.dart b/pkg/dartdev/test/commands/create_integration_test.dart
index e6f2bf5..4856b47 100644
--- a/pkg/dartdev/test/commands/create_integration_test.dart
+++ b/pkg/dartdev/test/commands/create_integration_test.dart
@@ -2,13 +2,9 @@
// 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:convert';
import 'dart:io';
import 'package:dartdev/src/commands/create.dart';
-import 'package:dartdev/src/templates.dart';
-import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import '../utils.dart';
@@ -27,22 +23,21 @@
// Create tests for each template.
for (String templateId in CreateCommand.legalTemplateIds) {
test(templateId, () async {
- const projectName = 'template_project';
p = project();
- final templateGenerator = getGenerator(templateId);
ProcessResult createResult = await p.run([
'create',
'--force',
'--template',
templateId,
- projectName,
+ 'template_project',
]);
expect(createResult.exitCode, 0, reason: createResult.stderr);
// Validate that the project analyzes cleanly.
+ // TODO: Should we use --fatal-infos here?
ProcessResult analyzeResult =
- await p.run(['analyze', '--fatal-infos', projectName]);
+ await p.run(['analyze'], workingDir: p.dir.path);
expect(analyzeResult.exitCode, 0, reason: analyzeResult.stdout);
// Validate that the code is well formatted.
@@ -51,86 +46,9 @@
'--output',
'none',
'--set-exit-if-changed',
- projectName,
+ 'template_project',
]);
expect(formatResult.exitCode, 0, reason: formatResult.stdout);
-
- // Process the execution instructions provided by the template.
- final runCommands = templateGenerator
- .getInstallInstructions(
- projectName,
- projectName,
- )
- .split('\n')
- // Remove directory change instructions.
- .sublist(1)
- .map((command) => command.trim())
- .map((command) {
- final commandParts = command.split(' ');
- if (command.startsWith('dart ')) {
- return commandParts.sublist(1);
- }
- return commandParts;
- }).toList();
-
- final isServerTemplate = templateGenerator.categories.contains('server');
- final isWebTemplate = templateGenerator.categories.contains('web');
- final workingDir = path.join(p.dirPath, projectName);
-
- // Execute the templates run instructions.
- for (int i = 0; i < runCommands.length; ++i) {
- // The last command is always the command to execute the code generated
- // by the template.
- final isLastCommand = i == runCommands.length - 1;
- final command = runCommands[i];
- Process process;
-
- if (isLastCommand && isWebTemplate) {
- // The web template uses `webdev` to execute, not `dart`, so don't
- // run the test through the project utility method.
- process = await Process.start(
- path.join(
- p.pubCacheBinPath,
- Platform.isWindows ? '${command.first}.bat' : command.first,
- ),
- command.sublist(1),
- workingDirectory: workingDir,
- );
- } else {
- process = await p.start(
- command,
- workingDir: workingDir,
- );
- }
-
- if (isLastCommand && (isServerTemplate || isWebTemplate)) {
- final completer = Completer<void>();
- StreamSubscription sub;
- // Listen for well-known output from specific templates to determine
- // if they've executed correctly. These templates won't exit on their
- // own, so we'll need to terminate the process once we've verified it
- // runs correctly.
- sub = process.stdout.transform(utf8.decoder).listen((e) {
- if ((isServerTemplate && e.contains('Server listening on port')) ||
- (isWebTemplate && e.contains('Succeeded after'))) {
- sub.cancel();
- process.kill();
- completer.complete();
- }
- });
- await completer.future;
-
- // Since we had to terminate the process manually, we aren't certain
- // as to what the exit code will be on all platforms (should be -15
- // for POSIX systems), so we'll just wait for the process to exit
- // here.
- await process.exitCode;
- } else {
- // If the sample should exit on its own, it should always result in
- // an exit code of 0.
- expect(await process.exitCode, 0);
- }
- }
});
}
}
diff --git a/pkg/dartdev/test/no_such_file_test.dart b/pkg/dartdev/test/no_such_file_test.dart
index bf4eaa3..549c059 100644
--- a/pkg/dartdev/test/no_such_file_test.dart
+++ b/pkg/dartdev/test/no_such_file_test.dart
@@ -32,7 +32,8 @@
final result = await p.run(['--snapshot=abc', 'foo.dart']);
expect(result.stderr, isNotEmpty);
expect(result.stderr, contains("Error when reading 'foo.dart':"));
- expect(result.stdout, isEmpty);
+ expect(result.stdout, isNotEmpty);
+ expect(result.stdout, contains("Info: Compiling with sound null safety\n"));
expect(result.exitCode, 254);
});
}
diff --git a/pkg/dartdev/test/utils.dart b/pkg/dartdev/test/utils.dart
index 404b05e..8f8147a 100644
--- a/pkg/dartdev/test/utils.dart
+++ b/pkg/dartdev/test/utils.dart
@@ -39,10 +39,6 @@
String get dirPath => dir.path;
- String get pubCachePath => path.join(dirPath, 'pub_cache');
-
- String get pubCacheBinPath => path.join(pubCachePath, 'bin');
-
String get mainPath => path.join(dirPath, relativeFilePath);
final String name;
@@ -117,10 +113,7 @@
...arguments,
],
workingDirectory: workingDir ?? dir.path,
- environment: {
- if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true',
- 'PUB_CACHE': pubCachePath
- });
+ environment: {if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true'});
final stdoutContents = _process.stdout.transform(utf8.decoder).join();
final stderrContents = _process.stderr.transform(utf8.decoder).join();
final code = await _process.exitCode;
@@ -143,10 +136,7 @@
...arguments,
],
workingDirectory: workingDir ?? dir.path,
- environment: {
- if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true',
- 'PUB_CACHE': pubCachePath,
- })
+ environment: {if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true'})
..then((p) => _process = p);
}
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart
index 18d185d..d008fd6 100644
--- a/pkg/front_end/lib/src/api_unstable/dart2js.dart
+++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -228,9 +228,11 @@
// dart2js.
// TODO(sigmund): delete after all constant evaluation is done in the CFE, as
// this data will no longer be needed on the dart2js side.
-Iterable<String> getSupportedLibraryNames(
- Uri librariesSpecificationUri, String json, String target) {
- return LibrariesSpecification.parse(librariesSpecificationUri, json)
+Future<Iterable<String>> getSupportedLibraryNames(
+ Uri librariesSpecificationUri, String target,
+ {required Future<String> readJson(Uri uri)}) async {
+ return (await LibrariesSpecification.load(
+ librariesSpecificationUri, readJson))
.specificationFor(target)
.allLibraries
.where((l) => l.isSupported)
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index 65088a1..db25cec 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -533,12 +533,10 @@
return new TargetLibrariesSpecification(name);
}
- String json = await fileSystem
- .entityForUri(librariesSpecificationUri!)
- .readAsString();
try {
- LibrariesSpecification spec =
- await LibrariesSpecification.parse(librariesSpecificationUri!, json);
+ LibrariesSpecification spec = await LibrariesSpecification.load(
+ librariesSpecificationUri!,
+ (Uri uri) => fileSystem.entityForUri(uri).readAsString());
return spec.specificationFor(name);
} on LibrariesSpecificationException catch (e) {
reportWithoutLocation(
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 8d0de2f..613e0b7 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -45,6 +45,7 @@
ansi
answering
anyone
+aot
ap
api
apis
@@ -374,6 +375,7 @@
dmitryas
doc
docs
+doesn\'t
dom
dont
doubles
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/common_lib.dart b/pkg/front_end/testcases/general/nested_lib_spec/common_lib.dart
new file mode 100644
index 0000000..a4ce2de
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/common_lib.dart
@@ -0,0 +1,5 @@
+// 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.
+
+class Common {}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/extra_lib.dart b/pkg/front_end/testcases/general/nested_lib_spec/extra_lib.dart
new file mode 100644
index 0000000..77f761f
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/extra_lib.dart
@@ -0,0 +1,5 @@
+// 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.
+
+class Extra {}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/extra_libraries.json b/pkg/front_end/testcases/general/nested_lib_spec/extra_libraries.json
new file mode 100644
index 0000000..4ef762a
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/extra_libraries.json
@@ -0,0 +1,18 @@
+{
+ "_none": {
+ "include": [
+ {
+ "path": "subfolder/sub_libraries.json",
+ "target": "subtarget"
+ }
+ ],
+ "libraries": {
+ "extra": {
+ "patches": [
+ "extra_patch_lib.dart"
+ ],
+ "uri": "extra_lib.dart"
+ }
+ }
+ }
+}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/extra_patch_lib.dart b/pkg/front_end/testcases/general/nested_lib_spec/extra_patch_lib.dart
new file mode 100644
index 0000000..71d7fc2
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/extra_patch_lib.dart
@@ -0,0 +1,9 @@
+// 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.
+
+// ignore: import_internal_library
+import 'dart:_internal';
+
+@patch
+class Extra {}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/libraries.json b/pkg/front_end/testcases/general/nested_lib_spec/libraries.json
new file mode 100644
index 0000000..14705fe
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/libraries.json
@@ -0,0 +1,28 @@
+{
+ "none": {
+ "include": [
+ {
+ "path": "extra_libraries.json",
+ "target": "_none"
+ },
+ {
+ "target": "common"
+ }
+ ],
+ "libraries": {
+ "test": {
+ "patches": [
+ "patch_lib.dart"
+ ],
+ "uri": "origin_lib.dart"
+ }
+ }
+ },
+ "common": {
+ "libraries": {
+ "common": {
+ "uri": "common_lib.dart"
+ }
+ }
+ }
+}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/main.dart b/pkg/front_end/testcases/general/nested_lib_spec/main.dart
new file mode 100644
index 0000000..67e18ef
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/main.dart
@@ -0,0 +1,21 @@
+// 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:test';
+import 'dart:extra';
+import 'dart:sub';
+import 'dart:sub2';
+import 'dart:super1';
+import 'dart:super2';
+import 'dart:common';
+
+main() {
+ new Class();
+ new Extra();
+ new Sub();
+ new Sub2();
+ new Super1();
+ new Super2();
+ new Common();
+}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/nested_lib_spec/main.dart.textual_outline.expect
new file mode 100644
index 0000000..c544d3d
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/main.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import 'dart:test';
+import 'dart:extra';
+import 'dart:sub';
+import 'dart:sub2';
+import 'dart:super1';
+import 'dart:super2';
+import 'dart:common';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/nested_lib_spec/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..033e3d1
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import 'dart:common';
+import 'dart:extra';
+import 'dart:sub';
+import 'dart:sub2';
+import 'dart:super1';
+import 'dart:super2';
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/main.dart.weak.expect b/pkg/front_end/testcases/general/nested_lib_spec/main.dart.weak.expect
new file mode 100644
index 0000000..bbfc87a
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/main.dart.weak.expect
@@ -0,0 +1,109 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:test" as test;
+import "dart:extra" as ext;
+import "dart:sub" as sub;
+import "dart:sub2" as sub2;
+import "dart:super1" as sup;
+import "dart:super2" as sup2;
+import "dart:common" as com;
+
+import "dart:test";
+import "dart:extra";
+import "dart:sub";
+import "dart:sub2";
+import "dart:super1";
+import "dart:super2";
+import "dart:common";
+
+static method main() → dynamic {
+ new test::Class::•();
+ new ext::Extra::•();
+ new sub::Sub::•();
+ new sub2::Sub2::•();
+ new sup::Super1::•();
+ new sup2::Super2::•();
+ new com::Common::•();
+}
+
+library /*isNonNullableByDefault*/;
+import self as test;
+import "dart:_internal" as _in;
+import "dart:core" as core;
+
+import "dart:_internal";
+
+@#C1
+class Class extends core::Object {
+ synthetic constructor •() → test::Class
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as ext;
+import "dart:_internal" as _in;
+import "dart:core" as core;
+
+import "dart:_internal";
+
+@#C1
+class Extra extends core::Object {
+ synthetic constructor •() → ext::Extra
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as sub;
+import "dart:core" as core;
+
+class Sub extends core::Object {
+ synthetic constructor •() → sub::Sub
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as sub2;
+import "dart:core" as core;
+
+class Sub2 extends core::Object {
+ synthetic constructor •() → sub2::Sub2
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as sup;
+import "dart:core" as core;
+
+class Super1 extends core::Object {
+ synthetic constructor •() → sup::Super1
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as sup2;
+import "dart:core" as core;
+
+class Super2 extends core::Object {
+ synthetic constructor •() → sup2::Super2
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as com;
+import "dart:core" as core;
+
+class Common extends core::Object {
+ synthetic constructor •() → com::Common
+ : super core::Object::•()
+ ;
+}
+
+constants {
+ #C1 = _in::_Patch {}
+}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/main.dart.weak.modular.expect b/pkg/front_end/testcases/general/nested_lib_spec/main.dart.weak.modular.expect
new file mode 100644
index 0000000..bbfc87a
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/main.dart.weak.modular.expect
@@ -0,0 +1,109 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:test" as test;
+import "dart:extra" as ext;
+import "dart:sub" as sub;
+import "dart:sub2" as sub2;
+import "dart:super1" as sup;
+import "dart:super2" as sup2;
+import "dart:common" as com;
+
+import "dart:test";
+import "dart:extra";
+import "dart:sub";
+import "dart:sub2";
+import "dart:super1";
+import "dart:super2";
+import "dart:common";
+
+static method main() → dynamic {
+ new test::Class::•();
+ new ext::Extra::•();
+ new sub::Sub::•();
+ new sub2::Sub2::•();
+ new sup::Super1::•();
+ new sup2::Super2::•();
+ new com::Common::•();
+}
+
+library /*isNonNullableByDefault*/;
+import self as test;
+import "dart:_internal" as _in;
+import "dart:core" as core;
+
+import "dart:_internal";
+
+@#C1
+class Class extends core::Object {
+ synthetic constructor •() → test::Class
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as ext;
+import "dart:_internal" as _in;
+import "dart:core" as core;
+
+import "dart:_internal";
+
+@#C1
+class Extra extends core::Object {
+ synthetic constructor •() → ext::Extra
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as sub;
+import "dart:core" as core;
+
+class Sub extends core::Object {
+ synthetic constructor •() → sub::Sub
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as sub2;
+import "dart:core" as core;
+
+class Sub2 extends core::Object {
+ synthetic constructor •() → sub2::Sub2
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as sup;
+import "dart:core" as core;
+
+class Super1 extends core::Object {
+ synthetic constructor •() → sup::Super1
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as sup2;
+import "dart:core" as core;
+
+class Super2 extends core::Object {
+ synthetic constructor •() → sup2::Super2
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as com;
+import "dart:core" as core;
+
+class Common extends core::Object {
+ synthetic constructor •() → com::Common
+ : super core::Object::•()
+ ;
+}
+
+constants {
+ #C1 = _in::_Patch {}
+}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/main.dart.weak.outline.expect b/pkg/front_end/testcases/general/nested_lib_spec/main.dart.weak.outline.expect
new file mode 100644
index 0000000..9c88621
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/main.dart.weak.outline.expect
@@ -0,0 +1,90 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "dart:test";
+import "dart:extra";
+import "dart:sub";
+import "dart:sub2";
+import "dart:super1";
+import "dart:super2";
+import "dart:common";
+
+static method main() → dynamic
+ ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:_internal" as _in;
+import "dart:core" as core;
+
+import "dart:_internal";
+
+@_in::patch
+class Class extends core::Object {
+ synthetic constructor •() → self2::Class
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as self3;
+import "dart:_internal" as _in;
+import "dart:core" as core;
+
+import "dart:_internal";
+
+@_in::patch
+class Extra extends core::Object {
+ synthetic constructor •() → self3::Extra
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as self4;
+import "dart:core" as core;
+
+class Sub extends core::Object {
+ synthetic constructor •() → self4::Sub
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as self5;
+import "dart:core" as core;
+
+class Sub2 extends core::Object {
+ synthetic constructor •() → self5::Sub2
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as self6;
+import "dart:core" as core;
+
+class Super1 extends core::Object {
+ synthetic constructor •() → self6::Super1
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as self7;
+import "dart:core" as core;
+
+class Super2 extends core::Object {
+ synthetic constructor •() → self7::Super2
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as self8;
+import "dart:core" as core;
+
+class Common extends core::Object {
+ synthetic constructor •() → self8::Common
+ ;
+}
+
+
+Extra constant evaluation status:
+Evaluated: StaticGet @ (unknown position in org-dartlang-testcase:///origin_lib.dart) -> InstanceConstant(const _Patch{})
+Evaluated: StaticGet @ (unknown position in org-dartlang-testcase:///extra_lib.dart) -> InstanceConstant(const _Patch{})
+Extra constant evaluation: evaluated: 2, effectively constant: 2
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/main.dart.weak.transformed.expect b/pkg/front_end/testcases/general/nested_lib_spec/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..bbfc87a
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/main.dart.weak.transformed.expect
@@ -0,0 +1,109 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:test" as test;
+import "dart:extra" as ext;
+import "dart:sub" as sub;
+import "dart:sub2" as sub2;
+import "dart:super1" as sup;
+import "dart:super2" as sup2;
+import "dart:common" as com;
+
+import "dart:test";
+import "dart:extra";
+import "dart:sub";
+import "dart:sub2";
+import "dart:super1";
+import "dart:super2";
+import "dart:common";
+
+static method main() → dynamic {
+ new test::Class::•();
+ new ext::Extra::•();
+ new sub::Sub::•();
+ new sub2::Sub2::•();
+ new sup::Super1::•();
+ new sup2::Super2::•();
+ new com::Common::•();
+}
+
+library /*isNonNullableByDefault*/;
+import self as test;
+import "dart:_internal" as _in;
+import "dart:core" as core;
+
+import "dart:_internal";
+
+@#C1
+class Class extends core::Object {
+ synthetic constructor •() → test::Class
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as ext;
+import "dart:_internal" as _in;
+import "dart:core" as core;
+
+import "dart:_internal";
+
+@#C1
+class Extra extends core::Object {
+ synthetic constructor •() → ext::Extra
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as sub;
+import "dart:core" as core;
+
+class Sub extends core::Object {
+ synthetic constructor •() → sub::Sub
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as sub2;
+import "dart:core" as core;
+
+class Sub2 extends core::Object {
+ synthetic constructor •() → sub2::Sub2
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as sup;
+import "dart:core" as core;
+
+class Super1 extends core::Object {
+ synthetic constructor •() → sup::Super1
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as sup2;
+import "dart:core" as core;
+
+class Super2 extends core::Object {
+ synthetic constructor •() → sup2::Super2
+ : super core::Object::•()
+ ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as com;
+import "dart:core" as core;
+
+class Common extends core::Object {
+ synthetic constructor •() → com::Common
+ : super core::Object::•()
+ ;
+}
+
+constants {
+ #C1 = _in::_Patch {}
+}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/origin_lib.dart b/pkg/front_end/testcases/general/nested_lib_spec/origin_lib.dart
new file mode 100644
index 0000000..6d966e0
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/origin_lib.dart
@@ -0,0 +1,5 @@
+// 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.
+
+class Class {}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/patch_lib.dart b/pkg/front_end/testcases/general/nested_lib_spec/patch_lib.dart
new file mode 100644
index 0000000..c134e75
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/patch_lib.dart
@@ -0,0 +1,9 @@
+// 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.
+
+// ignore: import_internal_library
+import 'dart:_internal';
+
+@patch
+class Class {}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/sub2_lib.dart b/pkg/front_end/testcases/general/nested_lib_spec/sub2_lib.dart
new file mode 100644
index 0000000..5a1f9b0
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/sub2_lib.dart
@@ -0,0 +1,5 @@
+// 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.
+
+class Sub2 {}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/subfolder/sub_lib.dart b/pkg/front_end/testcases/general/nested_lib_spec/subfolder/sub_lib.dart
new file mode 100644
index 0000000..2e54c8c
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/subfolder/sub_lib.dart
@@ -0,0 +1,5 @@
+// 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.
+
+class Sub {}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/subfolder/sub_libraries.json b/pkg/front_end/testcases/general/nested_lib_spec/subfolder/sub_libraries.json
new file mode 100644
index 0000000..ca8782a
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/subfolder/sub_libraries.json
@@ -0,0 +1,21 @@
+{
+ "subtarget": {
+ "include": [
+ {
+ "path": "../super1_libraries.json",
+ "target": "none"
+ },
+ { "path": "../../nested_lib_spec/super2_libraries.json",
+ "target": "none"
+ }
+ ],
+ "libraries": {
+ "sub": {
+ "uri": "sub_lib.dart"
+ },
+ "sub2": {
+ "uri": "../sub2_lib.dart"
+ }
+ }
+ }
+}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/subfolder/super2_lib.dart b/pkg/front_end/testcases/general/nested_lib_spec/subfolder/super2_lib.dart
new file mode 100644
index 0000000..9ac3219
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/subfolder/super2_lib.dart
@@ -0,0 +1,5 @@
+// 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.
+
+class Super2 {}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/super1_lib.dart b/pkg/front_end/testcases/general/nested_lib_spec/super1_lib.dart
new file mode 100644
index 0000000..b7b4486
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/super1_lib.dart
@@ -0,0 +1,5 @@
+// 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.
+
+class Super1 {}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/super1_libraries.json b/pkg/front_end/testcases/general/nested_lib_spec/super1_libraries.json
new file mode 100644
index 0000000..28bd7f2
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/super1_libraries.json
@@ -0,0 +1,9 @@
+{
+ "none": {
+ "libraries": {
+ "super1": {
+ "uri": "super1_lib.dart"
+ }
+ }
+ }
+}
diff --git a/pkg/front_end/testcases/general/nested_lib_spec/super2_libraries.json b/pkg/front_end/testcases/general/nested_lib_spec/super2_libraries.json
new file mode 100644
index 0000000..f89a448
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_lib_spec/super2_libraries.json
@@ -0,0 +1,9 @@
+{
+ "none": {
+ "libraries": {
+ "super2": {
+ "uri": "subfolder/super2_lib.dart"
+ }
+ }
+ }
+}
diff --git a/pkg/js_ast/lib/src/equivalence_visitor.dart b/pkg/js_ast/lib/src/equivalence_visitor.dart
index 8068319..b1a150b 100644
--- a/pkg/js_ast/lib/src/equivalence_visitor.dart
+++ b/pkg/js_ast/lib/src/equivalence_visitor.dart
@@ -340,8 +340,6 @@
if (arg is! VariableInitialization) return failAt(node, arg);
VariableInitialization other = arg;
return testNodes(node.declaration, other.declaration) &&
- testNodes(node.leftHandSide, other.leftHandSide) &&
- testValues(node, node.op, other, other.op) &&
testNodes(node.value, other.value);
}
diff --git a/pkg/js_ast/lib/src/nodes.dart b/pkg/js_ast/lib/src/nodes.dart
index 56a2b40..7c62eab 100644
--- a/pkg/js_ast/lib/src/nodes.dart
+++ b/pkg/js_ast/lib/src/nodes.dart
@@ -126,13 +126,8 @@
T visitVariableDeclarationList(VariableDeclarationList node) =>
visitExpression(node);
T visitAssignment(Assignment node) => visitExpression(node);
- T visitVariableInitialization(VariableInitialization node) {
- if (node.value != null) {
- return visitAssignment(node);
- } else {
- return visitExpression(node);
- }
- }
+ T visitVariableInitialization(VariableInitialization node) =>
+ visitExpression(node);
T visitConditional(Conditional node) => visitExpression(node);
T visitNew(New node) => visitExpression(node);
@@ -338,13 +333,8 @@
R visitVariableDeclarationList(VariableDeclarationList node, A arg) =>
visitExpression(node, arg);
R visitAssignment(Assignment node, A arg) => visitExpression(node, arg);
- R visitVariableInitialization(VariableInitialization node, A arg) {
- if (node.value != null) {
- return visitAssignment(node, arg);
- } else {
- return visitExpression(node, arg);
- }
- }
+ R visitVariableInitialization(VariableInitialization node, A arg) =>
+ visitExpression(node, arg);
R visitConditional(Conditional node, A arg) => visitExpression(node, arg);
R visitNew(New node, A arg) => visitExpression(node, arg);
@@ -1162,12 +1152,13 @@
class Assignment extends Expression {
final Expression leftHandSide;
final String op; // Null, if the assignment is not compound.
- final Expression value; // May be null, for [VariableInitialization]s.
+ final Expression value;
Assignment(leftHandSide, value) : this.compound(leftHandSide, null, value);
// If `this.op == null` this will be a non-compound assignment.
- Assignment.compound(this.leftHandSide, this.op, this.value);
+ Assignment.compound(this.leftHandSide, this.op, this.value)
+ : assert(value != null);
int get precedenceLevel => ASSIGNMENT;
@@ -1180,23 +1171,26 @@
void visitChildren<T>(NodeVisitor<T> visitor) {
leftHandSide.accept(visitor);
- if (value != null) value.accept(visitor);
+ value.accept(visitor);
}
void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
leftHandSide.accept1(visitor, arg);
- if (value != null) value.accept1(visitor, arg);
+ value.accept1(visitor, arg);
}
Assignment _clone() => Assignment.compound(leftHandSide, op, value);
}
-class VariableInitialization extends Assignment {
- /// [value] may be null.
- VariableInitialization(Declaration declaration, Expression value)
- : super(declaration, value);
+class VariableInitialization extends Expression {
+ // TODO(sra): Can [VariableInitialization] be a non-expression?
- Declaration get declaration => leftHandSide;
+ final Declaration declaration;
+ final Expression value; // [value] may be null.
+
+ VariableInitialization(this.declaration, this.value);
+
+ int get precedenceLevel => ASSIGNMENT;
T accept<T>(NodeVisitor<T> visitor) =>
visitor.visitVariableInitialization(this);
@@ -1204,6 +1198,16 @@
R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
visitor.visitVariableInitialization(this, arg);
+ void visitChildren<T>(NodeVisitor<T> visitor) {
+ declaration.accept(visitor);
+ value?.accept(visitor);
+ }
+
+ void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
+ declaration.accept1(visitor, arg);
+ value?.accept1(visitor, arg);
+ }
+
VariableInitialization _clone() => VariableInitialization(declaration, value);
}
diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart
index d5eb576..562107f 100644
--- a/pkg/js_ast/lib/src/printer.dart
+++ b/pkg/js_ast/lib/src/printer.dart
@@ -840,7 +840,15 @@
@override
visitVariableInitialization(VariableInitialization initialization) {
- visitAssignment(initialization);
+ visitNestedExpression(initialization.declaration, CALL,
+ newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
+ if (initialization.value != null) {
+ spaceOut();
+ out("=");
+ spaceOut();
+ visitNestedExpression(initialization.value, ASSIGNMENT,
+ newInForInit: inForInit, newAtStatementBegin: false);
+ }
}
@override
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 701967b..b29c8c1 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -194,6 +194,21 @@
package_config, verbosity());
}
+Dart_KernelCompilationResult DFE::CompileScriptWithGivenNullsafety(
+ const char* script_uri,
+ const char* package_config,
+ bool snapshot,
+ bool null_safety) {
+ // TODO(aam): When Frontend is ready, VM should be passing vm_outline.dill
+ // instead of vm_platform.dill to Frontend for compilation.
+ PathSanitizer path_sanitizer(script_uri);
+ const char* sanitized_uri = path_sanitizer.sanitized_uri();
+
+ return Dart_CompileToKernelWithGivenNullsafety(
+ sanitized_uri, platform_strong_dill, platform_strong_dill_size, snapshot,
+ package_config, null_safety, verbosity());
+}
+
void DFE::CompileAndReadScript(const char* script_uri,
uint8_t** kernel_buffer,
intptr_t* kernel_buffer_size,
diff --git a/runtime/bin/dfe.h b/runtime/bin/dfe.h
index 038bca7..eb18df6 100644
--- a/runtime/bin/dfe.h
+++ b/runtime/bin/dfe.h
@@ -72,6 +72,19 @@
const char* package_config,
bool snapshot);
+ // Compiles specified script.
+ // Returns result from compiling the script.
+ //
+ // `snapshot` is used by the frontend to determine if compilation
+ // related information should be printed to console (e.g., null safety mode).
+ // `null_safety` specifies compilation mode, which is normally
+ // retrieved either from vm flags or from vm isolate group.
+ Dart_KernelCompilationResult CompileScriptWithGivenNullsafety(
+ const char* script_uri,
+ const char* package_config,
+ bool snapshot,
+ bool null_safety);
+
// Compiles specified script and reads the resulting kernel file.
// If the compilation is successful, returns a valid in memory kernel
// representation of the script, NULL otherwise
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index d03555a..cf76d5f 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -96,7 +96,7 @@
SAVE_ERROR_AND_EXIT(result); \
}
-static void WriteDepsFile(Dart_Isolate isolate) {
+static void WriteDepsFile() {
if (Options::depfile() == NULL) {
return;
}
@@ -142,7 +142,7 @@
if (Options::gen_snapshot_kind() == kAppJIT) {
Snapshot::GenerateAppJIT(Options::snapshot_filename());
}
- WriteDepsFile(main_isolate);
+ WriteDepsFile();
}
}
@@ -937,6 +937,20 @@
ErrorExit(exit_code, "%s\n", Dart_GetError(result)); \
}
+static void CompileAndSaveKernel(const char* script_name,
+ const char* package_config_override,
+ CommandLineOptions* dart_options) {
+ if (vm_run_app_snapshot) {
+ Syslog::PrintErr("Cannot create a script snapshot from an app snapshot.\n");
+ // The snapshot would contain references to the app snapshot instead of
+ // the core snapshot.
+ Platform::Exit(kErrorExitCode);
+ }
+ Snapshot::GenerateKernel(Options::snapshot_filename(), script_name,
+ package_config_override);
+ WriteDepsFile();
+}
+
void RunMainIsolate(const char* script_name,
const char* package_config_override,
CommandLineOptions* dart_options) {
@@ -1001,71 +1015,59 @@
Dart_EnterScope();
- auto isolate_group_data =
- reinterpret_cast<IsolateGroupData*>(Dart_IsolateGroupData(isolate));
- if (Options::gen_snapshot_kind() == kKernel) {
- if (vm_run_app_snapshot) {
- Syslog::PrintErr(
- "Cannot create a script snapshot from an app snapshot.\n");
- // The snapshot would contain references to the app snapshot instead of
- // the core snapshot.
- Platform::Exit(kErrorExitCode);
- }
- Snapshot::GenerateKernel(Options::snapshot_filename(), script_name,
- isolate_group_data->resolved_packages_config());
- } else {
- // Lookup the library of the root script.
- Dart_Handle root_lib = Dart_RootLibrary();
+ // Kernel snapshots should have been handled before reaching this point.
+ ASSERT(Options::gen_snapshot_kind() != kKernel);
+ // Lookup the library of the root script.
+ Dart_Handle root_lib = Dart_RootLibrary();
#if !defined(DART_PRECOMPILED_RUNTIME)
- if (Options::compile_all()) {
- result = Dart_CompileAll();
- CHECK_RESULT(result);
- }
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
-
- if (Dart_IsNull(root_lib)) {
- ErrorExit(kErrorExitCode, "Unable to find root library for '%s'\n",
- script_name);
- }
-
- // Create a closure for the main entry point which is in the exported
- // namespace of the root library or invoke a getter of the same name
- // in the exported namespace and return the resulting closure.
- Dart_Handle main_closure =
- Dart_GetField(root_lib, Dart_NewStringFromCString("main"));
- CHECK_RESULT(main_closure);
- if (!Dart_IsClosure(main_closure)) {
- ErrorExit(kErrorExitCode, "Unable to find 'main' in root library '%s'\n",
- script_name);
- }
-
- // Call _startIsolate in the isolate library to enable dispatching the
- // initial startup message.
- const intptr_t kNumIsolateArgs = 2;
- Dart_Handle isolate_args[kNumIsolateArgs];
- isolate_args[0] = main_closure; // entryPoint
- isolate_args[1] = dart_options->CreateRuntimeOptions(); // args
-
- Dart_Handle isolate_lib =
- Dart_LookupLibrary(Dart_NewStringFromCString("dart:isolate"));
- result =
- Dart_Invoke(isolate_lib, Dart_NewStringFromCString("_startMainIsolate"),
- kNumIsolateArgs, isolate_args);
- CHECK_RESULT(result);
-
- // Keep handling messages until the last active receive port is closed.
- result = Dart_RunLoop();
- // Generate an app snapshot after execution if specified.
- if (Options::gen_snapshot_kind() == kAppJIT) {
- if (!Dart_IsCompilationError(result)) {
- Snapshot::GenerateAppJIT(Options::snapshot_filename());
- }
- }
+ if (Options::compile_all()) {
+ result = Dart_CompileAll();
CHECK_RESULT(result);
}
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
- WriteDepsFile(isolate);
+ if (Dart_IsNull(root_lib)) {
+ ErrorExit(kErrorExitCode, "Unable to find root library for '%s'\n",
+ script_name);
+ }
+
+ // Create a closure for the main entry point which is in the exported
+ // namespace of the root library or invoke a getter of the same name
+ // in the exported namespace and return the resulting closure.
+ Dart_Handle main_closure =
+ Dart_GetField(root_lib, Dart_NewStringFromCString("main"));
+ CHECK_RESULT(main_closure);
+ if (!Dart_IsClosure(main_closure)) {
+ ErrorExit(kErrorExitCode, "Unable to find 'main' in root library '%s'\n",
+ script_name);
+ }
+
+ // Call _startIsolate in the isolate library to enable dispatching the
+ // initial startup message.
+ const intptr_t kNumIsolateArgs = 2;
+ Dart_Handle isolate_args[kNumIsolateArgs];
+ isolate_args[0] = main_closure; // entryPoint
+ isolate_args[1] = dart_options->CreateRuntimeOptions(); // args
+
+ Dart_Handle isolate_lib =
+ Dart_LookupLibrary(Dart_NewStringFromCString("dart:isolate"));
+ result =
+ Dart_Invoke(isolate_lib, Dart_NewStringFromCString("_startMainIsolate"),
+ kNumIsolateArgs, isolate_args);
+ CHECK_RESULT(result);
+
+ // Keep handling messages until the last active receive port is closed.
+ result = Dart_RunLoop();
+ // Generate an app snapshot after execution if specified.
+ if (Options::gen_snapshot_kind() == kAppJIT) {
+ if (!Dart_IsCompilationError(result)) {
+ Snapshot::GenerateAppJIT(Options::snapshot_filename());
+ }
+ }
+ CHECK_RESULT(result);
+
+ WriteDepsFile();
Dart_ExitScope();
@@ -1350,8 +1352,14 @@
script_name);
Platform::Exit(kErrorExitCode);
} else {
- // Run the main isolate until we aren't told to restart.
- RunMainIsolate(script_name, package_config_override, &dart_options);
+ if (Options::gen_snapshot_kind() == kKernel) {
+ CompileAndSaveKernel(script_name, package_config_override,
+ &dart_options);
+
+ } else {
+ // Run the main isolate until we aren't told to restart.
+ RunMainIsolate(script_name, package_config_override, &dart_options);
+ }
}
}
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index e213e70..83c1408 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -141,8 +141,10 @@
if (!Options::verbose_option()) {
Syslog::Print(
"Common VM flags:\n"
+#if !defined(PRODUCT)
"--enable-asserts\n"
" Enable assert statements.\n"
+#endif // !defined(PRODUCT)
"--help or -h\n"
" Display this message (add -v or --verbose for information about\n"
" all VM options).\n"
@@ -151,6 +153,7 @@
"--define=<key>=<value> or -D<key>=<value>\n"
" Define an environment declaration. To specify multiple declarations,\n"
" use multiple instances of this option.\n"
+#if !defined(PRODUCT)
"--observe[=<port>[/<bind-address>]]\n"
" The observe flag is a convenience flag used to run a program with a\n"
" set of options which are often useful for debugging under Observatory.\n"
@@ -166,6 +169,7 @@
" Outputs information necessary to connect to the VM service to the\n"
" specified file in JSON format. Useful for clients which are unable to\n"
" listen to stdout for the Observatory listening message.\n"
+#endif // !defined(PRODUCT)
"--snapshot-kind=<snapshot_kind>\n"
"--snapshot=<file_name>\n"
" These snapshot options are used to generate a snapshot of the loaded\n"
@@ -178,8 +182,10 @@
} else {
Syslog::Print(
"Supported options:\n"
+#if !defined(PRODUCT)
"--enable-asserts\n"
" Enable assert statements.\n"
+#endif // !defined(PRODUCT)
"--help or -h\n"
" Display this message (add -v or --verbose for information about\n"
" all VM options).\n"
@@ -188,6 +194,7 @@
"--define=<key>=<value> or -D<key>=<value>\n"
" Define an environment declaration. To specify multiple declarations,\n"
" use multiple instances of this option.\n"
+#if !defined(PRODUCT)
"--observe[=<port>[/<bind-address>]]\n"
" The observe flag is a convenience flag used to run a program with a\n"
" set of options which are often useful for debugging under Observatory.\n"
@@ -199,12 +206,14 @@
" --warn-on-pause-with-no-debugger\n"
" This set is subject to change.\n"
" Please see these options for further documentation.\n"
+#endif // !defined(PRODUCT)
"--version\n"
" Print the VM version.\n"
"\n"
"--trace-loading\n"
" enables tracing of library and script loading\n"
"\n"
+#if !defined(PRODUCT)
"--enable-vm-service[=<port>[/<bind-address>]]\n"
" Enables the VM service and listens on specified port for connections\n"
" (default port number is 8181, default bind address is localhost).\n"
@@ -219,6 +228,7 @@
" When the VM service is told to bind to a particular port, fallback to 0 if\n"
" it fails to bind instead of failing to start.\n"
"\n"
+#endif // !defined(PRODUCT)
"--root-certs-file=<path>\n"
" The path to a file containing the trusted root certificates to use for\n"
" secure socket connections.\n"
@@ -321,6 +331,7 @@
int Options::vm_service_server_port_ = INVALID_VM_SERVICE_SERVER_PORT;
bool Options::ProcessEnableVmServiceOption(const char* arg,
CommandLineOptions* vm_options) {
+#if !defined(PRODUCT)
const char* value =
OptionProcessor::ProcessOption(arg, "--enable-vm-service");
if (value == NULL) {
@@ -339,10 +350,15 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
enable_vm_service_ = true;
return true;
+#else
+ // VM service not available in product mode.
+ return false;
+#endif // !defined(PRODUCT)
}
bool Options::ProcessObserveOption(const char* arg,
CommandLineOptions* vm_options) {
+#if !defined(PRODUCT)
const char* value = OptionProcessor::ProcessOption(arg, "--observe");
if (value == NULL) {
return false;
@@ -366,6 +382,10 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
enable_vm_service_ = true;
return true;
+#else
+ // VM service not available in product mode.
+ return false;
+#endif // !defined(PRODUCT)
}
// Explicitly handle VM flags that can be parsed by DartDev's run command.
diff --git a/runtime/bin/snapshot_utils.cc b/runtime/bin/snapshot_utils.cc
index 754043a..4650da4 100644
--- a/runtime/bin/snapshot_utils.cc
+++ b/runtime/bin/snapshot_utils.cc
@@ -471,6 +471,8 @@
const char* script_name,
const char* package_config) {
#if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) && !defined(TESTING)
+ ASSERT(Dart_CurrentIsolate() == nullptr);
+
uint8_t* kernel_buffer = NULL;
intptr_t kernel_buffer_size = 0;
dfe.ReadScript(script_name, &kernel_buffer, &kernel_buffer_size);
@@ -478,10 +480,23 @@
WriteSnapshotFile(snapshot_filename, kernel_buffer, kernel_buffer_size);
free(kernel_buffer);
} else {
- Dart_KernelCompilationResult result =
- dfe.CompileScript(script_name, false, package_config, true);
+ PathSanitizer script_uri_sanitizer(script_name);
+ PathSanitizer packages_config_sanitizer(package_config);
+
+ bool null_safety =
+ Dart_DetectNullSafety(script_uri_sanitizer.sanitized_uri(),
+ packages_config_sanitizer.sanitized_uri(),
+ DartUtils::original_working_directory,
+ /*isolate_snapshot_data=*/nullptr,
+ /*isolate_snapshot_instructions=*/nullptr,
+ /*kernel_buffer=*/nullptr,
+ /*kernel_buffer_size=*/0);
+
+ Dart_KernelCompilationResult result = dfe.CompileScriptWithGivenNullsafety(
+ script_name, package_config, /*snapshot=*/true, null_safety);
if (result.status != Dart_KernelCompilationStatus_Ok) {
- ErrorExit(kErrorExitCode, "%s\n", result.error);
+ Syslog::PrintErr("%s\n", result.error);
+ Platform::Exit(kCompilationErrorExitCode);
}
WriteSnapshotFile(snapshot_filename, result.kernel, result.kernel_size);
free(result.kernel);
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index f37de2b..1eccda2 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -3685,6 +3685,43 @@
const char* package_config,
Dart_KernelCompilationVerbosityLevel verbosity);
+/**
+ * Compiles the given `script_uri` to a kernel file.
+ *
+ * \param platform_kernel A buffer containing the kernel of the platform (e.g.
+ * `vm_platform_strong.dill`). The VM does not take ownership of this memory.
+ *
+ * \param platform_kernel_size The length of the platform_kernel buffer.
+ *
+ * \param snapshot_compile Set to `true` when the compilation is for a snapshot.
+ * This is used by the frontend to determine if compilation related information
+ * should be printed to console (e.g., null safety mode).
+ *
+ * \param null_safety Provides null-safety mode setting for the compiler.
+ *
+ * \param verbosity Specifies the logging behavior of the kernel compilation
+ * service.
+ *
+ * \return Returns the result of the compilation.
+ *
+ * On a successful compilation the returned [Dart_KernelCompilationResult] has
+ * a status of [Dart_KernelCompilationStatus_Ok] and the `kernel`/`kernel_size`
+ * fields are set. The caller takes ownership of the malloc()ed buffer.
+ *
+ * On a failed compilation the `error` might be set describing the reason for
+ * the failed compilation. The caller takes ownership of the malloc()ed
+ * error.
+ */
+DART_EXPORT Dart_KernelCompilationResult
+Dart_CompileToKernelWithGivenNullsafety(
+ const char* script_uri,
+ const uint8_t* platform_kernel,
+ const intptr_t platform_kernel_size,
+ bool snapshot_compile,
+ const char* package_config,
+ const bool null_safety,
+ Dart_KernelCompilationVerbosityLevel verbosity);
+
typedef struct {
const char* uri;
const char* source;
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 2a2c087..3891afc 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -197,40 +197,15 @@
#if defined(_M_X64) || defined(__x86_64__)
#define HOST_ARCH_X64 1
#define ARCH_IS_64_BIT 1
-#define kFpuRegisterSize 16
-typedef simd128_value_t fpu_register_t;
#elif defined(_M_IX86) || defined(__i386__)
#define HOST_ARCH_IA32 1
#define ARCH_IS_32_BIT 1
-#define kFpuRegisterSize 16
-typedef simd128_value_t fpu_register_t;
#elif defined(__ARMEL__)
#define HOST_ARCH_ARM 1
#define ARCH_IS_32_BIT 1
-#define kFpuRegisterSize 16
-// Mark the fact that we have defined simd_value_t.
-#define SIMD_VALUE_T_
-typedef struct {
- union {
- uint32_t u;
- float f;
- } data_[4];
-} simd_value_t;
-typedef simd_value_t fpu_register_t;
-#define simd_value_safe_load(addr) (*reinterpret_cast<simd_value_t*>(addr))
-#define simd_value_safe_store(addr, value) \
- do { \
- reinterpret_cast<simd_value_t*>(addr)->data_[0] = value.data_[0]; \
- reinterpret_cast<simd_value_t*>(addr)->data_[1] = value.data_[1]; \
- reinterpret_cast<simd_value_t*>(addr)->data_[2] = value.data_[2]; \
- reinterpret_cast<simd_value_t*>(addr)->data_[3] = value.data_[3]; \
- } while (0)
-
#elif defined(__aarch64__)
#define HOST_ARCH_ARM64 1
#define ARCH_IS_64_BIT 1
-#define kFpuRegisterSize 16
-typedef simd128_value_t fpu_register_t;
#else
#error Architecture was not detected as supported by Dart.
#endif
diff --git a/runtime/tests/vm/dart/regress_48043_test.dart b/runtime/tests/vm/dart/regress_48043_test.dart
new file mode 100644
index 0000000..19cf04f
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_48043_test.dart
@@ -0,0 +1,56 @@
+// 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.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/48043.
+// Verifies that loads which may call initializer are not forwarded to
+// a previously stored value if it could be an uninitialized sentinel.
+
+// VMOptions=--deterministic --optimization_counter_threshold=120
+
+import "package:expect/expect.dart";
+
+class LateField1 {
+ late int n;
+
+ LateField1() {
+ print(n);
+ }
+}
+
+class LateField2 {
+ late int n;
+
+ LateField2() {
+ print(n);
+ n = 31999;
+ }
+}
+
+class LateField3 {
+ late int n;
+
+ LateField3() {
+ print(n);
+ n = DateTime.now().millisecondsSinceEpoch;
+ }
+}
+
+void doTests() {
+ Expect.throws(() {
+ LateField1();
+ });
+ Expect.throws(() {
+ LateField2();
+ });
+ Expect.throws(() {
+ final obj = LateField3();
+ print(obj.n);
+ });
+}
+
+void main() {
+ for (int i = 0; i < 150; ++i) {
+ doTests();
+ }
+}
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 2d58396..f4d01aa 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1133,7 +1133,7 @@
}
FinalizeMemberTypes(cls);
- if (cls.is_enum_class()) {
+ if (cls.is_enum_class() && !FLAG_precompiled_mode) {
AllocateEnumValues(cls);
}
@@ -1216,69 +1216,58 @@
}
}
-// Allocate instances for each enumeration value, and populate the
-// static field 'values'.
-// By allocating the instances programmatically, we save an implicit final
-// getter function object for each enumeration value and for the
-// values field. We also don't have to generate the code for these getters
-// from thin air (no source code is available).
+// Eagerly allocate instances for enumeration values by evaluating
+// static const field 'values'. Also, pre-allocate
+// deleted sentinel value. This is needed to correctly
+// migrate enumeration values in case of hot reload.
void ClassFinalizer::AllocateEnumValues(const Class& enum_cls) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
+ const auto& values_field =
+ Field::Handle(zone, enum_cls.LookupStaticField(Symbols::Values()));
+ ASSERT(!values_field.IsNull() && values_field.is_static() &&
+ values_field.is_const());
+
+ const auto& values =
+ Object::Handle(zone, values_field.StaticConstFieldValue());
+ if (values.IsError()) {
+ ReportError(Error::Cast(values));
+ }
+ ASSERT(values.IsArray());
+
// The enum_cls is the actual declared class.
// The shared super-class holds the fields for index and name.
- const Class& super_cls = Class::Handle(zone, enum_cls.SuperClass());
+ const auto& super_cls = Class::Handle(zone, enum_cls.SuperClass());
- const Field& index_field =
+ const auto& index_field =
Field::Handle(zone, super_cls.LookupInstanceField(Symbols::Index()));
ASSERT(!index_field.IsNull());
- const Field& name_field = Field::Handle(
+ const auto& name_field = Field::Handle(
zone, super_cls.LookupInstanceFieldAllowPrivate(Symbols::_name()));
ASSERT(!name_field.IsNull());
- const String& enum_name = String::Handle(zone, enum_cls.ScrubbedName());
+ const auto& enum_name = String::Handle(zone, enum_cls.ScrubbedName());
- const Array& fields = Array::Handle(zone, enum_cls.fields());
- Field& field = Field::Handle(zone);
- Instance& enum_value = Instance::Handle(zone);
- String& enum_ident = String::Handle(zone);
-
- enum_ident =
- Symbols::FromConcat(thread, Symbols::_DeletedEnumPrefix(), enum_name);
- enum_value = Instance::New(enum_cls, Heap::kOld);
- enum_value.SetField(index_field, Smi::Handle(zone, Smi::New(-1)));
- enum_value.SetField(name_field, enum_ident);
- enum_value = enum_value.Canonicalize(thread);
- ASSERT(!enum_value.IsNull());
- ASSERT(enum_value.IsCanonical());
- const Field& sentinel = Field::Handle(
+ const auto& sentinel_ident = String::Handle(
+ zone,
+ Symbols::FromConcat(thread, Symbols::_DeletedEnumPrefix(), enum_name));
+ auto& sentinel_value =
+ Instance::Handle(zone, Instance::New(enum_cls, Heap::kOld));
+ sentinel_value.SetField(index_field, Smi::Handle(zone, Smi::New(-1)));
+ sentinel_value.SetField(name_field, sentinel_ident);
+ sentinel_value = sentinel_value.Canonicalize(thread);
+ ASSERT(!sentinel_value.IsNull());
+ ASSERT(sentinel_value.IsCanonical());
+ const auto& sentinel_field = Field::Handle(
zone, enum_cls.LookupStaticField(Symbols::_DeletedEnumSentinel()));
- ASSERT(!sentinel.IsNull());
+ ASSERT(!sentinel_field.IsNull());
// The static const field contains `Object::null()` instead of
// `Object::sentinel()` - so it's not considered an initializing store.
- sentinel.SetStaticConstFieldValue(enum_value,
- /*assert_initializing_store*/ false);
-
- ASSERT(enum_cls.kernel_offset() > 0);
- Object& error = Error::Handle(zone);
- for (intptr_t i = 0; i < fields.Length(); i++) {
- field = Field::RawCast(fields.At(i));
- if (!field.is_static() || !field.is_const() ||
- (sentinel.ptr() == field.ptr())) {
- continue;
- }
- // Hot-reload expects the static const fields to be evaluated when
- // performing a reload.
- if (!FLAG_precompiled_mode) {
- error = field.StaticConstFieldValue();
- if (error.IsError()) {
- ReportError(Error::Cast(error));
- }
- }
- }
+ sentinel_field.SetStaticConstFieldValue(sentinel_value,
+ /*assert_initializing_store*/ false);
}
void ClassFinalizer::PrintClassInformation(const Class& cls) {
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index a893335..143546b 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -2455,11 +2455,6 @@
if (cls.is_allocated()) {
retain = true;
}
- if (cls.is_enum_class()) {
- // Enum classes have live instances, so we cannot unregister
- // them.
- retain = true;
- }
constants = cls.constants();
retained_constants = GrowableObjectArray::New();
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 0c396e7..12398f9 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -1379,6 +1379,17 @@
}
}
+void Assembler::LoadDImmediate(FpuRegister dst, double immediate) {
+ int64_t bits = bit_cast<int64_t>(immediate);
+ if (bits == 0) {
+ xorps(dst, dst);
+ } else {
+ intptr_t index = FindImmediate(bits);
+ LoadUnboxedDouble(
+ dst, PP, target::ObjectPool::element_offset(index) - kHeapObjectTag);
+ }
+}
+
void Assembler::LoadCompressed(Register dest, const Address& slot) {
#if !defined(DART_COMPRESSED_POINTERS)
movq(dest, slot);
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 5312859..3f4bf92 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -747,6 +747,7 @@
void LoadImmediate(Register reg, int32_t immediate) {
LoadImmediate(reg, Immediate(immediate));
}
+ void LoadDImmediate(FpuRegister dst, double immediate);
void LoadIsolate(Register dst);
void LoadIsolateGroup(Register dst);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index 91cc786..bed125b 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -866,14 +866,7 @@
} else {
ASSERT(!source.IsInvalid());
ASSERT(source.IsConstant());
- if (destination.IsFpuRegister() || destination.IsDoubleStackSlot()) {
- Register scratch = tmp->AllocateTemporary();
- source.constant_instruction()->EmitMoveToLocation(this, destination,
- scratch);
- tmp->ReleaseTemporary();
- } else {
- source.constant_instruction()->EmitMoveToLocation(this, destination);
- }
+ source.constant_instruction()->EmitMoveToLocation(this, destination);
}
}
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 378537a..3066d10 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -560,22 +560,9 @@
__ LoadObject(destination.reg(), value_);
}
} else if (destination.IsFpuRegister()) {
- if (Utils::DoublesBitEqual(Double::Cast(value_).value(), 0.0)) {
- __ xorps(destination.fpu_reg(), destination.fpu_reg());
- } else {
- ASSERT(tmp != kNoRegister);
- __ LoadObject(tmp, value_);
- __ movsd(destination.fpu_reg(),
- compiler::FieldAddress(tmp, Double::value_offset()));
- }
+ __ LoadDImmediate(destination.fpu_reg(), Double::Cast(value_).value());
} else if (destination.IsDoubleStackSlot()) {
- if (Utils::DoublesBitEqual(Double::Cast(value_).value(), 0.0)) {
- __ xorps(FpuTMP, FpuTMP);
- } else {
- ASSERT(tmp != kNoRegister);
- __ LoadObject(tmp, value_);
- __ movsd(FpuTMP, compiler::FieldAddress(tmp, Double::value_offset()));
- }
+ __ LoadDImmediate(FpuTMP, Double::Cast(value_).value());
__ movsd(LocationToStackSlotAddress(destination), FpuTMP);
} else {
ASSERT(destination.IsStackSlot());
@@ -5438,13 +5425,11 @@
XmmRegister base = locs->in(0).fpu_reg();
XmmRegister exp = locs->in(1).fpu_reg();
XmmRegister result = locs->out(0).fpu_reg();
- Register temp = locs->temp(InvokeMathCFunctionInstr::kObjectTempIndex).reg();
XmmRegister zero_temp =
locs->temp(InvokeMathCFunctionInstr::kDoubleTempIndex).fpu_reg();
__ xorps(zero_temp, zero_temp);
- __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)));
- __ movsd(result, compiler::FieldAddress(temp, Double::value_offset()));
+ __ LoadDImmediate(result, 1.0);
compiler::Label check_base, skip_call;
// exponent == 0.0 -> return 1.0;
@@ -5458,15 +5443,13 @@
__ j(EQUAL, &return_base, compiler::Assembler::kNearJump);
// exponent == 2.0 ?
- __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(2.0)));
- __ movsd(XMM0, compiler::FieldAddress(temp, Double::value_offset()));
+ __ LoadDImmediate(XMM0, 2.0);
__ comisd(exp, XMM0);
compiler::Label return_base_times_2;
__ j(EQUAL, &return_base_times_2, compiler::Assembler::kNearJump);
// exponent == 3.0 ?
- __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(3.0)));
- __ movsd(XMM0, compiler::FieldAddress(temp, Double::value_offset()));
+ __ LoadDImmediate(XMM0, 3.0);
__ comisd(exp, XMM0);
__ j(NOT_EQUAL, &check_base);
@@ -5500,22 +5483,19 @@
__ j(PARITY_ODD, &try_sqrt, compiler::Assembler::kNearJump);
// Return NaN.
__ Bind(&return_nan);
- __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(NAN)));
- __ movsd(result, compiler::FieldAddress(temp, Double::value_offset()));
+ __ LoadDImmediate(result, NAN);
__ jmp(&skip_call);
compiler::Label do_pow, return_zero;
__ Bind(&try_sqrt);
// Before calling pow, check if we could use sqrt instead of pow.
- __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(kNegInfinity)));
- __ movsd(result, compiler::FieldAddress(temp, Double::value_offset()));
+ __ LoadDImmediate(result, kNegInfinity);
// base == -Infinity -> call pow;
__ comisd(base, result);
__ j(EQUAL, &do_pow, compiler::Assembler::kNearJump);
// exponent == 0.5 ?
- __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0.5)));
- __ movsd(result, compiler::FieldAddress(temp, Double::value_offset()));
+ __ LoadDImmediate(result, 0.5);
__ comisd(exp, result);
__ j(NOT_EQUAL, &do_pow, compiler::Assembler::kNearJump);
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index e356875..35070d4 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -1837,6 +1837,12 @@
}
}
+ bool CanForwardLoadTo(Definition* load, Definition* replacement) {
+ // Loads which check initialization status can only be replaced if
+ // we can guarantee that forwarded value is not a sentinel.
+ return !(CallsInitializer(load) && replacement->Type()->can_be_sentinel());
+ }
+
// Returns true if given instruction stores the sentinel value.
// Such a store doesn't initialize corresponding field.
bool IsSentinelStore(Instruction* instr) {
@@ -2259,16 +2265,18 @@
ASSERT((out_values != NULL) && ((*out_values)[place_id] != NULL));
Definition* replacement = (*out_values)[place_id];
- graph_->EnsureSSATempIndex(defn, replacement);
- if (FLAG_trace_optimization) {
- THR_Print("Replacing load v%" Pd " with v%" Pd "\n",
- defn->ssa_temp_index(), replacement->ssa_temp_index());
- }
+ if (CanForwardLoadTo(defn, replacement)) {
+ graph_->EnsureSSATempIndex(defn, replacement);
+ if (FLAG_trace_optimization) {
+ THR_Print("Replacing load v%" Pd " with v%" Pd "\n",
+ defn->ssa_temp_index(), replacement->ssa_temp_index());
+ }
- ReplaceLoad(defn, replacement);
- instr_it.RemoveCurrentFromGraph();
- forwarded_ = true;
- continue;
+ ReplaceLoad(defn, replacement);
+ instr_it.RemoveCurrentFromGraph();
+ forwarded_ = true;
+ continue;
+ }
} else if (!kill->Contains(place_id)) {
// This is an exposed load: it is the first representative of a
// given expression id and it is not killed on the path from
@@ -2630,7 +2638,7 @@
// as replaced and store a pointer to the replacement.
replacement = replacement->Replacement();
- if (load != replacement) {
+ if ((load != replacement) && CanForwardLoadTo(load, replacement)) {
graph_->EnsureSSATempIndex(load, replacement);
if (FLAG_trace_optimization) {
diff --git a/runtime/vm/compiler/backend/typed_data_aot_test.cc b/runtime/vm/compiler/backend/typed_data_aot_test.cc
index 1087c72..9b8891e 100644
--- a/runtime/vm/compiler/backend/typed_data_aot_test.cc
+++ b/runtime/vm/compiler/backend/typed_data_aot_test.cc
@@ -95,7 +95,7 @@
void reverse%s(%s list) {
final length = list.length;
- final halfLength = length ~/ 2;
+ final halfLength = length >> 1;
for (int i = 0; i < halfLength; ++i) {
final tmp = list[length-i-1];
list[length-i-1] = list[i];
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index c774203..94b214a 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -288,6 +288,8 @@
typedef QRegister FpuRegister;
const FpuRegister FpuTMP = QTMP;
+const int kFpuRegisterSize = 16;
+typedef simd128_value_t fpu_register_t;
const int kNumberOfFpuRegisters = kNumberOfQRegisters;
const FpuRegister kNoFpuRegister = kNoQRegister;
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 7947a60..9e4213d 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -123,6 +123,8 @@
// Architecture independent aliases.
typedef VRegister FpuRegister;
const FpuRegister FpuTMP = VTMP;
+const int kFpuRegisterSize = 16;
+typedef simd128_value_t fpu_register_t;
const int kNumberOfFpuRegisters = kNumberOfVRegisters;
const FpuRegister kNoFpuRegister = kNoVRegister;
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index 4a497730..bac9dd5 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -61,6 +61,8 @@
// Architecture independent aliases.
typedef XmmRegister FpuRegister;
const FpuRegister FpuTMP = XMM7;
+const int kFpuRegisterSize = 16;
+typedef simd128_value_t fpu_register_t;
const int kNumberOfFpuRegisters = kNumberOfXmmRegisters;
const FpuRegister kNoFpuRegister = kNoXmmRegister;
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 3e7f3c5..2bc9444 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -93,6 +93,8 @@
// Architecture independent aliases.
typedef XmmRegister FpuRegister;
const FpuRegister FpuTMP = XMM15;
+const int kFpuRegisterSize = 16;
+typedef simd128_value_t fpu_register_t;
const int kNumberOfFpuRegisters = kNumberOfXmmRegisters;
const FpuRegister kNoFpuRegister = kNoXmmRegister;
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index fe7dcc4..a4e6c1a 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -6076,7 +6076,7 @@
result = KernelIsolate::CompileToKernel(
script_uri, platform_kernel, platform_kernel_size, 0, NULL,
incremental_compile, snapshot_compile, package_config, NULL, NULL,
- verbosity);
+ FLAG_sound_null_safety, verbosity);
if (result.status == Dart_KernelCompilationStatus_Ok) {
Dart_KernelCompilationResult accept_result =
KernelIsolate::AcceptCompilation();
@@ -6091,6 +6091,34 @@
return result;
}
+DART_EXPORT Dart_KernelCompilationResult
+Dart_CompileToKernelWithGivenNullsafety(
+ const char* script_uri,
+ const uint8_t* platform_kernel,
+ intptr_t platform_kernel_size,
+ bool snapshot_compile,
+ const char* package_config,
+ bool null_safety,
+ Dart_KernelCompilationVerbosityLevel verbosity) {
+ API_TIMELINE_DURATION(Thread::Current());
+
+ Dart_KernelCompilationResult result = {};
+#if defined(DART_PRECOMPILED_RUNTIME)
+ result.status = Dart_KernelCompilationStatus_Unknown;
+ result.error = Utils::StrDup("Dart_CompileToKernel is unsupported.");
+#else
+ intptr_t null_safety_option =
+ null_safety ? kNullSafetyOptionStrong : kNullSafetyOptionWeak;
+ result = KernelIsolate::CompileToKernel(
+ script_uri, platform_kernel, platform_kernel_size,
+ /*source_files_count=*/0, /*source_files=*/nullptr,
+ /*incremental_compile=*/false, snapshot_compile, package_config,
+ /*multiroot_filepaths=*/nullptr, /*multiroot_scheme=*/nullptr,
+ null_safety_option, verbosity);
+#endif
+ return result;
+}
+
DART_EXPORT Dart_KernelCompilationResult Dart_KernelListDependencies() {
Dart_KernelCompilationResult result = {};
#if defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 11d116a..c61d766 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -991,7 +991,11 @@
TransitionVMToNative transition(Thread::Current());
retval = KernelIsolate::CompileToKernel(
root_lib_url, nullptr, 0, modified_scripts_count, modified_scripts,
- true, false, nullptr);
+ /*incremental_compile=*/true,
+ /*snapshot_compile=*/false,
+ /*package_config=*/nullptr,
+ /*multiroot_filepaths=*/nullptr,
+ /*multiroot_scheme=*/nullptr, FLAG_sound_null_safety);
}
if (retval.status != Dart_KernelCompilationStatus_Ok) {
if (retval.kernel != nullptr) {
@@ -1556,9 +1560,8 @@
ASSERT(new_cls.is_enum_class() == old_cls.is_enum_class());
if (new_cls.is_enum_class() && new_cls.is_finalized()) {
new_cls.ReplaceEnum(this, old_cls);
- } else {
- new_cls.CopyStaticFieldValues(this, old_cls);
}
+ new_cls.CopyStaticFieldValues(this, old_cls);
old_cls.PatchFieldsAndFunctions();
old_cls.MigrateImplicitStaticClosures(this, new_cls);
}
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 8926b5d..7e098bf 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -721,6 +721,7 @@
const char* package_config,
const char* multiroot_filepaths,
const char* multiroot_scheme,
+ intptr_t default_null_safety,
const MallocGrowableArray<char*>* experimental_flags,
const char* original_working_directory,
Dart_KernelCompilationVerbosityLevel verbosity) {
@@ -809,7 +810,7 @@
(isolate_group != nullptr)
? (isolate_group->null_safety() ? kNullSafetyOptionStrong
: kNullSafetyOptionWeak)
- : FLAG_sound_null_safety;
+ : default_null_safety;
intptr_t num_experimental_flags = experimental_flags->length();
Dart_CObject** experimental_flags_array =
@@ -1052,6 +1053,7 @@
const char* package_config,
const char* multiroot_filepaths,
const char* multiroot_scheme,
+ intptr_t default_null_safety,
Dart_KernelCompilationVerbosityLevel verbosity) {
// Start the kernel Isolate if it is not already running.
if (!Start()) {
@@ -1076,8 +1078,8 @@
kCompileTag, kernel_port, script_uri, platform_kernel,
platform_kernel_size, source_file_count, source_files,
incremental_compile, snapshot_compile, package_config,
- multiroot_filepaths, multiroot_scheme, experimental_flags_, NULL,
- verbosity);
+ multiroot_filepaths, multiroot_scheme, default_null_safety,
+ experimental_flags_, NULL, verbosity);
}
bool KernelIsolate::DetectNullSafety(const char* script_uri,
@@ -1095,7 +1097,8 @@
KernelCompilationRequest request;
Dart_KernelCompilationResult result = request.SendAndWaitForResponse(
kDetectNullabilityTag, kernel_port, script_uri, nullptr, -1, 0, nullptr,
- false, false, package_config, nullptr, nullptr, experimental_flags_,
+ false, false, package_config, nullptr, nullptr,
+ /*default_null_safety=*/kNullSafetyOptionUnspecified, experimental_flags_,
original_working_directory, Dart_KernelCompilationVerbosityLevel_Error);
return result.null_safety;
}
@@ -1112,8 +1115,8 @@
KernelCompilationRequest request;
return request.SendAndWaitForResponse(
kListDependenciesTag, kernel_port, NULL, NULL, 0, 0, NULL, false, false,
- NULL, NULL, NULL, experimental_flags_, NULL,
- Dart_KernelCompilationVerbosityLevel_Error);
+ NULL, NULL, NULL, /*default_null_safety=*/kNullSafetyOptionUnspecified,
+ experimental_flags_, NULL, Dart_KernelCompilationVerbosityLevel_Error);
}
Dart_KernelCompilationResult KernelIsolate::AcceptCompilation() {
@@ -1130,8 +1133,8 @@
KernelCompilationRequest request;
return request.SendAndWaitForResponse(
kAcceptTag, kernel_port, NULL, NULL, 0, 0, NULL, true, false, NULL, NULL,
- NULL, experimental_flags_, NULL,
- Dart_KernelCompilationVerbosityLevel_Error);
+ NULL, /*default_null_safety=*/kNullSafetyOptionUnspecified,
+ experimental_flags_, NULL, Dart_KernelCompilationVerbosityLevel_Error);
}
Dart_KernelCompilationResult KernelIsolate::CompileExpressionToKernel(
@@ -1177,8 +1180,9 @@
KernelCompilationRequest request;
return request.SendAndWaitForResponse(
kUpdateSourcesTag, kernel_port, NULL, NULL, 0, source_files_count,
- source_files, true, false, NULL, NULL, NULL, experimental_flags_, NULL,
- Dart_KernelCompilationVerbosityLevel_Error);
+ source_files, true, false, NULL, NULL, NULL,
+ /*default_null_safety=*/kNullSafetyOptionUnspecified, experimental_flags_,
+ NULL, Dart_KernelCompilationVerbosityLevel_Error);
}
void KernelIsolate::NotifyAboutIsolateGroupShutdown(
diff --git a/runtime/vm/kernel_isolate.h b/runtime/vm/kernel_isolate.h
index 5880beb..d5d5297 100644
--- a/runtime/vm/kernel_isolate.h
+++ b/runtime/vm/kernel_isolate.h
@@ -55,6 +55,7 @@
const char* package_config = NULL,
const char* multiroot_filepaths = NULL,
const char* multiroot_scheme = NULL,
+ intptr_t default_null_safety = kNullSafetyOptionUnspecified,
Dart_KernelCompilationVerbosityLevel verbosity =
Dart_KernelCompilationVerbosityLevel_All);
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index 5ed79a5..d4ed8d0 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -192,9 +192,6 @@
void Class::CopyStaticFieldValues(ProgramReloadContext* reload_context,
const Class& old_cls) const {
- // We only update values for non-enum classes.
- const bool update_values = !is_enum_class();
-
const Array& old_field_list = Array::Handle(old_cls.fields());
Field& old_field = Field::Handle();
String& old_name = String::Handle();
@@ -215,7 +212,7 @@
if (field.is_static()) {
// We only copy values if requested and if the field is not a const
// field. We let const fields be updated with a reload.
- if (update_values && !field.is_const()) {
+ if (!field.is_const()) {
// Make new field point to the old field value so that both
// old and new code see and update same value.
reload_context->isolate_group()->FreeStaticField(field);
@@ -307,15 +304,15 @@
Zone* zone = Thread::Current()->zone();
- Array& enum_fields = Array::Handle(zone);
Field& field = Field::Handle(zone);
+ Class& cls = Class::Handle(zone);
String& enum_ident = String::Handle();
Instance& old_enum_value = Instance::Handle(zone);
Instance& enum_value = Instance::Handle(zone);
// The E.values array.
- Instance& old_enum_values = Instance::Handle(zone);
+ Array& old_enum_values = Array::Handle(zone);
// The E.values array.
- Instance& enum_values = Instance::Handle(zone);
+ Array& enum_values = Array::Handle(zone);
// The E._deleted_enum_sentinel instance.
Instance& old_deleted_enum_sentinel = Instance::Handle(zone);
// The E._deleted_enum_sentinel instance.
@@ -327,31 +324,26 @@
TIR_Print("Replacing enum `%s`\n", String::Handle(Name()).ToCString());
{
+ field = old_enum.LookupStaticField(Symbols::Values());
+ ASSERT(!field.IsNull() && field.is_static() && field.is_const());
+ old_enum_values ^= field.StaticConstFieldValue();
+ ASSERT(!old_enum_values.IsNull());
+
+ field = old_enum.LookupStaticField(Symbols::_DeletedEnumSentinel());
+ ASSERT(!field.IsNull() && field.is_static() && field.is_const());
+ old_deleted_enum_sentinel ^= field.StaticConstFieldValue();
+ ASSERT(!old_deleted_enum_sentinel.IsNull());
+
+ cls = old_enum.SuperClass();
+ field = cls.LookupInstanceFieldAllowPrivate(Symbols::_name());
+ ASSERT(!field.IsNull());
+
UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.ptr());
// Build a map of all enum name -> old enum instance.
- enum_fields = old_enum.fields();
- for (intptr_t i = 0; i < enum_fields.Length(); i++) {
- field = Field::RawCast(enum_fields.At(i));
- enum_ident = field.name();
- if (!field.is_static()) {
- // Enum instances are only held in static fields.
- continue;
- }
- ASSERT(field.is_const());
- if (enum_ident.Equals(Symbols::Values())) {
- old_enum_values = Instance::RawCast(field.StaticConstFieldValue());
- // Non-enum instance.
- continue;
- }
- if (enum_ident.Equals(Symbols::_DeletedEnumSentinel())) {
- old_deleted_enum_sentinel =
- Instance::RawCast(field.StaticConstFieldValue());
- // Non-enum instance.
- continue;
- }
- old_enum_value = Instance::RawCast(field.StaticConstFieldValue());
-
+ for (intptr_t i = 0, n = old_enum_values.Length(); i < n; ++i) {
+ old_enum_value ^= old_enum_values.At(i);
ASSERT(!old_enum_value.IsNull());
+ enum_ident ^= old_enum_value.GetField(field);
VTIR_Print("Element %s being added to mapping\n", enum_ident.ToCString());
bool update = enum_map.UpdateOrInsert(enum_ident, old_enum_value);
VTIR_Print("Element %s added to mapping\n", enum_ident.ToCString());
@@ -364,31 +356,27 @@
bool enums_deleted = false;
{
+ field = LookupStaticField(Symbols::Values());
+ ASSERT(!field.IsNull() && field.is_static() && field.is_const());
+ enum_values ^= field.StaticConstFieldValue();
+ ASSERT(!enum_values.IsNull());
+
+ field = LookupStaticField(Symbols::_DeletedEnumSentinel());
+ ASSERT(!field.IsNull() && field.is_static() && field.is_const());
+ deleted_enum_sentinel ^= field.StaticConstFieldValue();
+ ASSERT(!deleted_enum_sentinel.IsNull());
+
+ cls = SuperClass();
+ field = cls.LookupInstanceFieldAllowPrivate(Symbols::_name());
+ ASSERT(!field.IsNull());
+
UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.ptr());
// Add a become mapping from the old instances to the new instances.
- enum_fields = fields();
- for (intptr_t i = 0; i < enum_fields.Length(); i++) {
- field = Field::RawCast(enum_fields.At(i));
- enum_ident = field.name();
- if (!field.is_static()) {
- // Enum instances are only held in static fields.
- continue;
- }
- ASSERT(field.is_const());
- if (enum_ident.Equals(Symbols::Values())) {
- enum_values = Instance::RawCast(field.StaticConstFieldValue());
- // Non-enum instance.
- continue;
- }
- if (enum_ident.Equals(Symbols::_DeletedEnumSentinel())) {
- deleted_enum_sentinel =
- Instance::RawCast(field.StaticConstFieldValue());
- // Non-enum instance.
- continue;
- }
- enum_value = Instance::RawCast(field.StaticConstFieldValue());
-
+ for (intptr_t i = 0, n = enum_values.Length(); i < n; ++i) {
+ enum_value ^= enum_values.At(i);
ASSERT(!enum_value.IsNull());
+ enum_ident ^= enum_value.GetField(field);
+
old_enum_value ^= enum_map.GetOrNull(enum_ident);
if (old_enum_value.IsNull()) {
VTIR_Print("New element %s was not found in mapping\n",
@@ -408,13 +396,9 @@
}
// Map the old E.values array to the new E.values array.
- ASSERT(!old_enum_values.IsNull());
- ASSERT(!enum_values.IsNull());
reload_context->AddBecomeMapping(old_enum_values, enum_values);
// Map the old E._deleted_enum_sentinel to the new E._deleted_enum_sentinel.
- ASSERT(!old_deleted_enum_sentinel.IsNull());
- ASSERT(!deleted_enum_sentinel.IsNull());
reload_context->AddBecomeMapping(old_deleted_enum_sentinel,
deleted_enum_sentinel);
diff --git a/runtime/vm/simulator_arm.h b/runtime/vm/simulator_arm.h
index 8074d56..61beaec 100644
--- a/runtime/vm/simulator_arm.h
+++ b/runtime/vm/simulator_arm.h
@@ -25,14 +25,12 @@
class SimulatorSetjmpBuffer;
class Thread;
-#if !defined(SIMD_VALUE_T_)
typedef struct {
union {
uint32_t u;
float f;
} data_[4];
} simd_value_t;
-#endif
class Simulator {
public:
diff --git a/sdk/lib/core/pattern.dart b/sdk/lib/core/pattern.dart
index 23b4445..7facb38 100644
--- a/sdk/lib/core/pattern.dart
+++ b/sdk/lib/core/pattern.dart
@@ -26,7 +26,7 @@
///
/// Returns a match if the pattern matches a substring of [string]
/// starting at [start], and `null` if the pattern doesn't match
- /// a that point.
+ /// at that point.
///
/// The [start] must be non-negative and no greater than `string.length`.
Match? matchAsPrefix(String string, [int start = 0]);
@@ -41,10 +41,10 @@
/// The following example finds all matches of a [RegExp] in a [String]
/// and iterates through the returned iterable of `Match` objects.
/// ```dart
-/// RegExp exp = RegExp(r"(\w+)");
-/// String str = "Parse my string";
-/// Iterable<Match> matches = exp.allMatches(str);
-/// for (Match m in matches) {
+/// final regExp = RegExp(r'(\w+)');
+/// const string = 'Parse my string';
+/// final matches = regExp.allMatches(string);
+/// for (final m in matches) {
/// String match = m[0]!;
/// print(match);
/// }
@@ -72,6 +72,17 @@
///
/// The result may be `null` if the pattern didn't assign a value to it
/// as part of this match.
+ /// ```dart import dart:convert
+ ///
+ /// final string = '[00:13.37] This is a chat message.';
+ /// final regExp = RegExp(r'^\[\s*(\d+):(\d+)\.(\d+)\]\s*(.*)$');
+ /// final match = regExp.firstMatch(string)!;
+ /// final message = jsonEncode(match[0]!); // '[00:13.37] This is a chat message.'
+ /// final hours = jsonEncode(match[1]!); // '00'
+ /// final minutes = jsonEncode(match[2]!); // '13'
+ /// final seconds = jsonEncode(match[3]!); // '37'
+ /// final text = jsonEncode(match[4]!); // 'This is a chat message.'
+ /// ```
String? group(int group);
/// The string matched by the given [group].
@@ -85,6 +96,14 @@
///
/// The list contains the strings returned by [group] for each index in
/// [groupIndices].
+ /// ```dart import dart:convert
+ ///
+ /// final string = '[00:13.37] This is a chat message.';
+ /// final regExp = RegExp(r'^\[\s*(\d+):(\d+)\.(\d+)\]\s*(.*)$');
+ /// final match = regExp.firstMatch(string)!;
+ /// final message = jsonEncode(match.groups([1, 2, 3, 4]));
+ /// // ['00','13','37','This is a chat message.']
+ /// ```
List<String?> groups(List<int> groupIndices);
/// Returns the number of captured groups in the match.
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index c59dc6f..c9a168a 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -154,27 +154,12 @@
}
},
"dart2js": {
+ "include": [
+ {
+ "target": "_dart2js_common"
+ }
+ ],
"libraries": {
- "async": {
- "uri": "async/async.dart",
- "patches": "_internal/js_runtime/lib/async_patch.dart"
- },
- "collection": {
- "uri": "collection/collection.dart",
- "patches": "_internal/js_runtime/lib/collection_patch.dart"
- },
- "convert": {
- "uri": "convert/convert.dart",
- "patches": "_internal/js_runtime/lib/convert_patch.dart"
- },
- "core": {
- "uri": "core/core.dart",
- "patches": "_internal/js_runtime/lib/core_patch.dart"
- },
- "developer": {
- "uri": "developer/developer.dart",
- "patches": "_internal/js_runtime/lib/developer_patch.dart"
- },
"html": {
"uri": "html/dart2js/html_dart2js.dart"
},
@@ -184,44 +169,10 @@
"indexed_db": {
"uri": "indexed_db/dart2js/indexed_db_dart2js.dart"
},
- "_http": {
- "uri": "_http/http.dart"
- },
- "io": {
- "uri": "io/io.dart",
- "patches": "_internal/js_runtime/lib/io_patch.dart",
- "supported": false
- },
- "isolate": {
- "uri": "isolate/isolate.dart",
- "patches": "_internal/js_runtime/lib/isolate_patch.dart",
- "supported": false
- },
- "js": {
- "uri": "js/js.dart",
- "patches": "_internal/js_runtime/lib/js_patch.dart"
- },
"_js": {
"uri": "js/_js.dart",
"patches": "js/_js_client.dart"
},
- "_js_annotations": {
- "uri": "js/_js_annotations.dart"
- },
- "js_util": {
- "uri": "js_util/js_util.dart"
- },
- "math": {
- "uri": "math/math.dart",
- "patches": "_internal/js_runtime/lib/math_patch.dart"
- },
- "typed_data": {
- "uri": "typed_data/typed_data.dart",
- "patches": "_internal/js_runtime/lib/typed_data_patch.dart"
- },
- "_native_typed_data": {
- "uri": "_internal/js_runtime/lib/native_typed_data.dart"
- },
"svg": {
"uri": "svg/dart2js/svg_dart2js.dart"
},
@@ -234,46 +185,25 @@
"_dart2js_runtime_metrics": {
"uri": "_internal/js_runtime/lib/dart2js_runtime_metrics.dart"
},
- "_internal": {
- "uri": "internal/internal.dart",
- "patches": "_internal/js_runtime/lib/internal_patch.dart"
- },
- "_js_helper": {
- "uri": "_internal/js_runtime/lib/js_helper.dart"
- },
- "_late_helper": {
- "uri": "_internal/js_runtime/lib/late_helper.dart"
- },
- "_rti": {
- "uri": "_internal/js_runtime/lib/rti.dart"
- },
- "_interceptors": {
- "uri": "_internal/js_runtime/lib/interceptors.dart"
- },
- "_foreign_helper": {
- "uri": "_internal/js_runtime/lib/foreign_helper.dart"
- },
- "_js_names": {
- "uri": "_internal/js_runtime/lib/js_names.dart"
- },
- "_js_primitives": {
- "uri": "_internal/js_runtime/lib/js_primitives.dart"
- },
- "_js_embedded_names": {
- "uri": "_internal/js_runtime/lib/shared/embedded_names.dart"
- },
- "_async_await_error_codes": {
- "uri": "_internal/js_runtime/lib/shared/async_await_error_codes.dart"
- },
- "_recipe_syntax": {
- "uri": "_internal/js_runtime/lib/shared/recipe_syntax.dart"
- },
"_metadata": {
"uri": "html/html_common/metadata.dart"
}
}
},
"dart2js_server": {
+ "include": [
+ {
+ "target": "_dart2js_common"
+ }
+ ],
+ "libraries": {
+ "_js": {
+ "uri": "js/_js.dart",
+ "patches": "js/_js_server.dart"
+ }
+ }
+ },
+ "_dart2js_common": {
"libraries": {
"async": {
"uri": "async/async.dart",
@@ -312,10 +242,6 @@
"uri": "js/js.dart",
"patches": "_internal/js_runtime/lib/js_patch.dart"
},
- "_js": {
- "uri": "js/_js.dart",
- "patches": "js/_js_server.dart"
- },
"_js_annotations": {
"uri": "js/_js_annotations.dart"
},
@@ -476,4 +402,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index 812487a..4aab70c 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -152,27 +152,9 @@
uri: "_internal/vm/bin/vmservice_io.dart"
dart2js:
+ include:
+ - target: "_dart2js_common"
libraries:
- async:
- uri: "async/async.dart"
- patches: "_internal/js_runtime/lib/async_patch.dart"
-
- collection:
- uri: "collection/collection.dart"
- patches: "_internal/js_runtime/lib/collection_patch.dart"
-
- convert:
- uri: "convert/convert.dart"
- patches: "_internal/js_runtime/lib/convert_patch.dart"
-
- core:
- uri: "core/core.dart"
- patches: "_internal/js_runtime/lib/core_patch.dart"
-
- developer:
- uri: "developer/developer.dart"
- patches: "_internal/js_runtime/lib/developer_patch.dart"
-
html:
uri: "html/dart2js/html_dart2js.dart"
@@ -182,44 +164,10 @@
indexed_db:
uri: "indexed_db/dart2js/indexed_db_dart2js.dart"
- _http:
- uri: "_http/http.dart"
-
- io:
- uri: "io/io.dart"
- patches: "_internal/js_runtime/lib/io_patch.dart"
- supported: false
-
- isolate:
- uri: "isolate/isolate.dart"
- patches: "_internal/js_runtime/lib/isolate_patch.dart"
- supported: false
-
- js:
- uri: "js/js.dart"
- patches: "_internal/js_runtime/lib/js_patch.dart"
-
_js:
uri: "js/_js.dart"
patches: "js/_js_client.dart"
- _js_annotations:
- uri: "js/_js_annotations.dart"
-
- js_util:
- uri: "js_util/js_util.dart"
-
- math:
- uri: "math/math.dart"
- patches: "_internal/js_runtime/lib/math_patch.dart"
-
- typed_data:
- uri: "typed_data/typed_data.dart"
- patches: "_internal/js_runtime/lib/typed_data_patch.dart"
-
- _native_typed_data:
- uri: "_internal/js_runtime/lib/native_typed_data.dart"
-
svg:
uri: "svg/dart2js/svg_dart2js.dart"
@@ -229,47 +177,18 @@
web_gl:
uri: "web_gl/dart2js/web_gl_dart2js.dart"
- _dart2js_runtime_metrics:
- uri: "_internal/js_runtime/lib/dart2js_runtime_metrics.dart"
-
- _internal:
- uri: "internal/internal.dart"
- patches: "_internal/js_runtime/lib/internal_patch.dart"
-
- _js_helper:
- uri: "_internal/js_runtime/lib/js_helper.dart"
-
- _late_helper:
- uri: "_internal/js_runtime/lib/late_helper.dart"
-
- _rti:
- uri: "_internal/js_runtime/lib/rti.dart"
-
- _interceptors:
- uri: "_internal/js_runtime/lib/interceptors.dart"
-
- _foreign_helper:
- uri: "_internal/js_runtime/lib/foreign_helper.dart"
-
- _js_names:
- uri: "_internal/js_runtime/lib/js_names.dart"
-
- _js_primitives:
- uri: "_internal/js_runtime/lib/js_primitives.dart"
-
- _js_embedded_names:
- uri: "_internal/js_runtime/lib/shared/embedded_names.dart"
-
- _async_await_error_codes:
- uri: "_internal/js_runtime/lib/shared/async_await_error_codes.dart"
-
- _recipe_syntax:
- uri: "_internal/js_runtime/lib/shared/recipe_syntax.dart"
-
_metadata:
uri: "html/html_common/metadata.dart"
dart2js_server:
+ include:
+ - target: "_dart2js_common"
+ libraries:
+ _js:
+ uri: "js/_js.dart"
+ patches: "js/_js_server.dart"
+
+_dart2js_common:
libraries:
async:
uri: "async/async.dart"
@@ -308,10 +227,6 @@
uri: "js/js.dart"
patches: "_internal/js_runtime/lib/js_patch.dart"
- _js:
- uri: "js/_js.dart"
- patches: "js/_js_server.dart"
-
_js_annotations:
uri: "js/_js_annotations.dart"
diff --git a/tools/VERSION b/tools/VERSION
index 0eafd3c..e8362d8 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 16
PATCH 0
-PRERELEASE 153
+PRERELEASE 154
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/utils/application_snapshot.gni b/utils/application_snapshot.gni
index 9c4cd3f..bd07d3a 100644
--- a/utils/application_snapshot.gni
+++ b/utils/application_snapshot.gni
@@ -112,6 +112,7 @@
]
script = gen_kernel_kernel
+ is_product_flag = dart_runtime_mode == "release"
args = [
"--packages=" + rebase_path(dot_packages),
@@ -128,6 +129,7 @@
# (Instead of ensuring every user of the "application_snapshot" /
# "kernel_snapshot" passes this if needed, we always pass it)
"-Dsdk_hash=$sdk_hash",
+ "-Ddart.vm.product=$is_product_flag",
]
args += [ rebase_path(main_dart) ]
}