From cc40080d967fc9f522b12a4bfbe990bc1b0d230c Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sun, 17 Oct 2021 06:25:00 +0000 Subject: [PATCH] dart2js_info: enable and fix lints, validate analysis on CI Also updated dependencies and dropped publish information Change-Id: Ie5d8ca907599c5e504c747d97413d32ef9e329e3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/217061 Auto-Submit: Kevin Moore Reviewed-by: Sigmund Cherem Commit-Queue: Kevin Moore --- .dart_tool/package_config.json | 4 +- pkg/dart2js_info/analysis_options.yaml | 6 + pkg/dart2js_info/bin/src/code_deps.dart | 18 +-- pkg/dart2js_info/bin/src/convert.dart | 8 +- .../bin/src/coverage_log_server.dart | 44 +++---- pkg/dart2js_info/bin/src/debug_info.dart | 46 ++++---- .../bin/src/deferred_library_check.dart | 5 +- .../bin/src/deferred_library_layout.dart | 8 +- .../bin/src/deferred_library_size.dart | 10 +- pkg/dart2js_info/bin/src/diff.dart | 3 + .../bin/src/function_size_analysis.dart | 39 ++++--- pkg/dart2js_info/bin/src/inject_text.dart | 26 +++-- .../bin/src/library_size_split.dart | 23 ++-- .../bin/src/live_code_size_analysis.dart | 5 +- .../bin/src/show_inferred_types.dart | 5 +- pkg/dart2js_info/bin/src/text_print.dart | 34 ++++-- pkg/dart2js_info/bin/src/to_binary.dart | 7 +- pkg/dart2js_info/bin/src/to_json.dart | 9 +- pkg/dart2js_info/bin/src/to_proto.dart | 9 +- pkg/dart2js_info/bin/src/usage_exception.dart | 1 + pkg/dart2js_info/bin/tools.dart | 28 ++--- .../lib/binary_serialization.dart | 55 +++++---- .../lib/deferred_library_check.dart | 32 ++--- pkg/dart2js_info/lib/info.dart | 48 ++++++-- pkg/dart2js_info/lib/json_info_codec.dart | 109 ++++++++++-------- pkg/dart2js_info/lib/proto_info_codec.dart | 62 +++++----- pkg/dart2js_info/lib/src/binary/sink.dart | 79 ++++++------- pkg/dart2js_info/lib/src/binary/source.dart | 48 ++++---- pkg/dart2js_info/lib/src/diff.dart | 20 ++-- pkg/dart2js_info/lib/src/graph.dart | 39 ++++--- pkg/dart2js_info/lib/src/io.dart | 4 +- .../lib/src/string_edit_buffer.dart | 20 ++-- pkg/dart2js_info/lib/src/table.dart | 17 +-- pkg/dart2js_info/lib/src/util.dart | 8 +- pkg/dart2js_info/pubspec.yaml | 12 +- .../test/binary_serialization_test.dart | 6 +- pkg/dart2js_info/test/graph_test.dart | 2 +- .../test/json_to_proto_deferred_test.dart | 4 +- pkg/dart2js_info/test/json_to_proto_test.dart | 10 +- pkg/dart2js_info/test/parse_test.dart | 9 +- tools/bots/test_matrix.json | 9 ++ 41 files changed, 538 insertions(+), 393 deletions(-) create mode 100644 pkg/dart2js_info/analysis_options.yaml diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json index d041f09cd1d..9c19e785b8b 100644 --- a/.dart_tool/package_config.json +++ b/.dart_tool/package_config.json @@ -11,7 +11,7 @@ "constraint, update this by running tools/generate_package_config.dart." ], "configVersion": 2, - "generated": "2021-10-13T14:43:47.733371", + "generated": "2021-10-15T13:46:59.969883", "generator": "tools/generate_package_config.dart", "packages": [ { @@ -208,7 +208,7 @@ "name": "dart2js_info", "rootUri": "../pkg/dart2js_info", "packageUri": "lib/", - "languageVersion": "2.3" + "languageVersion": "2.11" }, { "name": "dart2js_runtime_metrics", diff --git a/pkg/dart2js_info/analysis_options.yaml b/pkg/dart2js_info/analysis_options.yaml new file mode 100644 index 00000000000..7ad2eaf081f --- /dev/null +++ b/pkg/dart2js_info/analysis_options.yaml @@ -0,0 +1,6 @@ +include: package:lints/recommended.yaml + +analyzer: + errors: + # Until the protobuf package generates the right code - or the right ignores + constant_identifier_names: ignore diff --git a/pkg/dart2js_info/bin/src/code_deps.dart b/pkg/dart2js_info/bin/src/code_deps.dart index 91b92221076..056e08b1e38 100644 --- a/pkg/dart2js_info/bin/src/code_deps.dart +++ b/pkg/dart2js_info/bin/src/code_deps.dart @@ -37,16 +37,20 @@ import 'package:dart2js_info/src/util.dart'; import 'usage_exception.dart'; class CodeDepsCommand extends Command with PrintUsageException { + @override final String name = "code_deps"; + @override final String description = ""; CodeDepsCommand() { - addSubcommand(new _SomePathQuery()); + addSubcommand(_SomePathQuery()); } } class _SomePathQuery extends Command with PrintUsageException { + @override final String name = "some_path"; + @override final String description = "find a call-graph path between two elements."; @override @@ -62,9 +66,9 @@ class _SomePathQuery extends Command with PrintUsageException { var graph = graphFromInfo(info); var source = info.functions - .firstWhere(_longNameMatcher(new RegExp(args[1])), orElse: () => null); + .firstWhere(_longNameMatcher(RegExp(args[1])), orElse: () => null); var target = info.functions - .firstWhere(_longNameMatcher(new RegExp(args[2])), orElse: () => null); + .firstWhere(_longNameMatcher(RegExp(args[2])), orElse: () => null); print('query: some_path'); if (source == null) { usageException("source '${args[1]}' not found in '${args[0]}'"); @@ -74,7 +78,7 @@ class _SomePathQuery extends Command with PrintUsageException { usageException("target '${args[2]}' not found in '${args[0]}'"); } print('target: ${longName(target)}'); - var path = new SomePathQuery(source, target).run(graph); + var path = SomePathQuery(source, target).run(graph); if (path.isEmpty) { print('result: no path found'); } else { @@ -103,12 +107,12 @@ class SomePathQuery { List run(Graph graph) { var seen = {source: null}; - var queue = new Queue(); + var queue = Queue(); queue.addLast(source); while (queue.isNotEmpty) { var node = queue.removeFirst(); if (identical(node, target)) { - var result = new Queue(); + var result = Queue(); while (node != null) { result.addFirst(node); node = seen[node]; @@ -125,7 +129,7 @@ class SomePathQuery { } } -typedef bool LongNameMatcher(FunctionInfo info); +typedef LongNameMatcher = bool Function(FunctionInfo info); LongNameMatcher _longNameMatcher(RegExp regexp) => (e) => regexp.hasMatch(longName(e)); diff --git a/pkg/dart2js_info/bin/src/convert.dart b/pkg/dart2js_info/bin/src/convert.dart index f79233dd627..743995725df 100644 --- a/pkg/dart2js_info/bin/src/convert.dart +++ b/pkg/dart2js_info/bin/src/convert.dart @@ -11,13 +11,15 @@ import 'usage_exception.dart'; /// This tool reports how code is divided among deferred chunks. class ConvertCommand extends Command with PrintUsageException { + @override final String name = "convert"; + @override final String description = "Convert between info formats."; ConvertCommand() { - _addSubcommand(new ToJsonCommand()); - _addSubcommand(new ToBinaryCommand()); - _addSubcommand(new ToProtoCommand()); + _addSubcommand(ToJsonCommand()); + _addSubcommand(ToBinaryCommand()); + _addSubcommand(ToProtoCommand()); } _addSubcommand(Command command) { diff --git a/pkg/dart2js_info/bin/src/coverage_log_server.dart b/pkg/dart2js_info/bin/src/coverage_log_server.dart index d43d4101c75..f86654a15f7 100644 --- a/pkg/dart2js_info/bin/src/coverage_log_server.dart +++ b/pkg/dart2js_info/bin/src/coverage_log_server.dart @@ -31,7 +31,9 @@ import 'package:shelf/shelf_io.dart' as shelf; import 'usage_exception.dart'; class CoverageLogServerCommand extends Command with PrintUsageException { + @override final String name = 'coverage_server'; + @override final String description = 'Server to gather code coverage data'; CoverageLogServerCommand() { @@ -46,30 +48,29 @@ class CoverageLogServerCommand extends Command with PrintUsageException { ' into the .js file', defaultsTo: '') ..addOption('out', - abbr: 'o', - help: 'output log file', - defaultsTo: _DEFAULT_OUT_TEMPLATE); + abbr: 'o', help: 'output log file', defaultsTo: _defaultOutTemplate); } + @override void run() async { if (argResults.rest.isEmpty) { usageException('Missing arguments: []'); } var jsPath = argResults.rest[0]; - var htmlPath = null; + String htmlPath; if (argResults.rest.length > 1) { htmlPath = argResults.rest[1]; } var outPath = argResults['out']; - if (outPath == _DEFAULT_OUT_TEMPLATE) outPath = '$jsPath.coverage.json'; - var server = new _Server(argResults['host'], int.parse(argResults['port']), + if (outPath == _defaultOutTemplate) outPath = '$jsPath.coverage.json'; + var server = _Server(argResults['host'], int.parse(argResults['port']), jsPath, htmlPath, outPath, argResults['uri-prefix']); await server.run(); } } -const _DEFAULT_OUT_TEMPLATE = '.coverage.json'; +const _defaultOutTemplate = '.coverage.json'; class _Server { /// Server hostname, typically `localhost`, but can be `0.0.0.0`. @@ -102,12 +103,11 @@ class _Server { /// against dump-info data. Map data = {}; - String get _serializedData => new JsonEncoder.withIndent(' ').convert(data); + String get _serializedData => JsonEncoder.withIndent(' ').convert(data); - _Server(this.hostname, this.port, String jsPath, this.htmlPath, this.outPath, + _Server(this.hostname, this.port, this.jsPath, this.htmlPath, this.outPath, String prefix) - : jsPath = jsPath, - jsCode = _adjustRequestUrl(new File(jsPath).readAsStringSync(), prefix), + : jsCode = _adjustRequestUrl(File(jsPath).readAsStringSync(), prefix), prefix = _normalize(prefix); run() async { @@ -135,29 +135,29 @@ class _Server { urlPath == _expectedPath(baseHtmlName)) { var contents = htmlPath == null ? '' - : await new File(htmlPath).readAsString(); - return new shelf.Response.ok(contents, headers: HTML_HEADERS); + : await File(htmlPath).readAsString(); + return shelf.Response.ok(contents, headers: _htmlHeaders); } if (urlPath == _expectedPath(baseJsName)) { - return new shelf.Response.ok(jsCode, headers: JS_HEADERS); + return shelf.Response.ok(jsCode, headers: _jsHeaders); } // Handle POST requests to record coverage data, and GET requests to display // the currently coverage results. if (urlPath == _expectedPath('coverage')) { if (request.method == 'GET') { - return new shelf.Response.ok(_serializedData, headers: TEXT_HEADERS); + return shelf.Response.ok(_serializedData, headers: _textHeaders); } if (request.method == 'POST') { _record(jsonDecode(await request.readAsString())); - return new shelf.Response.ok("Thanks!"); + return shelf.Response.ok("Thanks!"); } } // Any other request is not supported. - return new shelf.Response.notFound('Not found: "$urlPath"'); + return shelf.Response.notFound('Not found: "$urlPath"'); } _record(List entries) { @@ -174,8 +174,8 @@ class _Server { _enqueueSave() async { if (!_savePending) { _savePending = true; - await new Future.delayed(new Duration(seconds: 3)); - await new File(outPath).writeAsString(_serializedData); + await Future.delayed(Duration(seconds: 3)); + await File(outPath).writeAsString(_serializedData); var diff = data.length - _total; print(diff == 0 ? ' - no new element covered' @@ -215,6 +215,6 @@ _adjustRequestUrl(String code, String prefix) { return '$hook$code'; } -const HTML_HEADERS = const {'content-type': 'text/html'}; -const JS_HEADERS = const {'content-type': 'text/javascript'}; -const TEXT_HEADERS = const {'content-type': 'text/plain'}; +const _htmlHeaders = {'content-type': 'text/html'}; +const _jsHeaders = {'content-type': 'text/javascript'}; +const _textHeaders = {'content-type': 'text/plain'}; diff --git a/pkg/dart2js_info/bin/src/debug_info.dart b/pkg/dart2js_info/bin/src/debug_info.dart index 4851e0164cc..6199ee4ff88 100644 --- a/pkg/dart2js_info/bin/src/debug_info.dart +++ b/pkg/dart2js_info/bin/src/debug_info.dart @@ -7,7 +7,6 @@ library dart2js_info.bin.debug_info; import 'package:args/command_runner.dart'; - import 'package:dart2js_info/info.dart'; import 'package:dart2js_info/src/graph.dart'; import 'package:dart2js_info/src/io.dart'; @@ -16,7 +15,9 @@ import 'package:dart2js_info/src/util.dart'; import 'usage_exception.dart'; class DebugCommand extends Command with PrintUsageException { + @override final String name = "debug"; + @override final String description = "Dart2js-team diagnostics on a dump-info file."; DebugCommand() { @@ -24,9 +25,10 @@ class DebugCommand extends Command with PrintUsageException { help: "Show detailed data for a library with the given name"); } + @override void run() async { var args = argResults.rest; - if (args.length < 1) { + if (args.isEmpty) { usageException('Missing argument: info.data'); } @@ -43,24 +45,22 @@ class DebugCommand extends Command with PrintUsageException { /// Validates that codesize of elements adds up to total codesize. validateSize(AllInfo info, String debugLibName) { // Gather data from visiting all info elements. - var tracker = new _SizeTracker(debugLibName); + var tracker = _SizeTracker(debugLibName); info.accept(tracker); // Validate that listed elements include elements of each library. - Set listed = new Set() - ..addAll(info.functions) - ..addAll(info.fields); + final listed = {...info.functions, ...info.fields}; // For our sanity we do some validation of dump-info invariants var diff1 = listed.difference(tracker.discovered); var diff2 = tracker.discovered.difference(listed); - if (diff1.length == 0 || diff2.length == 0) { + if (diff1.isEmpty || diff2.isEmpty) { _pass('all fields and functions are covered'); } else { - if (diff1.length > 0) { + if (diff1.isNotEmpty) { _fail("some elements where listed globally that weren't part of any " "library (non-zero ${diff1.where((f) => f.size > 0).length})"); } - if (diff2.length > 0) { + if (diff2.isNotEmpty) { _fail("some elements found in libraries weren't part of the global list" " (non-zero ${diff2.where((f) => f.size > 0).length})"); } @@ -87,7 +87,7 @@ validateSize(AllInfo info, String debugLibName) { /// Validates that every element in the model has a parent (except libraries). validateParents(AllInfo info) { - final parentlessInfos = new Set(); + final parentlessInfos = {}; failIfNoParents(List infos) { for (var info in infos) { @@ -118,7 +118,7 @@ class _SizeTracker extends RecursiveInfoVisitor { /// [FunctionInfo]s and [FieldInfo]s transitively reachable from [LibraryInfo] /// elements. - final Set discovered = new Set(); + final Set discovered = {}; /// Total number of bytes missing if you look at the reported size compared /// to the sum of the nested infos (e.g. if a class size is smaller than the @@ -131,13 +131,13 @@ class _SizeTracker extends RecursiveInfoVisitor { final List unused = []; /// Tracks the current state of this visitor. - List<_State> stack = [new _State()]; + List<_State> stack = [_State()]; /// Code discovered for a [LibraryInfo], only used for debugging. - final StringBuffer _debugCode = new StringBuffer(); + final StringBuffer _debugCode = StringBuffer(); int _indent = 2; - void _push() => stack.add(new _State()); + void _push() => stack.add(_State()); void _pop(info) { var last = stack.removeLast(); @@ -158,6 +158,7 @@ class _SizeTracker extends RecursiveInfoVisitor { } bool _debug = false; + @override visitLibrary(LibraryInfo info) { if (_debugLibName != null) _debug = info.name.contains(_debugLibName); _push(); @@ -189,7 +190,7 @@ class _SizeTracker extends RecursiveInfoVisitor { _debugCode.write('...\n'); } - print('$info ${isClosureClass} \n${info.code}'); + print('$info $isClosureClass \n${info.code}'); _debugCode.write(' ' * _indent); var endsInNewLine = code.endsWith('\n'); if (endsInNewLine) code = code.substring(0, code.length - 1); @@ -206,22 +207,26 @@ class _SizeTracker extends RecursiveInfoVisitor { stack.last._count++; } + @override visitField(FieldInfo info) { _handleCodeInfo(info); super.visitField(info); } + @override visitFunction(FunctionInfo info) { _handleCodeInfo(info); super.visitFunction(info); } + @override visitTypedef(TypedefInfo info) { if (_debug) print('$info'); stack.last._totalSize += info.size; super.visitTypedef(info); } + @override visitClass(ClassInfo info) { if (_debug) { print('$info'); @@ -239,6 +244,7 @@ class _SizeTracker extends RecursiveInfoVisitor { } } + @override visitClassType(ClassTypeInfo info) { if (_debug) { print('$info'); @@ -265,8 +271,8 @@ class _State { /// Validates that both forms of dependency information match. void compareGraphs(AllInfo info) { - var g1 = new EdgeListGraph(); - var g2 = new EdgeListGraph(); + var g1 = EdgeListGraph(); + var g2 = EdgeListGraph(); for (var f in info.functions) { g1.addNode(f); for (var g in f.uses) { @@ -320,11 +326,9 @@ void compareGraphs(AllInfo info) { verifyDeps(AllInfo info) { var graph = graphFromInfo(info); var entrypoint = info.program.entrypoint; - var reachables = new Set.from(graph.preOrder(entrypoint)); + var reachables = Set.from(graph.preOrder(entrypoint)); - var functionsAndFields = [] - ..addAll(info.functions) - ..addAll(info.fields); + var functionsAndFields = [...info.functions, ...info.fields]; var unreachables = functionsAndFields.where((func) => !reachables.contains(func)); if (unreachables.isNotEmpty) { diff --git a/pkg/dart2js_info/bin/src/deferred_library_check.dart b/pkg/dart2js_info/bin/src/deferred_library_check.dart index 5493c66be40..a54bdebf0e2 100644 --- a/pkg/dart2js_info/bin/src/deferred_library_check.dart +++ b/pkg/dart2js_info/bin/src/deferred_library_check.dart @@ -47,10 +47,13 @@ import 'usage_exception.dart'; /// A command that computes the diff between two info files. class DeferredLibraryCheck extends Command with PrintUsageException { + @override final String name = "deferred_check"; + @override final String description = "Verify that deferred libraries are split as expected"; + @override void run() async { var args = argResults.rest; if (args.length < 2) { @@ -66,6 +69,6 @@ class DeferredLibraryCheck extends Command with PrintUsageException { } Future manifestFromFile(String fileName) async { - var file = await new File(fileName).readAsString(); + var file = await File(fileName).readAsString(); return loadYaml(file); } diff --git a/pkg/dart2js_info/bin/src/deferred_library_layout.dart b/pkg/dart2js_info/bin/src/deferred_library_layout.dart index 0584119a31e..1c4f13ffb88 100644 --- a/pkg/dart2js_info/bin/src/deferred_library_layout.dart +++ b/pkg/dart2js_info/bin/src/deferred_library_layout.dart @@ -8,7 +8,6 @@ library dart2js_info.bin.deferred_library_layout; import 'dart:io'; import 'package:args/command_runner.dart'; - import 'package:dart2js_info/info.dart'; import 'package:dart2js_info/src/io.dart'; @@ -16,12 +15,15 @@ import 'usage_exception.dart'; /// This tool reports how code is divided among deferred chunks. class DeferredLibraryLayout extends Command with PrintUsageException { + @override final String name = "deferred_layout"; + @override final String description = "Show how code is divided among deferred parts."; + @override void run() async { var args = argResults.rest; - if (args.length < 1) { + if (args.isEmpty) { usageException('Missing argument: info.data'); } await _showLayout(args.first); @@ -37,7 +39,7 @@ _showLayout(String file) async { var unit = info.outputUnit; var lib = _libOf(info); if (lib == null) return; - libToHunks.putIfAbsent(lib, () => new Set()).add(unit); + libToHunks.putIfAbsent(lib, () => {}).add(unit); hunkMembers .putIfAbsent(unit, () => {}) .putIfAbsent(lib, () => []) diff --git a/pkg/dart2js_info/bin/src/deferred_library_size.dart b/pkg/dart2js_info/bin/src/deferred_library_size.dart index 2ea7089cf7e..46455edc6ff 100644 --- a/pkg/dart2js_info/bin/src/deferred_library_size.dart +++ b/pkg/dart2js_info/bin/src/deferred_library_size.dart @@ -16,12 +16,15 @@ import 'usage_exception.dart'; /// This tool gives a breakdown of code size by deferred part in the program. class DeferredLibrarySize extends Command with PrintUsageException { + @override final String name = "deferred_size"; + @override final String description = "Show breakdown of codesize by deferred part."; + @override void run() async { var args = argResults.rest; - if (args.length < 1) { + if (args.isEmpty) { usageException('Missing argument: info.data'); } // TODO(het): Would be faster to only parse the 'outputUnits' part @@ -37,6 +40,7 @@ class ImportSize { const ImportSize(this.import, this.size); + @override String toString() { return '$import: $size'; } @@ -45,14 +49,14 @@ class ImportSize { void printSizes(Map sizeByImport, int programSize) { var importSizes = []; sizeByImport.forEach((import, size) { - importSizes.add(new ImportSize(import, size)); + importSizes.add(ImportSize(import, size)); }); // Sort by size, largest first. importSizes.sort((a, b) => b.size - a.size); int longest = importSizes.fold('Percent of code deferred'.length, (longest, importSize) => max(longest, importSize.import.length)); - _printRow(label, data, {int width: 15}) { + _printRow(label, data, {int width = 15}) { print('${label.toString().padRight(longest + 1)}' '${data.toString().padLeft(width)}'); } diff --git a/pkg/dart2js_info/bin/src/diff.dart b/pkg/dart2js_info/bin/src/diff.dart index d013349e64e..b811071bcc3 100644 --- a/pkg/dart2js_info/bin/src/diff.dart +++ b/pkg/dart2js_info/bin/src/diff.dart @@ -13,7 +13,9 @@ import 'usage_exception.dart'; /// A command that computes the diff between two info files. class DiffCommand extends Command with PrintUsageException { + @override final String name = "diff"; + @override final String description = "See code size differences between two dump-info files."; @@ -23,6 +25,7 @@ class DiffCommand extends Command with PrintUsageException { help: "Show only a summary and hide details of each library"); } + @override void run() async { var args = argResults.rest; if (args.length < 2) { diff --git a/pkg/dart2js_info/bin/src/function_size_analysis.dart b/pkg/dart2js_info/bin/src/function_size_analysis.dart index cb2c591975a..704155dc668 100644 --- a/pkg/dart2js_info/bin/src/function_size_analysis.dart +++ b/pkg/dart2js_info/bin/src/function_size_analysis.dart @@ -8,7 +8,6 @@ library compiler.tool.function_size_analysis; import 'dart:math' as math; import 'package:args/command_runner.dart'; - import 'package:dart2js_info/info.dart'; import 'package:dart2js_info/src/graph.dart'; import 'package:dart2js_info/src/io.dart'; @@ -18,12 +17,15 @@ import 'usage_exception.dart'; /// Command presenting how much each function contributes to the total code. class FunctionSizeCommand extends Command with PrintUsageException { + @override final String name = "function_size"; + @override final String description = "See breakdown of code size by function."; + @override void run() async { var args = argResults.rest; - if (args.length < 1) { + if (args.isEmpty) { usageException('Missing argument: info.data'); } var info = await infoFromFile(args.first); @@ -32,12 +34,13 @@ class FunctionSizeCommand extends Command with PrintUsageException { } showCodeDistribution(AllInfo info, - {bool filter(Info info), bool showLibrarySizes: false}) { + {bool Function(Info info) filter, bool showLibrarySizes = false}) { var realTotal = info.program.size; - if (filter == null) filter = (i) => true; - var reported = [] - ..addAll(info.functions.where(filter)) - ..addAll(info.fields.where(filter)); + filter ??= (i) => true; + var reported = [ + ...info.functions.where(filter), + ...info.fields.where(filter) + ]; // Compute a graph from the dependencies in [info]. Graph graph = graphFromInfo(info); @@ -51,7 +54,7 @@ showCodeDistribution(AllInfo info, var minS = totalCount; var nodeData = {}; for (var scc in components) { - var sccData = new _SccData(); + var sccData = _SccData(); maxS = math.max(maxS, scc.length); minS = math.min(minS, scc.length); for (var f in scc) { @@ -85,7 +88,9 @@ showCodeDistribution(AllInfo info, } helper(mainMethod); - reported.forEach((n) => dominatedSize.putIfAbsent(n, () => n.size)); + for (var n in reported) { + dominatedSize.putIfAbsent(n, () => n.size); + } reported.sort((a, b) => (dominatedSize[b] + nodeData[b].maxSize) - (dominatedSize[a] + nodeData[a].maxSize)); @@ -94,7 +99,7 @@ showCodeDistribution(AllInfo info, print(' --- Results per library ---'); var totals = {}; var longest = 0; - reported.forEach((info) { + for (var info in reported) { var size = info.size; while (info != null && info is! LibraryInfo) { info = info.parent; @@ -104,31 +109,31 @@ showCodeDistribution(AllInfo info, totals.putIfAbsent(lib, () => 0); totals[lib] += size; longest = math.max(longest, '${lib.uri}'.length); - }); + } _showLibHeader(longest + 1); var reportedByLibrary = totals.keys.toList(); reportedByLibrary.sort((a, b) => totals[b] - totals[a]); - reportedByLibrary.forEach((info) { + for (var info in reportedByLibrary) { _showLib('${info.uri}', totals[info], realTotal, longest + 1); - }); + } } print('\n --- Results per element (field or function) ---'); _showElementHeader(); - reported.forEach((info) { + for (var info in reported) { var size = info.size; var min = dominatedSize[info]; var max = nodeData[info].maxSize; _showElement( longName(info, useLibraryUri: true), size, min, max, realTotal); - }); + } } /// Data associated with an SCC. Used to compute the reachable code size. class _SccData { int size = 0; - Set deps = new Set(); + Set deps = {}; _SccData(); int _maxSize; @@ -140,7 +145,7 @@ class _SccData { void compute() { if (_maxSize != null) return; var max = 0; - var seen = new Set(); + var seen = {}; helper(n) { if (!seen.add(n)) return; max += n.size; diff --git a/pkg/dart2js_info/bin/src/inject_text.dart b/pkg/dart2js_info/bin/src/inject_text.dart index 8dfe1570e96..18bd5bdb1e4 100644 --- a/pkg/dart2js_info/bin/src/inject_text.dart +++ b/pkg/dart2js_info/bin/src/inject_text.dart @@ -14,22 +14,28 @@ import 'package:dart2js_info/info.dart'; void injectText(AllInfo info) { // Fill the text of each code span. The binary form produced by dart2js // produces code spans, but excludes the orignal text - info.functions.forEach((f) { - f.code.forEach((span) => _fillSpan(span, f.outputUnit)); - }); - info.fields.forEach((f) { - f.code.forEach((span) => _fillSpan(span, f.outputUnit)); - }); - info.constants.forEach((c) { - c.code.forEach((span) => _fillSpan(span, c.outputUnit)); - }); + for (var f in info.functions) { + for (var span in f.code) { + _fillSpan(span, f.outputUnit); + } + } + for (var f in info.fields) { + for (var span in f.code) { + _fillSpan(span, f.outputUnit); + } + } + for (var c in info.constants) { + for (var span in c.code) { + _fillSpan(span, c.outputUnit); + } + } } Map _cache = {}; _getContents(OutputUnitInfo unit) => _cache.putIfAbsent(unit.filename, () { var uri = Uri.base.resolve(unit.filename); - return new File.fromUri(uri).readAsStringSync(); + return File.fromUri(uri).readAsStringSync(); }); _fillSpan(CodeSpan span, OutputUnitInfo unit) { diff --git a/pkg/dart2js_info/bin/src/library_size_split.dart b/pkg/dart2js_info/bin/src/library_size_split.dart index 1d252c4b0a4..da6d85db0a4 100644 --- a/pkg/dart2js_info/bin/src/library_size_split.dart +++ b/pkg/dart2js_info/bin/src/library_size_split.dart @@ -72,7 +72,9 @@ import 'usage_exception.dart'; /// Command presenting how much each library contributes to the total code. class LibrarySizeCommand extends Command with PrintUsageException { + @override final String name = "library_size"; + @override final String description = "See breakdown of code size by library."; LibrarySizeCommand() { @@ -80,9 +82,10 @@ class LibrarySizeCommand extends Command with PrintUsageException { help: 'YAML file specifying how libraries should be grouped.'); } + @override void run() async { var args = argResults.rest; - if (args.length < 1) { + if (args.isEmpty) { usageException('Missing argument: info.data'); print('usage: dart tool/library_size_split.dart ' 'path-to-info.json [grouping.yaml]'); @@ -93,29 +96,29 @@ class LibrarySizeCommand extends Command with PrintUsageException { var groupingFile = argResults['grouping']; var groupingText = groupingFile != null - ? new File(groupingFile).readAsStringSync() + ? File(groupingFile).readAsStringSync() : defaultGrouping; var groupingYaml = loadYaml(groupingText); var groups = []; for (var group in groupingYaml['groups']) { - groups.add(new _Group( - group['name'], new RegExp(group['regexp']), group['cluster'] ?? 0)); + groups.add(_Group( + group['name'], RegExp(group['regexp']), group['cluster'] ?? 0)); } var sizes = {}; var allLibs = 0; for (LibraryInfo lib in info.libraries) { allLibs += lib.size; - groups.forEach((group) { + for (var group in groups) { var match = group.matcher.firstMatch('${lib.uri}'); if (match != null) { var name = group.name; if (name == null && match.groupCount > 0) name = match.group(1); - if (name == null) name = match.group(0); - sizes.putIfAbsent(name, () => new _SizeEntry(name, group.cluster)); + name ??= match.group(0); + sizes.putIfAbsent(name, () => _SizeEntry(name, group.cluster)); sizes[name].size += lib.size; } - }); + } } var allConstants = 0; @@ -129,7 +132,7 @@ class LibrarySizeCommand extends Command with PrintUsageException { var longest = 0; var rows = <_Row>[]; _addRow(String label, int value) { - rows.add(new _Row(label, value)); + rows.add(_Row(label, value)); longest = max(longest, label.length); } @@ -204,7 +207,7 @@ class _Divider extends _Row { const _Divider() : super('', 0); } -_pad(value, n, {bool right: false}) { +_pad(value, n, {bool right = false}) { var s = '$value'; if (s.length >= n) return s; var pad = ' ' * (n - s.length); diff --git a/pkg/dart2js_info/bin/src/live_code_size_analysis.dart b/pkg/dart2js_info/bin/src/live_code_size_analysis.dart index 77c02fdf986..23d4e32d2c5 100644 --- a/pkg/dart2js_info/bin/src/live_code_size_analysis.dart +++ b/pkg/dart2js_info/bin/src/live_code_size_analysis.dart @@ -47,7 +47,9 @@ import 'function_size_analysis.dart'; import 'usage_exception.dart'; class LiveCodeAnalysisCommand extends Command with PrintUsageException { + @override final String name = "coverage_analysis"; + @override final String description = "Analyze coverage data collected via the" " 'coverage_server' command"; @@ -56,6 +58,7 @@ class LiveCodeAnalysisCommand extends Command with PrintUsageException { abbr: 'v', negatable: false, help: 'Show verbose details.'); } + @override void run() async { var args = argResults.rest; if (args.length < 2) { @@ -67,7 +70,7 @@ class LiveCodeAnalysisCommand extends Command with PrintUsageException { _liveCodeAnalysis(infoFile, coverageFile, bool verbose) async { var info = await infoFromFile(infoFile); - var coverage = jsonDecode(new File(coverageFile).readAsStringSync()); + var coverage = jsonDecode(File(coverageFile).readAsStringSync()); int realTotal = info.program.size; int totalLib = info.libraries.fold(0, (n, lib) => n + lib.size); diff --git a/pkg/dart2js_info/bin/src/show_inferred_types.dart b/pkg/dart2js_info/bin/src/show_inferred_types.dart index 521af34335b..9c3b1193715 100644 --- a/pkg/dart2js_info/bin/src/show_inferred_types.dart +++ b/pkg/dart2js_info/bin/src/show_inferred_types.dart @@ -15,7 +15,9 @@ import 'package:dart2js_info/src/io.dart'; import 'usage_exception.dart'; class ShowInferredTypesCommand extends Command with PrintUsageException { + @override final String name = "show_inferred"; + @override final String description = "Show data inferred by dart2js global inference"; ShowInferredTypesCommand() { @@ -23,6 +25,7 @@ class ShowInferredTypesCommand extends Command with PrintUsageException { abbr: 'l', negatable: false, help: 'Show long qualified names.'); } + @override void run() async { var args = argResults.rest; if (args.length < 2) { @@ -35,7 +38,7 @@ class ShowInferredTypesCommand extends Command with PrintUsageException { _showInferredTypes(String infoFile, String pattern, bool showLongName) async { var info = await infoFromFile(infoFile); - var nameRegExp = new RegExp(pattern); + var nameRegExp = RegExp(pattern); matches(e) => nameRegExp.hasMatch(longName(e)); bool noResults = true; diff --git a/pkg/dart2js_info/bin/src/text_print.dart b/pkg/dart2js_info/bin/src/text_print.dart index 167ad03c615..3615b4db1a6 100644 --- a/pkg/dart2js_info/bin/src/text_print.dart +++ b/pkg/dart2js_info/bin/src/text_print.dart @@ -3,18 +3,20 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:io'; -import 'package:args/command_runner.dart'; +import 'package:args/command_runner.dart'; import 'package:dart2js_info/info.dart'; -import 'package:dart2js_info/src/util.dart'; import 'package:dart2js_info/src/io.dart'; +import 'package:dart2js_info/src/util.dart'; import 'inject_text.dart'; import 'usage_exception.dart'; /// Shows the contents of an info file as text. class ShowCommand extends Command with PrintUsageException { + @override final String name = "show"; + @override final String description = "Show a text representation of the info file."; ShowCommand() { @@ -28,8 +30,9 @@ class ShowCommand extends Command with PrintUsageException { 'option can be used to embed the text directly in the output.'); } + @override void run() async { - if (argResults.rest.length < 1) { + if (argResults.rest.isEmpty) { usageException('Missing argument: '); } @@ -37,13 +40,13 @@ class ShowCommand extends Command with PrintUsageException { AllInfo info = await infoFromFile(filename); if (argResults['inject-text']) injectText(info); - var buffer = new StringBuffer(); - info.accept(new TextPrinter(buffer, argResults['inject-text'])); + var buffer = StringBuffer(); + info.accept(TextPrinter(buffer, argResults['inject-text'])); var outputPath = argResults['out']; if (outputPath == null) { print(buffer); } else { - new File(outputPath).writeAsStringSync('$buffer'); + File(outputPath).writeAsStringSync('$buffer'); } } } @@ -65,13 +68,14 @@ class TextPrinter implements InfoVisitor { buffer.writeln(s.replaceAll('\n', '\n$_textIndent')); } - void _writeBlock(String s, void f()) { - _writeIndented("$s"); + void _writeBlock(String s, void Function() f) { + _writeIndented(s); _indent++; f(); _indent--; } + @override void visitAll(AllInfo info) { _writeBlock("Summary data", () => visitProgram(info.program)); buffer.writeln(); @@ -87,6 +91,7 @@ class TextPrinter implements InfoVisitor { _writeBlock("Output units", () => info.outputUnits.forEach(visitOutput)); } + @override void visitProgram(ProgramInfo info) { _writeIndented('main: ${longName(info.entrypoint, useLibraryUri: true)}'); _writeIndented('size: ${info.size}'); @@ -109,6 +114,7 @@ class TextPrinter implements InfoVisitor { return "${(size / (1024 * 1024)).toStringAsFixed(2)} Mb ($size b)"; } + @override void visitLibrary(LibraryInfo info) { _writeBlock('${info.uri}: ${_size(info.size)}', () { if (info.topLevelFunctions.isNotEmpty) { @@ -135,6 +141,7 @@ class TextPrinter implements InfoVisitor { }); } + @override void visitClass(ClassInfo info) { _writeBlock( '${info.name}: ${_size(info.size)} [${info.outputUnit.filename}]', () { @@ -148,12 +155,14 @@ class TextPrinter implements InfoVisitor { }); } + @override void visitClassType(ClassTypeInfo info) { _writeBlock( '${info.name}: ${_size(info.size)} [${info.outputUnit.filename}]', () {}); } + @override void visitField(FieldInfo info) { _writeBlock('${info.type} ${info.name}: ${_size(info.size)}', () { _writeIndented('inferred type: ${info.inferredType}'); @@ -167,6 +176,7 @@ class TextPrinter implements InfoVisitor { }); } + @override void visitFunction(FunctionInfo info) { var outputUnitFile = ''; if (info.functionKind == FunctionInfo.TOP_LEVEL_FUNCTION_KIND) { @@ -177,7 +187,7 @@ class TextPrinter implements InfoVisitor { _writeBlock( '${info.returnType} ${info.name}($params): ${_size(info.size)}$outputUnitFile', () { - String params = info.parameters.map((p) => "${p.type}").join(', '); + String params = info.parameters.map((p) => p.type).join(', '); _writeIndented('declared type: ${info.type}'); _writeIndented( 'inferred type: ${info.inferredReturnType} Function($params)'); @@ -197,14 +207,17 @@ class TextPrinter implements InfoVisitor { _writeIndented('- ${longName(info.target, useLibraryUri: true)} $mask'); } + @override void visitTypedef(TypedefInfo info) { _writeIndented('${info.name}: ${info.type}'); } + @override void visitClosure(ClosureInfo info) { - _writeBlock('${info.name}', () => visitFunction(info.function)); + _writeBlock(info.name, () => visitFunction(info.function)); } + @override void visitConstant(ConstantInfo info) { _writeBlock('${_size(info.size)}:', () => _writeCode(info.code)); } @@ -213,6 +226,7 @@ class TextPrinter implements InfoVisitor { _writeIndented(code.map((c) => c.text).join('\n')); } + @override void visitOutput(OutputUnitInfo info) { _writeIndented('${info.filename}: ${_size(info.size)}'); } diff --git a/pkg/dart2js_info/bin/src/to_binary.dart b/pkg/dart2js_info/bin/src/to_binary.dart index 1d90ed21cac..e1170f38fcb 100644 --- a/pkg/dart2js_info/bin/src/to_binary.dart +++ b/pkg/dart2js_info/bin/src/to_binary.dart @@ -15,11 +15,14 @@ import 'usage_exception.dart'; /// Converts a dump-info file emitted by dart2js in JSON to binary format. class ToBinaryCommand extends Command with PrintUsageException { + @override final String name = "to_binary"; + @override final String description = "Convert any info file to binary format."; + @override void run() async { - if (argResults.rest.length < 1) { + if (argResults.rest.isEmpty) { usageException('Missing argument: '); exit(1); } @@ -28,7 +31,7 @@ class ToBinaryCommand extends Command with PrintUsageException { AllInfo info = await infoFromFile(filename); if (argResults['inject-text']) injectText(info); String outputFilename = argResults['out'] ?? '$filename.data'; - var outstream = new File(outputFilename).openWrite(); + var outstream = File(outputFilename).openWrite(); binary.encode(info, outstream); await outstream.done; } diff --git a/pkg/dart2js_info/bin/src/to_json.dart b/pkg/dart2js_info/bin/src/to_json.dart index fff4d34055d..15e2722f600 100644 --- a/pkg/dart2js_info/bin/src/to_json.dart +++ b/pkg/dart2js_info/bin/src/to_json.dart @@ -16,7 +16,9 @@ import 'usage_exception.dart'; /// Converts a dump-info file emitted by dart2js in binary format to JSON. class ToJsonCommand extends Command with PrintUsageException { + @override final String name = "to_json"; + @override final String description = "Convert any info file to JSON format."; ToJsonCommand() { @@ -32,8 +34,9 @@ class ToJsonCommand extends Command with PrintUsageException { 'available in the input file.'); } + @override void run() async { - if (argResults.rest.length < 1) { + if (argResults.rest.isEmpty) { usageException('Missing argument: '); } @@ -45,10 +48,10 @@ class ToJsonCommand extends Command with PrintUsageException { injectText(info); } - var json = new AllInfoJsonCodec(isBackwardCompatible: isBackwardCompatible) + var json = AllInfoJsonCodec(isBackwardCompatible: isBackwardCompatible) .encode(info); String outputFilename = argResults['out'] ?? '$filename.json'; - new File(outputFilename) + File(outputFilename) .writeAsStringSync(const JsonEncoder.withIndent(" ").convert(json)); } } diff --git a/pkg/dart2js_info/bin/src/to_proto.dart b/pkg/dart2js_info/bin/src/to_proto.dart index fcbfaa80654..5af45033f28 100644 --- a/pkg/dart2js_info/bin/src/to_proto.dart +++ b/pkg/dart2js_info/bin/src/to_proto.dart @@ -17,11 +17,14 @@ import 'usage_exception.dart'; /// Converts a dump-info file emitted by dart2js to the proto format class ToProtoCommand extends Command with PrintUsageException { + @override final String name = "to_proto"; + @override final String description = "Convert any info file to proto format."; + @override void run() async { - if (argResults.rest.length < 1) { + if (argResults.rest.isEmpty) { usageException('Missing argument: '); exit(1); } @@ -29,9 +32,9 @@ class ToProtoCommand extends Command with PrintUsageException { String filename = argResults.rest[0]; final info = await infoFromFile(filename); if (argResults['inject-text']) injectText(info); - final proto = new AllInfoProtoCodec().encode(info); + final proto = AllInfoProtoCodec().encode(info); String outputFilename = argResults['out'] ?? '$filename.pb'; - final outputFile = new File(outputFilename); + final outputFile = File(outputFilename); await outputFile.writeAsBytes(proto.writeToBuffer(), mode: FileMode.write); } } diff --git a/pkg/dart2js_info/bin/src/usage_exception.dart b/pkg/dart2js_info/bin/src/usage_exception.dart index 4499da313f1..30651003f19 100644 --- a/pkg/dart2js_info/bin/src/usage_exception.dart +++ b/pkg/dart2js_info/bin/src/usage_exception.dart @@ -8,6 +8,7 @@ import 'package:args/command_runner.dart'; abstract class PrintUsageException implements Command { // TODO(rnystrom): Use "Never" for the return type when this package is // migrated to null safety. + @override usageException(String message) { print(message); printUsage(); diff --git a/pkg/dart2js_info/bin/tools.dart b/pkg/dart2js_info/bin/tools.dart index 40495a82e95..26a188b3f00 100644 --- a/pkg/dart2js_info/bin/tools.dart +++ b/pkg/dart2js_info/bin/tools.dart @@ -20,20 +20,20 @@ import 'src/text_print.dart'; /// Entrypoint to run all dart2js_info tools. void main(args) { - var commandRunner = new CommandRunner("dart2js_info", + var commandRunner = CommandRunner("dart2js_info", "collection of tools to digest the output of dart2js's --dump-info") - ..addCommand(new CodeDepsCommand()) - ..addCommand(new CoverageLogServerCommand()) - ..addCommand(new DebugCommand()) - ..addCommand(new DiffCommand()) - ..addCommand(new DeferredLibraryCheck()) - ..addCommand(new DeferredLibrarySize()) - ..addCommand(new DeferredLibraryLayout()) - ..addCommand(new ConvertCommand()) - ..addCommand(new FunctionSizeCommand()) - ..addCommand(new LibrarySizeCommand()) - ..addCommand(new LiveCodeAnalysisCommand()) - ..addCommand(new ShowInferredTypesCommand()) - ..addCommand(new ShowCommand()); + ..addCommand(CodeDepsCommand()) + ..addCommand(CoverageLogServerCommand()) + ..addCommand(DebugCommand()) + ..addCommand(DiffCommand()) + ..addCommand(DeferredLibraryCheck()) + ..addCommand(DeferredLibrarySize()) + ..addCommand(DeferredLibraryLayout()) + ..addCommand(ConvertCommand()) + ..addCommand(FunctionSizeCommand()) + ..addCommand(LibrarySizeCommand()) + ..addCommand(LiveCodeAnalysisCommand()) + ..addCommand(ShowInferredTypesCommand()) + ..addCommand(ShowCommand()); commandRunner.run(args); } diff --git a/pkg/dart2js_info/lib/binary_serialization.dart b/pkg/dart2js_info/lib/binary_serialization.dart index ecf0cec9537..23b626d6e4b 100644 --- a/pkg/dart2js_info/lib/binary_serialization.dart +++ b/pkg/dart2js_info/lib/binary_serialization.dart @@ -13,11 +13,11 @@ import 'src/binary/source.dart'; import 'info.dart'; void encode(AllInfo info, Sink> sink) { - new BinaryPrinter(new BinarySink(sink)).visitAll(info); + BinaryPrinter(BinarySink(sink)).visitAll(info); } AllInfo decode(List data) { - return new BinaryReader(new BinarySource(data)).readAll(); + return BinaryReader(BinarySource(data)).readAll(); } class BinaryPrinter implements InfoVisitor { @@ -38,6 +38,7 @@ class BinaryPrinter implements InfoVisitor { info.accept(this); } + @override void visitAll(AllInfo info) { sink.writeInt(info.version); sink.writeInt(info.minorVersion); @@ -70,6 +71,7 @@ class BinaryPrinter implements InfoVisitor { sink.close(); } + @override void visitProgram(ProgramInfo info) { visitFunction(info.entrypoint); sink.writeInt(info.size); @@ -94,6 +96,7 @@ class BinaryPrinter implements InfoVisitor { // Note: parent-pointers are not serialized, they get deduced during deserialization. } + @override void visitLibrary(LibraryInfo library) { sink.writeCached(library, (LibraryInfo info) { sink.writeUri(info.uri); @@ -106,6 +109,7 @@ class BinaryPrinter implements InfoVisitor { }); } + @override void visitClass(ClassInfo cls) { sink.writeCached(cls, (ClassInfo info) { _visitBasicInfo(info); @@ -115,12 +119,14 @@ class BinaryPrinter implements InfoVisitor { }); } + @override void visitClassType(ClassTypeInfo cls) { sink.writeCached(cls, (ClassTypeInfo info) { _visitBasicInfo(info); }); } + @override void visitField(FieldInfo field) { sink.writeCached(field, (FieldInfo info) { _visitBasicInfo(info); @@ -148,6 +154,7 @@ class BinaryPrinter implements InfoVisitor { } } + @override void visitConstant(ConstantInfo constant) { sink.writeCached(constant, (ConstantInfo info) { _visitBasicInfo(info); @@ -170,6 +177,7 @@ class BinaryPrinter implements InfoVisitor { sink.writeString(info.declaredType); } + @override void visitFunction(FunctionInfo function) { sink.writeCached(function, (FunctionInfo info) { _visitBasicInfo(info); @@ -190,6 +198,7 @@ class BinaryPrinter implements InfoVisitor { sink.writeStringOrNull(info.mask); } + @override void visitClosure(ClosureInfo closure) { sink.writeCached(closure, (ClosureInfo info) { _visitBasicInfo(info); @@ -197,6 +206,7 @@ class BinaryPrinter implements InfoVisitor { }); } + @override void visitTypedef(TypedefInfo typedef) { sink.writeCached(typedef, (TypedefInfo info) { _visitBasicInfo(info); @@ -211,6 +221,7 @@ class BinaryPrinter implements InfoVisitor { } } + @override void visitOutput(OutputUnitInfo output) { sink.writeCached(output, (OutputUnitInfo info) { _visitBasicInfo(info); @@ -229,7 +240,7 @@ class BinaryReader { } Duration readDuration() { - return new Duration(microseconds: source.readInt()); + return Duration(microseconds: source.readInt()); } Info readInfoWithKind() { @@ -258,7 +269,7 @@ class BinaryReader { } AllInfo readAll() { - var info = new AllInfo(); + var info = AllInfo(); int version = source.readInt(); int minorVersion = source.readInt(); if (info.version != version || info.minorVersion != minorVersion) { @@ -311,13 +322,13 @@ class BinaryReader { } ProgramInfo readProgram() { - var info = new ProgramInfo(); + var info = ProgramInfo(); info.entrypoint = readFunction(); info.size = source.readInt(); info.dart2jsVersion = source.readStringOrNull(); info.compilationMoment = readDate(); info.compilationDuration = readDuration(); - info.toJsonDuration = new Duration(microseconds: 0); + info.toJsonDuration = Duration(microseconds: 0); info.dumpInfoDuration = readDuration(); info.noSuchMethodEnabled = source.readBool(); info.isRuntimeTypeUsed = source.readBool(); @@ -337,7 +348,7 @@ class BinaryReader { } LibraryInfo readLibrary() => source.readCached(() { - LibraryInfo info = new LibraryInfo.internal(); + LibraryInfo info = LibraryInfo.internal(); info.uri = source.readUri(); _readBasicInfo(info); info.topLevelFunctions = source.readList(readFunction); @@ -356,7 +367,7 @@ class BinaryReader { }); ClassInfo readClass() => source.readCached(() { - ClassInfo info = new ClassInfo.internal(); + ClassInfo info = ClassInfo.internal(); _readBasicInfo(info); info.isAbstract = source.readBool(); info.fields = source.readList(readField); @@ -375,7 +386,7 @@ class BinaryReader { }); FieldInfo readField() => source.readCached(() { - FieldInfo info = new FieldInfo.internal(); + FieldInfo info = FieldInfo.internal(); _readBasicInfo(info); info.closures = source.readList(readClosure); info.inferredType = source.readString(); @@ -385,12 +396,14 @@ class BinaryReader { if (info.isConst) { info.initializer = _readConstantOrNull(); } - info.closures.forEach((c) => c.parent = info); + for (var c in info.closures) { + c.parent = info; + } return info; }); CodeSpan _readCodeSpan() { - return new CodeSpan() + return CodeSpan() ..start = source.readIntOrNull() ..end = source.readIntOrNull() ..text = source.readStringOrNull(); @@ -403,7 +416,7 @@ class BinaryReader { } ConstantInfo readConstant() => source.readCached(() { - ConstantInfo info = new ConstantInfo.internal(); + ConstantInfo info = ConstantInfo.internal(); _readBasicInfo(info); info.code = source.readList(_readCodeSpan); return info; @@ -411,7 +424,7 @@ class BinaryReader { FunctionModifiers _readFunctionModifiers() { int value = source.readInt(); - return new FunctionModifiers( + return FunctionModifiers( isStatic: value & _staticMask != 0, isConst: value & _constMask != 0, isFactory: value & _factoryMask != 0, @@ -419,12 +432,12 @@ class BinaryReader { } ParameterInfo _readParameterInfo() { - return new ParameterInfo( + return ParameterInfo( source.readString(), source.readString(), source.readString()); } FunctionInfo readFunction() => source.readCached(() { - FunctionInfo info = new FunctionInfo.internal(); + FunctionInfo info = FunctionInfo.internal(); _readBasicInfo(info); info.closures = source.readList(readClosure); info.modifiers = _readFunctionModifiers(); @@ -435,15 +448,17 @@ class BinaryReader { info.inlinedCount = source.readIntOrNull(); info.code = source.readList(_readCodeSpan); info.type = source.readString(); - info.closures.forEach((c) => c.parent = info); + for (var c in info.closures) { + c.parent = info; + } return info; }); DependencyInfo _readDependencyInfo() => - new DependencyInfo(readInfoWithKind(), source.readStringOrNull()); + DependencyInfo(readInfoWithKind(), source.readStringOrNull()); ClosureInfo readClosure() => source.readCached(() { - ClosureInfo info = new ClosureInfo.internal(); + ClosureInfo info = ClosureInfo.internal(); _readBasicInfo(info); info.function = readFunction(); info.function.parent = info; @@ -451,7 +466,7 @@ class BinaryReader { }); TypedefInfo readTypedef() => source.readCached(() { - TypedefInfo info = new TypedefInfo.internal(); + TypedefInfo info = TypedefInfo.internal(); _readBasicInfo(info); info.type = source.readString(); return info; @@ -464,7 +479,7 @@ class BinaryReader { } OutputUnitInfo readOutput() => source.readCached(() { - OutputUnitInfo info = new OutputUnitInfo.internal(); + OutputUnitInfo info = OutputUnitInfo.internal(); _readBasicInfo(info); info.filename = source.readStringOrNull(); info.imports = source.readList(source.readString); diff --git a/pkg/dart2js_info/lib/deferred_library_check.dart b/pkg/dart2js_info/lib/deferred_library_check.dart index 8a7e98bef58..ef35cec1709 100644 --- a/pkg/dart2js_info/lib/deferred_library_check.dart +++ b/pkg/dart2js_info/lib/deferred_library_check.dart @@ -42,8 +42,8 @@ import 'info.dart'; List checkDeferredLibraryManifest( AllInfo info, Map manifest) { - var includedPackages = new Map>(); - var excludedPackages = new Map>(); + var includedPackages = >{}; + var excludedPackages = >{}; for (var part in manifest.keys) { for (var package in manifest[part]['include'] ?? []) { (includedPackages[part] ??= {}).add(package); @@ -59,16 +59,20 @@ List checkDeferredLibraryManifest( // the outputUnits whose list of 'imports' contains a single import. If the // part is shared, it will have more than one import since it will include the // imports of all the top-level deferred parts that will load the shared part. - List validParts = ['main']..addAll(info.outputUnits - .where((unit) => unit.imports.length == 1) - .map((unit) => unit.imports.single)); - List mentionedParts = [] - ..addAll(includedPackages.keys) - ..addAll(excludedPackages.keys); + List validParts = [ + 'main', + ...info.outputUnits + .where((unit) => unit.imports.length == 1) + .map((unit) => unit.imports.single) + ]; + List mentionedParts = [ + ...includedPackages.keys, + ...excludedPackages.keys + ]; var partNameFailures = <_InvalidPartName>[]; for (var part in mentionedParts) { if (!validParts.contains(part)) { - partNameFailures.add(new _InvalidPartName(part, validParts)); + partNameFailures.add(_InvalidPartName(part, validParts)); } } if (partNameFailures.isNotEmpty) { @@ -79,7 +83,7 @@ List checkDeferredLibraryManifest( for (var values in includedPackages.values) ...values, for (var values in excludedPackages.values) ...values }; - var actualIncludedPackages = new Map>(); + var actualIncludedPackages = >{}; var failures = []; @@ -98,8 +102,7 @@ List checkDeferredLibraryManifest( for (var part in containingParts) { (actualIncludedPackages[part] ??= {}).add(packageName); if (excludedPackages[part].contains(packageName)) { - failures - .add(new _PartContainedExcludedPackage(part, packageName, info)); + failures.add(_PartContainedExcludedPackage(part, packageName, info)); } } } @@ -112,7 +115,7 @@ List checkDeferredLibraryManifest( for (var package in packages) { if (!actualIncludedPackages.containsKey(part) || !actualIncludedPackages[part].contains(package)) { - failures.add(new _PartDidNotContainPackage(part, package)); + failures.add(_PartDidNotContainPackage(part, package)); } } }); @@ -146,6 +149,7 @@ class _InvalidPartName extends ManifestComplianceFailure { final List validPartNames; const _InvalidPartName(this.part, this.validPartNames); + @override String toString() { return 'Manifest file declares invalid part "$part". ' 'Valid part names are: $validPartNames'; @@ -158,6 +162,7 @@ class _PartContainedExcludedPackage extends ManifestComplianceFailure { final BasicInfo info; const _PartContainedExcludedPackage(this.part, this.package, this.info); + @override String toString() { return 'Part "$part" was specified to exclude package "$package" but it ' 'actually contains ${kindToString(info.kind)} "${info.name}" which ' @@ -170,6 +175,7 @@ class _PartDidNotContainPackage extends ManifestComplianceFailure { final String package; const _PartDidNotContainPackage(this.part, this.package); + @override String toString() { return 'Part "$part" was specified to include package "$package" but it ' 'does not contain any elements from that package.'; diff --git a/pkg/dart2js_info/lib/info.dart b/pkg/dart2js_info/lib/info.dart index 850029ab4ef..1ebb2a7359a 100644 --- a/pkg/dart2js_info/lib/info.dart +++ b/pkg/dart2js_info/lib/info.dart @@ -33,12 +33,17 @@ abstract class Info { // TODO(sigmund): add more: // - inputSize: bytes used in the Dart source program abstract class BasicInfo implements Info { + @override final InfoKind kind; + @override String coverageId; + @override int size; + @override Info parent; + @override String name; /// If using deferred libraries, where the element associated with this info @@ -49,6 +54,7 @@ abstract class BasicInfo implements Info { BasicInfo.internal(this.kind); + @override String toString() => '$kind $name [$size]'; } @@ -205,6 +211,7 @@ class LibraryInfo extends BasicInfo { LibraryInfo.internal() : super.internal(InfoKind.library); + @override T accept(InfoVisitor visitor) => visitor.visitLibrary(this); } @@ -222,6 +229,7 @@ class OutputUnitInfo extends BasicInfo { OutputUnitInfo.internal() : super.internal(InfoKind.outputUnit); + @override T accept(InfoVisitor visitor) => visitor.visitOutput(this); } @@ -240,11 +248,12 @@ class ClassInfo extends BasicInfo { List fields = []; ClassInfo( - {String name, this.isAbstract, OutputUnitInfo outputUnit, int size: 0}) + {String name, this.isAbstract, OutputUnitInfo outputUnit, int size = 0}) : super(InfoKind.clazz, name, outputUnit, size, null); ClassInfo.internal() : super.internal(InfoKind.clazz); + @override T accept(InfoVisitor visitor) => visitor.visitClass(this); } @@ -252,11 +261,12 @@ class ClassInfo extends BasicInfo { /// [ClassInfo] because a class and its type may end up in different output /// units. class ClassTypeInfo extends BasicInfo { - ClassTypeInfo({String name, OutputUnitInfo outputUnit, int size: 0}) + ClassTypeInfo({String name, OutputUnitInfo outputUnit, int size = 0}) : super(InfoKind.classType, name, outputUnit, size, null); ClassTypeInfo.internal() : super.internal(InfoKind.classType); + @override T accept(InfoVisitor visitor) => visitor.visitClassType(this); } @@ -284,11 +294,12 @@ class ConstantInfo extends BasicInfo { List code; // TODO(sigmund): Add coverage support to constants? - ConstantInfo({int size: 0, this.code, OutputUnitInfo outputUnit}) + ConstantInfo({int size = 0, this.code, OutputUnitInfo outputUnit}) : super(InfoKind.constant, null, outputUnit, size, null); ConstantInfo.internal() : super.internal(InfoKind.constant); + @override T accept(InfoVisitor visitor) => visitor.visitConstant(this); } @@ -315,7 +326,7 @@ class FieldInfo extends BasicInfo with CodeInfo { FieldInfo( {String name, String coverageId, - int size: 0, + int size = 0, this.type, this.inferredType, this.closures, @@ -326,6 +337,7 @@ class FieldInfo extends BasicInfo with CodeInfo { FieldInfo.internal() : super.internal(InfoKind.field); + @override T accept(InfoVisitor visitor) => visitor.visitField(this); } @@ -339,6 +351,7 @@ class TypedefInfo extends BasicInfo { TypedefInfo.internal() : super.internal(InfoKind.typedef); + @override T accept(InfoVisitor visitor) => visitor.visitTypedef(this); } @@ -384,7 +397,7 @@ class FunctionInfo extends BasicInfo with CodeInfo { {String name, String coverageId, OutputUnitInfo outputUnit, - int size: 0, + int size = 0, this.functionKind, this.modifiers, this.closures, @@ -399,6 +412,7 @@ class FunctionInfo extends BasicInfo with CodeInfo { FunctionInfo.internal() : super.internal(InfoKind.function); + @override T accept(InfoVisitor visitor) => visitor.visitFunction(this); } @@ -408,11 +422,12 @@ class ClosureInfo extends BasicInfo { FunctionInfo function; ClosureInfo( - {String name, OutputUnitInfo outputUnit, int size: 0, this.function}) + {String name, OutputUnitInfo outputUnit, int size = 0, this.function}) : super(InfoKind.closure, name, outputUnit, size, null); ClosureInfo.internal() : super.internal(InfoKind.closure); + @override T accept(InfoVisitor visitor) => visitor.visitClosure(this); } @@ -446,10 +461,10 @@ class FunctionModifiers { final bool isExternal; FunctionModifiers( - {this.isStatic: false, - this.isConst: false, - this.isFactory: false, - this.isExternal: false}); + {this.isStatic = false, + this.isConst = false, + this.isFactory = false, + this.isExternal = false}); } /// Possible values of the `kind` field in the serialized infos. @@ -536,7 +551,8 @@ abstract class InfoVisitor { /// visitAll contains references to functions, this visitor only recurses to /// visit libraries, then from each library we visit functions and classes, and /// so on. -class RecursiveInfoVisitor extends InfoVisitor { +class RecursiveInfoVisitor extends InfoVisitor { + @override visitAll(AllInfo info) { // Note: we don't visit functions, fields, classes, and typedefs because // they are reachable from the library info. @@ -544,8 +560,10 @@ class RecursiveInfoVisitor extends InfoVisitor { info.constants.forEach(visitConstant); } + @override visitProgram(ProgramInfo info) {} + @override visitLibrary(LibraryInfo info) { info.topLevelFunctions.forEach(visitFunction); info.topLevelVariables.forEach(visitField); @@ -554,25 +572,33 @@ class RecursiveInfoVisitor extends InfoVisitor { info.typedefs.forEach(visitTypedef); } + @override visitClass(ClassInfo info) { info.functions.forEach(visitFunction); info.fields.forEach(visitField); } + @override visitClassType(ClassTypeInfo info) {} + @override visitField(FieldInfo info) { info.closures.forEach(visitClosure); } + @override visitConstant(ConstantInfo info) {} + @override visitFunction(FunctionInfo info) { info.closures.forEach(visitClosure); } + @override visitTypedef(TypedefInfo info) {} + @override visitOutput(OutputUnitInfo info) {} + @override visitClosure(ClosureInfo info) { visitFunction(info.function); } diff --git a/pkg/dart2js_info/lib/json_info_codec.dart b/pkg/dart2js_info/lib/json_info_codec.dart index 16e33fd0b95..1b741a714ea 100644 --- a/pkg/dart2js_info/lib/json_info_codec.dart +++ b/pkg/dart2js_info/lib/json_info_codec.dart @@ -3,13 +3,13 @@ // BSD-style license that can be found in the LICENSE file. /// Converters and codecs for converting between JSON and [Info] classes. - import 'dart:collection'; import 'dart:convert'; import 'package:collection/collection.dart'; -import 'src/util.dart'; + import 'info.dart'; +import 'src/util.dart'; List _toSortedSerializedIds( Iterable infos, Id Function(Info) getId) => @@ -18,13 +18,14 @@ List _toSortedSerializedIds( // TODO(sigmund): add unit tests. class JsonToAllInfoConverter extends Converter, AllInfo> { // Using `MashMap` here because it's faster than the default `LinkedHashMap`. - final Map registry = new HashMap(); + final Map registry = HashMap(); - AllInfo convert(Map json) { + @override + AllInfo convert(Map input) { registry.clear(); - var result = new AllInfo(); - var elements = json['elements']; + var result = AllInfo(); + var elements = input['elements']; // TODO(srawlins): Since only the Map values are being extracted below, // replace `as` with `cast` when `cast` becomes available in Dart 2.0: // @@ -50,29 +51,29 @@ class JsonToAllInfoConverter extends Converter, AllInfo> { result.constants.addAll( (elements['constant'] as Map).values.map((c) => parseConstant(c))); - json['holding'].forEach((k, deps) { + input['holding'].forEach((k, deps) { CodeInfo src = registry[k]; assert(src != null); for (var dep in deps) { var target = registry[dep['id']]; assert(target != null); - src.uses.add(new DependencyInfo(target, dep['mask'])); + src.uses.add(DependencyInfo(target, dep['mask'])); } }); - json['dependencies']?.forEach((String k, dependencies) { + input['dependencies']?.forEach((String k, dependencies) { List deps = dependencies; result.dependencies[registry[k]] = deps.map((d) => registry[d]).toList(); }); result.outputUnits - .addAll((json['outputUnits'] as List).map((o) => parseOutputUnit(o))); + .addAll((input['outputUnits'] as List).map((o) => parseOutputUnit(o))); - result.program = parseProgram(json['program']); + result.program = parseProgram(input['program']); - if (json['deferredFiles'] != null) { + if (input['deferredFiles'] != null) { final deferredFilesMap = - (json['deferredFiles'] as Map).cast>(); + (input['deferredFiles'] as Map).cast>(); for (final library in deferredFilesMap.values) { if (library['imports'] != null) { // The importMap needs to be typed as >, but the @@ -192,7 +193,7 @@ class JsonToAllInfoConverter extends Converter, AllInfo> { } ProgramInfo parseProgram(Map json) { - var programInfo = new ProgramInfo() + var programInfo = ProgramInfo() ..entrypoint = parseId(json['entrypoint']) ..size = json['size'] ..compilationMoment = DateTime.parse(json['compilationMoment']) @@ -211,7 +212,7 @@ class JsonToAllInfoConverter extends Converter, AllInfo> { } else { assert(compilationDuration is int); programInfo.compilationDuration = - new Duration(microseconds: compilationDuration); + Duration(microseconds: compilationDuration); } var toJsonDuration = json['toJsonDuration']; @@ -219,7 +220,7 @@ class JsonToAllInfoConverter extends Converter, AllInfo> { programInfo.toJsonDuration = _parseDuration(toJsonDuration); } else { assert(toJsonDuration is int); - programInfo.toJsonDuration = new Duration(microseconds: toJsonDuration); + programInfo.toJsonDuration = Duration(microseconds: toJsonDuration); } var dumpInfoDuration = json['dumpInfoDuration']; @@ -227,8 +228,7 @@ class JsonToAllInfoConverter extends Converter, AllInfo> { programInfo.dumpInfoDuration = _parseDuration(dumpInfoDuration); } else { assert(dumpInfoDuration is int); - programInfo.dumpInfoDuration = - new Duration(microseconds: dumpInfoDuration); + programInfo.dumpInfoDuration = Duration(microseconds: dumpInfoDuration); } return programInfo; @@ -237,7 +237,7 @@ class JsonToAllInfoConverter extends Converter, AllInfo> { /// Parse a string formatted as "XX:YY:ZZ.ZZZZZ" into a [Duration]. Duration _parseDuration(String duration) { if (!duration.contains(':')) { - return new Duration(milliseconds: int.parse(duration)); + return Duration(milliseconds: int.parse(duration)); } var parts = duration.split(':'); var hours = double.parse(parts[0]); @@ -249,7 +249,7 @@ class JsonToAllInfoConverter extends Converter, AllInfo> { var totalMillis = secondsInMillis * seconds + minutesInMillis * minutes + hoursInMillis * hours; - return new Duration(milliseconds: totalMillis.round()); + return Duration(milliseconds: totalMillis.round()); } FunctionInfo parseFunction(Map json) { @@ -268,18 +268,17 @@ class JsonToAllInfoConverter extends Converter, AllInfo> { ..code = parseCode(json['code']) ..sideEffects = json['sideEffects'] ..inlinedCount = json['inlinedCount'] - ..modifiers = - parseModifiers(new Map.from(json['modifiers'])) + ..modifiers = parseModifiers(Map.from(json['modifiers'])) ..closures = (json['children'] as List) .map((c) => parseId(c)) .toList(); } ParameterInfo parseParameter(Map json) => - new ParameterInfo(json['name'], json['type'], json['declaredType']); + ParameterInfo(json['name'], json['type'], json['declaredType']); FunctionModifiers parseModifiers(Map json) { - return new FunctionModifiers( + return FunctionModifiers( isStatic: json['static'] == true, isConst: json['const'] == true, isFactory: json['factory'] == true, @@ -303,23 +302,23 @@ class JsonToAllInfoConverter extends Converter, AllInfo> { } return registry.putIfAbsent(serializedId, () { if (serializedId.startsWith('function/')) { - return new FunctionInfo.internal(); + return FunctionInfo.internal(); } else if (serializedId.startsWith('closure/')) { - return new ClosureInfo.internal(); + return ClosureInfo.internal(); } else if (serializedId.startsWith('library/')) { - return new LibraryInfo.internal(); + return LibraryInfo.internal(); } else if (serializedId.startsWith('class/')) { - return new ClassInfo.internal(); + return ClassInfo.internal(); } else if (serializedId.startsWith('classType/')) { - return new ClassTypeInfo.internal(); + return ClassTypeInfo.internal(); } else if (serializedId.startsWith('field/')) { - return new FieldInfo.internal(); + return FieldInfo.internal(); } else if (serializedId.startsWith('constant/')) { - return new ConstantInfo.internal(); + return ConstantInfo.internal(); } else if (serializedId.startsWith('typedef/')) { - return new TypedefInfo.internal(); + return TypedefInfo.internal(); } else if (serializedId.startsWith('outputUnit/')) { - return new OutputUnitInfo.internal(); + return OutputUnitInfo.internal(); } assert(false); return null; @@ -329,13 +328,13 @@ class JsonToAllInfoConverter extends Converter, AllInfo> { List parseCode(dynamic json) { // backwards compatibility with format 5.1: if (json is String) { - return [new CodeSpan(start: null, end: null, text: json)]; + return [CodeSpan(start: null, end: null, text: json)]; } if (json is List) { return json.map((dynamic value) { Map jsonCode = value; - return new CodeSpan( + return CodeSpan( start: jsonCode['start'], end: jsonCode['end'], text: jsonCode['text']); @@ -350,10 +349,10 @@ class AllInfoToJsonConverter extends Converter implements InfoVisitor { /// Whether to generate json compatible with format 5.1 final bool isBackwardCompatible; - final Map ids = new HashMap(); - final Set usedIds = new Set(); + final Map ids = HashMap(); + final Set usedIds = {}; - AllInfoToJsonConverter({this.isBackwardCompatible: false}); + AllInfoToJsonConverter({this.isBackwardCompatible = false}); Id idFor(Info info) { var serializedId = ids[info]; @@ -381,17 +380,18 @@ class AllInfoToJsonConverter extends Converter while (!usedIds.add(id)) { id++; } - serializedId = new Id(info.kind, '$id'); + serializedId = Id(info.kind, '$id'); return ids[info] = serializedId; } - Map convert(AllInfo info) => info.accept(this); + @override + Map convert(AllInfo input) => input.accept(this); Map _visitList(List infos) { // Using SplayTree to maintain a consistent order of keys - var map = new SplayTreeMap(compareNatural); + var map = SplayTreeMap(compareNatural); for (var info in infos) { - map['${idFor(info).id}'] = info.accept(this); + map[idFor(info).id] = info.accept(this); } return map; } @@ -421,7 +421,7 @@ class AllInfoToJsonConverter extends Converter {'id': idFor(info.target).serializedId, 'mask': info.mask}; Map _visitAllInfoHolding(AllInfo allInfo) { - var map = new SplayTreeMap(compareNatural); + var map = SplayTreeMap(compareNatural); void helper(CodeInfo info) { if (info.uses.isEmpty) return; map[idFor(info).serializedId] = info.uses @@ -436,13 +436,14 @@ class AllInfoToJsonConverter extends Converter } Map _visitAllInfoDependencies(AllInfo allInfo) { - var map = new SplayTreeMap(compareNatural); + var map = SplayTreeMap(compareNatural); allInfo.dependencies.forEach((k, v) { map[idFor(k).serializedId] = _toSortedSerializedIds(v, idFor); }); return map; } + @override Map visitAll(AllInfo info) { var elements = _visitAllInfoElements(info); var jsonHolding = _visitAllInfoHolding(info); @@ -459,6 +460,7 @@ class AllInfoToJsonConverter extends Converter }; } + @override Map visitProgram(ProgramInfo info) { return { 'entrypoint': idFor(info.entrypoint).serializedId, @@ -494,6 +496,7 @@ class AllInfoToJsonConverter extends Converter return res; } + @override Map visitLibrary(LibraryInfo info) { return _visitBasicInfo(info) ..addAll({ @@ -510,6 +513,7 @@ class AllInfoToJsonConverter extends Converter }); } + @override Map visitClass(ClassInfo info) { return _visitBasicInfo(info) ..addAll({ @@ -520,10 +524,12 @@ class AllInfoToJsonConverter extends Converter }); } + @override Map visitClassType(ClassTypeInfo info) { return _visitBasicInfo(info); } + @override Map visitField(FieldInfo info) { var result = _visitBasicInfo(info) ..addAll({ @@ -541,6 +547,7 @@ class AllInfoToJsonConverter extends Converter return result; } + @override Map visitConstant(ConstantInfo info) => _visitBasicInfo(info) ..addAll({'code': _serializeCode(info.code)}); @@ -561,6 +568,7 @@ class AllInfoToJsonConverter extends Converter Map _visitParameterInfo(ParameterInfo info) => {'name': info.name, 'type': info.type, 'declaredType': info.declaredType}; + @override Map visitFunction(FunctionInfo info) { return _visitBasicInfo(info) ..addAll({ @@ -579,13 +587,16 @@ class AllInfoToJsonConverter extends Converter }); } + @override Map visitClosure(ClosureInfo info) { return _visitBasicInfo(info) ..addAll({'function': idFor(info.function).serializedId}); } + @override visitTypedef(TypedefInfo info) => _visitBasicInfo(info)..['type'] = info.type; + @override visitOutput(OutputUnitInfo info) => _visitBasicInfo(info) ..['filename'] = info.filename ..['imports'] = info.imports; @@ -605,12 +616,14 @@ class AllInfoToJsonConverter extends Converter } class AllInfoJsonCodec extends Codec { + @override final Converter encoder; - final Converter decoder = new JsonToAllInfoConverter(); + @override + final Converter decoder = JsonToAllInfoConverter(); - AllInfoJsonCodec({bool isBackwardCompatible: false}) - : encoder = new AllInfoToJsonConverter( - isBackwardCompatible: isBackwardCompatible); + AllInfoJsonCodec({bool isBackwardCompatible = false}) + : encoder = + AllInfoToJsonConverter(isBackwardCompatible: isBackwardCompatible); } class Id { diff --git a/pkg/dart2js_info/lib/proto_info_codec.dart b/pkg/dart2js_info/lib/proto_info_codec.dart index d5425a886f8..4d42457dc0b 100644 --- a/pkg/dart2js_info/lib/proto_info_codec.dart +++ b/pkg/dart2js_info/lib/proto_info_codec.dart @@ -3,8 +3,8 @@ // BSD-style license that can be found in the LICENSE file. /// Converters and codecs for converting between Protobuf and [Info] classes. - import 'dart:convert'; + import 'package:fixnum/fixnum.dart'; import 'info.dart'; @@ -14,18 +14,19 @@ import 'src/util.dart'; export 'src/proto/info.pb.dart'; class ProtoToAllInfoConverter extends Converter { - AllInfo convert(AllInfoPB info) { + @override + AllInfo convert(AllInfoPB input) { // TODO(lorenvs): Implement this conversion. It is unlikely to to be used // by production code since the goal of the proto codec is to consume this // information from other languages. However, it is useful for roundtrip // testing, so we should support it. - throw new UnimplementedError('ProtoToAllInfoConverter is not implemented'); + throw UnimplementedError('ProtoToAllInfoConverter is not implemented'); } } class AllInfoToProtoConverter extends Converter { final Map ids = {}; - final Set usedIds = new Set(); + final Set usedIds = {}; Id idFor(Info info) { if (info == null) return null; @@ -51,14 +52,15 @@ class AllInfoToProtoConverter extends Converter { while (!usedIds.add(id)) { id++; } - serializedId = new Id(info.kind, id); + serializedId = Id(info.kind, id); return ids[info] = serializedId; } - AllInfoPB convert(AllInfo info) => _convertToAllInfoPB(info); + @override + AllInfoPB convert(AllInfo input) => _convertToAllInfoPB(input); DependencyInfoPB _convertToDependencyInfoPB(DependencyInfo info) { - var result = new DependencyInfoPB() + var result = DependencyInfoPB() ..targetId = idFor(info.target)?.serializedId; if (info.mask != null) { result.mask = info.mask; @@ -67,14 +69,14 @@ class AllInfoToProtoConverter extends Converter { } static ParameterInfoPB _convertToParameterInfoPB(ParameterInfo info) { - return new ParameterInfoPB() + return ParameterInfoPB() ..name = info.name ..type = info.type ..declaredType = info.declaredType; } LibraryInfoPB _convertToLibraryInfoPB(LibraryInfo info) { - final proto = new LibraryInfoPB()..uri = info.uri.toString(); + final proto = LibraryInfoPB()..uri = info.uri.toString(); proto.childrenIds .addAll(info.topLevelFunctions.map((func) => idFor(func).serializedId)); @@ -91,7 +93,7 @@ class AllInfoToProtoConverter extends Converter { } ClassInfoPB _convertToClassInfoPB(ClassInfo info) { - final proto = new ClassInfoPB()..isAbstract = info.isAbstract; + final proto = ClassInfoPB()..isAbstract = info.isAbstract; proto.childrenIds .addAll(info.functions.map((func) => idFor(func).serializedId)); @@ -107,7 +109,7 @@ class AllInfoToProtoConverter extends Converter { static FunctionModifiersPB _convertToFunctionModifiers( FunctionModifiers modifiers) { - return new FunctionModifiersPB() + return FunctionModifiersPB() ..isStatic = modifiers.isStatic ..isConst = modifiers.isConst ..isFactory = modifiers.isFactory @@ -115,7 +117,7 @@ class AllInfoToProtoConverter extends Converter { } FunctionInfoPB _convertToFunctionInfoPB(FunctionInfo info) { - final proto = new FunctionInfoPB() + final proto = FunctionInfoPB() ..functionModifiers = _convertToFunctionModifiers(info.modifiers) ..inlinedCount = info.inlinedCount ?? 0; @@ -143,7 +145,7 @@ class AllInfoToProtoConverter extends Converter { } FieldInfoPB _convertToFieldInfoPB(FieldInfo info) { - final proto = new FieldInfoPB() + final proto = FieldInfoPB() ..type = info.type ..inferredType = info.inferredType ..isConst = info.isConst; @@ -163,25 +165,25 @@ class AllInfoToProtoConverter extends Converter { } static ConstantInfoPB _convertToConstantInfoPB(ConstantInfo info) { - return new ConstantInfoPB()..code = info.code.map((c) => c.text).join('\n'); + return ConstantInfoPB()..code = info.code.map((c) => c.text).join('\n'); } static OutputUnitInfoPB _convertToOutputUnitInfoPB(OutputUnitInfo info) { - final proto = new OutputUnitInfoPB(); + final proto = OutputUnitInfoPB(); proto.imports.addAll(info.imports.where((import) => import != null)); return proto; } static TypedefInfoPB _convertToTypedefInfoPB(TypedefInfo info) { - return new TypedefInfoPB()..type = info.type; + return TypedefInfoPB()..type = info.type; } ClosureInfoPB _convertToClosureInfoPB(ClosureInfo info) { - return new ClosureInfoPB()..functionId = idFor(info.function).serializedId; + return ClosureInfoPB()..functionId = idFor(info.function).serializedId; } InfoPB _convertToInfoPB(Info info) { - final proto = new InfoPB() + final proto = InfoPB() ..id = idFor(info).id ..serializedId = idFor(info).serializedId ..size = info.size; @@ -233,14 +235,13 @@ class AllInfoToProtoConverter extends Converter { } ProgramInfoPB _convertToProgramInfoPB(ProgramInfo info) { - var result = new ProgramInfoPB() + var result = ProgramInfoPB() ..entrypointId = idFor(info.entrypoint).serializedId ..size = info.size - ..compilationMoment = - new Int64(info.compilationMoment.microsecondsSinceEpoch) - ..compilationDuration = new Int64(info.compilationDuration.inMicroseconds) - ..toProtoDuration = new Int64(info.toJsonDuration.inMicroseconds) - ..dumpInfoDuration = new Int64(info.dumpInfoDuration.inMicroseconds) + ..compilationMoment = Int64(info.compilationMoment.microsecondsSinceEpoch) + ..compilationDuration = Int64(info.compilationDuration.inMicroseconds) + ..toProtoDuration = Int64(info.toJsonDuration.inMicroseconds) + ..dumpInfoDuration = Int64(info.dumpInfoDuration.inMicroseconds) ..noSuchMethodEnabled = info.noSuchMethodEnabled ?? false ..isRuntimeTypeUsed = info.isRuntimeTypeUsed ?? false ..isIsolateUsed = info.isIsolateInUse ?? false @@ -265,13 +266,13 @@ class AllInfoToProtoConverter extends Converter { static LibraryDeferredImportsPB _convertToLibraryDeferredImportsPB( String libraryUri, Map fields) { - final proto = new LibraryDeferredImportsPB() + final proto = LibraryDeferredImportsPB() ..libraryUri = libraryUri ..libraryName = fields['name'] ?? ''; Map> imports = fields['imports']; imports.forEach((prefix, files) { - final import = new DeferredImportPB()..prefix = prefix; + final import = DeferredImportPB()..prefix = prefix; import.files.addAll(files); proto.imports.add(import); }); @@ -280,8 +281,7 @@ class AllInfoToProtoConverter extends Converter { } AllInfoPB _convertToAllInfoPB(AllInfo info) { - final proto = new AllInfoPB() - ..program = _convertToProgramInfoPB(info.program); + final proto = AllInfoPB()..program = _convertToProgramInfoPB(info.program); proto.allInfos.addEntries(_convertToAllInfosEntries(info.libraries)); proto.allInfos.addEntries(_convertToAllInfosEntries(info.classes)); @@ -307,8 +307,10 @@ class AllInfoToProtoConverter extends Converter { /// This codec is still experimental, and will likely crash on certain output /// from dart2js. class AllInfoProtoCodec extends Codec { - final Converter encoder = new AllInfoToProtoConverter(); - final Converter decoder = new ProtoToAllInfoConverter(); + @override + final Converter encoder = AllInfoToProtoConverter(); + @override + final Converter decoder = ProtoToAllInfoConverter(); } class Id { diff --git a/pkg/dart2js_info/lib/src/binary/sink.dart b/pkg/dart2js_info/lib/src/binary/sink.dart index 7cacadc879c..4905b49ac23 100644 --- a/pkg/dart2js_info/lib/src/binary/sink.dart +++ b/pkg/dart2js_info/lib/src/binary/sink.dart @@ -20,22 +20,22 @@ abstract class DataSink { /// Writes a reference to [value] to this data sink. If [value] has not yet /// been serialized, [f] is called to serialize the value itself. - void writeCached(E value, void f(E value)); + void writeCached(E value, void Function(E value) f); /// Writes the potentially `null` [value] to this data sink. If [value] is /// non-null [f] is called to write the non-null value to the data sink. /// /// This is a convenience method to be used together with /// [DataSource.readValueOrNull]. - void writeValueOrNull(E value, void f(E value)); + void writeValueOrNull(E value, void Function(E value) f); /// Writes the [values] to this data sink calling [f] to write each value to /// the data sink. If [allowNull] is `true`, [values] is allowed to be `null`. /// /// This is a convenience method to be used together with /// [DataSource.readList]. - void writeList(Iterable values, void f(E value), - {bool allowNull: false}); + void writeList(Iterable values, void Function(E value) f, + {bool allowNull = false}); /// Writes the boolean [value] to this data sink. void writeBool(bool value); @@ -63,7 +63,7 @@ abstract class DataSink { /// /// This is a convenience method to be used together with /// [DataSource.readStrings]. - void writeStrings(Iterable values, {bool allowNull: false}); + void writeStrings(Iterable values, {bool allowNull = false}); /// Writes the [map] from string to [V] values to this data sink, calling [f] /// to write each value to the data sink. If [allowNull] is `true`, [map] is @@ -71,8 +71,8 @@ abstract class DataSink { /// /// This is a convenience method to be used together with /// [DataSource.readStringMap]. - void writeStringMap(Map map, void f(V value), - {bool allowNull: false}); + void writeStringMap(Map map, void Function(V value) f, + {bool allowNull = false}); /// Writes the enum value [value] to this data sink. // TODO(johnniwinther): Change the signature to @@ -103,7 +103,7 @@ abstract class DataSinkMixin implements DataSink { } @override - void writeStrings(Iterable values, {bool allowNull: false}) { + void writeStrings(Iterable values, {bool allowNull = false}) { if (values == null) { assert(allowNull); writeInt(0); @@ -116,8 +116,8 @@ abstract class DataSinkMixin implements DataSink { } @override - void writeStringMap(Map map, void f(V value), - {bool allowNull: false}) { + void writeStringMap(Map map, void Function(V value) f, + {bool allowNull = false}) { if (map == null) { assert(allowNull); writeInt(0); @@ -131,8 +131,8 @@ abstract class DataSinkMixin implements DataSink { } @override - void writeList(Iterable values, void f(E value), - {bool allowNull: false}) { + void writeList(Iterable values, void Function(E value) f, + {bool allowNull = false}) { if (values == null) { assert(allowNull); writeInt(0); @@ -143,7 +143,7 @@ abstract class DataSinkMixin implements DataSink { } @override - void writeValueOrNull(E value, void f(E value)) { + void writeValueOrNull(E value, void Function(E value) f) { writeBool(value != null); if (value != null) { f(value); @@ -162,7 +162,7 @@ class IndexedSink { /// /// If [value] has not been canonicalized yet, [writeValue] is called to /// serialize the [value] itself. - void write(E value, void writeValue(E value)) { + void write(E value, void Function(E value) writeValue) { int index = _cache[value]; if (index == null) { index = _cache.length; @@ -180,17 +180,16 @@ class IndexedSink { abstract class AbstractDataSink extends DataSinkMixin implements DataSink { IndexedSink _stringIndex; IndexedSink _uriIndex; - Map _generalCaches = {}; + final Map _generalCaches = {}; AbstractDataSink() { - _stringIndex = new IndexedSink(_writeIntInternal); - _uriIndex = new IndexedSink(_writeIntInternal); + _stringIndex = IndexedSink(_writeIntInternal); + _uriIndex = IndexedSink(_writeIntInternal); } @override - void writeCached(E value, void f(E value)) { - IndexedSink sink = - _generalCaches[E] ??= new IndexedSink(_writeIntInternal); + void writeCached(E value, void Function(E value) f) { + IndexedSink sink = _generalCaches[E] ??= IndexedSink(_writeIntInternal); sink.write(value, (v) => f(v)); } @@ -254,7 +253,7 @@ class BinarySink extends AbstractDataSink { BufferedSink _bufferedSink; int _length = 0; - BinarySink(this.sink) : _bufferedSink = new BufferedSink(sink); + BinarySink(this.sink) : _bufferedSink = BufferedSink(sink); @override void _writeUriInternal(Uri value) { @@ -290,6 +289,7 @@ class BinarySink extends AbstractDataSink { _writeIntInternal(value.index); } + @override void close() { _bufferedSink.flushAndDestroy(); _bufferedSink = null; @@ -297,6 +297,7 @@ class BinarySink extends AbstractDataSink { } /// Returns the number of bytes written to this data sink. + @override int get length => _length; } @@ -304,15 +305,15 @@ class BinarySink extends AbstractDataSink { // TODO(sigmund): share with the implementation in // package:kernel/binary/ast_to_binary.dart class BufferedSink { - static const int SIZE = 100000; - static const int SAFE_SIZE = SIZE - 5; - static const int SMALL = 10000; + static const int _size = 100000; + static const int _safeSize = _size - 5; + static const int _small = 10000; final Sink> _sink; - Uint8List _buffer = new Uint8List(SIZE); + Uint8List _buffer = Uint8List(_size); int length = 0; int flushedLength = 0; - Float64List _doubleBuffer = new Float64List(1); + final Float64List _doubleBuffer = Float64List(1); Uint8List _doubleBufferUint8; int get offset => length + flushedLength; @@ -330,16 +331,16 @@ class BufferedSink { void addByte(int byte) { _buffer[length++] = byte; - if (length == SIZE) { + if (length == _size) { _sink.add(_buffer); - _buffer = new Uint8List(SIZE); + _buffer = Uint8List(_size); length = 0; - flushedLength += SIZE; + flushedLength += _size; } } void addByte2(int byte1, int byte2) { - if (length < SAFE_SIZE) { + if (length < _safeSize) { _buffer[length++] = byte1; _buffer[length++] = byte2; } else { @@ -349,7 +350,7 @@ class BufferedSink { } void addByte4(int byte1, int byte2, int byte3, int byte4) { - if (length < SAFE_SIZE) { + if (length < _safeSize) { _buffer[length++] = byte1; _buffer[length++] = byte2; _buffer[length++] = byte3; @@ -365,22 +366,22 @@ class BufferedSink { void addBytes(List bytes) { // Avoid copying a large buffer into the another large buffer. Also, if // the bytes buffer is too large to fit in our own buffer, just emit both. - if (length + bytes.length < SIZE && - (bytes.length < SMALL || length < SMALL)) { + if (length + bytes.length < _size && + (bytes.length < _small || length < _small)) { _buffer.setRange(length, length + bytes.length, bytes); length += bytes.length; - } else if (bytes.length < SMALL) { + } else if (bytes.length < _small) { // Flush as much as we can in the current buffer. - _buffer.setRange(length, SIZE, bytes); + _buffer.setRange(length, _size, bytes); _sink.add(_buffer); // Copy over the remainder into a new buffer. It is guaranteed to fit // because the input byte array is small. - int alreadyEmitted = SIZE - length; + int alreadyEmitted = _size - length; int remainder = bytes.length - alreadyEmitted; - _buffer = new Uint8List(SIZE); + _buffer = Uint8List(_size); _buffer.setRange(0, remainder, bytes, alreadyEmitted); length = remainder; - flushedLength += SIZE; + flushedLength += _size; } else { flush(); _sink.add(bytes); @@ -390,7 +391,7 @@ class BufferedSink { void flush() { _sink.add(_buffer.sublist(0, length)); - _buffer = new Uint8List(SIZE); + _buffer = Uint8List(_size); flushedLength += length; length = 0; } diff --git a/pkg/dart2js_info/lib/src/binary/source.dart b/pkg/dart2js_info/lib/src/binary/source.dart index 5ada98355fc..d423f3f7edd 100644 --- a/pkg/dart2js_info/lib/src/binary/source.dart +++ b/pkg/dart2js_info/lib/src/binary/source.dart @@ -2,29 +2,29 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'dart:typed_data'; import 'dart:convert'; +import 'dart:typed_data'; /// Interface for deserialization. // TODO(sigmund): share this with pkg:compiler/src/serialization/* abstract class DataSource { /// Reads a reference to an [E] value from this data source. If the value has /// not yet been deserialized, [f] is called to deserialize the value itself. - E readCached(E f()); + E readCached(E Function() f); /// Reads a potentially `null` [E] value from this data source, calling [f] to /// read the non-null value from the data source. /// /// This is a convenience method to be used together with /// [DataSink.writeValueOrNull]. - E readValueOrNull(E f()); + E readValueOrNull(E Function() f); /// Reads a list of [E] values from this data source. If [emptyAsNull] is /// `true`, `null` is returned instead of an empty list. /// /// This is a convenience method to be used together with /// [DataSink.writeList]. - List readList(E f(), {bool emptyAsNull: false}); + List readList(E Function() f, {bool emptyAsNull = false}); /// Reads a boolean value from this data source. bool readBool(); @@ -53,7 +53,7 @@ abstract class DataSource { /// /// This is a convenience method to be used together with /// [DataSink.writeStrings]. - List readStrings({bool emptyAsNull: false}); + List readStrings({bool emptyAsNull = false}); /// Reads a map from string values to [V] values from this data source, /// calling [f] to read each value from the data source. If [emptyAsNull] is @@ -61,7 +61,7 @@ abstract class DataSource { /// /// This is a convenience method to be used together with /// [DataSink.writeStringMap]. - Map readStringMap(V f(), {bool emptyAsNull: false}); + Map readStringMap(V Function() f, {bool emptyAsNull = false}); /// Reads an enum value from the list of enum [values] from this data source. /// @@ -81,7 +81,7 @@ abstract class DataSource { /// Mixin that implements all convenience methods of [DataSource]. abstract class DataSourceMixin implements DataSource { @override - E readValueOrNull(E f()) { + E readValueOrNull(E Function() f) { bool hasValue = readBool(); if (hasValue) { return f(); @@ -90,14 +90,10 @@ abstract class DataSourceMixin implements DataSource { } @override - List readList(E f(), {bool emptyAsNull: false}) { + List readList(E Function() f, {bool emptyAsNull = false}) { int count = readInt(); if (count == 0 && emptyAsNull) return null; - List list = new List(count); - for (int i = 0; i < count; i++) { - list[i] = f(); - } - return list; + return List.generate(count, (i) => f()); } @override @@ -119,18 +115,14 @@ abstract class DataSourceMixin implements DataSource { } @override - List readStrings({bool emptyAsNull: false}) { + List readStrings({bool emptyAsNull = false}) { int count = readInt(); if (count == 0 && emptyAsNull) return null; - List list = new List(count); - for (int i = 0; i < count; i++) { - list[i] = readString(); - } - return list; + return List.generate(count, (index) => readString()); } @override - Map readStringMap(V f(), {bool emptyAsNull: false}) { + Map readStringMap(V Function() f, {bool emptyAsNull = false}) { int count = readInt(); if (count == 0 && emptyAsNull) return null; Map map = {}; @@ -147,7 +139,7 @@ abstract class DataSourceMixin implements DataSource { class IndexedSource { final int Function() _readInt; final List _cache = []; - final Set _pending = new Set(); + final Set _pending = {}; IndexedSource(this._readInt); @@ -155,7 +147,7 @@ class IndexedSource { /// /// If the value hasn't yet been read, [readValue] is called to deserialize /// the value itself. - E read(E readValue()) { + E read(E Function() readValue) { int index = _readInt(); if (_pending.contains(index)) throw "serialization cycles not supported"; if (index >= _cache.length) { @@ -177,17 +169,17 @@ abstract class AbstractDataSource extends DataSourceMixin implements DataSource { IndexedSource _stringIndex; IndexedSource _uriIndex; - Map _generalCaches = {}; + final Map _generalCaches = {}; AbstractDataSource() { - _stringIndex = new IndexedSource(_readIntInternal); - _uriIndex = new IndexedSource(_readIntInternal); + _stringIndex = IndexedSource(_readIntInternal); + _uriIndex = IndexedSource(_readIntInternal); } @override - E readCached(E f()) { + E readCached(E Function() f) { IndexedSource source = - _generalCaches[E] ??= new IndexedSource(_readIntInternal); + _generalCaches[E] ??= IndexedSource(_readIntInternal); return source.read(f); } @@ -254,7 +246,7 @@ class BinarySource extends AbstractDataSource { @override String _readStringInternal() { int length = _readIntInternal(); - List bytes = new Uint8List(length); + List bytes = Uint8List(length); bytes.setRange(0, bytes.length, _bytes, _byteOffset); _byteOffset += bytes.length; return utf8.decode(bytes); diff --git a/pkg/dart2js_info/lib/src/diff.dart b/pkg/dart2js_info/lib/src/diff.dart index 500f935b6e0..29dd6983496 100644 --- a/pkg/dart2js_info/lib/src/diff.dart +++ b/pkg/dart2js_info/lib/src/diff.dart @@ -29,12 +29,12 @@ class DeferredStatusDiff extends Diff { } List diff(AllInfo oldInfo, AllInfo newInfo) { - var differ = new _InfoDiffer(oldInfo, newInfo); + var differ = _InfoDiffer(oldInfo, newInfo); differ.diff(); return differ.diffs; } -class _InfoDiffer extends InfoVisitor { +class _InfoDiffer extends InfoVisitor { final AllInfo _old; final AllInfo _new; @@ -50,23 +50,23 @@ class _InfoDiffer extends InfoVisitor { @override visitAll(AllInfo info) { - throw new StateError('should not diff AllInfo'); + throw StateError('should not diff AllInfo'); } @override visitProgram(ProgramInfo info) { - throw new StateError('should not diff ProgramInfo'); + throw StateError('should not diff ProgramInfo'); } @override visitOutput(OutputUnitInfo info) { - throw new StateError('should not diff OutputUnitInfo'); + throw StateError('should not diff OutputUnitInfo'); } // TODO(het): diff constants @override visitConstant(ConstantInfo info) { - throw new StateError('should not diff ConstantInfo'); + throw StateError('should not diff ConstantInfo'); } @override @@ -127,7 +127,7 @@ class _InfoDiffer extends InfoVisitor { void _checkSize(BasicInfo info, BasicInfo other) { if (info.size != other.size) { - diffs.add(new SizeDiff(info, other.size - info.size)); + diffs.add(SizeDiff(info, other.size - info.size)); } } @@ -135,7 +135,7 @@ class _InfoDiffer extends InfoVisitor { var oldIsDeferred = _isDeferred(oldInfo); var newIsDeferred = _isDeferred(newInfo); if (oldIsDeferred != newIsDeferred) { - diffs.add(new DeferredStatusDiff(oldInfo, oldIsDeferred)); + diffs.add(DeferredStatusDiff(oldInfo, oldIsDeferred)); } } @@ -157,7 +157,7 @@ class _InfoDiffer extends InfoVisitor { } for (var oldName in oldNames.keys) { if (newNames[oldName] == null) { - diffs.add(new RemoveDiff(oldNames[oldName])); + diffs.add(RemoveDiff(oldNames[oldName])); } else { _other = newNames[oldName]; oldNames[oldName].accept(this); @@ -165,7 +165,7 @@ class _InfoDiffer extends InfoVisitor { } for (var newName in newNames.keys) { if (oldNames[newName] == null) { - diffs.add(new AddDiff(newNames[newName])); + diffs.add(AddDiff(newNames[newName])); } } } diff --git a/pkg/dart2js_info/lib/src/graph.dart b/pkg/dart2js_info/lib/src/graph.dart index 1eaabce93d4..9233d9f6098 100644 --- a/pkg/dart2js_info/lib/src/graph.dart +++ b/pkg/dart2js_info/lib/src/graph.dart @@ -25,13 +25,13 @@ abstract class Graph { /// of nodes. The nodes in each strongly connected components only have edges /// that point to nodes in the same component or earlier components. List> computeTopologicalSort() { - _SccFinder finder = new _SccFinder(this); + _SccFinder finder = _SccFinder(this); return finder.computeTopologicalSort(); } /// Whether [source] can transitively reach [target]. bool containsPath(N source, N target) { - Set seen = new Set(); + Set seen = {}; bool helper(N node) { if (identical(node, target)) return true; if (!seen.add(node)) return false; @@ -43,7 +43,7 @@ abstract class Graph { /// Returns all nodes reachable from [root] in post order. Iterable postOrder(N root) sync* { - var seen = new Set(); + var seen = {}; Iterable helper(N n) sync* { if (!seen.add(n)) return; for (var x in targetsOf(n)) { @@ -57,7 +57,7 @@ abstract class Graph { /// Returns an iterable of all nodes reachable from [root] in preorder. Iterable preOrder(N root) sync* { - var seen = new Set(); + var seen = {}; var stack = [root]; while (stack.isNotEmpty) { var next = stack.removeLast(); @@ -74,7 +74,7 @@ abstract class Graph { /// the node itself will be returned. List findCycleContaining(N node) { assert(node != null); - _SccFinder finder = new _SccFinder(this); + _SccFinder finder = _SccFinder(this); return finder._componentContaining(node); } @@ -103,8 +103,8 @@ abstract class Graph { /// Internally we compute dominators using (Cooper, Harvey, and Kennedy's /// algorithm)[http://www.cs.rice.edu/~keith/EMBED/dom.pdf]. Graph dominatorTree(N root) { - var iDom = (new _DominatorFinder(this)..run(root)).immediateDominators; - var graph = new EdgeListGraph(); + var iDom = (_DominatorFinder(this)..run(root)).immediateDominators; + var graph = EdgeListGraph(); for (N node in iDom.keys) { if (node != root) graph.addEdge(iDom[node], node); } @@ -114,18 +114,23 @@ abstract class Graph { class EdgeListGraph extends Graph { /// Edges in the graph. - Map> _edges = new Map>(); + final Map> _edges = >{}; /// The reverse of _edges. - Map> _revEdges = new Map>(); + final Map> _revEdges = >{}; + @override Iterable get nodes => _edges.keys; + @override bool get isEmpty => _edges.isEmpty; + @override int get nodeCount => _edges.length; - final _empty = new Set(); + final _empty = {}; + @override Iterable targetsOf(N source) => _edges[source] ?? _empty; + @override Iterable sourcesOf(N source) => _revEdges[source] ?? _empty; void addEdge(N source, N target) { @@ -139,8 +144,8 @@ class EdgeListGraph extends Graph { void addNode(N node) { assert(node != null); - _edges.putIfAbsent(node, () => new Set()); - _revEdges.putIfAbsent(node, () => new Set()); + _edges.putIfAbsent(node, () => {}); + _revEdges.putIfAbsent(node, () => {}); } /// Remove the edge from the given [source] node to the given [target] node. @@ -200,15 +205,15 @@ class _SccFinder { int _index = 0; /// Nodes that are being visited in order to identify components. - List _stack = new List(); + final List _stack = []; /// Information associated with each node. - Map> _info = >{}; + final Map> _info = >{}; /// All strongly connected components found, in topological sort order (each /// node in a strongly connected component only has edges that point to nodes /// in the same component or earlier components). - List> _allComponents = new List>(); + final List> _allComponents = >[]; _SccFinder(this._graph); @@ -246,7 +251,7 @@ class _SccFinder { /// component. _NodeInfo _strongConnect(N v) { // Set the depth index for v to the smallest unused index - var vInfo = new _NodeInfo(_index++); + var vInfo = _NodeInfo(_index++); _info[v] = vInfo; _push(v); @@ -264,7 +269,7 @@ class _SccFinder { // If v is a root node, pop the stack and generate an SCC if (vInfo.lowlink == vInfo.index) { - var component = new List(); + var component = []; N w; do { w = _pop(); diff --git a/pkg/dart2js_info/lib/src/io.dart b/pkg/dart2js_info/lib/src/io.dart index b37c33199f5..affc8deeba7 100644 --- a/pkg/dart2js_info/lib/src/io.dart +++ b/pkg/dart2js_info/lib/src/io.dart @@ -6,9 +6,9 @@ import 'package:dart2js_info/json_info_codec.dart'; import 'package:dart2js_info/binary_serialization.dart' as binary; Future infoFromFile(String fileName) async { - var file = new File(fileName); + var file = File(fileName); if (fileName.endsWith('.json')) { - return new AllInfoJsonCodec().decode(jsonDecode(await file.readAsString())); + return AllInfoJsonCodec().decode(jsonDecode(await file.readAsString())); } else { return binary.decode(file.readAsBytesSync()); } diff --git a/pkg/dart2js_info/lib/src/string_edit_buffer.dart b/pkg/dart2js_info/lib/src/string_edit_buffer.dart index dc314f71a70..7630bf2b39a 100644 --- a/pkg/dart2js_info/lib/src/string_edit_buffer.dart +++ b/pkg/dart2js_info/lib/src/string_edit_buffer.dart @@ -18,12 +18,12 @@ class StringEditBuffer { StringEditBuffer(this.original); - bool get hasEdits => _edits.length > 0; + bool get hasEdits => _edits.isNotEmpty; /// Edit the original text, replacing text on the range [begin] and /// exclusive [end] with the [replacement] string. void replace(int begin, int end, String replacement, [int sortId]) { - _edits.add(new _StringEdit(begin, end, replacement, sortId)); + _edits.add(_StringEdit(begin, end, replacement, sortId)); } /// Insert [string] at [offset]. @@ -43,9 +43,10 @@ class StringEditBuffer { /// /// Throws [UnsupportedError] if the edits were overlapping. If no edits were /// made, the original string will be returned. + @override String toString() { - var sb = new StringBuffer(); - if (_edits.length == 0) return original; + var sb = StringBuffer(); + if (_edits.isEmpty) return original; // Sort edits by start location. _edits.sort(); @@ -53,7 +54,7 @@ class StringEditBuffer { int consumed = 0; for (var edit in _edits) { if (consumed > edit.begin) { - sb = new StringBuffer(); + sb = StringBuffer(); sb.write('overlapping edits. Insert at offset '); sb.write(edit.begin); sb.write(' but have consumed '); @@ -63,7 +64,7 @@ class StringEditBuffer { sb.write('\n '); sb.write(e); } - throw new UnsupportedError(sb.toString()); + throw UnsupportedError(sb.toString()); } // Add characters from the original string between this edit and the last @@ -94,14 +95,15 @@ class _StringEdit implements Comparable<_StringEdit> { // String to insert final String string; - _StringEdit(int begin, this.end, this.string, [int sortId]) - : begin = begin, - sortId = sortId == null ? begin : sortId; + _StringEdit(this.begin, this.end, this.string, [int sortId]) + : sortId = sortId ?? begin; int get length => end - begin; + @override String toString() => '(Edit @ $begin,$end: "$string")'; + @override int compareTo(_StringEdit other) { int diff = begin - other.begin; if (diff != 0) return diff; diff --git a/pkg/dart2js_info/lib/src/table.dart b/pkg/dart2js_info/lib/src/table.dart index 85abcd3faf7..23f44f0f160 100644 --- a/pkg/dart2js_info/lib/src/table.dart +++ b/pkg/dart2js_info/lib/src/table.dart @@ -28,7 +28,7 @@ class Table { List rows = []; /// Columns to skip, for example, if they are all zero entries. - List _skipped = []; + final List _skipped = []; /// Whether we started adding entries. Indicates that no more columns can be /// added. @@ -39,14 +39,16 @@ class Table { /// Add a column with the given [name]. void declareColumn(String name, - {bool abbreviate: false, String color: _NO_COLOR}) { + {bool abbreviate = false, String color = _noColor}) { assert(!_sealed); var headerName = name; if (abbreviate) { // abbreviate the header by using only the initials of each word headerName = name.split(' ').map((s) => s.substring(0, 1).toUpperCase()).join(''); - while (abbreviations[headerName] != null) headerName = "$headerName'"; + while (abbreviations[headerName] != null) { + headerName = "$headerName'"; + } abbreviations[headerName] = name; } widths.add(max(5, headerName.length + 1)); @@ -94,11 +96,12 @@ class Table { /// Generates a string representation of the table to print on a terminal. // TODO(sigmund): add also a .csv format + @override String toString() { - var sb = new StringBuffer(); + var sb = StringBuffer(); sb.write('\n'); for (var row in rows) { - var lastColor = _NO_COLOR; + var lastColor = _noColor; for (int i = 0; i < _totalColumns; i++) { if (_skipped[i]) continue; var entry = row[i]; @@ -111,7 +114,7 @@ class Table { sb.write( i == 0 ? entry.padRight(widths[i]) : entry.padLeft(widths[i] + 1)); } - if (lastColor != _NO_COLOR) sb.write(_NO_COLOR); + if (lastColor != _noColor) sb.write(_noColor); sb.write('\n'); } sb.write('\nWhere:\n'); @@ -123,4 +126,4 @@ class Table { } } -const _NO_COLOR = "\x1b[0m"; +const _noColor = "\x1b[0m"; diff --git a/pkg/dart2js_info/lib/src/util.dart b/pkg/dart2js_info/lib/src/util.dart index 31e9ffc70bd..2566c76cfc0 100644 --- a/pkg/dart2js_info/lib/src/util.dart +++ b/pkg/dart2js_info/lib/src/util.dart @@ -18,7 +18,7 @@ Graph graphFromInfo(AllInfo info) { // of them. // TODO(sigmund): create a concrete implementation of InfoGraph, instead of // using the EdgeListGraph. - var graph = new EdgeListGraph(); + var graph = EdgeListGraph(); for (var f in info.functions) { graph.addNode(f); for (var g in f.uses) { @@ -48,13 +48,13 @@ Graph graphFromInfo(AllInfo info) { /// Provide a unique long name associated with [info]. // TODO(sigmund): guarantee that the name is actually unique. -String longName(Info info, {bool useLibraryUri: false, bool forId: false}) { +String longName(Info info, {bool useLibraryUri = false, bool forId = false}) { var infoPath = []; while (info != null) { infoPath.add(info); info = info.parent; } - var sb = new StringBuffer(); + var sb = StringBuffer(); var first = true; for (var segment in infoPath.reversed) { if (!first) sb.write('.'); @@ -91,7 +91,7 @@ String longName(Info info, {bool useLibraryUri: false, bool forId: false}) { } /// Produce a string containing [value] padded with white space up to [n] chars. -pad(value, n, {bool right: false}) { +pad(value, n, {bool right = false}) { var s = '$value'; if (s.length >= n) return s; var pad = ' ' * (n - s.length); diff --git a/pkg/dart2js_info/pubspec.yaml b/pkg/dart2js_info/pubspec.yaml index 77980f67c01..441e3ae8581 100644 --- a/pkg/dart2js_info/pubspec.yaml +++ b/pkg/dart2js_info/pubspec.yaml @@ -1,24 +1,24 @@ name: dart2js_info -version: 0.6.5 +publish_to: none description: >- Libraries and tools to process data produced when running dart2js with --dump-info. -homepage: https://github.com/dart-lang/dart2js_info/ environment: - sdk: '>=2.3.0 <3.0.0' + sdk: '>=2.11.99 <3.0.0' dependencies: - args: ^1.4.3 + args: ^2.3.0 collection: ^1.10.1 fixnum: '>=0.10.5 <2.0.0' path: ^1.3.6 protobuf: '>=1.0.1 <3.0.0' - shelf: ^0.7.3 - yaml: ^2.1.0 + shelf: ^1.2.0 + yaml: ^3.1.0 dev_dependencies: + lints: ^1.0.0 test: ^1.2.0 executables: diff --git a/pkg/dart2js_info/test/binary_serialization_test.dart b/pkg/dart2js_info/test/binary_serialization_test.dart index 116003e7d72..b622d04a1bd 100644 --- a/pkg/dart2js_info/test/binary_serialization_test.dart +++ b/pkg/dart2js_info/test/binary_serialization_test.dart @@ -12,15 +12,17 @@ import 'package:test/test.dart'; class ByteSink implements Sink> { BytesBuilder builder = BytesBuilder(); + @override add(List data) => builder.add(data); + @override close() {} } main() { group('json to proto conversion with deferred files', () { test('hello_world_deferred', () { - var uri = Platform.script.resolve( - 'hello_world_deferred/hello_world_deferred.js.info.json'); + var uri = Platform.script + .resolve('hello_world_deferred/hello_world_deferred.js.info.json'); var helloWorld = File.fromUri(uri); var contents = helloWorld.readAsStringSync(); var json = jsonDecode(contents); diff --git a/pkg/dart2js_info/test/graph_test.dart b/pkg/dart2js_info/test/graph_test.dart index 4934adfeeb8..71afc236c20 100644 --- a/pkg/dart2js_info/test/graph_test.dart +++ b/pkg/dart2js_info/test/graph_test.dart @@ -60,7 +60,7 @@ main() { /// C /// ``` Graph makeTestGraph() { - var graph = new EdgeListGraph(); + var graph = EdgeListGraph(); graph.addEdge('A', 'B'); graph.addEdge('A', 'D'); graph.addEdge('A', 'E'); diff --git a/pkg/dart2js_info/test/json_to_proto_deferred_test.dart b/pkg/dart2js_info/test/json_to_proto_deferred_test.dart index 70d7681bd82..fc0af001768 100644 --- a/pkg/dart2js_info/test/json_to_proto_deferred_test.dart +++ b/pkg/dart2js_info/test/json_to_proto_deferred_test.dart @@ -12,8 +12,8 @@ import 'package:test/test.dart'; main() { group('json to proto conversion with deferred files', () { test('hello_world_deferred', () { - var uri = Platform.script.resolve( - 'hello_world_deferred/hello_world_deferred.js.info.json'); + var uri = Platform.script + .resolve('hello_world_deferred/hello_world_deferred.js.info.json'); final helloWorld = File.fromUri(uri); final json = jsonDecode(helloWorld.readAsStringSync()); final decoded = AllInfoJsonCodec().decode(json); diff --git a/pkg/dart2js_info/test/json_to_proto_test.dart b/pkg/dart2js_info/test/json_to_proto_test.dart index 8393827349f..67f7ef06a26 100644 --- a/pkg/dart2js_info/test/json_to_proto_test.dart +++ b/pkg/dart2js_info/test/json_to_proto_test.dart @@ -13,8 +13,7 @@ import 'package:test/test.dart'; main() { group('json to proto conversion', () { test('hello_world', () { - var uri = Platform.script.resolve( - 'hello_world/hello_world.js.info.json'); + var uri = Platform.script.resolve('hello_world/hello_world.js.info.json'); final helloWorld = File.fromUri(uri); final json = jsonDecode(helloWorld.readAsStringSync()); final decoded = AllInfoJsonCodec().decode(json); @@ -33,8 +32,7 @@ main() { }); test('has proper id format', () { - var uri = Platform.script.resolve( - 'hello_world/hello_world.js.info.json'); + var uri = Platform.script.resolve('hello_world/hello_world.js.info.json'); final helloWorld = File.fromUri(uri); final json = jsonDecode(helloWorld.readAsStringSync()); final decoded = AllInfoJsonCodec().decode(json); @@ -54,8 +52,8 @@ main() { expect( value.serializedId, startsWith(expectedPrefixes[InfoKind.clazz])); } else if (value.hasClassTypeInfo()) { - expect( - value.serializedId, startsWith(expectedPrefixes[InfoKind.classType])); + expect(value.serializedId, + startsWith(expectedPrefixes[InfoKind.classType])); } else if (value.hasFunctionInfo()) { expect(value.serializedId, startsWith(expectedPrefixes[InfoKind.function])); diff --git a/pkg/dart2js_info/test/parse_test.dart b/pkg/dart2js_info/test/parse_test.dart index bc0cfed49c0..bc5883b9cae 100644 --- a/pkg/dart2js_info/test/parse_test.dart +++ b/pkg/dart2js_info/test/parse_test.dart @@ -11,8 +11,7 @@ import 'package:test/test.dart'; main() { group('parse', () { test('hello_world', () { - var uri = - Platform.script.resolve('hello_world/hello_world.js.info.json'); + var uri = Platform.script.resolve('hello_world/hello_world.js.info.json'); var helloWorld = File.fromUri(uri); var json = jsonDecode(helloWorld.readAsStringSync()); var decoded = AllInfoJsonCodec().decode(json); @@ -24,9 +23,9 @@ main() { expect(program.size, 94182); expect(program.compilationMoment, DateTime.parse("2021-09-27 15:32:00.380236")); - expect(program.compilationDuration, new Duration(microseconds: 2848001)); - expect(program.toJsonDuration, new Duration(milliseconds: 3)); - expect(program.dumpInfoDuration, new Duration(seconds: 0)); + expect(program.compilationDuration, Duration(microseconds: 2848001)); + expect(program.toJsonDuration, Duration(milliseconds: 3)); + expect(program.dumpInfoDuration, Duration(seconds: 0)); expect(program.noSuchMethodEnabled, false); expect(program.minified, false); }); diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json index f1079d2d4f8..9c1191c6d34 100644 --- a/tools/bots/test_matrix.json +++ b/tools/bots/test_matrix.json @@ -3247,6 +3247,15 @@ "pkg/dartdev" ] }, + { + "name": "analyze pkg/dart2js_info", + "script": "out/ReleaseX64/dart-sdk/bin/dart", + "arguments": [ + "analyze", + "--fatal-infos", + "pkg/dart2js_info" + ] + }, { "name": "analyze pkg/dart2js_tools", "script": "out/ReleaseX64/dart-sdk/bin/dart",