[roll] Update third-party dart packages
Updated:
Change-Id: If8bf2bc8d032b982afd7d2f60a4f9a7fde5a6e73
diff --git a/built_value/BUILD.gn b/built_value/BUILD.gn
index 6aa0abe..b928ca8 100644
--- a/built_value/BUILD.gn
+++ b/built_value/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for built_value-6.6.0
+# This file is generated by importer.py for built_value-6.7.0
import("//build/dart/dart_library.gni")
diff --git a/built_value/CHANGELOG.md b/built_value/CHANGELOG.md
index 56109c9..ec1b90c 100644
--- a/built_value/CHANGELOG.md
+++ b/built_value/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+# 6.7.0
+
+- Generate code compatible with 'no raw types'.
+
# 6.6.0
- Allow providing your own `toString` via a mixin.
diff --git a/built_value/README.md b/built_value/README.md
index 0bf40f5..5238780 100644
--- a/built_value/README.md
+++ b/built_value/README.md
@@ -104,7 +104,7 @@
snippets support in your favourite text editor. For example, in IntelliJ you
can use following live template:
-```
+```dart
abstract class $CLASS_NAME$ implements Built<$CLASS_NAME$, $CLASS_NAME$Builder> {
$CLASS_NAME$._();
factory $CLASS_NAME$([void Function($CLASS_NAME$Builder) updates]) = _$$$CLASS_NAME$;
@@ -188,12 +188,12 @@
a common usage example is shown here. This example assumes that you are writing
a client for a JSON API representing a person that looks like the following:
-```
+```json
{
- id: 12345,
- age: 35,
- first_name: 'Jimmy',
- hobbies: ['jumping', 'basketball']
+ "id": 12345,
+ "age": 35,
+ "first_name": "Jimmy",
+ "hobbies": ["jumping", "basketball"]
}
```
@@ -206,7 +206,7 @@
annotation to map between the property name on the response and the name of the
member variable in the `Person` class.
-```
+```dart
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:built_collection/built_collection.dart';
diff --git a/built_value/pubspec.yaml b/built_value/pubspec.yaml
index 5b19e01..5667d9e 100644
--- a/built_value/pubspec.yaml
+++ b/built_value/pubspec.yaml
@@ -1,5 +1,5 @@
name: built_value
-version: 6.6.0
+version: 6.7.0
description: >
Value types with builders, Dart classes as enums, and serialization.
This library is the runtime dependency.
diff --git a/connectivity/BUILD.gn b/connectivity/BUILD.gn
index cdd798a..c3ea74e 100644
--- a/connectivity/BUILD.gn
+++ b/connectivity/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for connectivity-0.4.3+2
+# This file is generated by importer.py for connectivity-0.4.3+4
import("//build/dart/dart_library.gni")
diff --git a/connectivity/CHANGELOG.md b/connectivity/CHANGELOG.md
index 8e68043..4aa2f43 100644
--- a/connectivity/CHANGELOG.md
+++ b/connectivity/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 0.4.3+4
+
+* [Android] Updated logic to retrieve network info.
+
+## 0.4.3+3
+
+* Support for TYPE_MOBILE_HIPRI on Android.
+
## 0.4.3+2
* Add missing template type parameter to `invokeMethod` calls.
diff --git a/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityPlugin.java b/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityPlugin.java
index ca2f522..830e701 100644
--- a/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityPlugin.java
+++ b/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityPlugin.java
@@ -70,6 +70,7 @@
return "wifi";
case ConnectivityManager.TYPE_MOBILE:
case ConnectivityManager.TYPE_MOBILE_DUN:
+ case ConnectivityManager.TYPE_MOBILE_HIPRI:
return "mobile";
default:
return "none";
@@ -98,11 +99,15 @@
}
private void handleCheck(MethodCall call, final Result result) {
+ result.success(checkNetworkType());
+ }
+
+ private String checkNetworkType() {
NetworkInfo info = manager.getActiveNetworkInfo();
if (info != null && info.isConnected()) {
- result.success(getNetworkType(info.getType()));
+ return getNetworkType(info.getType());
} else {
- result.success("none");
+ return "none";
}
}
@@ -153,14 +158,7 @@
return new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- boolean isLost = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
- if (isLost) {
- events.success("none");
- return;
- }
-
- int type = intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, -1);
- events.success(getNetworkType(type));
+ events.success(checkNetworkType());
}
};
}
diff --git a/connectivity/pubspec.yaml b/connectivity/pubspec.yaml
index 0f1f83b..788e1d0 100644
--- a/connectivity/pubspec.yaml
+++ b/connectivity/pubspec.yaml
@@ -3,7 +3,7 @@
mobile/cellular) connectivity on Android and iOS.
author: Flutter Team <flutter-dev@googlegroups.com>
homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity
-version: 0.4.3+2
+version: 0.4.3+4
flutter:
plugin:
diff --git a/coverage/.github/no-response.yml b/coverage/.github/no-response.yml
new file mode 100644
index 0000000..d017e04
--- /dev/null
+++ b/coverage/.github/no-response.yml
@@ -0,0 +1,16 @@
+# Configuration for probot-no-response - https://github.com/probot/no-response
+
+# Number of days of inactivity before an Issue is closed for lack of response
+daysUntilClose: 21
+
+# Label requiring a response
+responseRequiredLabel: "awaiting response"
+
+# Comment to post when closing an Issue for lack of response. Set to `false` to disable
+closeComment: >-
+ Without additional information, we are unfortunately not sure how to resolve
+ this issue. We are therefore reluctantly going to close this issue for now.
+ Please don't hesitate to comment on the issue if you have any more
+ information for us; we will reopen it right away!
+
+ Thanks for your contribution.
diff --git a/coverage/.travis.yml b/coverage/.travis.yml
index fecc637..b8b72a4 100644
--- a/coverage/.travis.yml
+++ b/coverage/.travis.yml
@@ -1,10 +1,24 @@
language: dart
+
dart:
- - stable
+ - 2.0.0
+ - dev
+
install:
- gem install coveralls-lcov
+
script: ./tool/travis.sh
+
after_success:
- coveralls-lcov var/lcov.info
+
env:
- DARTANALYZER_FLAGS=--fatal-warnings
+
+# Only building master means that we don't run two builds for each pull request.
+branches:
+ only: [master]
+
+cache:
+ directories:
+ - $HOME/.pub-cache
diff --git a/coverage/BUILD.gn b/coverage/BUILD.gn
index 90fc26d..4768b2a 100644
--- a/coverage/BUILD.gn
+++ b/coverage/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for coverage-0.12.4
+# This file is generated by importer.py for coverage-0.13.0
import("//build/dart/dart_library.gni")
@@ -15,8 +15,8 @@
"//third_party/dart-pkg/pub/stack_trace",
"//third_party/dart-pkg/pub/package_config",
"//third_party/dart-pkg/pub/logging",
- "//third_party/dart-pkg/pub/vm_service_client",
"//third_party/dart-pkg/pub/path",
+ "//third_party/dart-pkg/pub/vm_service_lib",
"//third_party/dart-pkg/pub/args",
]
}
diff --git a/coverage/CHANGELOG.md b/coverage/CHANGELOG.md
index 3f1efec..ae85ed4 100644
--- a/coverage/CHANGELOG.md
+++ b/coverage/CHANGELOG.md
@@ -1,8 +1,21 @@
+## 0.13.0 - 2019-07-10
+
+ * BREAKING CHANGE: Skips collecting coverage for `dart:` libaries by default,
+ which provides a significant performance boost. To restore the previous
+ behaviour and collect coverage for these libraries, use the `--include-dart`
+ flag.
+ * Disables WebSocket compression for coverage collection. Since almost all
+ coverage collection runs happen over the loopback interface to localhost,
+ this improves performance and reduces CPU usage.
+ * Migrates implementation of VM service protocol library from
+ `package:vm_service_client`, which is no longer maintained, to
+ `package:vm_service_lib`, which is.
+
## 0.12.4 - 2019-01-11
* `collect()` now immediately throws `ArgumentError` if a null URI is passed
- in the `serviceUri` parameter to avoid a less-easily debuggable null
- dereference later. See dart-lang/coverage#240 for details.
+ in the `serviceUri` parameter to avoid a less-easily debuggable null
+ dereference later. See dart-lang/coverage#240 for details.
## 0.12.3 - 2018-10-19
diff --git a/coverage/analysis_options.yaml b/coverage/analysis_options.yaml
index 9cc7184..5960f55 100644
--- a/coverage/analysis_options.yaml
+++ b/coverage/analysis_options.yaml
@@ -13,8 +13,6 @@
errors:
# treat missing required parameters as a warning (not a hint)
missing_required_param: warning
- # allow overriding fields (if they use super, ideally...)
- strong_mode_invalid_field_override: ignore
# allow type narrowing
strong_mode_down_cast_composite: ignore
# allow having TODOs in the code
@@ -54,7 +52,6 @@
- await_only_futures
- camel_case_types
- constant_identifier_names
- - control_flow_in_finally
- empty_constructor_bodies
- implementation_imports
- library_names
@@ -65,17 +62,20 @@
- overridden_fields
- package_api_docs
- package_prefixed_library_names
- # - prefer_final_locals
+ - prefer_equal_for_default_values
+ - prefer_final_locals
+ - prefer_generic_function_type_aliases
- prefer_is_not_empty
# - public_member_api_docs
- slash_for_doc_comments
- sort_constructors_first
- sort_unnamed_constructors_first
- - super_goes_last
- type_annotate_public_apis # subset of always_specify_types
- type_init_formals
- unnecessary_brace_in_string_interps
+ - unnecessary_const
- unnecessary_getters_setters
+ - unnecessary_new
# === pub rules ===
- package_names
diff --git a/coverage/bin/collect_coverage.dart b/coverage/bin/collect_coverage.dart
index ddb1ce3..dccb996 100644
--- a/coverage/bin/collect_coverage.dart
+++ b/coverage/bin/collect_coverage.dart
@@ -17,10 +17,10 @@
print('${rec.level.name}: ${rec.time}: ${rec.message}');
});
- var options = _parseArgs(arguments);
+ final options = _parseArgs(arguments);
await Chain.capture(() async {
- var coverage = await collect(
- options.serviceUri, options.resume, options.waitPaused,
+ final coverage = await collect(options.serviceUri, options.resume,
+ options.waitPaused, options.includeDart,
timeout: options.timeout);
options.out.write(json.encode(coverage));
await options.out.close();
@@ -34,18 +34,19 @@
}
class Options {
- Options(
- this.serviceUri, this.out, this.timeout, this.waitPaused, this.resume);
+ Options(this.serviceUri, this.out, this.timeout, this.waitPaused, this.resume,
+ this.includeDart);
final Uri serviceUri;
final IOSink out;
final Duration timeout;
final bool waitPaused;
final bool resume;
+ final bool includeDart;
}
Options _parseArgs(List<String> arguments) {
- var parser = new ArgParser()
+ final parser = ArgParser()
..addOption('host',
abbr: 'H',
help: 'remote VM host. DEPRECATED: use --uri',
@@ -65,9 +66,11 @@
help: 'wait for all isolates to be paused before collecting coverage')
..addFlag('resume-isolates',
abbr: 'r', defaultsTo: false, help: 'resume all isolates on exit')
+ ..addFlag('include-dart',
+ abbr: 'd', defaultsTo: false, help: 'include "dart:" libraries')
..addFlag('help', abbr: 'h', negatable: false, help: 'show this help');
- var args = parser.parse(arguments);
+ final args = parser.parse(arguments);
void printUsage() {
print('Usage: dart collect_coverage.dart --uri=http://... [OPTION...]\n');
@@ -102,12 +105,12 @@
if (args['out'] == 'stdout') {
out = stdout;
} else {
- var outfile = new File(args['out'])..createSync(recursive: true);
+ final outfile = File(args['out'])..createSync(recursive: true);
out = outfile.openWrite();
}
- var timeout = (args['connect-timeout'] == null)
+ final timeout = (args['connect-timeout'] == null)
? null
- : new Duration(seconds: int.parse(args['connect-timeout']));
- return new Options(
- serviceUri, out, timeout, args['wait-paused'], args['resume-isolates']);
+ : Duration(seconds: int.parse(args['connect-timeout']));
+ return Options(serviceUri, out, timeout, args['wait-paused'],
+ args['resume-isolates'], args['include-dart']);
}
diff --git a/coverage/bin/format_coverage.dart b/coverage/bin/format_coverage.dart
index 4e65129..259e1c7 100644
--- a/coverage/bin/format_coverage.dart
+++ b/coverage/bin/format_coverage.dart
@@ -30,7 +30,7 @@
Future<Null> main(List<String> arguments) async {
final env = parseArgs(arguments);
- List<File> files = filesToProcess(env.input);
+ final List<File> files = filesToProcess(env.input);
if (env.verbose) {
print('Environment:');
print(' # files: ${files.length}');
@@ -41,8 +41,8 @@
print(' report-on: ${env.reportOn}');
}
- var clock = new Stopwatch()..start();
- var hitmap = await parseCoverage(files, env.workers);
+ final clock = Stopwatch()..start();
+ final hitmap = await parseCoverage(files, env.workers);
// All workers are done. Process the data.
if (env.verbose) {
@@ -50,20 +50,20 @@
}
String output;
- var resolver = env.bazel
- ? new BazelResolver(workspacePath: env.bazelWorkspace)
- : new Resolver(
+ final resolver = env.bazel
+ ? BazelResolver(workspacePath: env.bazelWorkspace)
+ : Resolver(
packagesPath: env.packagesPath,
packageRoot: env.pkgRoot,
sdkRoot: env.sdkRoot);
- var loader = new Loader();
+ final loader = Loader();
if (env.prettyPrint) {
output =
- await new PrettyPrintFormatter(resolver, loader, reportOn: env.reportOn)
+ await PrettyPrintFormatter(resolver, loader, reportOn: env.reportOn)
.format(hitmap);
} else {
assert(env.lcov);
- output = await new LcovFormatter(resolver,
+ output = await LcovFormatter(resolver,
reportOn: env.reportOn, basePath: env.baseDirectory)
.format(hitmap);
}
@@ -94,8 +94,8 @@
/// Checks the validity of the provided arguments. Does not initialize actual
/// processing.
Environment parseArgs(List<String> arguments) {
- final env = new Environment();
- var parser = new ArgParser();
+ final env = Environment();
+ final parser = ArgParser();
parser.addOption('sdk-root', abbr: 's', help: 'path to the SDK root');
parser.addOption('package-root', abbr: 'p', help: 'path to the package root');
@@ -126,7 +126,7 @@
abbr: 'v', negatable: false, help: 'verbose output');
parser.addFlag('help', abbr: 'h', negatable: false, help: 'show this help');
- var args = parser.parse(arguments);
+ final args = parser.parse(arguments);
void printUsage() {
print('Usage: dart format_coverage.dart [OPTION...]\n');
@@ -182,8 +182,8 @@
if (args['out'] == 'stdout') {
env.output = stdout;
} else {
- var outpath = p.absolute(p.normalize(args['out']));
- var outfile = new File(outpath)..createSync(recursive: true);
+ final outpath = p.absolute(p.normalize(args['out']));
+ final outfile = File(outpath)..createSync(recursive: true);
env.output = outfile.openWrite();
}
@@ -220,13 +220,13 @@
/// are contained by it if it is a directory, or a [List] containing the file if
/// it is a file.
List<File> filesToProcess(String absPath) {
- var filePattern = new RegExp(r'^dart-cov-\d+-\d+.json$');
+ final filePattern = RegExp(r'^dart-cov-\d+-\d+.json$');
if (FileSystemEntity.isDirectorySync(absPath)) {
- return new Directory(absPath)
+ return Directory(absPath)
.listSync(recursive: true)
.whereType<File>()
.where((e) => filePattern.hasMatch(p.basename(e.path)))
.toList();
}
- return <File>[new File(absPath)];
+ return <File>[File(absPath)];
}
diff --git a/coverage/bin/run_and_collect.dart b/coverage/bin/run_and_collect.dart
index 9cbba0d..ead8792 100644
--- a/coverage/bin/run_and_collect.dart
+++ b/coverage/bin/run_and_collect.dart
@@ -7,6 +7,6 @@
import 'package:coverage/src/run_and_collect.dart';
Future<Null> main(List<String> args) async {
- Map results = await runAndCollect(args[0], packageRoot: args[1]);
+ final Map results = await runAndCollect(args[0], packageRoot: args[1]);
print(results);
}
diff --git a/coverage/codereview.settings b/coverage/codereview.settings
deleted file mode 100644
index 4b0ed74..0000000
--- a/coverage/codereview.settings
+++ /dev/null
@@ -1,4 +0,0 @@
-# This file is used by gcl to get repository specific information.
-CODE_REVIEW_SERVER: http://codereview.chromium.org/
-VIEW_VC: https://github.com/dart-lang/coverage/commit/
-CC_LIST: reviews@dartlang.org
diff --git a/coverage/lib/src/collect.dart b/coverage/lib/src/collect.dart
index c85031d..cc8ec42 100644
--- a/coverage/lib/src/collect.dart
+++ b/coverage/lib/src/collect.dart
@@ -3,11 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'dart:io';
-import 'package:vm_service_client/vm_service_client.dart';
+import 'package:vm_service_lib/vm_service_lib.dart';
import 'util.dart';
-const _retryInterval = const Duration(milliseconds: 200);
+const _retryInterval = Duration(milliseconds: 200);
/// Collects coverage for all isolates in the running VM.
///
@@ -24,104 +25,163 @@
/// If [waitPaused] is true, collection will not begin until all isolates are
/// in the paused state.
Future<Map<String, dynamic>> collect(
- Uri serviceUri, bool resume, bool waitPaused,
+ Uri serviceUri, bool resume, bool waitPaused, bool includeDart,
{Duration timeout}) async {
if (serviceUri == null) throw ArgumentError('serviceUri must not be null');
// Create websocket URI. Handle any trailing slashes.
- var pathSegments = serviceUri.pathSegments.where((c) => c.isNotEmpty).toList()
- ..add('ws');
- var uri = serviceUri.replace(scheme: 'ws', pathSegments: pathSegments);
+ final pathSegments =
+ serviceUri.pathSegments.where((c) => c.isNotEmpty).toList()..add('ws');
+ final uri = serviceUri.replace(scheme: 'ws', pathSegments: pathSegments);
- VMServiceClient vmService;
+ VmService service;
await retry(() async {
try {
- vmService = new VMServiceClient.connect(uri);
- await vmService.getVM().timeout(_retryInterval);
+ final options = const CompressionOptions(enabled: false);
+ final socket = await WebSocket.connect('$uri', compression: options);
+ final controller = StreamController<String>();
+ socket.listen((dynamic data) => controller.add(data));
+ service = VmService(
+ controller.stream, (String message) => socket.add(message),
+ log: StdoutLog(), disposeHandler: () => socket.close());
+ await service.getVM().timeout(_retryInterval);
} on TimeoutException {
- vmService.close();
+ service.dispose();
rethrow;
}
}, _retryInterval, timeout: timeout);
try {
if (waitPaused) {
- await _waitIsolatesPaused(vmService, timeout: timeout);
+ await _waitIsolatesPaused(service, timeout: timeout);
}
- return await _getAllCoverage(vmService);
+ return await _getAllCoverage(service, includeDart);
} finally {
if (resume) {
- await _resumeIsolates(vmService);
+ await _resumeIsolates(service);
}
- await vmService.close();
+ service.dispose();
}
}
-Future<Map<String, dynamic>> _getAllCoverage(VMServiceClient service) async {
- var vm = await service.getVM();
- var allCoverage = <Map<String, dynamic>>[];
+Future<Map<String, dynamic>> _getAllCoverage(
+ VmService service, bool includeDart) async {
+ final vm = await service.getVM();
+ final allCoverage = <Map<String, dynamic>>[];
for (var isolateRef in vm.isolates) {
- var isolate = await isolateRef.load();
- var report = await isolate.getSourceReport(forceCompile: true);
- var coverage = await _getCoverageJson(service, report);
+ final SourceReport report = await service.getSourceReport(
+ isolateRef.id,
+ <String>[SourceReportKind.kCoverage],
+ forceCompile: true,
+ );
+ final coverage =
+ await _getCoverageJson(service, isolateRef, report, includeDart);
allCoverage.addAll(coverage);
}
return <String, dynamic>{'type': 'CodeCoverage', 'coverage': allCoverage};
}
-Future _resumeIsolates(VMServiceClient service) async {
- var vm = await service.getVM();
+Future _resumeIsolates(VmService service) async {
+ final vm = await service.getVM();
for (var isolateRef in vm.isolates) {
- var isolate = await isolateRef.load();
- if (isolate.isPaused) {
- await isolateRef.resume();
+ final Isolate isolate = await service.getIsolate(isolateRef.id);
+ if (isolate.pauseEvent.kind != EventKind.kResume) {
+ await service.resume(isolateRef.id);
}
}
}
-Future _waitIsolatesPaused(VMServiceClient service, {Duration timeout}) async {
+Future _waitIsolatesPaused(VmService service, {Duration timeout}) async {
+ final pauseEvents = Set<String>.from(<String>[
+ EventKind.kPauseStart,
+ EventKind.kPauseException,
+ EventKind.kPauseExit,
+ EventKind.kPauseInterrupted,
+ EventKind.kPauseBreakpoint
+ ]);
+
Future allPaused() async {
- var vm = await service.getVM();
+ final VM vm = await service.getVM();
for (var isolateRef in vm.isolates) {
- var isolate = await isolateRef.load();
- if (!isolate.isPaused) throw "Unpaused isolates remaining.";
+ final Isolate isolate = await service.getIsolate(isolateRef.id);
+ if (!pauseEvents.contains(isolate.pauseEvent.kind)) {
+ throw "Unpaused isolates remaining.";
+ }
}
}
return retry(allPaused, _retryInterval, timeout: timeout);
}
-/// Returns a JSON coverage list backward-compatible with pre-1.16.0 SDKs.
-Future<List<Map<String, dynamic>>> _getCoverageJson(
- VMServiceClient service, VMSourceReport report) async {
- var scriptRefs = report.ranges.map((r) => r.script).toSet();
- var scripts = <VMScriptRef, VMScript>{};
- for (var ref in scriptRefs) {
- scripts[ref] = await ref.load();
+/// Returns the line number to which the specified token position maps.
+///
+/// Performs a binary search within the script's token position table to locate
+/// the line in question.
+int _getLineFromTokenPos(Script script, int tokenPos) {
+ // TODO(cbracken): investigate whether caching this lookup results in
+ // significant performance gains.
+ var min = 0;
+ var max = script.tokenPosTable.length;
+ while (min < max) {
+ final mid = min + ((max - min) >> 1);
+ final row = script.tokenPosTable[mid];
+ if (row[1] > tokenPos) {
+ max = mid;
+ } else {
+ for (var i = 1; i < row.length; i += 2) {
+ if (row[i] == tokenPos) return row.first;
+ }
+ min = mid + 1;
+ }
}
+ return null;
+}
+/// Returns a JSON coverage list backward-compatible with pre-1.16.0 SDKs.
+Future<List<Map<String, dynamic>>> _getCoverageJson(VmService service,
+ IsolateRef isolateRef, SourceReport report, bool includeDart) async {
// script uri -> { line -> hit count }
- var hitMaps = <Uri, Map<int, int>>{};
+ final hitMaps = <Uri, Map<int, int>>{};
+ final scripts = <ScriptRef, Script>{};
for (var range in report.ranges) {
- // Not returned in scripts section of source report.
- if (range.script.uri.scheme == 'evaluate') continue;
+ final scriptRef = report.scripts[range.scriptIndex];
+ final Uri scriptUri = Uri.parse(report.scripts[range.scriptIndex].uri);
- hitMaps.putIfAbsent(range.script.uri, () => <int, int>{});
- var hitMap = hitMaps[range.script.uri];
- var script = scripts[range.script];
- for (VMScriptToken hit in range.hits ?? []) {
- var line = script.sourceLocation(hit).line + 1;
+ // Not returned in scripts section of source report.
+ if (scriptUri.scheme == 'evaluate') continue;
+
+ // Skip scripts from dart:.
+ if (!includeDart && scriptUri.scheme == 'dart') continue;
+
+ if (!scripts.containsKey(scriptRef)) {
+ scripts[scriptRef] = await service.getObject(isolateRef.id, scriptRef.id);
+ }
+ final script = scripts[scriptRef];
+
+ // Look up the hit map for this script (shared across isolates).
+ final hitMap = hitMaps.putIfAbsent(scriptUri, () => <int, int>{});
+
+ // Collect hits and misses.
+ final coverage = range.coverage;
+ for (final tokenPos in coverage.hits) {
+ final line = _getLineFromTokenPos(script, tokenPos);
+ if (line == null) {
+ print('tokenPos $tokenPos has no line mapping for script $scriptUri');
+ }
hitMap[line] = hitMap.containsKey(line) ? hitMap[line] + 1 : 1;
}
- for (VMScriptToken miss in range.misses ?? []) {
- var line = script.sourceLocation(miss).line + 1;
+ for (final tokenPos in coverage.misses) {
+ final line = _getLineFromTokenPos(script, tokenPos);
+ if (line == null) {
+ print('tokenPos $tokenPos has no line mapping for script $scriptUri');
+ }
hitMap.putIfAbsent(line, () => 0);
}
}
// Output JSON
- var coverage = <Map<String, dynamic>>[];
+ final coverage = <Map<String, dynamic>>[];
hitMaps.forEach((uri, hitMap) {
coverage.add(_toScriptCoverageJson(uri, hitMap));
});
@@ -131,8 +191,8 @@
/// Returns a JSON hit map backward-compatible with pre-1.16.0 SDKs.
Map<String, dynamic> _toScriptCoverageJson(
Uri scriptUri, Map<int, int> hitMap) {
- var json = <String, dynamic>{};
- var hits = <int>[];
+ final json = <String, dynamic>{};
+ final hits = <int>[];
hitMap.forEach((line, hitCount) {
hits.add(line);
hits.add(hitCount);
@@ -148,3 +208,10 @@
json['hits'] = hits;
return json;
}
+
+class StdoutLog extends Log {
+ @override
+ void warning(String message) => print(message);
+ @override
+ void severe(String message) => print(message);
+}
diff --git a/coverage/lib/src/formatter.dart b/coverage/lib/src/formatter.dart
index 1c4f7c2..1d8383e 100644
--- a/coverage/lib/src/formatter.dart
+++ b/coverage/lib/src/formatter.dart
@@ -19,7 +19,7 @@
/// Returns a [Future] that completes as soon as all map entries have been
/// emitted.
class LcovFormatter implements Formatter {
- /// Creates a new LCOV formatter.
+ /// Creates a LCOV formatter.
///
/// If [reportOn] is provided, coverage report output is limited to files
/// prefixed with one of the paths included. If [basePath] is provided, paths
@@ -32,10 +32,10 @@
@override
Future<String> format(Map hitmap) async {
- _PathFilter pathFilter = _getPathFilter(reportOn);
- var buf = new StringBuffer();
+ final _PathFilter pathFilter = _getPathFilter(reportOn);
+ final buf = StringBuffer();
for (var key in hitmap.keys) {
- Map<int, int> v = hitmap[key];
+ final Map<int, int> v = hitmap[key];
var source = resolver.resolve(key);
if (source == null) {
continue;
@@ -69,7 +69,7 @@
/// Returns a [Future] that completes as soon as all map entries have been
/// emitted.
class PrettyPrintFormatter implements Formatter {
- /// Creates a new pretty-print formatter.
+ /// Creates a pretty-print formatter.
///
/// If [reportOn] is provided, coverage report output is limited to files
/// prefixed with one of the paths included.
@@ -81,11 +81,11 @@
@override
Future<String> format(Map hitmap) async {
- _PathFilter pathFilter = _getPathFilter(reportOn);
- var buf = new StringBuffer();
+ final _PathFilter pathFilter = _getPathFilter(reportOn);
+ final buf = StringBuffer();
for (var key in hitmap.keys) {
- Map<int, int> v = hitmap[key];
- var source = resolver.resolve(key);
+ final Map<int, int> v = hitmap[key];
+ final source = resolver.resolve(key);
if (source == null) {
continue;
}
@@ -94,7 +94,7 @@
continue;
}
- var lines = await loader.load(source);
+ final lines = await loader.load(source);
if (lines == null) {
continue;
}
@@ -114,11 +114,11 @@
const _prefix = ' ';
-typedef bool _PathFilter(String path);
+typedef _PathFilter = bool Function(String path);
_PathFilter _getPathFilter(List<String> reportOn) {
if (reportOn == null) return (String path) => true;
- var absolutePaths = reportOn.map(p.absolute).toList();
+ final absolutePaths = reportOn.map(p.absolute).toList();
return (String path) => absolutePaths.any((item) => path.startsWith(item));
}
diff --git a/coverage/lib/src/hitmap.dart b/coverage/lib/src/hitmap.dart
index da7c5ee..ab6fb69 100644
--- a/coverage/lib/src/hitmap.dart
+++ b/coverage/lib/src/hitmap.dart
@@ -12,37 +12,37 @@
/// `jsonResult` is expected to be a List<Map<String, dynamic>>.
Map<String, Map<int, int>> createHitmap(List jsonResult) {
// Map of source file to map of line to hit count for that line.
- var globalHitMap = <String, Map<int, int>>{};
+ final globalHitMap = <String, Map<int, int>>{};
void addToMap(Map<int, int> map, int line, int count) {
- var oldCount = map.putIfAbsent(line, () => 0);
+ final oldCount = map.putIfAbsent(line, () => 0);
map[line] = count + oldCount;
}
for (Map<String, dynamic> e in jsonResult) {
- String source = e['source'];
+ final String source = e['source'];
if (source == null) {
// Couldn't resolve import, so skip this entry.
continue;
}
- var sourceHitMap = globalHitMap.putIfAbsent(source, () => <int, int>{});
- List<dynamic> hits = e['hits'];
+ final sourceHitMap = globalHitMap.putIfAbsent(source, () => <int, int>{});
+ final List<dynamic> hits = e['hits'];
// hits is a flat array of the following format:
// [ <line|linerange>, <hitcount>,...]
// line: number.
// linerange: '<line>-<line>'.
for (var i = 0; i < hits.length; i += 2) {
- dynamic k = hits[i];
+ final dynamic k = hits[i];
if (k is num) {
// Single line.
addToMap(sourceHitMap, k, hits[i + 1]);
} else {
assert(k is String);
// Linerange. We expand line ranges to actual lines at this point.
- int splitPos = k.indexOf('-');
- int start = int.parse(k.substring(0, splitPos));
- int end = int.parse(k.substring(splitPos + 1));
+ final int splitPos = k.indexOf('-');
+ final start = int.parse(k.substring(0, splitPos));
+ final end = int.parse(k.substring(splitPos + 1));
for (var j = start; j <= end; j++) {
addToMap(sourceHitMap, j, hits[i + 1]);
}
@@ -72,10 +72,10 @@
/// Generates a merged hitmap from a set of coverage JSON files.
Future<Map> parseCoverage(Iterable<File> files, int _) async {
- var globalHitmap = <String, Map<int, int>>{};
+ final globalHitmap = <String, Map<int, int>>{};
for (var file in files) {
- String contents = file.readAsStringSync();
- List jsonResult = json.decode(contents)['coverage'];
+ final contents = file.readAsStringSync();
+ final List jsonResult = json.decode(contents)['coverage'];
mergeHitmaps(createHitmap(jsonResult), globalHitmap);
}
return globalHitmap;
diff --git a/coverage/lib/src/resolver.dart b/coverage/lib/src/resolver.dart
index 472d41f..cff28b5 100644
--- a/coverage/lib/src/resolver.dart
+++ b/coverage/lib/src/resolver.dart
@@ -23,7 +23,7 @@
/// Returns the absolute path wrt. to the given environment or null, if the
/// import could not be resolved.
String resolve(String scriptUri) {
- var uri = Uri.parse(scriptUri);
+ final uri = Uri.parse(scriptUri);
if (uri.scheme == 'dart') {
if (sdkRoot == null) {
// No sdk-root given, do not resolve dart: URIs.
@@ -40,11 +40,12 @@
}
// Canonicalize path. For instance: _collection-dev => _collection_dev.
path = path.replaceAll('-', '_');
- var pathSegments = [sdkRoot, path]..addAll(uri.pathSegments.sublist(1));
+ final pathSegments = [sdkRoot, path]
+ ..addAll(uri.pathSegments.sublist(1));
filePath = p.joinAll(pathSegments);
} else {
// Resolve 'dart:something' to be something/something.dart in the SDK.
- var lib = uri.path;
+ final lib = uri.path;
filePath = p.join(sdkRoot, lib, '$lib.dart');
}
return resolveSymbolicLinks(filePath);
@@ -55,15 +56,15 @@
return null;
}
- var packageName = uri.pathSegments[0];
+ final packageName = uri.pathSegments[0];
if (_packages != null) {
- var packageUri = _packages[packageName];
+ final packageUri = _packages[packageName];
if (packageUri == null) {
failed.add('$uri');
return null;
}
- var packagePath = p.fromUri(packageUri);
- var pathInPackage = p.joinAll(uri.pathSegments.sublist(1));
+ final packagePath = p.fromUri(packageUri);
+ final pathInPackage = p.joinAll(uri.pathSegments.sublist(1));
return resolveSymbolicLinks(p.join(packagePath, pathInPackage));
}
return resolveSymbolicLinks(p.join(packageRoot, uri.path));
@@ -78,22 +79,22 @@
/// Returns a canonicalized path, or `null` if the path cannot be resolved.
String resolveSymbolicLinks(String path) {
- var normalizedPath = p.normalize(path);
- var type = FileSystemEntity.typeSync(normalizedPath, followLinks: true);
+ final normalizedPath = p.normalize(path);
+ final type = FileSystemEntity.typeSync(normalizedPath, followLinks: true);
if (type == FileSystemEntityType.notFound) return null;
- return new File(normalizedPath).resolveSymbolicLinksSync();
+ return File(normalizedPath).resolveSymbolicLinksSync();
}
static Map<String, Uri> _parsePackages(String packagesPath) {
- var source = new File(packagesPath).readAsBytesSync();
- return packages_file.parse(source, new Uri.file(packagesPath));
+ final source = File(packagesPath).readAsBytesSync();
+ return packages_file.parse(source, Uri.file(packagesPath));
}
}
/// Bazel URI resolver.
class BazelResolver extends Resolver {
/// Creates a Bazel resolver with the specified workspace path, if any.
- BazelResolver({this.workspacePath: ''});
+ BazelResolver({this.workspacePath = ''});
final String workspacePath;
@@ -101,7 +102,7 @@
/// import could not be resolved.
@override
String resolve(String scriptUri) {
- var uri = Uri.parse(scriptUri);
+ final uri = Uri.parse(scriptUri);
if (uri.scheme == 'dart') {
// Ignore the SDK
return null;
@@ -111,12 +112,11 @@
return _resolveBazelPackage(uri.pathSegments);
}
if (uri.scheme == 'file') {
- var runfilesPathSegment = '.runfiles/$workspacePath';
- runfilesPathSegment =
- runfilesPathSegment.replaceAll(new RegExp(r'/*$'), '/');
- var runfilesPos = uri.path.indexOf(runfilesPathSegment);
+ final runfilesPathSegment =
+ '.runfiles/$workspacePath'.replaceAll(RegExp(r'/*$'), '/');
+ final runfilesPos = uri.path.indexOf(runfilesPathSegment);
if (runfilesPos >= 0) {
- int pathStart = runfilesPos + runfilesPathSegment.length;
+ final pathStart = runfilesPos + runfilesPathSegment.length;
return uri.path.substring(pathStart);
}
return null;
@@ -130,9 +130,9 @@
}
String _extractHttpPath(Uri uri) {
- int packagesPos = uri.pathSegments.indexOf('packages');
+ final packagesPos = uri.pathSegments.indexOf('packages');
if (packagesPos >= 0) {
- var workspacePath = uri.pathSegments.sublist(packagesPos + 1);
+ final workspacePath = uri.pathSegments.sublist(packagesPos + 1);
return _resolveBazelPackage(workspacePath);
}
return uri.pathSegments.join('/');
@@ -140,14 +140,11 @@
String _resolveBazelPackage(List<String> pathSegments) {
// TODO(cbracken) belongs in a Bazel package
- var packageName = pathSegments[0];
- var pathInPackage = pathSegments.sublist(1).join('/');
- String packagePath;
- if (packageName.contains('.')) {
- packagePath = packageName.replaceAll('.', '/');
- } else {
- packagePath = 'third_party/dart/$packageName';
- }
+ final packageName = pathSegments[0];
+ final pathInPackage = pathSegments.sublist(1).join('/');
+ final packagePath = packageName.contains('.')
+ ? packageName.replaceAll('.', '/')
+ : 'third_party/dart/$packageName';
return '$packagePath/lib/$pathInPackage';
}
}
@@ -160,7 +157,7 @@
/// Returns `null` if the resource could not be loaded.
Future<List<String>> load(String path) async {
try {
- return new File(path).readAsLines();
+ return File(path).readAsLines();
} catch (_) {
failed.add(path);
return null;
diff --git a/coverage/lib/src/run_and_collect.dart b/coverage/lib/src/run_and_collect.dart
index d12d130..448009b 100644
--- a/coverage/lib/src/run_and_collect.dart
+++ b/coverage/lib/src/run_and_collect.dart
@@ -11,10 +11,11 @@
Future<Map<String, dynamic>> runAndCollect(String scriptPath,
{List<String> scriptArgs,
- bool checked: false,
+ bool checked = false,
String packageRoot,
+ bool includeDart = false,
Duration timeout}) async {
- var dartArgs = [
+ final dartArgs = [
'--enable-vm-service',
'--pause_isolates_on_exit',
];
@@ -33,26 +34,27 @@
dartArgs.addAll(scriptArgs);
}
- var process = await Process.start('dart', dartArgs);
- var serviceUriCompleter = new Completer<Uri>();
+ final process = await Process.start('dart', dartArgs);
+ final serviceUriCompleter = Completer<Uri>();
process.stdout
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen((line) {
- var uri = extractObservatoryUri(line);
+ final uri = extractObservatoryUri(line);
if (uri != null) {
serviceUriCompleter.complete(uri);
}
});
- var serviceUri = await serviceUriCompleter.future;
+ final serviceUri = await serviceUriCompleter.future;
Map<String, dynamic> coverage;
try {
- coverage = await collect(serviceUri, true, true, timeout: timeout);
+ coverage =
+ await collect(serviceUri, true, true, includeDart, timeout: timeout);
} finally {
await process.stderr.drain<List<int>>();
}
- int exitStatus = await process.exitCode;
+ final exitStatus = await process.exitCode;
if (exitStatus != 0) {
throw "Process exited with exit code $exitStatus";
}
diff --git a/coverage/lib/src/util.dart b/coverage/lib/src/util.dart
index 071d991..8f8ed15 100644
--- a/coverage/lib/src/util.dart
+++ b/coverage/lib/src/util.dart
@@ -18,10 +18,10 @@
return f().timeout(duration, onTimeout: () {
keepGoing = false;
- var msg = duration.inSeconds == 0
+ final msg = duration.inSeconds == 0
? '${duration.inMilliseconds}ms'
: '${duration.inSeconds}s';
- throw new StateError('Failed to complete within $msg');
+ throw StateError('Failed to complete within $msg');
});
}
@@ -31,7 +31,7 @@
return await f();
} catch (_) {
if (keepGoing) {
- await new Future<dynamic>.delayed(interval);
+ await Future<dynamic>.delayed(interval);
}
}
}
@@ -43,10 +43,10 @@
/// Potentially useful as a means to extract it from log statements.
Uri extractObservatoryUri(String str) {
const kObservatoryListening = 'Observatory listening on ';
- int msgPos = str.indexOf(kObservatoryListening);
+ final msgPos = str.indexOf(kObservatoryListening);
if (msgPos == -1) return null;
- int startPos = msgPos + kObservatoryListening.length;
- int endPos = str.indexOf(new RegExp(r'(\s|$)'), startPos);
+ final startPos = msgPos + kObservatoryListening.length;
+ final endPos = str.indexOf(RegExp(r'(\s|$)'), startPos);
try {
return Uri.parse(str.substring(startPos, endPos));
} on FormatException {
diff --git a/coverage/pubspec.yaml b/coverage/pubspec.yaml
index 0d203b4..3b87e2f 100644
--- a/coverage/pubspec.yaml
+++ b/coverage/pubspec.yaml
@@ -1,19 +1,23 @@
name: coverage
-version: 0.12.4
+version: 0.13.0
author: Dart Team <misc@dartlang.org>
description: Coverage data manipulation and formatting
homepage: https://github.com/dart-lang/coverage
+
environment:
- sdk: '>=2.0.0-dev.64.1 <3.0.0'
+ sdk: '>=2.0.0 <3.0.0'
+
dependencies:
args: '>=1.4.0 <2.0.0'
logging: '>=0.9.0 <0.12.0'
package_config: '>=0.1.5 <2.0.0'
path: '>=0.9.0 <2.0.0'
stack_trace: ^1.3.0
- vm_service_client: ^0.2.2+1
+ vm_service_lib: ^3.21.0
+
dev_dependencies:
test: ^1.0.0
+
executables:
collect_coverage:
format_coverage:
diff --git a/coverage/tool/travis.sh b/coverage/tool/travis.sh
index a2499e8..0c25614 100755
--- a/coverage/tool/travis.sh
+++ b/coverage/tool/travis.sh
@@ -34,7 +34,7 @@
echo "Collecting coverage on port $OBS_PORT..."
# Start tests in one VM.
- dart \
+ dart --disable-service-auth-codes \
--enable-vm-service=$OBS_PORT \
--pause-isolates-on-exit \
test/test_all.dart &
diff --git a/csslib/BUILD.gn b/csslib/BUILD.gn
index e3bcecd..74b3f9d 100644
--- a/csslib/BUILD.gn
+++ b/csslib/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for csslib-0.16.0
+# This file is generated by importer.py for csslib-0.16.1
import("//build/dart/dart_library.gni")
diff --git a/csslib/CHANGELOG.md b/csslib/CHANGELOG.md
index 162975f..783393d 100644
--- a/csslib/CHANGELOG.md
+++ b/csslib/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.16.1
+
+- Fixed a crash caused by parsing certain calc() expressions and variables names that contain numbers.
+
## 0.16.0
- Removed support for the shadow-piercing comibnators `/deep/` and `>>>`. These
diff --git a/csslib/lib/parser.dart b/csslib/lib/parser.dart
index fbf291c..d8ba671 100644
--- a/csslib/lib/parser.dart
+++ b/csslib/lib/parser.dart
@@ -1681,14 +1681,8 @@
}
if (keepParsing && value != null) {
- LiteralTerm unitTerm;
- // Don't process the dimension if MINUS or PLUS is next.
- if (_peek() != TokenKind.MINUS && _peek() != TokenKind.PLUS) {
- unitTerm = processDimension(termToken, value, _makeSpan(start));
- }
- if (unitTerm == null) {
- unitTerm = LiteralTerm(value, value.name, _makeSpan(start));
- }
+ LiteralTerm unitTerm =
+ processDimension(termToken, value, _makeSpan(start));
expressions.add(unitTerm);
value = null;
@@ -2498,12 +2492,13 @@
_next(); // Skip the unit
break;
default:
- if (value != null && t != null) {
- term = (value is Identifier)
- ? LiteralTerm(value, value.name, span)
- : NumberTerm(value, t.text, span);
+ if (value != null) {
+ if (value is Identifier) {
+ term = LiteralTerm(value, value.name, span);
+ } else if (t != null) {
+ term = NumberTerm(value, t.text, span);
+ }
}
- break;
}
return term;
diff --git a/csslib/lib/src/tree_base.dart b/csslib/lib/src/tree_base.dart
index d8fee1d..5011f3d 100644
--- a/csslib/lib/src/tree_base.dart
+++ b/csslib/lib/src/tree_base.dart
@@ -57,21 +57,23 @@
}
String toValue(value) {
- if (value == null)
+ if (value == null) {
return 'null';
- else if (value is Identifier)
+ } else if (value is Identifier) {
return value.name;
- else
+ } else {
return value.toString();
+ }
}
void writeNode(String label, TreeNode node) {
write('${label}: ');
depth += 1;
- if (node != null)
+ if (node != null) {
node.visit(printer);
- else
+ } else {
writeln('null');
+ }
depth -= 1;
}
diff --git a/csslib/pubspec.yaml b/csslib/pubspec.yaml
index 8ce1c79..f4c6d83 100644
--- a/csslib/pubspec.yaml
+++ b/csslib/pubspec.yaml
@@ -1,5 +1,5 @@
name: csslib
-version: 0.16.0
+version: 0.16.1
description: A library for parsing CSS.
author: Dart Team <misc@dartlang.org>
diff --git a/dart_style/BUILD.gn b/dart_style/BUILD.gn
index 2b32eba..bfc42f4 100644
--- a/dart_style/BUILD.gn
+++ b/dart_style/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for dart_style-1.2.8
+# This file is generated by importer.py for dart_style-1.2.9
import("//build/dart/dart_library.gni")
diff --git a/dart_style/CHANGELOG.md b/dart_style/CHANGELOG.md
index e31a726..993eafc 100644
--- a/dart_style/CHANGELOG.md
+++ b/dart_style/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 1.2.9
+
+* Support `package:analyzer` `0.37.0`.
+
# 1.2.8
* Better indentation of function expressions inside trailing comma argument
diff --git a/dart_style/codereview.settings b/dart_style/codereview.settings
deleted file mode 100644
index 25510f0..0000000
--- a/dart_style/codereview.settings
+++ /dev/null
@@ -1,3 +0,0 @@
-CODE_REVIEW_SERVER: https://codereview.chromium.org/
-VIEW_VC: https://github.com/dart-lang/dart_style/commit/
-CC_LIST: reviews@dartlang.org
diff --git a/dart_style/lib/src/source_visitor.dart b/dart_style/lib/src/source_visitor.dart
index 47230c6..ffef68d 100644
--- a/dart_style/lib/src/source_visitor.dart
+++ b/dart_style/lib/src/source_visitor.dart
@@ -1162,9 +1162,8 @@
var requiredParams = node.parameters
.where((param) => param is! DefaultFormalParameter)
.toList();
- var optionalParams = node.parameters
- .where((param) => param is DefaultFormalParameter)
- .toList();
+ var optionalParams =
+ node.parameters.whereType<DefaultFormalParameter>().toList();
if (nestExpression) builder.nestExpression();
token(node.leftParenthesis);
diff --git a/dart_style/pubspec.yaml b/dart_style/pubspec.yaml
index 3f2b24c..71eb65a 100644
--- a/dart_style/pubspec.yaml
+++ b/dart_style/pubspec.yaml
@@ -1,6 +1,6 @@
name: dart_style
# Note: See tool/grind.dart for how to bump the version.
-version: 1.2.8
+version: 1.2.9
author: Dart Team <misc@dartlang.org>
description: >-
Opinionated, automatic Dart source code formatter.
@@ -11,7 +11,7 @@
sdk: '>=2.3.0 <3.0.0'
dependencies:
- analyzer: '>=0.36.3 <0.37.0'
+ analyzer: '>=0.36.3 <0.38.0'
args: '>=0.12.1 <2.0.0'
path: ^1.0.0
source_span: ^1.4.0
diff --git a/protobuf/BUILD.gn b/protobuf/BUILD.gn
index 4dfa2da..ba921a0 100644
--- a/protobuf/BUILD.gn
+++ b/protobuf/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for protobuf-0.13.12
+# This file is generated by importer.py for protobuf-0.13.15
import("//build/dart/dart_library.gni")
diff --git a/protobuf/CHANGELOG.md b/protobuf/CHANGELOG.md
index a151f52..06ed05d 100644
--- a/protobuf/CHANGELOG.md
+++ b/protobuf/CHANGELOG.md
@@ -1,3 +1,16 @@
+## 0.13.15
+
+* Add new getter `GeneratedMessage.isFrozen` to query if the message has been frozen.
+
+## 0.13.14
+
+* Avoid needless copy when reading from a Uint8List buffer.
+
+## 0.13.13
+
+* `Added `ExtensionRegistry.reparseMessage()` for decoding extensions from unknown fields after the initial
+ decoding.
+
## 0.13.12
* `BuilderInfo.add` now ignores fields with tag number 0.
diff --git a/protobuf/lib/meta.dart b/protobuf/lib/meta.dart
index f50bc77..920ac6e 100644
--- a/protobuf/lib/meta.dart
+++ b/protobuf/lib/meta.dart
@@ -36,6 +36,7 @@
'hasRequiredFields',
'hashCode',
'info_',
+ 'isFrozen',
'isInitialized',
'mergeFromBuffer',
'mergeFromCodedBufferReader',
diff --git a/protobuf/lib/src/protobuf/coded_buffer_reader.dart b/protobuf/lib/src/protobuf/coded_buffer_reader.dart
index aae3e98..94dcc30 100644
--- a/protobuf/lib/src/protobuf/coded_buffer_reader.dart
+++ b/protobuf/lib/src/protobuf/coded_buffer_reader.dart
@@ -19,8 +19,7 @@
CodedBufferReader(List<int> buffer,
{int recursionLimit = DEFAULT_RECURSION_LIMIT,
int sizeLimit = DEFAULT_SIZE_LIMIT})
- : _buffer = buffer is Uint8List ? buffer : Uint8List(buffer.length)
- ..setRange(0, buffer.length, buffer),
+ : _buffer = buffer is Uint8List ? buffer : Uint8List.fromList(buffer),
_recursionLimit = recursionLimit,
_sizeLimit = math.min(sizeLimit, buffer.length) {
_currentLimit = _sizeLimit;
diff --git a/protobuf/lib/src/protobuf/extension_registry.dart b/protobuf/lib/src/protobuf/extension_registry.dart
index 243d609..0892c2d 100644
--- a/protobuf/lib/src/protobuf/extension_registry.dart
+++ b/protobuf/lib/src/protobuf/extension_registry.dart
@@ -33,13 +33,91 @@
}
return null;
}
+
+ /// Returns a shallow copy of [message], with all extensions in [this] parsed
+ /// from the unknown fields of [message].
+ ///
+ /// Extensions already present in [message] will be preserved.
+ ///
+ /// If [message] is frozen, the result will be as well.
+ ///
+ /// Throws an [InvalidProtocolBufferException] if the parsed extensions are
+ /// malformed.
+ ///
+ /// Using this method to retrieve extensions is more expensive overall than
+ /// using an [ExtensionRegistry] with all the needed extensions when doing
+ /// [GeneratedMessage.fromBuffer].
+ ///
+ /// Example:
+ ///
+ /// `foo.proto`
+ /// ```proto
+ /// syntax = "proto2";
+ ///
+ /// message Foo {
+ /// extensions 1 to max;
+ /// }
+ ///
+ /// extend Foo {
+ /// optional string val1 = 1;
+ /// optional string val2 = 2;
+ /// }
+ /// ```
+ /// `main.dart`
+ /// ```
+ /// import 'package:protobuf/protobuf.dart';
+ /// import 'package:test/test.dart';
+ /// import 'src/generated/sample.pb.dart';
+ ///
+ /// void main() {
+ /// ExtensionRegistry r1 = ExtensionRegistry()..add(Sample.val1);
+ /// ExtensionRegistry r2 = ExtensionRegistry()..add(Sample.val2);
+ /// Foo original = Foo()..setExtension(Sample.val1, 'a')..setExtension(Sample.val2, 'b');
+ /// Foo withUnknownFields = Foo.fromBuffer(original.writeToBuffer());
+ /// Foo reparsed1 = r1.reparseMessage(withUnknownFields);
+ /// Foo reparsed2 = r2.reparseMessage(reparsed1);
+ /// expect(withUnknownFields.hasExtension(Sample.val1), isFalse);
+ /// expect(withUnknownFields.hasExtension(Sample.val2), isFalse);
+ /// expect(reparsed1.hasExtension(Sample.val1), isTrue);
+ /// expect(reparsed1.hasExtension(Sample.val2), isFalse);
+ /// expect(reparsed2.hasExtension(Sample.val1), isTrue);
+ /// expect(reparsed2.hasExtension(Sample.val2), isTrue);
+ /// }
+ /// ```
+ T reparseMessage<T extends GeneratedMessage>(T message) =>
+ _reparseMessage(message, this);
+}
+
+T _reparseMessage<T extends GeneratedMessage>(
+ T message, ExtensionRegistry extensionRegistry) {
+ T result = message.createEmptyInstance();
+
+ result._fieldSet._shallowCopyValues(message._fieldSet);
+ UnknownFieldSet resultUnknownFields = result._fieldSet._unknownFields;
+ if (resultUnknownFields != null) {
+ CodedBufferWriter codedBufferWriter = CodedBufferWriter();
+ extensionRegistry._extensions[message.info_.qualifiedMessageName]
+ ?.forEach((tagNumber, extension) {
+ final UnknownFieldSetField unknownField =
+ resultUnknownFields._fields[tagNumber];
+ if (unknownField != null) {
+ unknownField.writeTo(tagNumber, codedBufferWriter);
+ }
+ resultUnknownFields._fields.remove(tagNumber);
+ });
+
+ result.mergeFromBuffer(codedBufferWriter.toBuffer(), extensionRegistry);
+ }
+ if (message._fieldSet._isReadOnly) {
+ result.freeze();
+ }
+ return result;
}
class _EmptyExtensionRegistry implements ExtensionRegistry {
const _EmptyExtensionRegistry();
- // Needed to quiet missing member warning.
- get _extensions => null;
+ get _extensions => const <String, Map<int, Extension>>{};
void add(Extension extension) {
throw UnsupportedError('Immutable ExtensionRegistry');
@@ -50,4 +128,7 @@
}
Extension getExtension(String messageName, int tagNumber) => null;
+
+ T reparseMessage<T extends GeneratedMessage>(T message) =>
+ _reparseMessage(message, this);
}
diff --git a/protobuf/lib/src/protobuf/field_set.dart b/protobuf/lib/src/protobuf/field_set.dart
index 1b76048..97071c6 100644
--- a/protobuf/lib/src/protobuf/field_set.dart
+++ b/protobuf/lib/src/protobuf/field_set.dart
@@ -797,5 +797,7 @@
if (original._hasUnknownFields) {
_ensureUnknownFields()._fields?.addAll(original._unknownFields._fields);
}
+
+ _oneofCases?.addAll(original._oneofCases);
}
}
diff --git a/protobuf/lib/src/protobuf/generated_message.dart b/protobuf/lib/src/protobuf/generated_message.dart
index 1ad45fe..24d1d1f 100644
--- a/protobuf/lib/src/protobuf/generated_message.dart
+++ b/protobuf/lib/src/protobuf/generated_message.dart
@@ -61,6 +61,13 @@
return this;
}
+ /// Returns `true` if this message is marked read-only. Otherwise `false`.
+ ///
+ /// Even when `false`, some sub-message could be read-only.
+ ///
+ /// If `true` all sub-messages are frozen.
+ bool get isFrozen => _fieldSet._isReadOnly;
+
/// Returns a writable, shallow copy of this message.
///
/// Sub messages will be shared with [this] and will still be frozen if [this]
diff --git a/protobuf/pubspec.yaml b/protobuf/pubspec.yaml
index 20e8044..4e2a03f 100644
--- a/protobuf/pubspec.yaml
+++ b/protobuf/pubspec.yaml
@@ -1,5 +1,5 @@
name: protobuf
-version: 0.13.12
+version: 0.13.15
author: Dart Team <misc@dartlang.org>
description: >
Runtime library for protocol buffers support.
diff --git a/url_launcher/BUILD.gn b/url_launcher/BUILD.gn
index e5d1a3b..f3483cb 100644
--- a/url_launcher/BUILD.gn
+++ b/url_launcher/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for url_launcher-5.0.3
+# This file is generated by importer.py for url_launcher-5.0.5
import("//build/dart/dart_library.gni")
diff --git a/url_launcher/CHANGELOG.md b/url_launcher/CHANGELOG.md
index 23cfe54..20b64b1 100644
--- a/url_launcher/CHANGELOG.md
+++ b/url_launcher/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 5.0.5
+
+* Add `enableDomStorage` field to `launch` to enable DOM storage in Android WebView.
+
+## 5.0.4
+
+* Update Dart code to conform to current Dart formatter.
+
## 5.0.3
* Add missing template type parameter to `invokeMethod` calls.
@@ -5,6 +13,7 @@
* Replace invokeMethod with invokeMapMethod wherever necessary.
## 5.0.2
+
* Fixes `closeWebView` failure on iOS.
## 5.0.1
diff --git a/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java b/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java
index 888d3c3..30d0676 100644
--- a/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java
+++ b/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java
@@ -68,6 +68,7 @@
Intent launchIntent;
boolean useWebView = call.argument("useWebView");
boolean enableJavaScript = call.argument("enableJavaScript");
+ boolean enableDomStorage = call.argument("enableDomStorage");
Activity activity = mRegistrar.activity();
if (activity == null) {
result.error("NO_ACTIVITY", "Launching a URL requires a foreground activity.", null);
@@ -77,6 +78,7 @@
launchIntent = new Intent(activity, WebViewActivity.class);
launchIntent.putExtra("url", url);
launchIntent.putExtra("enableJavaScript", enableJavaScript);
+ launchIntent.putExtra("enableDomStorage", enableDomStorage);
} else {
launchIntent = new Intent(Intent.ACTION_VIEW);
launchIntent.setData(Uri.parse(url));
@@ -105,10 +107,14 @@
Intent intent = getIntent();
String url = intent.getStringExtra("url");
Boolean enableJavaScript = intent.getBooleanExtra("enableJavaScript", false);
+ Boolean enableDomStorage = intent.getBooleanExtra("enableDomStorage", false);
webview.loadUrl(url);
if (enableJavaScript) {
webview.getSettings().setJavaScriptEnabled(enableJavaScript);
}
+ if (enableDomStorage) {
+ webview.getSettings().setDomStorageEnabled(enableDomStorage);
+ }
// Open new urls inside the webview itself.
webview.setWebViewClient(
new WebViewClient() {
diff --git a/url_launcher/example/lib/main.dart b/url_launcher/example/lib/main.dart
index 6ef6790..66b5e9f 100644
--- a/url_launcher/example/lib/main.dart
+++ b/url_launcher/example/lib/main.dart
@@ -65,6 +65,19 @@
}
}
+ Future<void> _launchInWebViewWithDomStorage(String url) async {
+ if (await canLaunch(url)) {
+ await launch(
+ url,
+ forceSafariVC: true,
+ forceWebView: true,
+ enableDomStorage: true,
+ );
+ } else {
+ throw 'Could not launch $url';
+ }
+ }
+
Future<void> _launchUniversalLinkIos(String url) async {
if (await canLaunch('https://youtube.com')) {
final bool nativeAppLaunchSucceeded = await launch(
@@ -104,69 +117,77 @@
appBar: AppBar(
title: Text(widget.title),
),
- body: Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- Padding(
- padding: const EdgeInsets.all(16.0),
- child: TextField(
- onChanged: (String text) => _phone = text,
- decoration: const InputDecoration(
- hintText: 'Input the phone number to launch')),
- ),
- RaisedButton(
- onPressed: () => setState(() {
- _launched = _makePhoneCall('tel:$_phone');
- }),
- child: const Text('Make phone call'),
- ),
- const Padding(
- padding: EdgeInsets.all(16.0),
- child: Text(toLaunch),
- ),
- RaisedButton(
- onPressed: () => setState(() {
- _launched = _launchInBrowser(toLaunch);
- }),
- child: const Text('Launch in browser'),
- ),
- const Padding(padding: EdgeInsets.all(16.0)),
- RaisedButton(
- onPressed: () => setState(() {
- _launched = _launchInWebViewOrVC(toLaunch);
- }),
- child: const Text('Launch in app'),
- ),
- const Padding(padding: EdgeInsets.all(16.0)),
- RaisedButton(
- onPressed: () => setState(() {
- _launched = _launchInWebViewWithJavaScript(toLaunch);
- }),
- child: const Text('Launch in app(JavaScript ON)'),
- ),
- RaisedButton(
- onPressed: () => setState(() {
- _launched = _launchUniversalLinkIos(toLaunch);
- }),
- child: const Text(
- 'Launch a universal link in a native app, fallback to Safari.(Youtube)'),
- ),
- const Padding(padding: EdgeInsets.all(16.0)),
- RaisedButton(
- onPressed: () => setState(() {
- _launched = _launchInWebViewOrVC(toLaunch);
- Timer(const Duration(seconds: 5), () {
- print('Closing WebView after 5 seconds...');
- closeWebView();
- });
- }),
- child: const Text('Launch in app + close after 5 seconds'),
- ),
- const Padding(padding: EdgeInsets.all(16.0)),
- FutureBuilder<void>(future: _launched, builder: _launchStatus),
- ],
- ),
+ body: ListView(
+ children: <Widget>[
+ Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: <Widget>[
+ Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: TextField(
+ onChanged: (String text) => _phone = text,
+ decoration: const InputDecoration(
+ hintText: 'Input the phone number to launch')),
+ ),
+ RaisedButton(
+ onPressed: () => setState(() {
+ _launched = _makePhoneCall('tel:$_phone');
+ }),
+ child: const Text('Make phone call'),
+ ),
+ const Padding(
+ padding: EdgeInsets.all(16.0),
+ child: Text(toLaunch),
+ ),
+ RaisedButton(
+ onPressed: () => setState(() {
+ _launched = _launchInBrowser(toLaunch);
+ }),
+ child: const Text('Launch in browser'),
+ ),
+ const Padding(padding: EdgeInsets.all(16.0)),
+ RaisedButton(
+ onPressed: () => setState(() {
+ _launched = _launchInWebViewOrVC(toLaunch);
+ }),
+ child: const Text('Launch in app'),
+ ),
+ RaisedButton(
+ onPressed: () => setState(() {
+ _launched = _launchInWebViewWithJavaScript(toLaunch);
+ }),
+ child: const Text('Launch in app(JavaScript ON)'),
+ ),
+ RaisedButton(
+ onPressed: () => setState(() {
+ _launched = _launchInWebViewWithDomStorage(toLaunch);
+ }),
+ child: const Text('Launch in app(DOM storage ON)'),
+ ),
+ const Padding(padding: EdgeInsets.all(16.0)),
+ RaisedButton(
+ onPressed: () => setState(() {
+ _launched = _launchUniversalLinkIos(toLaunch);
+ }),
+ child: const Text(
+ 'Launch a universal link in a native app, fallback to Safari.(Youtube)'),
+ ),
+ const Padding(padding: EdgeInsets.all(16.0)),
+ RaisedButton(
+ onPressed: () => setState(() {
+ _launched = _launchInWebViewOrVC(toLaunch);
+ Timer(const Duration(seconds: 5), () {
+ print('Closing WebView after 5 seconds...');
+ closeWebView();
+ });
+ }),
+ child: const Text('Launch in app + close after 5 seconds'),
+ ),
+ const Padding(padding: EdgeInsets.all(16.0)),
+ FutureBuilder<void>(future: _launched, builder: _launchStatus),
+ ],
+ ),
+ ],
),
);
}
diff --git a/url_launcher/lib/url_launcher.dart b/url_launcher/lib/url_launcher.dart
index a942b50..edae489 100644
--- a/url_launcher/lib/url_launcher.dart
+++ b/url_launcher/lib/url_launcher.dart
@@ -42,6 +42,8 @@
/// WebViews.
/// [enableJavaScript] is an Android only setting. If true, WebView enable
/// javascript.
+/// [enableDomStorage] is an Android only setting. If true, WebView enable
+/// DOM storage.
///
/// Note that if any of the above are set to true but the URL is not a web URL,
/// this will throw a [PlatformException].
@@ -57,6 +59,7 @@
bool forceSafariVC,
bool forceWebView,
bool enableJavaScript,
+ bool enableDomStorage,
bool universalLinksOnly,
Brightness statusBarBrightness,
}) async {
@@ -86,6 +89,7 @@
'useSafariVC': forceSafariVC ?? isWebURL,
'useWebView': forceWebView ?? false,
'enableJavaScript': enableJavaScript ?? false,
+ 'enableDomStorage': enableDomStorage ?? false,
'universalLinksOnly': universalLinksOnly ?? false,
},
);
diff --git a/url_launcher/pubspec.yaml b/url_launcher/pubspec.yaml
index f67afe5..0c07112 100644
--- a/url_launcher/pubspec.yaml
+++ b/url_launcher/pubspec.yaml
@@ -3,7 +3,7 @@
web, phone, SMS, and email schemes.
author: Flutter Team <flutter-dev@googlegroups.com>
homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher
-version: 5.0.3
+version: 5.0.5
flutter:
plugin:
diff --git a/vm_service_lib/BUILD.gn b/vm_service_lib/BUILD.gn
index 0f1329e..5541891 100644
--- a/vm_service_lib/BUILD.gn
+++ b/vm_service_lib/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for vm_service_lib-3.21.0
+# This file is generated by importer.py for vm_service_lib-3.22.0
import("//build/dart/dart_library.gni")
diff --git a/vm_service_lib/CHANGELOG.md b/vm_service_lib/CHANGELOG.md
index 5b5d6c7..e4a47b4 100644
--- a/vm_service_lib/CHANGELOG.md
+++ b/vm_service_lib/CHANGELOG.md
@@ -1,5 +1,16 @@
# Changelog
+## 3.22.0
+- The `registerService` RPC and `Service` stream are now public.
+- `Event` has been updated to include the optional `service`, `method`, and
+ `alias` properties.
+
+## 3.21.1
+- **breaking**: Fixed issue where an `InstanceRef` of type `null` could be returned
+ instead of null for non-`InstanceRef` properties and return values. As a
+ result, some property and return types have been changed from Obj to their
+ correct types.
+
## 3.21.0
- support service protocol version 3.21
diff --git a/vm_service_lib/example/vm_service_assert.dart b/vm_service_lib/example/vm_service_assert.dart
index 613defc..0357cf4 100644
--- a/vm_service_lib/example/vm_service_assert.dart
+++ b/vm_service_lib/example/vm_service_assert.dart
@@ -600,6 +600,7 @@
assertString(obj.type);
assertString(obj.id);
assertInstanceKind(obj.kind);
+ assertClassRef(obj.classRef);
return obj;
}
@@ -757,6 +758,7 @@
assertString(obj.id);
assertInstanceKind(obj.kind);
assertClassRef(obj.classRef);
+ assertString(obj.valueAsString);
return obj;
}
@@ -772,6 +774,8 @@
assertString(obj.type);
assertString(obj.id);
assertInstanceKind(obj.kind);
+ assertClassRef(obj.classRef);
+ assertString(obj.valueAsString);
return obj;
}
diff --git a/vm_service_lib/example/vm_service_lib_tester.dart b/vm_service_lib/example/vm_service_lib_tester.dart
index 898af1b..7b22ae2 100644
--- a/vm_service_lib/example/vm_service_lib_tester.dart
+++ b/vm_service_lib/example/vm_service_lib_tester.dart
@@ -76,7 +76,8 @@
expect(originalJson, isNotNull, reason: 'Unrecognized event type! $json');
// ignore: invalid_use_of_visible_for_testing_member
- var instance = createServiceObject(originalJson);
+ var instance =
+ createServiceObject(originalJson, const ['Event', 'Success']);
expect(instance, isNotNull,
reason: 'failed to deserialize object $originalJson!');
diff --git a/vm_service_lib/lib/vm_service_lib.dart b/vm_service_lib/lib/vm_service_lib.dart
index 6f72fe9..5b78bb0 100644
--- a/vm_service_lib/lib/vm_service_lib.dart
+++ b/vm_service_lib/lib/vm_service_lib.dart
@@ -17,7 +17,7 @@
export 'src/service_extension_registry.dart' show ServiceExtensionRegistry;
-const String vmServiceVersion = '3.21.0';
+const String vmServiceVersion = '3.22.0';
/// @optional
const String optional = 'optional';
@@ -29,13 +29,20 @@
/// This is useful for handling the results of the Stdout or Stderr events.
String decodeBase64(String str) => utf8.decode(base64.decode(str));
-Object createServiceObject(dynamic json) {
+// Returns true if a response is the Dart `null` instance.
+bool _isNullInstance(Map json) =>
+ ((json['type'] == '@Instance') && (json['kind'] == 'Null'));
+
+Object createServiceObject(dynamic json, List<String> expectedTypes) {
if (json == null) return null;
if (json is List) {
- return json.map((e) => createServiceObject(e)).toList();
+ return json.map((e) => createServiceObject(e, expectedTypes)).toList();
} else if (json is Map) {
String type = json['type'];
+ if (_isNullInstance(json) && (!expectedTypes.contains(type))) {
+ return null;
+ }
if (_typeFactories[type] == null) {
return null;
} else {
@@ -142,6 +149,48 @@
'HeapSpace': HeapSpace.parse,
};
+Map<String, List<String>> _methodReturnTypes = {
+ 'addBreakpoint': const ['Breakpoint'],
+ 'addBreakpointWithScriptUri': const ['Breakpoint'],
+ 'addBreakpointAtEntry': const ['Breakpoint'],
+ 'clearVMTimeline': const ['Success'],
+ 'invoke': const ['InstanceRef', 'ErrorRef', 'Sentinel'],
+ 'evaluate': const ['InstanceRef', 'ErrorRef', 'Sentinel'],
+ 'evaluateInFrame': const ['InstanceRef', 'ErrorRef', 'Sentinel'],
+ 'getAllocationProfile': const ['AllocationProfile'],
+ 'getFlagList': const ['FlagList'],
+ 'getInstances': const ['InstanceSet'],
+ 'getIsolate': const ['Isolate', 'Sentinel'],
+ 'getMemoryUsage': const ['MemoryUsage', 'Sentinel'],
+ 'getScripts': const ['ScriptList'],
+ 'getObject': const ['Obj', 'Sentinel'],
+ 'getStack': const ['Stack'],
+ 'getSourceReport': const ['SourceReport'],
+ 'getVersion': const ['Version'],
+ 'getVM': const ['VM'],
+ 'getVMTimeline': const ['Timeline'],
+ 'getVMTimelineFlags': const ['TimelineFlags'],
+ 'getVMTimelineMicros': const ['Timestamp'],
+ 'pause': const ['Success'],
+ 'kill': const ['Success'],
+ 'reloadSources': const ['ReloadReport'],
+ 'removeBreakpoint': const ['Success'],
+ 'resume': const ['Success'],
+ 'setExceptionPauseMode': const ['Success'],
+ 'setFlag': const ['Success'],
+ 'setLibraryDebuggable': const ['Success'],
+ 'setName': const ['Success'],
+ 'setVMName': const ['Success'],
+ 'setVMTimelineFlags': const ['Success'],
+ 'streamCancel': const ['Success'],
+ 'streamListen': const ['Success'],
+ '_collectAllGarbage': const ['Success'],
+ '_requestHeapSnapshot': const ['Success'],
+ '_clearCpuProfile': const ['Success'],
+ '_getCpuProfile': const ['_CpuProfile'],
+ '_registerService': const ['Success'],
+};
+
/// A class representation of the Dart VM Service Protocol.
///
/// Both clients and servers should implement this interface.
@@ -242,9 +291,8 @@
///
/// If `disableBreakpoints` is provided and set to true, any breakpoints hit
/// as a result of this invocation are ignored, including pauses resulting
- /// from a call to <code>debugger()</code>debugger() from
- /// <code>dart:developer</code>dart:developer. Defaults to false if not
- /// provided.
+ /// from a call to `debugger()` from `dart:developer`. Defaults to false if
+ /// not provided.
///
/// If `targetId` or any element of `argumentIds` is a temporary id which has
/// expired, then the `Expired` [Sentinel] is returned.
@@ -364,9 +412,8 @@
/// The `getInstances` RPC is used to retrieve a set of instances which are of
/// a specific type.
///
- /// `objectId` is the ID of the <code>Class</code>Class to retrieve instances
- /// for. `objectId` must be the ID of a <code>Class</code>Class, otherwise an
- /// error is returned.
+ /// `objectId` is the ID of the `Class` to retrieve instances for. `objectId`
+ /// must be the ID of a `Class`, otherwise an error is returned.
///
/// `limit` is the maximum number of instances to be returned.
///
@@ -495,19 +542,16 @@
///
/// The `timeOriginMicros` parameter is the beginning of the time range used
/// to filter timeline events. It uses the same monotonic clock as
- /// dart:developer's <code>Timeline.now</code>Timeline.now and the VM
- /// embedding API's <code>Dart_TimelineGetMicros</code>Dart_TimelineGetMicros.
- /// See [getVMTimelineMicros] for access to this clock through the service
- /// protocol.
+ /// dart:developer's `Timeline.now` and the VM embedding API's
+ /// `Dart_TimelineGetMicros`. See [getVMTimelineMicros] for access to this
+ /// clock through the service protocol.
///
/// The `timeExtentMicros` parameter specifies how large the time range used
/// to filter timeline events should be.
///
/// For example, given `timeOriginMicros` and `timeExtentMicros`, only
/// timeline events from the following time range will be returned:
- /// <code>(timeOriginMicros, timeOriginMicros +
- /// timeExtentMicros)</code>(timeOriginMicros, timeOriginMicros +
- /// timeExtentMicros).
+ /// `(timeOriginMicros, timeOriginMicros + timeExtentMicros)`.
///
/// If `getVMTimeline` is invoked while the current recorder is one of Fuchsia
/// or Systrace, the `114` error code, invalid timeline request, will be
@@ -524,11 +568,8 @@
Future<TimelineFlags> getVMTimelineFlags();
/// The `getVMTimelineMicros` RPC returns the current time stamp from the
- /// clock used by the timeline, similar to
- /// <code>Timeline.now</code>Timeline.now in
- /// <code>dart:developer</code>dart:developer and
- /// <code>Dart_TimelineGetMicros</code>Dart_TimelineGetMicros in the VM
- /// embedding API.
+ /// clock used by the timeline, similar to `Timeline.now` in `dart:developer`
+ /// and `Dart_TimelineGetMicros` in the VM embedding API.
///
/// See [Timestamp] and [getVMTimeline].
Future<Timestamp> getVMTimelineMicros();
@@ -543,13 +584,23 @@
Future<Success> pause(String isolateId);
/// The `kill` RPC is used to kill an isolate as if by dart:isolate's
- /// <code>Isolate.kill(IMMEDIATE)</code>Isolate.kill(IMMEDIATE).
+ /// `Isolate.kill(IMMEDIATE)`.
///
/// The isolate is killed regardless of whether it is paused or running.
///
/// See [Success].
Future<Success> kill(String isolateId);
+ /// Registers a service that can be invoked by other VM service clients, where
+ /// `service` is the name of the service to advertise and `alias` is an
+ /// alternative name for the registered service.
+ ///
+ /// Requests made to the new service will be forwarded to the client which
+ /// originally registered the service.
+ ///
+ /// See [Success].
+ Future<Success> registerService(String service, String alias);
+
/// The `reloadSources` RPC is used to perform a hot reload of an Isolate's
/// sources.
///
@@ -681,6 +732,7 @@
/// Extension | Extension
/// Timeline | TimelineEvents
/// Logging | Logging
+ /// Service | ServiceRegistered, ServiceUnregistered
///
/// Additionally, some embedders provide the `Stdout` and `Stderr` streams.
/// These streams allow the client to subscribe to writes to stdout and
@@ -713,8 +765,6 @@
/// `tags` is one of UserVM, UserOnly, VMUser, VMOnly, or None.
@undocumented
Future<CpuProfile> getCpuProfile(String isolateId, String tags);
- @undocumented
- Future<Success> registerService(String service, String alias);
}
/// A Dart VM Service Protocol connection that delegates requests to a
@@ -927,6 +977,12 @@
params['isolateId'],
);
break;
+ case 'registerService':
+ response = await _serviceImplementation.registerService(
+ params['service'],
+ params['alias'],
+ );
+ break;
case 'reloadSources':
response = await _serviceImplementation.reloadSources(
params['isolateId'],
@@ -1120,6 +1176,9 @@
// Logging
Stream<Event> get onLoggingEvent => _getEventController('Logging').stream;
+ // ServiceRegistered, ServiceUnregistered
+ Stream<Event> get onServiceEvent => _getEventController('Service').stream;
+
// WriteEvent
Stream<Event> get onStdoutEvent => _getEventController('Stdout').stream;
@@ -1348,6 +1407,11 @@
}
@override
+ Future<Success> registerService(String service, String alias) {
+ return _call('registerService', {'service': service, 'alias': alias});
+ }
+
+ @override
Future<ReloadReport> reloadSources(
String isolateId, {
bool force,
@@ -1466,12 +1530,6 @@
return _call('_getCpuProfile', {'isolateId': isolateId, 'tags': tags});
}
- @undocumented
- @override
- Future<Success> registerService(String service, String alias) {
- return _call('_registerService', {'service': service, 'alias': alias});
- }
-
/// Call an arbitrary service protocol method. This allows clients to call
/// methods not explicitly exposed by this library.
Future<Response> callMethod(String method, {String isolateId, Map args}) {
@@ -1557,7 +1615,8 @@
String streamId = map['params']['streamId'];
Map event = map['params']['event'];
event['_data'] = data;
- _getEventController(streamId).add(createServiceObject(event));
+ _getEventController(streamId)
+ .add(createServiceObject(event, const ['Event']));
}
}
@@ -1589,7 +1648,7 @@
void _processResponse(Map<String, dynamic> json) {
Completer completer = _completers.remove(json['id']);
String methodName = _methodCalls.remove(json['id']);
-
+ List<String> returnTypes = _methodReturnTypes[methodName];
if (completer == null) {
_log.severe('unmatched request response: ${jsonEncode(json)}');
} else if (json['error'] != null) {
@@ -1600,7 +1659,7 @@
if (_typeFactories[type] == null) {
completer.complete(Response.parse(result));
} else {
- completer.complete(createServiceObject(result));
+ completer.complete(createServiceObject(result, returnTypes));
}
}
}
@@ -1619,7 +1678,8 @@
final Map params = json['params'];
if (method == 'streamNotify') {
String streamId = params['streamId'];
- _getEventController(streamId).add(createServiceObject(params['event']));
+ _getEventController(streamId)
+ .add(createServiceObject(params['event'], const ['Event']));
} else {
await _routeRequest(method, params);
}
@@ -1741,6 +1801,7 @@
static const String kExtension = 'Extension';
static const String kTimeline = 'Timeline';
static const String kLogging = 'Logging';
+ static const String kService = 'Service';
static const String kStdout = 'Stdout';
static const String kStderr = 'Stderr';
}
@@ -2011,15 +2072,16 @@
AllocationProfile._fromJson(Map<String, dynamic> json)
: super._fromJson(json) {
- memoryUsage = createServiceObject(json['memoryUsage']);
+ memoryUsage =
+ createServiceObject(json['memoryUsage'], const ['MemoryUsage']);
dateLastAccumulatorReset = json['dateLastAccumulatorReset'] is String
? int.parse(json['dateLastAccumulatorReset'])
: json['dateLastAccumulatorReset'];
dateLastServiceGC = json['dateLastServiceGC'] is String
? int.parse(json['dateLastServiceGC'])
: json['dateLastServiceGC'];
- members =
- new List<ClassHeapStats>.from(createServiceObject(json['members']));
+ members = new List<ClassHeapStats>.from(
+ createServiceObject(json['members'], const ['ClassHeapStats']));
}
@override
@@ -2059,8 +2121,9 @@
BoundField();
BoundField._fromJson(Map<String, dynamic> json) {
- decl = createServiceObject(json['decl']);
- value = createServiceObject(json['value']);
+ decl = createServiceObject(json['decl'], const ['FieldRef']);
+ value =
+ createServiceObject(json['value'], const ['InstanceRef', 'Sentinel']);
}
Map<String, dynamic> toJson() {
@@ -2108,7 +2171,8 @@
BoundVariable._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
- value = createServiceObject(json['value']);
+ value = createServiceObject(
+ json['value'], const ['InstanceRef', 'TypeArgumentsRef', 'Sentinel']);
declarationTokenPos = json['declarationTokenPos'];
scopeStartTokenPos = json['scopeStartTokenPos'];
scopeEndTokenPos = json['scopeEndTokenPos'];
@@ -2166,7 +2230,8 @@
breakpointNumber = json['breakpointNumber'];
resolved = json['resolved'];
isSyntheticAsyncContinuation = json['isSyntheticAsyncContinuation'];
- location = createServiceObject(json['location']);
+ location = createServiceObject(
+ json['location'], const ['SourceLocation', 'UnresolvedSourceLocation']);
}
@override
@@ -2284,20 +2349,22 @@
Class._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
- error = createServiceObject(json['error']);
+ error = createServiceObject(json['error'], const ['ErrorRef']);
isAbstract = json['abstract'];
isConst = json['const'];
- library = createServiceObject(json['library']);
- location = createServiceObject(json['location']);
- superClass = createServiceObject(json['super']);
- superType = createServiceObject(json['superType']);
- interfaces =
- new List<InstanceRef>.from(createServiceObject(json['interfaces']));
- mixin = createServiceObject(json['mixin']);
- fields = new List<FieldRef>.from(createServiceObject(json['fields']));
- functions = new List<FuncRef>.from(createServiceObject(json['functions']));
- subclasses =
- new List<ClassRef>.from(createServiceObject(json['subclasses']));
+ library = createServiceObject(json['library'], const ['ObjRef']);
+ location = createServiceObject(json['location'], const ['SourceLocation']);
+ superClass = createServiceObject(json['super'], const ['ClassRef']);
+ superType = createServiceObject(json['superType'], const ['InstanceRef']);
+ interfaces = new List<InstanceRef>.from(
+ createServiceObject(json['interfaces'], const ['InstanceRef']));
+ mixin = createServiceObject(json['mixin'], const ['InstanceRef']);
+ fields = new List<FieldRef>.from(
+ createServiceObject(json['fields'], const ['FieldRef']));
+ functions = new List<FuncRef>.from(
+ createServiceObject(json['functions'], const ['FuncRef']));
+ subclasses = new List<ClassRef>.from(
+ createServiceObject(json['subclasses'], const ['ClassRef']));
}
@override
@@ -2366,7 +2433,7 @@
bytesCurrent = json['bytesCurrent'];
instancesAccumulated = json['instancesAccumulated'];
instancesCurrent = json['instancesCurrent'];
- classRef = createServiceObject(json['class']);
+ classRef = createServiceObject(json['class'], const ['ClassRef']);
new_ = json['new'] == null ? null : new List<int>.from(json['new']);
old = json['old'] == null ? null : new List<int>.from(json['old']);
promotedBytes = json['promotedBytes'];
@@ -2403,7 +2470,8 @@
ClassList();
ClassList._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
- classes = new List<ClassRef>.from(createServiceObject(json['classes']));
+ classes = new List<ClassRef>.from(
+ createServiceObject(json['classes'], const ['ClassRef']));
}
@override
@@ -2544,9 +2612,9 @@
Context._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
length = json['length'];
- parent = createServiceObject(json['parent']);
- variables =
- new List<ContextElement>.from(createServiceObject(json['variables']));
+ parent = createServiceObject(json['parent'], const ['Context']);
+ variables = new List<ContextElement>.from(
+ createServiceObject(json['variables'], const ['ContextElement']));
}
@override
@@ -2579,7 +2647,8 @@
ContextElement();
ContextElement._fromJson(Map<String, dynamic> json) {
- value = createServiceObject(json['value']);
+ value =
+ createServiceObject(json['value'], const ['InstanceRef', 'Sentinel']);
}
Map<String, dynamic> toJson() {
@@ -2657,8 +2726,8 @@
Error._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
message = json['message'];
- exception = createServiceObject(json['exception']);
- stacktrace = createServiceObject(json['stacktrace']);
+ exception = createServiceObject(json['exception'], const ['InstanceRef']);
+ stacktrace = createServiceObject(json['stacktrace'], const ['InstanceRef']);
}
@override
@@ -2843,28 +2912,28 @@
Event._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
- isolate = createServiceObject(json['isolate']);
- vm = createServiceObject(json['vm']);
+ isolate = createServiceObject(json['isolate'], const ['IsolateRef']);
+ vm = createServiceObject(json['vm'], const ['VMRef']);
timestamp = json['timestamp'];
- breakpoint = createServiceObject(json['breakpoint']);
+ breakpoint = createServiceObject(json['breakpoint'], const ['Breakpoint']);
pauseBreakpoints = json['pauseBreakpoints'] == null
? null
- : new List<Breakpoint>.from(
- createServiceObject(json['pauseBreakpoints']));
- topFrame = createServiceObject(json['topFrame']);
- exception = createServiceObject(json['exception']);
+ : new List<Breakpoint>.from(createServiceObject(
+ json['pauseBreakpoints'], const ['Breakpoint']));
+ topFrame = createServiceObject(json['topFrame'], const ['Frame']);
+ exception = createServiceObject(json['exception'], const ['InstanceRef']);
bytes = json['bytes'];
- inspectee = createServiceObject(json['inspectee']);
+ inspectee = createServiceObject(json['inspectee'], const ['InstanceRef']);
extensionRPC = json['extensionRPC'];
extensionKind = json['extensionKind'];
extensionData = ExtensionData.parse(json['extensionData']);
timelineEvents = json['timelineEvents'] == null
? null
- : new List<TimelineEvent>.from(
- createServiceObject(json['timelineEvents']));
+ : new List<TimelineEvent>.from(createServiceObject(
+ json['timelineEvents'], const ['TimelineEvent']));
atAsyncSuspension = json['atAsyncSuspension'];
status = json['status'];
- logRecord = createServiceObject(json['logRecord']);
+ logRecord = createServiceObject(json['logRecord'], const ['LogRecord']);
service = json['service'];
method = json['method'];
alias = json['alias'];
@@ -2935,8 +3004,9 @@
FieldRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
- owner = createServiceObject(json['owner']);
- declaredType = createServiceObject(json['declaredType']);
+ owner = createServiceObject(json['owner'], const ['ObjRef']);
+ declaredType =
+ createServiceObject(json['declaredType'], const ['InstanceRef']);
isConst = json['const'];
isFinal = json['final'];
isStatic = json['static'];
@@ -3002,13 +3072,15 @@
Field._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
- owner = createServiceObject(json['owner']);
- declaredType = createServiceObject(json['declaredType']);
+ owner = createServiceObject(json['owner'], const ['ObjRef']);
+ declaredType =
+ createServiceObject(json['declaredType'], const ['InstanceRef']);
isConst = json['const'];
isFinal = json['final'];
isStatic = json['static'];
- staticValue = createServiceObject(json['staticValue']);
- location = createServiceObject(json['location']);
+ staticValue =
+ createServiceObject(json['staticValue'], const ['InstanceRef']);
+ location = createServiceObject(json['location'], const ['SourceLocation']);
}
@override
@@ -3090,7 +3162,8 @@
FlagList();
FlagList._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
- flags = new List<Flag>.from(createServiceObject(json['flags']));
+ flags =
+ new List<Flag>.from(createServiceObject(json['flags'], const ['Flag']));
}
@override
@@ -3132,12 +3205,13 @@
Frame._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
index = json['index'];
- function = createServiceObject(json['function']);
- code = createServiceObject(json['code']);
- location = createServiceObject(json['location']);
+ function = createServiceObject(json['function'], const ['FuncRef']);
+ code = createServiceObject(json['code'], const ['CodeRef']);
+ location = createServiceObject(json['location'], const ['SourceLocation']);
vars = json['vars'] == null
? null
- : new List<BoundVariable>.from(createServiceObject(json['vars']));
+ : new List<BoundVariable>.from(
+ createServiceObject(json['vars'], const ['BoundVariable']));
kind = json['kind'];
}
@@ -3182,7 +3256,8 @@
FuncRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
- owner = createServiceObject(json['owner']);
+ owner = createServiceObject(
+ json['owner'], const ['LibraryRef', 'ClassRef', 'FuncRef']);
isStatic = json['static'];
isConst = json['const'];
}
@@ -3234,9 +3309,10 @@
Func._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
- owner = createServiceObject(json['owner']);
- location = createServiceObject(json['location']);
- code = createServiceObject(json['code']);
+ owner = createServiceObject(
+ json['owner'], const ['LibraryRef', 'ClassRef', 'FuncRef']);
+ location = createServiceObject(json['location'], const ['SourceLocation']);
+ code = createServiceObject(json['code'], const ['CodeRef']);
}
@override
@@ -3351,14 +3427,15 @@
InstanceRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
- classRef = createServiceObject(json['class']);
+ classRef = createServiceObject(json['class'], const ['ClassRef']);
valueAsString = json['valueAsString'];
valueAsStringIsTruncated = json['valueAsStringIsTruncated'] ?? false;
length = json['length'];
name = json['name'];
- typeClass = createServiceObject(json['typeClass']);
- parameterizedClass = createServiceObject(json['parameterizedClass']);
- pattern = createServiceObject(json['pattern']);
+ typeClass = createServiceObject(json['typeClass'], const ['ClassRef']);
+ parameterizedClass =
+ createServiceObject(json['parameterizedClass'], const ['ClassRef']);
+ pattern = createServiceObject(json['pattern'], const ['InstanceRef']);
}
@override
@@ -3396,6 +3473,10 @@
/// What kind of instance is this?
/*InstanceKind*/ String kind;
+ /// Instance references always include their class.
+ @override
+ ClassRef classRef;
+
/// The value of this instance as a string.
///
/// Provided for the instance kinds:
@@ -3553,13 +3634,14 @@
@optional
FuncRef closureFunction;
- /// TODO(devoncarew): this can return an InstanceRef
- ///
/// The context associated with a Closure instance.
///
/// Provided for instance kinds:
- /// - Closure@Context closureContext [optional]; The referent of a
- /// MirrorReference instance.
+ /// - Closure
+ @optional
+ ContextRef closureContext;
+
+ /// The referent of a MirrorReference instance.
///
/// Provided for instance kinds:
/// - MirrorReference
@@ -3642,36 +3724,47 @@
Instance._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
+ classRef = createServiceObject(json['class'], const ['ClassRef']);
valueAsString = json['valueAsString'];
valueAsStringIsTruncated = json['valueAsStringIsTruncated'] ?? false;
length = json['length'];
offset = json['offset'];
count = json['count'];
name = json['name'];
- typeClass = createServiceObject(json['typeClass']);
- parameterizedClass = createServiceObject(json['parameterizedClass']);
+ typeClass = createServiceObject(json['typeClass'], const ['ClassRef']);
+ parameterizedClass =
+ createServiceObject(json['parameterizedClass'], const ['ClassRef']);
fields = json['fields'] == null
? null
- : new List<BoundField>.from(createServiceObject(json['fields']));
+ : new List<BoundField>.from(
+ createServiceObject(json['fields'], const ['BoundField']));
elements = json['elements'] == null
? null
- : new List<dynamic>.from(createServiceObject(json['elements']));
+ : new List<dynamic>.from(
+ createServiceObject(json['elements'], const ['dynamic']));
associations = json['associations'] == null
? null
: new List<MapAssociation>.from(
_createSpecificObject(json['associations'], MapAssociation.parse));
bytes = json['bytes'];
- closureFunction = createServiceObject(json['closureFunction']);
- mirrorReferent = createServiceObject(json['mirrorReferent']);
+ closureFunction =
+ createServiceObject(json['closureFunction'], const ['FuncRef']);
+ closureContext =
+ createServiceObject(json['closureContext'], const ['ContextRef']);
+ mirrorReferent =
+ createServiceObject(json['mirrorReferent'], const ['InstanceRef']);
pattern = json['pattern'];
isCaseSensitive = json['isCaseSensitive'];
isMultiLine = json['isMultiLine'];
- propertyKey = createServiceObject(json['propertyKey']);
- propertyValue = createServiceObject(json['propertyValue']);
- typeArguments = createServiceObject(json['typeArguments']);
+ propertyKey =
+ createServiceObject(json['propertyKey'], const ['InstanceRef']);
+ propertyValue =
+ createServiceObject(json['propertyValue'], const ['InstanceRef']);
+ typeArguments =
+ createServiceObject(json['typeArguments'], const ['TypeArgumentsRef']);
parameterIndex = json['parameterIndex'];
- targetType = createServiceObject(json['targetType']);
- bound = createServiceObject(json['bound']);
+ targetType = createServiceObject(json['targetType'], const ['InstanceRef']);
+ bound = createServiceObject(json['bound'], const ['InstanceRef']);
}
@override
@@ -3680,6 +3773,7 @@
json['type'] = 'Instance';
json.addAll({
'kind': kind,
+ 'class': classRef.toJson(),
});
_setIfNotNull(json, 'valueAsString', valueAsString);
_setIfNotNull(
@@ -3697,6 +3791,7 @@
json, 'associations', associations?.map((f) => f?.toJson())?.toList());
_setIfNotNull(json, 'bytes', bytes);
_setIfNotNull(json, 'closureFunction', closureFunction?.toJson());
+ _setIfNotNull(json, 'closureContext', closureContext?.toJson());
_setIfNotNull(json, 'mirrorReferent', mirrorReferent?.toJson());
_setIfNotNull(json, 'pattern', pattern);
_setIfNotNull(json, 'isCaseSensitive', isCaseSensitive);
@@ -3714,7 +3809,8 @@
operator ==(other) => other is Instance && id == other.id;
- String toString() => '[Instance type: ${type}, id: ${id}, kind: ${kind}]';
+ String toString() => '[Instance ' //
+ 'type: ${type}, id: ${id}, kind: ${kind}, classRef: ${classRef}]';
}
/// `IsolateRef` is a reference to an `Isolate` object.
@@ -3827,13 +3923,13 @@
runnable = json['runnable'];
livePorts = json['livePorts'];
pauseOnExit = json['pauseOnExit'];
- pauseEvent = createServiceObject(json['pauseEvent']);
- rootLib = createServiceObject(json['rootLib']);
- libraries =
- new List<LibraryRef>.from(createServiceObject(json['libraries']));
- breakpoints =
- new List<Breakpoint>.from(createServiceObject(json['breakpoints']));
- error = createServiceObject(json['error']);
+ pauseEvent = createServiceObject(json['pauseEvent'], const ['Event']);
+ rootLib = createServiceObject(json['rootLib'], const ['LibraryRef']);
+ libraries = new List<LibraryRef>.from(
+ createServiceObject(json['libraries'], const ['LibraryRef']));
+ breakpoints = new List<Breakpoint>.from(
+ createServiceObject(json['breakpoints'], const ['Breakpoint']));
+ error = createServiceObject(json['error'], const ['Error']);
exceptionPauseMode = json['exceptionPauseMode'];
extensionRPCs = json['extensionRPCs'] == null
? null
@@ -3886,8 +3982,8 @@
InstanceSet._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
totalCount = json['totalCount'];
- instances = new List<ObjRef>.from(
- createServiceObject(json['instances'] ?? json['samples']));
+ instances = new List<ObjRef>.from(createServiceObject(
+ json['instances'] ?? json['samples'], const ['ObjRef']));
}
@override
@@ -3981,10 +4077,14 @@
debuggable = json['debuggable'];
dependencies = new List<LibraryDependency>.from(
_createSpecificObject(json['dependencies'], LibraryDependency.parse));
- scripts = new List<ScriptRef>.from(createServiceObject(json['scripts']));
- variables = new List<FieldRef>.from(createServiceObject(json['variables']));
- functions = new List<FuncRef>.from(createServiceObject(json['functions']));
- classes = new List<ClassRef>.from(createServiceObject(json['classes']));
+ scripts = new List<ScriptRef>.from(
+ createServiceObject(json['scripts'], const ['ScriptRef']));
+ variables = new List<FieldRef>.from(
+ createServiceObject(json['variables'], const ['FieldRef']));
+ functions = new List<FuncRef>.from(
+ createServiceObject(json['functions'], const ['FuncRef']));
+ classes = new List<ClassRef>.from(
+ createServiceObject(json['classes'], const ['ClassRef']));
}
@override
@@ -4034,7 +4134,7 @@
isImport = json['isImport'];
isDeferred = json['isDeferred'];
prefix = json['prefix'];
- target = createServiceObject(json['target']);
+ target = createServiceObject(json['target'], const ['LibraryRef']);
}
Map<String, dynamic> toJson() {
@@ -4087,14 +4187,14 @@
LogRecord();
LogRecord._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
- message = createServiceObject(json['message']);
+ message = createServiceObject(json['message'], const ['InstanceRef']);
time = json['time'];
level = json['level'];
sequenceNumber = json['sequenceNumber'];
- loggerName = createServiceObject(json['loggerName']);
- zone = createServiceObject(json['zone']);
- error = createServiceObject(json['error']);
- stackTrace = createServiceObject(json['stackTrace']);
+ loggerName = createServiceObject(json['loggerName'], const ['InstanceRef']);
+ zone = createServiceObject(json['zone'], const ['InstanceRef']);
+ error = createServiceObject(json['error'], const ['InstanceRef']);
+ stackTrace = createServiceObject(json['stackTrace'], const ['InstanceRef']);
}
@override
@@ -4130,8 +4230,9 @@
MapAssociation();
MapAssociation._fromJson(Map<String, dynamic> json) {
- key = createServiceObject(json['key']);
- value = createServiceObject(json['value']);
+ key = createServiceObject(json['key'], const ['InstanceRef', 'Sentinel']);
+ value =
+ createServiceObject(json['value'], const ['InstanceRef', 'Sentinel']);
}
Map<String, dynamic> toJson() {
@@ -4146,7 +4247,7 @@
String toString() => '[MapAssociation key: ${key}, value: ${value}]';
}
-/// An `MemoryUsage` object provides heap usage information for a specific
+/// A `MemoryUsage` object provides heap usage information for a specific
/// isolate at a given point in time.
class MemoryUsage extends Response {
static MemoryUsage parse(Map<String, dynamic> json) =>
@@ -4228,8 +4329,8 @@
name = json['name'];
messageObjectId = json['messageObjectId'];
size = json['size'];
- handler = createServiceObject(json['handler']);
- location = createServiceObject(json['location']);
+ handler = createServiceObject(json['handler'], const ['FuncRef']);
+ location = createServiceObject(json['location'], const ['SourceLocation']);
}
@override
@@ -4257,14 +4358,23 @@
static NullValRef parse(Map<String, dynamic> json) =>
json == null ? null : new NullValRef._fromJson(json);
+ /// Always 'null'.
+ @override
+ String valueAsString;
+
NullValRef();
- NullValRef._fromJson(Map<String, dynamic> json) : super._fromJson(json);
+ NullValRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
+ valueAsString = json['valueAsString'];
+ }
@override
Map<String, dynamic> toJson() {
var json = super.toJson();
json['type'] = '@Null';
+ json.addAll({
+ 'valueAsString': valueAsString,
+ });
return json;
}
@@ -4273,7 +4383,8 @@
operator ==(other) => other is NullValRef && id == other.id;
String toString() => '[NullValRef ' //
- 'type: ${type}, id: ${id}, kind: ${kind}, classRef: ${classRef}]';
+ 'type: ${type}, id: ${id}, kind: ${kind}, classRef: ${classRef}, ' //
+ 'valueAsString: ${valueAsString}]';
}
/// A `NullVal` object represents the Dart language value null.
@@ -4281,14 +4392,23 @@
static NullVal parse(Map<String, dynamic> json) =>
json == null ? null : new NullVal._fromJson(json);
+ /// Always 'null'.
+ @override
+ String valueAsString;
+
NullVal();
- NullVal._fromJson(Map<String, dynamic> json) : super._fromJson(json);
+ NullVal._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
+ valueAsString = json['valueAsString'];
+ }
@override
Map<String, dynamic> toJson() {
var json = super.toJson();
json['type'] = 'Null';
+ json.addAll({
+ 'valueAsString': valueAsString,
+ });
return json;
}
@@ -4296,7 +4416,9 @@
operator ==(other) => other is NullVal && id == other.id;
- String toString() => '[NullVal type: ${type}, id: ${id}, kind: ${kind}]';
+ String toString() => '[NullVal ' //
+ 'type: ${type}, id: ${id}, kind: ${kind}, classRef: ${classRef}, ' //
+ 'valueAsString: ${valueAsString}]';
}
/// `ObjRef` is a reference to a `Obj`.
@@ -4382,7 +4504,7 @@
Obj._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
id = json['id'];
fixedId = json['fixedId'];
- classRef = createServiceObject(json['class']);
+ classRef = createServiceObject(json['class'], const ['ClassRef']);
size = json['size'];
}
@@ -4587,7 +4709,7 @@
Script._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
uri = json['uri'];
- library = createServiceObject(json['library']);
+ library = createServiceObject(json['library'], const ['LibraryRef']);
lineOffset = json['lineOffset'];
columnOffset = json['columnOffset'];
source = json['source'];
@@ -4630,7 +4752,8 @@
ScriptList();
ScriptList._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
- scripts = new List<ScriptRef>.from(createServiceObject(json['scripts']));
+ scripts = new List<ScriptRef>.from(
+ createServiceObject(json['scripts'], const ['ScriptRef']));
}
@override
@@ -4665,7 +4788,7 @@
SourceLocation();
SourceLocation._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
- script = createServiceObject(json['script']);
+ script = createServiceObject(json['script'], const ['ScriptRef']);
tokenPos = json['tokenPos'];
endTokenPos = json['endTokenPos'];
}
@@ -4710,7 +4833,8 @@
SourceReport._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
ranges = new List<SourceReportRange>.from(
_createSpecificObject(json['ranges'], SourceReportRange.parse));
- scripts = new List<ScriptRef>.from(createServiceObject(json['scripts']));
+ scripts = new List<ScriptRef>.from(
+ createServiceObject(json['scripts'], const ['ScriptRef']));
}
@override
@@ -4812,7 +4936,7 @@
startPos = json['startPos'];
endPos = json['endPos'];
compiled = json['compiled'];
- error = createServiceObject(json['error']);
+ error = createServiceObject(json['error'], const ['ErrorRef']);
coverage =
_createSpecificObject(json['coverage'], SourceReportCoverage.parse);
possibleBreakpoints = json['possibleBreakpoints'] == null
@@ -4857,14 +4981,18 @@
Stack();
Stack._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
- frames = new List<Frame>.from(createServiceObject(json['frames']));
+ frames = new List<Frame>.from(
+ createServiceObject(json['frames'], const ['Frame']));
asyncCausalFrames = json['asyncCausalFrames'] == null
? null
- : new List<Frame>.from(createServiceObject(json['asyncCausalFrames']));
+ : new List<Frame>.from(
+ createServiceObject(json['asyncCausalFrames'], const ['Frame']));
awaiterFrames = json['awaiterFrames'] == null
? null
- : new List<Frame>.from(createServiceObject(json['awaiterFrames']));
- messages = new List<Message>.from(createServiceObject(json['messages']));
+ : new List<Frame>.from(
+ createServiceObject(json['awaiterFrames'], const ['Frame']));
+ messages = new List<Message>.from(
+ createServiceObject(json['messages'], const ['Message']));
}
@override
@@ -4922,8 +5050,8 @@
Timeline();
Timeline._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
- traceEvents =
- new List<TimelineEvent>.from(createServiceObject(json['traceEvents']));
+ traceEvents = new List<TimelineEvent>.from(
+ createServiceObject(json['traceEvents'], const ['TimelineEvent']));
timeOriginMicros = json['timeOriginMicros'];
timeExtentMicros = json['timeExtentMicros'];
}
@@ -5081,7 +5209,8 @@
TypeArguments._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
- types = new List<InstanceRef>.from(createServiceObject(json['types']));
+ types = new List<InstanceRef>.from(
+ createServiceObject(json['types'], const ['InstanceRef']));
}
@override
@@ -5145,7 +5274,7 @@
UnresolvedSourceLocation._fromJson(Map<String, dynamic> json)
: super._fromJson(json) {
- script = createServiceObject(json['script']);
+ script = createServiceObject(json['script'], const ['ScriptRef']);
scriptUri = json['scriptUri'];
tokenPos = json['tokenPos'];
line = json['line'];
@@ -5269,7 +5398,8 @@
version = json['version'];
pid = json['pid'];
startTime = json['startTime'];
- isolates = new List<IsolateRef>.from(createServiceObject(json['isolates']));
+ isolates = new List<IsolateRef>.from(
+ createServiceObject(json['isolates'], const ['IsolateRef']));
}
@override
@@ -5382,7 +5512,7 @@
kind = json['kind'];
inclusiveTicks = json['inclusiveTicks'];
exclusiveTicks = json['exclusiveTicks'];
- code = createServiceObject(json['code']);
+ code = createServiceObject(json['code'], const ['CodeRef']);
}
Map<String, dynamic> toJson() {
@@ -5421,7 +5551,7 @@
kind = json['kind'];
inclusiveTicks = json['inclusiveTicks'];
exclusiveTicks = json['exclusiveTicks'];
- function = createServiceObject(json['function']);
+ function = createServiceObject(json['function'], const ['FuncRef']);
codes = new List<int>.from(json['codes']);
}
diff --git a/vm_service_lib/pubspec.yaml b/vm_service_lib/pubspec.yaml
index fe2d6e7..a02f617 100644
--- a/vm_service_lib/pubspec.yaml
+++ b/vm_service_lib/pubspec.yaml
@@ -1,6 +1,6 @@
name: vm_service_lib
description: A library to access the VM Service API.
-version: 3.21.0
+version: 3.22.0
author: Dart Team <misc@dartlang.org>
homepage: https://github.com/dart-lang/vm_service_drivers
diff --git a/vm_service_lib/tool/common/src_gen_common.dart b/vm_service_lib/tool/common/src_gen_common.dart
index 8eeed99..0a47d1c 100644
--- a/vm_service_lib/tool/common/src_gen_common.dart
+++ b/vm_service_lib/tool/common/src_gen_common.dart
@@ -22,8 +22,10 @@
bool isH1(Node node) => node is Element && node.tag == 'h1';
bool isH3(Node node) => node is Element && node.tag == 'h3';
bool isHeader(Node node) => node is Element && node.tag.startsWith('h');
-String textForElement(Node node) => (((node as Element).children.first) as Text).text;
-String textForCode(Node node) => textForElement((node as Element).children.first);
+String textForElement(Node node) =>
+ (((node as Element).children.first) as Text).text;
+String textForCode(Node node) =>
+ textForElement((node as Element).children.first);
/// foo ==> Foo
String titleCase(String str) =>
diff --git a/vm_service_lib/tool/dart/generate_dart.dart b/vm_service_lib/tool/dart/generate_dart.dart
index 79d917f..515331f 100644
--- a/vm_service_lib/tool/dart/generate_dart.dart
+++ b/vm_service_lib/tool/dart/generate_dart.dart
@@ -31,6 +31,9 @@
return typeName;
}
+String _typeRefListToString(List<TypeRef> types) =>
+ 'const [' + types.map((e) => "'" + e.name + "'").join(',') + ']';
+
final String _headerCode = r'''
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -144,7 +147,7 @@
String streamId = map['params']['streamId'];
Map event = map['params']['event'];
event['_data'] = data;
- _getEventController(streamId).add(createServiceObject(event));
+ _getEventController(streamId).add(createServiceObject(event, const ['Event']));
}
}
@@ -178,7 +181,7 @@
void _processResponse(Map<String, dynamic> json) {
Completer completer = _completers.remove(json['id']);
String methodName = _methodCalls.remove(json['id']);
-
+ List<String> returnTypes = _methodReturnTypes[methodName];
if (completer == null) {
_log.severe('unmatched request response: ${jsonEncode(json)}');
} else if (json['error'] != null) {
@@ -189,7 +192,7 @@
if (_typeFactories[type] == null) {
completer.complete(Response.parse(result));
} else {
- completer.complete(createServiceObject(result));
+ completer.complete(createServiceObject(result, returnTypes));
}
}
}
@@ -208,7 +211,7 @@
final Map params = json['params'];
if (method == 'streamNotify') {
String streamId = params['streamId'];
- _getEventController(streamId).add(createServiceObject(params['event']));
+ _getEventController(streamId).add(createServiceObject(params['event'], const ['Event']));
} else {
await _routeRequest(method, params);
}
@@ -387,7 +390,7 @@
}
for (Type type in types) {
- type.removeDuplicateFieldDefs();
+ type.calculateFieldOverrides();
}
Method streamListenMethod =
@@ -454,13 +457,20 @@
/// This is useful for handling the results of the Stdout or Stderr events.
String decodeBase64(String str) => utf8.decode(base64.decode(str));
-Object createServiceObject(dynamic json) {
+// Returns true if a response is the Dart `null` instance.
+bool _isNullInstance(Map json) => ((json['type'] == '@Instance') &&
+ (json['kind'] == 'Null'));
+
+Object createServiceObject(dynamic json, List<String> expectedTypes) {
if (json == null) return null;
if (json is List) {
- return json.map((e) => createServiceObject(e)).toList();
+ return json.map((e) => createServiceObject(e, expectedTypes)).toList();
} else if (json is Map) {
String type = json['type'];
+ if (_isNullInstance(json) && (!expectedTypes.contains(type))) {
+ return null;
+ }
if (_typeFactories[type] == null) {
return null;
} else {
@@ -499,13 +509,21 @@
''');
gen.writeln();
- gen.write('Map<String, Function> _typeFactories = {');
+ gen.writeln('Map<String, Function> _typeFactories = {');
types.forEach((Type type) {
gen.writeln("'${type.rawName}': ${type.publicName}.parse,");
});
gen.writeln('};');
gen.writeln();
+ gen.writeln('Map<String, List<String>> _methodReturnTypes = {');
+ methods.forEach((Method method) {
+ String returnTypes = _typeRefListToString(method.returnType.types);
+ gen.writeln("'${method.name}' : $returnTypes,");
+ });
+ gen.writeln('};');
+ gen.writeln();
+
// The service interface, both servers and clients implement this.
gen.writeStatement('''
/// A class representation of the Dart VM Service Protocol.
@@ -1334,7 +1352,7 @@
if (name == 'AllocationProfile' && field.type.name == 'int') {
gen.write(
"${field.generatableName} = json['${field.name}'] is String ? "
- "int.parse(json['${field.name}']) : json['${field.name}']");
+ "int.parse(json['${field.name}']) : json['${field.name}']");
} else {
gen.write("${field.generatableName} = json['${field.name}']");
}
@@ -1387,6 +1405,7 @@
"((dynamic list) => new List<int>.from(list)));");
} else if (field.type.isArray) {
TypeRef fieldType = field.type.types.first;
+ String typesList = _typeRefListToString(field.type.types);
String ref = "json['${field.name}']";
if (field.optional) {
if (fieldType.isListTypeSimple) {
@@ -1394,7 +1413,7 @@
"new List<${fieldType.listTypeArg}>.from($ref);");
} else {
gen.writeln("${field.generatableName} = $ref == null ? null : "
- "new List<${fieldType.listTypeArg}>.from(createServiceObject($ref));");
+ "new List<${fieldType.listTypeArg}>.from(createServiceObject($ref, $typesList));");
}
} else {
if (fieldType.isListTypeSimple) {
@@ -1412,16 +1431,17 @@
// field named 'samples' instead of 'instances'.
if (name == 'InstanceSet') {
gen.writeln("${field.generatableName} = "
- "new List<${fieldType.listTypeArg}>.from(createServiceObject($ref ?? json['samples']));");
+ "new List<${fieldType.listTypeArg}>.from(createServiceObject($ref ?? json['samples'], $typesList));");
} else {
gen.writeln("${field.generatableName} = "
- "new List<${fieldType.listTypeArg}>.from(createServiceObject($ref));");
+ "new List<${fieldType.listTypeArg}>.from(createServiceObject($ref, $typesList));");
}
}
}
} else {
+ String typesList = _typeRefListToString(field.type.types);
gen.writeln("${field.generatableName} = "
- "createServiceObject(json['${field.name}']);");
+ "createServiceObject(json['${field.name}'], $typesList);");
}
});
if (fields.isNotEmpty) {
@@ -1599,13 +1619,12 @@
new TypeParser(token).parseInto(this);
}
- void removeDuplicateFieldDefs() {
+ void calculateFieldOverrides() {
for (TypeField field in fields.toList()) {
if (superName == null) continue;
if (getSuper().hasField(field.name)) {
- print('Removing duplicate field def: ${name}.${field.name}.');
- fields.remove(field);
+ field.setOverrides();
}
}
}
@@ -1633,9 +1652,14 @@
String name;
bool optional = false;
String defaultValue;
+ bool overrides = false;
TypeField(this.parent, this._docs);
+ void setOverrides() {
+ overrides = true;
+ }
+
String get docs {
String str = _docs == null ? '' : _docs;
if (type.isMultipleReturns) {
@@ -1653,6 +1677,7 @@
void generate(DartGenerator gen) {
if (docs.isNotEmpty) gen.writeDocs(docs);
if (optional) gen.write('@optional ');
+ if (overrides) gen.write('@override ');
String typeName =
api.isEnumName(type.name) ? '/*${type.name}*/ String' : type.name;
gen.writeStatement('${typeName} ${generatableName};');
@@ -1749,7 +1774,7 @@
TextOutputVisitor();
bool visitElementBefore(Element element) {
- if (element.tag == 'em') {
+ if (element.tag == 'em' || element.tag == 'code') {
buf.write('`');
_em = true;
} else if (element.tag == 'p') {
@@ -1759,9 +1784,6 @@
_blockquote = true;
} else if (element.tag == 'a') {
_href = true;
- } else {
- print('unknown tag: ${element.tag}');
- buf.write(renderToHtml([element]));
}
return true;
@@ -1783,16 +1805,19 @@
}
void visitElementAfter(Element element) {
- if (element.tag == 'p') {
+ if (element.tag == 'em' || element.tag == 'code') {
+ buf.write('`');
+ _em = false;
+ } else if (element.tag == 'p') {
buf.write('\n\n');
- } else if (element.tag == 'a') {
- _href = false;
} else if (element.tag == 'blockquote') {
//buf.write('```\n');
_blockquote = false;
- } else if (element.tag == 'em') {
- buf.write('`');
- _em = false;
+ } else if (element.tag == 'a') {
+ _href = false;
+ } else {
+ print(' </${element.tag}>');
+ buf.write(renderToHtml([element]));
}
}
diff --git a/vm_service_lib/tool/generate.dart b/vm_service_lib/tool/generate.dart
index e90b321..fd5b92b 100644
--- a/vm_service_lib/tool/generate.dart
+++ b/vm_service_lib/tool/generate.dart
@@ -24,7 +24,8 @@
var document = new Document();
StringBuffer buf = new StringBuffer(file.readAsStringSync());
buf.writeln();
- buf.write(new File(join(appDirPath, 'service_undocumented.md')).readAsStringSync());
+ buf.write(
+ new File(join(appDirPath, 'service_undocumented.md')).readAsStringSync());
var nodes = document.parseLines(buf.toString().split('\n'));
print('Parsed ${file.path}.');
print('Service protocol version ${ApiParseUtil.parseVersionString(nodes)}.');
@@ -115,7 +116,8 @@
Version v = new Version.parse(line.substring(pattern.length));
String pre = v.preRelease.isEmpty ? null : v.preRelease.join('-');
String build = v.build.isEmpty ? null : v.build.join('+');
- v = new Version(version.major, version.minor, v.patch, pre: pre, build: build);
+ v = new Version(version.major, version.minor, v.patch,
+ pre: pre, build: build);
return '${pattern}${v.toString()}';
} else {
return line;
@@ -133,6 +135,9 @@
File file = new File('CHANGELOG.md');
String text = file.readAsStringSync();
- bool containsReleaseNotes = text.split('\n').any((line) => line.startsWith(check));
- if (!containsReleaseNotes) throw '`${check}` not found in the CHANGELOG.md file';
+ bool containsReleaseNotes =
+ text.split('\n').any((line) => line.startsWith(check));
+ if (!containsReleaseNotes) {
+ throw '`${check}` not found in the CHANGELOG.md file';
+ }
}
diff --git a/vm_service_lib/tool/java/generate_java.dart b/vm_service_lib/tool/java/generate_java.dart
index 135427b..b4c0b3e 100644
--- a/vm_service_lib/tool/java/generate_java.dart
+++ b/vm_service_lib/tool/java/generate_java.dart
@@ -319,6 +319,10 @@
// or Enum values.
_mergeTypes();
_mergeEnums();
+
+ for (Type type in types) {
+ type.calculateFieldOverrides();
+ }
}
void setDefaultValue(String typeName, String propertyName) {
@@ -757,15 +761,6 @@
String toString() => buf.toString().trim();
- void visitElementAfter(Element element) {
- if (element.tag == 'p') {
- buf.write('\n\n');
- } else if (element.tag == 'em') {
- buf.write(']');
- _inRef = false;
- }
- }
-
bool visitElementBefore(Element element) {
if (element.tag == 'em') {
buf.write('[');
@@ -774,6 +769,8 @@
// Nothing to do.
} else if (element.tag == 'a') {
// Nothing to do - we're not writing out <a> refs (they won't resolve).
+ } else if (element.tag == 'code') {
+ buf.write(renderToHtml([element]));
} else {
print('unknown tag: ${element.tag}');
buf.write(renderToHtml([element]));
@@ -788,6 +785,15 @@
buf.write(t);
}
+ void visitElementAfter(Element element) {
+ if (element.tag == 'em') {
+ buf.write(']');
+ _inRef = false;
+ } else if (element.tag == 'p') {
+ buf.write('\n\n');
+ }
+ }
+
static String printText(Node node) {
TextOutputVisitor visitor = new TextOutputVisitor();
node.accept(visitor);
@@ -870,6 +876,18 @@
writer.addLine('super(json);');
});
+ if (name == 'InstanceRef' || name == 'Instance') {
+ writer.addMethod(
+ 'isNull',
+ [],
+ (StatementWriter writer) {
+ writer.addLine('return getKind() == InstanceKind.Null;');
+ },
+ returnType: 'boolean',
+ javadoc: 'Returns whether this instance represents null.',
+ );
+ }
+
for (var field in fields) {
field.generateAccessor(writer);
}
@@ -893,9 +911,24 @@
Type getSuper() => superName == null ? null : api.getType(superName);
+ bool hasField(String name) {
+ if (fields.any((field) => field.name == name)) return true;
+ return getSuper()?.hasField(name) ?? false;
+ }
+
void _parse(Token token) {
new TypeParser(token).parseInto(this);
}
+
+ void calculateFieldOverrides() {
+ for (TypeField field in fields.toList()) {
+ if (superName == null) continue;
+
+ if (getSuper().hasField(field.name)) {
+ field.setOverrides();
+ }
+ }
+ }
}
// @Instance|@Error|Sentinel evaluate(
@@ -918,9 +951,14 @@
String name;
bool optional = false;
String defaultValue;
+ bool overrides = false;
TypeField(this.parent, this._docs);
+ void setOverrides() {
+ overrides = true;
+ }
+
String get accessorName {
var remappedName = _nameRemap[name];
if (remappedName != null) {
@@ -967,12 +1005,22 @@
returnType = 'long';
}
- writer.addMethod(accessorName, [], (StatementWriter writer) {
- type.valueType.generateAccessStatements(writer, name,
+ writer.addMethod(
+ accessorName,
+ [],
+ (StatementWriter writer) {
+ type.valueType.generateAccessStatements(
+ writer,
+ name,
canBeSentinel: type.isValueAndSentinel,
defaultValue: defaultValue,
- optional: optional);
- }, javadoc: docs, returnType: returnType);
+ optional: optional,
+ );
+ },
+ javadoc: docs,
+ returnType: returnType,
+ isOverride: overrides,
+ );
}
}
}
@@ -1059,8 +1107,13 @@
Type get type => api.types.firstWhere((t) => t.name == name);
- void generateAccessStatements(StatementWriter writer, String propertyName,
- {bool canBeSentinel = false, String defaultValue, bool optional = false}) {
+ void generateAccessStatements(
+ StatementWriter writer,
+ String propertyName, {
+ bool canBeSentinel = false,
+ String defaultValue,
+ bool optional = false,
+ }) {
if (name == 'boolean') {
if (isArray) {
print('skipped accessor body for $propertyName');
@@ -1159,13 +1212,26 @@
writer.addLine('final JsonElement elem = json.get("$propertyName");');
writer.addLine('if (!elem.isJsonObject()) return null;');
writer.addLine('final JsonObject child = elem.getAsJsonObject();');
- writer.addLine('final String type = child.get("type").getAsString();');
+ writer
+ .addLine('final String type = child.get("type").getAsString();');
writer.addLine('if ("Sentinel".equals(type)) return null;');
writer.addLine('return new $name(child);');
} else {
if (optional) {
- writer.addLine('return json.get("$propertyName") == null ? '
- 'null : new $name((JsonObject) json.get("$propertyName"));');
+ writer.addLine(
+ 'JsonObject obj = (JsonObject) json.get("$propertyName");');
+ writer.addLine('if (obj == null) return null;');
+ if ((name != 'InstanceRef') && (name != 'Instance')) {
+ writer.addLine(
+ 'final String type = json.get("type").getAsString();');
+ writer.addLine(
+ 'if ("Instance".equals(type) || "@Instance".equals(type)) {');
+ writer.addLine(
+ ' final String kind = json.get("kind").getAsString();');
+ writer.addLine(' if ("Null".equals(kind)) return null;');
+ writer.addLine('}');
+ }
+ writer.addLine('return new $name(obj);');
} else {
writer.addLine(
'return new $name((JsonObject) json.get("$propertyName"));');
diff --git a/vm_service_lib/tool/service.md b/vm_service_lib/tool/service.md
index 62d3c8a..92fb0d3 100644
--- a/vm_service_lib/tool/service.md
+++ b/vm_service_lib/tool/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.21
+# Dart VM Service Protocol 3.22
> Please post feedback to the [observatory-discuss group][discuss-list]
-This document describes of _version 3.21_ of the Dart VM Service Protocol. This
+This document describes of _version 3.22_ of the Dart VM Service Protocol. This
protocol is used to communicate with a running Dart Virtual Machine.
To use the Service Protocol, start the VM with the *--observe* flag.
@@ -47,6 +47,7 @@
- [invoke](#invoke)
- [pause](#pause)
- [kill](#kill)
+ - [registerService](#registerService)
- [reloadSources](#reloadsources)
- [removeBreakpoint](#removebreakpoint)
- [resume](#resume)
@@ -878,6 +879,21 @@
See [Success](#success).
+### registerService
+
+```
+Success registerService(string service, string alias)
+```
+
+Registers a service that can be invoked by other VM service clients, where
+`service` is the name of the service to advertise and `alias` is an alternative
+name for the registered service.
+
+Requests made to the new service will be forwarded to the client which originally
+registered the service.
+
+See [Success](#success).
+
### reloadSources
```
@@ -1071,6 +1087,7 @@
Extension | Extension
Timeline | TimelineEvents
Logging | Logging
+Service | ServiceRegistered, ServiceUnregistered
Additionally, some embedders provide the _Stdout_ and _Stderr_
streams. These streams allow the client to subscribe to writes to
@@ -1599,6 +1616,26 @@
//
// This is provided for the Logging event.
LogRecord logRecord [optional];
+
+ // The service identifier.
+ //
+ // This is provided for the event kinds:
+ // ServiceRegistered
+ // ServiceUnregistered
+ String service [optional];
+
+ // The RPC method that should be used to invoke the service.
+ //
+ // This is provided for the event kinds:
+ // ServiceRegistered
+ // ServiceUnregistered
+ String method [optional];
+
+ // The alias of the registered service.
+ //
+ // This is provided for the event kinds:
+ // ServiceRegistered
+ String alias [optional];
}
```
@@ -1684,6 +1721,14 @@
// Event from dart:developer.log.
Logging
+
+ // Notification that a Service has been registered into the Service Protocol
+ // from another client.
+ ServiceRegistered,
+
+ // Notification that a Service has been removed from the Service Protocol
+ // from another client.
+ ServiceUnregistered
}
```
@@ -2086,13 +2131,11 @@
// Closure
@Function closureFunction [optional];
- // TODO(devoncarew): this can return an InstanceRef
- //
// The context associated with a Closure instance.
//
// Provided for instance kinds:
// Closure
- //@Context closureContext [optional];
+ @Context closureContext [optional];
// The referent of a MirrorReference instance.
//
@@ -2472,7 +2515,7 @@
}
```
-An _MemoryUsage_ object provides heap usage information for a specific
+A _MemoryUsage_ object provides heap usage information for a specific
isolate at a given point in time.
### Message
@@ -3084,5 +3127,6 @@
3.19 | Add 'clearVMTimeline', 'getVMTimeline', 'getVMTimelineFlags', 'setVMTimelineFlags', 'Timeline', and 'TimelineFlags'.
3.20 | Add 'getInstances' RPC and 'InstanceSet' object.
3.21 | Add 'getVMTimelineMicros' RPC and 'Timestamp' object.
+3.22 | Add `registerService` RPC, `Service` stream, and `ServiceRegistered` and `ServiceUnregistered` event kinds.
-[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
\ No newline at end of file
+[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/vm_service_lib/tool/service_undocumented.md b/vm_service_lib/tool/service_undocumented.md
index 4647939..376965e 100644
--- a/vm_service_lib/tool/service_undocumented.md
+++ b/vm_service_lib/tool/service_undocumented.md
@@ -128,53 +128,3 @@
<!-- _getCpuProfileTimeline -->
<!-- _getAllocationSamples -->
-
-streamId | event types provided
--------- | -----------
-_Service | ServiceRegistered, ServiceUnregistered
-
-### _registerService
-
-```
-Success _registerService(string service, string alias)
-```
-
-### EventKind
-
-```
-enum EventKind {
- // Notification that a Service has been registered into the Service Protocol
- // from another client.
- ServiceRegistered,
-
- // Notification that a Service has been removed from the Service Protocol
- // from another client.
- ServiceUnregistered
-}
-```
-
-### Event
-
-```
-class Event extends Response {
- // The service identifier.
- //
- // This is provided for the event kinds:
- // ServiceRegistered
- // ServiceUnregistered
- String service [optional];
-
- // The RPC method that should be used to invoke the service.
- //
- // This is provided for the event kinds:
- // ServiceRegistered
- // ServiceUnregistered
- String method [optional];
-
- // The alias of the registered service.
- //
- // This is provided for the event kinds:
- // ServiceRegistered
- String alias [optional];
-}
-```
diff --git a/web_socket_channel/BUILD.gn b/web_socket_channel/BUILD.gn
index be94a37..fe4501d 100644
--- a/web_socket_channel/BUILD.gn
+++ b/web_socket_channel/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for web_socket_channel-1.0.13
+# This file is generated by importer.py for web_socket_channel-1.0.14
import("//build/dart/dart_library.gni")
diff --git a/web_socket_channel/CHANGELOG.md b/web_socket_channel/CHANGELOG.md
index 5240a85..d446637 100644
--- a/web_socket_channel/CHANGELOG.md
+++ b/web_socket_channel/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.14
+
+* Updates to handle `Socket implements Stream<Uint8List>`
+
## 1.0.13
* Internal changes for consistency with the Dart SDK.
diff --git a/web_socket_channel/README.md b/web_socket_channel/README.md
index 7296560..c340775 100644
--- a/web_socket_channel/README.md
+++ b/web_socket_channel/README.md
@@ -6,16 +6,16 @@
class, and [a similar implementation][HtmlWebSocketChannel] that wrap's
`dart:html`'s.
-[stream_channel]: https://pub.dartlang.org/packages/stream_channel
-[WebSocketChannel]: https://pub.dartlang.org/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel-class.html
-[IOWebSocketChannel]: https://pub.dartlang.org/documentation/web_socket_channel/latest/web_socket_channel.io/IOWebSocketChannel-class.html
-[HtmlWebSocketChannel]: https://pub.dartlang.org/documentation/web_socket_channel/latest/web_socket_channel.html/HtmlWebSocketChannel-class.html
+[stream_channel]: https://pub.dev/packages/stream_channel
+[WebSocketChannel]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel-class.html
+[IOWebSocketChannel]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel.io/IOWebSocketChannel-class.html
+[HtmlWebSocketChannel]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel.html/HtmlWebSocketChannel-class.html
It also provides constants for the WebSocket protocol's pre-defined status codes
in the [`status.dart` library][status]. It's strongly recommended that users
import this library should be imported with the prefix `status`.
-[status]: https://pub.dartlang.org/documentation/web_socket_channel/latest/status/status-library.html
+[status]: https://pub.dev/documentation/web_socket_channel/latest/status/status-library.html
```dart
import 'package:web_socket_channel/io.dart';
@@ -40,9 +40,9 @@
socket, as well as [`closeCode`][closeCode] and [`closeReason`][closeReason]
getters that provide information about why the socket closed.
-[protocol]: https://pub.dartlang.org/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel/protocol.html
-[closeCode]: https://pub.dartlang.org/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel/closeCode.html
-[closeReason]: https://pub.dartlang.org/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel/closeReason.html
+[protocol]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel/protocol.html
+[closeCode]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel/closeCode.html
+[closeReason]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel/closeReason.html
The channel's [`sink` property][sink] is also special. It returns a
[`WebSocketSink`][WebSocketSink], which is just like a `StreamSink` except that
@@ -50,9 +50,9 @@
`closeReason` parameters. These parameters allow the caller to signal to the
other socket exactly why they're closing the connection.
-[sink]: https://pub.dartlang.org/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel/sink.html
-[WebSocketSink]: https://pub.dartlang.org/documentation/web_socket_channel/latest/web_socket_channel/WebSocketSink-class.html
-[sink.close]: https://pub.dartlang.org/documentation/web_socket_channel/latest/web_socket_channel/WebSocketSink/close.html
+[sink]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel/sink.html
+[WebSocketSink]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel/WebSocketSink-class.html
+[sink.close]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel/WebSocketSink/close.html
`WebSocketChannel` also works as a cross-platform implementation of the
WebSocket protocol. Because it can't initiate or handle HTTP requests in a
@@ -63,10 +63,10 @@
are used in the [`shelf_web_socket`][shelf_web_socket] package to support
WebSockets in a cross-platform way.
-[new]: https://pub.dartlang.org/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel-class.html
-[signKey]: https://pub.dartlang.org/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel/signKey.html
+[new]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel-class.html
+[signKey]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel/signKey.html
[initial WebSocket handshake]: https://tools.ietf.org/html/rfc6455#section-4.2.2
-[shelf_web_socket]: https://pub.dartlang.org/packages/shelf_web_socket
+[shelf_web_socket]: https://pub.dev/packages/shelf_web_socket
## `IOWebSocketChannel`
@@ -82,7 +82,7 @@
directly to a `ws://` or `wss://` URL, in which case
[`IOWebSocketChannel.connect()`][IOWebSocketChannel.connect] should be used.
-[IOWebSocketChannel.connect]: https://pub.dartlang.org/documentation/web_socket_channel/latest/web_socket_channel.io/IOWebSocketChannel/IOWebSocketChannel.connect.html
+[IOWebSocketChannel.connect]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel.io/IOWebSocketChannel/IOWebSocketChannel.connect.html
```dart
import 'package:web_socket_channel/io.dart';
@@ -110,7 +110,7 @@
directly to a `ws://` or `wss://` URL, in which case
[`HtmlWebSocketChannel.connect()`][HtmlWebSocketChannel.connect] should be used.
-[HtmlWebSocketChannel.connect]: https://pub.dartlang.org/documentation/web_socket_channel/latest/web_socket_channel.html/HtmlWebSocketChannel/HtmlWebSocketChannel.connect.html
+[HtmlWebSocketChannel.connect]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel.html/HtmlWebSocketChannel/HtmlWebSocketChannel.connect.html
```dart
import 'package:web_socket_channel/html.dart';
diff --git a/web_socket_channel/lib/src/copy/web_socket_impl.dart b/web_socket_channel/lib/src/copy/web_socket_impl.dart
index 6ac07cf..552b3e4 100644
--- a/web_socket_channel/lib/src/copy/web_socket_impl.dart
+++ b/web_socket_channel/lib/src/copy/web_socket_impl.dart
@@ -607,7 +607,7 @@
onResume: _onResume,
onCancel: _onListen);
var stream =
- _controller.stream.transform(_WebSocketOutgoingTransformer(webSocket));
+ _WebSocketOutgoingTransformer(webSocket).bind(_controller.stream);
sink.addStream(stream).then((_) {
_done();
_closeCompleter.complete(webSocket);
@@ -709,7 +709,7 @@
_readyState = WebSocket.OPEN;
var transformer = _WebSocketProtocolTransformer(_serverSide);
- _subscription = stream.transform(transformer).listen((data) {
+ _subscription = transformer.bind(stream).listen((data) {
if (data is _WebSocketPing) {
if (!_writeClosed) _consumer.add(_WebSocketPong(data.payload));
} else if (data is _WebSocketPong) {
diff --git a/web_socket_channel/pubspec.yaml b/web_socket_channel/pubspec.yaml
index b4cdedc..6f7f490 100644
--- a/web_socket_channel/pubspec.yaml
+++ b/web_socket_channel/pubspec.yaml
@@ -1,5 +1,5 @@
name: web_socket_channel
-version: 1.0.13
+version: 1.0.14
description: >-
StreamChannel wrappers for WebSockets. Provides a cross-platform
@@ -17,5 +17,5 @@
stream_channel: ">=1.2.0 <3.0.0"
dev_dependencies:
- pedantic:
+ pedantic: ^1.0.0
test: ^1.2.0