Add defer-layout tool.

This is a simple tool to tell you how libraries map to output units. Here is an
example output of the tool:

  Output unit main:
    loaded by default
    contains:
       - hello_world.dart
       - dart:core
       - dart:_internal
       - dart:_js_primitives
       - dart:_js_helper
       - dart:collection
       - dart:_interceptors
       - dart:_isolate_helper
       - dart:async
       - dart:_js_names
       - dart:_foreign_helper
       - dart:_js_embedded_names
       - dart:isolate
       - dart:_async_await_error_codes

  Output unit 2:
    loaded by importing: [a, b]
    contains:
       - c.dart

  Output unit 1:
    loaded by importing: [a]
    contains:
       - a.dart

  Output unit 3:
    loaded by importing: [b]
    contains:
       - b.dart

BUG=
R=het@google.com

Review URL: https://codereview.chromium.org//2469963002 .
diff --git a/README.md b/README.md
index e04a96b..0d4dd42 100644
--- a/README.md
+++ b/README.md
@@ -73,11 +73,14 @@
     was split into deferred parts as expected. This tool takes a specification
     of the expected layout of code into deferred parts, and checks that the
     output from `dart2js` meets the specification.
-    
+
   * [`deferred_library_size`][deferred_size]: a tool that gives a breakdown of
     the sizes of the deferred parts of the program. This can show how much of
     your total code size can be loaded deferred.
 
+  * [`deferred_library_layout`][deferred_layout]: a tool that reports which
+    code is included on each output unit.
+
   * [`function_size_analysis`][function_analysis]: a tool that shows how much
     code was attributed to each function. This tool also uses dependency
     information to compute dominance and reachability data. This information can
@@ -270,6 +273,48 @@
 Percent of code deferred                  41.86%
 ```
 
+### Deferred library layout tool
+
+This tool reports which code is included in each output unit.  It can be run as
+follows:
+
+```bash
+pub global activate dart2js_info # only needed once
+dart2js_info_deferred_library_layout out.js.info.json
+```
+
+The tool will output a table listing all of the deferred output units or chunks,
+for each unit it will list the set of libraries that contribute code to this
+unit. If a library contributes to more than one output unit, the tool lists
+which elements are in one or another output unit. For example, the output might
+look like this:
+
+```
+Output unit main:
+  loaded by default
+  contains:
+     - hello_world.dart
+     - dart:core
+     ...
+
+Output unit 2:
+  loaded by importing: [b]
+  contains:
+     - c.dart:
+       - function d
+     - b.dart
+
+Output unit 1:
+  loaded by importing: [a]
+  contains:
+     - c.dart:
+       - function c
+     - a.dart
+```
+
+In this example, all the code of `b.dart` after tree-shaking was included in the
+output unit 2, but `c.dart` was split between output unit 1 and output unit 2.
+
 ### Function size analysis tool
 
 This command-line tool presents how much each function contributes to the total
@@ -352,6 +397,7 @@
 [lib_split]: https://github.com/dart-lang/dart2js_info/blob/master/bin/library_size_split.dart
 [deferred_lib]: https://github.com/dart-lang/dart2js_info/blob/master/bin/deferred_library_check.dart
 [deferred_size]: https://github.com/dart-lang/dart2js_info/blob/master/bin/deferred_library_size.dart
+[deferred_layout]: https://github.com/dart-lang/dart2js_info/blob/master/bin/deferred_library_layout.dart
 [coverage]: https://github.com/dart-lang/dart2js_info/blob/master/bin/coverage_log_server.dart
 [live]: https://github.com/dart-lang/dart2js_info/blob/master/bin/live_code_size_analysis.dart
 [function_analysis]: https://github.com/dart-lang/dart2js_info/blob/master/bin/function_size_analysis.dart
diff --git a/bin/deferred_library_layout.dart b/bin/deferred_library_layout.dart
new file mode 100644
index 0000000..09caeb1
--- /dev/null
+++ b/bin/deferred_library_layout.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This tool reports how code is divided among deferred chunks.
+library dart2js_info.bin.deferred_library_size;
+
+import 'dart:io';
+import 'package:dart2js_info/info.dart';
+import 'package:dart2js_info/src/util.dart';
+
+main(args) async {
+  AllInfo info = await infoFromFile(args.first);
+
+  Map<OutputUnitInfo, Map<LibraryInfo, List<BasicInfo>>> hunkMembers = {};
+  Map<LibraryInfo, Set<OutputUnitInfo>> libToHunks = {};
+  void register(BasicInfo info) {
+    var unit = info.outputUnit;
+    var lib = _libOf(info);
+    if (lib == null) return;
+    libToHunks.putIfAbsent(lib, () => new Set()).add(unit);
+    hunkMembers.putIfAbsent(unit, () => {})
+      .putIfAbsent(lib, () => []).add(info);
+  }
+
+  info.functions.forEach(register);
+  info.classes.forEach(register);
+  info.fields.forEach(register);
+  info.closures.forEach(register);
+
+  var dir = Directory.current.path;
+  hunkMembers.forEach((unit, map) {
+    print('Output unit ${unit.name ?? "main"}:');
+    if (unit.name == null || unit.name == 'main')  {
+      print('  loaded by default');
+    } else {
+      print('  loaded by importing: ${unit.imports}');
+    }
+
+    print('  contains:');
+    map.forEach((lib, elements) {
+      var uri = lib.uri;
+      var shortUri = (uri.scheme == 'file' && uri.path.startsWith(dir))
+          ? uri.path.substring(dir.length + 1)
+          : '$uri';
+
+      // If the entire library is in one chunk, just report the library name
+      // otherwise report which functions are on this chunk.
+      if (libToHunks[lib].length == 1) {
+        print('     - $shortUri');
+      } else {
+        print('     - $shortUri:');
+        for (var e in elements) {
+          print('       - ${kindToString(e.kind)} ${e.name}');
+        }
+      }
+    });
+    print('');
+  });
+}
+
+_libOf(e) => e is LibraryInfo || e == null ? e : _libOf(e.parent);
diff --git a/pubspec.yaml b/pubspec.yaml
index 11541ee..665b08c 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: dart2js_info
-version: 0.5.1+1
+version: 0.5.2
 description: >
   Libraries and tools to process data produced when running dart2js with
   --dump-info.
@@ -25,6 +25,7 @@
   dart2js_info_debug_info:              debug_info
   dart2js_info_deferred_library_check:  deferred_library_check
   dart2js_info_deferred_library_size:   deferred_library_size
+  dart2js_info_deferred_library_layout: deferred_library_layout
   dart2js_info_function_size_analysis:  function_size_analysis
   dart2js_info_library_size_split:      library_size_split
   dart2js_info_live_code_size_analysis: live_code_size_analysis