Version 2.10.0-24.0.dev

Merge commit '33849927c97af61d65931cf06eb025b74c6987e2' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e5cace4..04aa7bd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -179,7 +179,9 @@
 * Fix git folder names in cache, allowing for ssh-style git
   dependencies.
 * Fix: Avoid precompilation of dependencies of global packages.
-* Fix: avoid multiple recompilation of binaries in global packages.
+* Fix: Avoid multiple recompilation of binaries in global packages.
+* Fix: Avoid exponential behaviour of error reporting from the solver.
+* Fix: Refresh binstubs after recompile in global run.
 
 ## 2.8.4 - 2020-06-04
 
diff --git a/DEPS b/DEPS
index 92fa1ff..984e608 100644
--- a/DEPS
+++ b/DEPS
@@ -128,7 +128,7 @@
   "ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_rev": "eedbd5fde84f9a1a8da643b475305a81841da599",
   "protobuf_rev": "3746c8fd3f2b0147623a8e3db89c3ff4330de760",
-  "pub_rev": "0d185a398a1684c15ea16a0facc17f5d170e5d51",
+  "pub_rev": "cf9795f3bb209504c349e20501f0b4b8ae31530c",
   "pub_semver_tag": "v1.4.4",
   "quiver-dart_tag": "246e754fe45cecb6aa5f3f13b4ed61037ff0d784",
   "resource_rev": "f8e37558a1c4f54550aa463b88a6a831e3e33cd6",
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index fb49ebe..87a3edf 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -60,6 +60,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageAbstractExternalField = const MessageCode(
     "AbstractExternalField",
+    index: 110,
     message: r"""Fields can't be declared both 'abstract' and 'external'.""",
     tip: r"""Try removing the 'abstract' or 'external' keyword.""");
 
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 095f89c..0211a54 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -574,6 +574,7 @@
   ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE,
   ParserErrorCode.ABSTRACT_CLASS_MEMBER,
   ParserErrorCode.ABSTRACT_ENUM,
+  ParserErrorCode.ABSTRACT_EXTERNAL_FIELD,
   ParserErrorCode.ABSTRACT_LATE_FIELD,
   ParserErrorCode.ABSTRACT_STATIC_FIELD,
   ParserErrorCode.ABSTRACT_STATIC_METHOD,
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index f40eb69..d93eff3 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -5223,9 +5223,6 @@
   /// computed yet.
   Namespace _publicNamespace;
 
-  /// A bit-encoded form of the capabilities associated with this library.
-  int _resolutionCapabilities = 0;
-
   /// The cached list of prefixes.
   List<PrefixElement> _prefixes;
 
@@ -5252,10 +5249,6 @@
         super.forLinkedNode(null, reference, linkedNode) {
     _name = name;
     _nameOffset = offset;
-    setResolutionCapability(
-        LibraryResolutionCapability.resolvedTypeNames, true);
-    setResolutionCapability(
-        LibraryResolutionCapability.constantExpressions, true);
   }
 
   @override
@@ -5707,14 +5700,6 @@
     return getTypeFromParts(className, _definingCompilationUnit, _parts);
   }
 
-  /// Set whether the library has the given [capability] to
-  /// correspond to the given [value].
-  void setResolutionCapability(
-      LibraryResolutionCapability capability, bool value) {
-    _resolutionCapabilities =
-        BooleanArray.set(_resolutionCapabilities, capability.index, value);
-  }
-
   @override
   T toLegacyElementIfOptOut<T extends Element>(T element) {
     if (isNonNullableByDefault) return element;
@@ -5776,23 +5761,6 @@
     }
     return null;
   }
-
-  /// Return `true` if the [library] has the given [capability].
-  static bool hasResolutionCapability(
-      LibraryElement library, LibraryResolutionCapability capability) {
-    return library is LibraryElementImpl &&
-        BooleanArray.get(library._resolutionCapabilities, capability.index);
-  }
-}
-
-/// Enum of possible resolution capabilities that a [LibraryElementImpl] has.
-enum LibraryResolutionCapability {
-  /// All elements have their types resolved.
-  resolvedTypeNames,
-
-  /// All (potentially) constants expressions are set into corresponding
-  /// elements.
-  constantExpressions,
 }
 
 /// A concrete implementation of a [LocalVariableElement].
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index c699cd0..1f388cf 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -783,6 +783,14 @@
   bool get isInitializingFormal => declaration.isInitializingFormal;
 
   @override
+  bool get isOptionalNamed {
+    if (isLegacy) {
+      return super.isNamed;
+    }
+    return super.isOptionalNamed;
+  }
+
+  @override
   bool get isRequiredNamed {
     if (isLegacy) {
       return false;
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index f55c540..bb3a66c 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -29,6 +29,9 @@
       'ABSTRACT_ENUM', "Enums can't be declared to be 'abstract'.",
       correction: "Try removing the keyword 'abstract'.");
 
+  static const ParserErrorCode ABSTRACT_EXTERNAL_FIELD =
+      _ABSTRACT_EXTERNAL_FIELD;
+
   static const ParserErrorCode ABSTRACT_LATE_FIELD = _ABSTRACT_LATE_FIELD;
 
   static const ParserErrorCode ABSTRACT_STATIC_FIELD = _ABSTRACT_STATIC_FIELD;
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index 8c50c14..71bc3ab 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -117,6 +117,7 @@
   _ABSTRACT_STATIC_FIELD,
   _ABSTRACT_LATE_FIELD,
   _EXTERNAL_LATE_FIELD,
+  _ABSTRACT_EXTERNAL_FIELD,
 ];
 
 const ParserErrorCode _ABSTRACT_CLASS_MEMBER = ParserErrorCode(
@@ -125,6 +126,11 @@
     correction:
         "Try removing the 'abstract' keyword. You can add the 'abstract' keyword before the class declaration.");
 
+const ParserErrorCode _ABSTRACT_EXTERNAL_FIELD = ParserErrorCode(
+    'ABSTRACT_EXTERNAL_FIELD',
+    r"Fields can't be declared both 'abstract' and 'external'.",
+    correction: "Try removing the 'abstract' or 'external' keyword.");
+
 const ParserErrorCode _ABSTRACT_LATE_FIELD = ParserErrorCode(
     'ABSTRACT_LATE_FIELD', r"Abstract fields cannot be late.",
     correction: "Try removing the 'abstract' or 'late' keyword.");
diff --git a/pkg/analyzer/lib/src/error/required_parameters_verifier.dart b/pkg/analyzer/lib/src/error/required_parameters_verifier.dart
index 6a1c7a2..b5f2080 100644
--- a/pkg/analyzer/lib/src/error/required_parameters_verifier.dart
+++ b/pkg/analyzer/lib/src/error/required_parameters_verifier.dart
@@ -95,11 +95,11 @@
         }
       }
       if (parameter.isOptionalNamed) {
-        ElementAnnotationImpl annotation = _requiredAnnotation(parameter);
+        var annotation = _requiredAnnotation(parameter);
         if (annotation != null) {
           String parameterName = parameter.name;
           if (!_containsNamedExpression(argumentList, parameterName)) {
-            String reason = _requiredReason(annotation);
+            String reason = annotation.reason;
             if (reason != null) {
               _errorReporter.reportErrorForNode(
                 HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS,
@@ -140,14 +140,35 @@
     }
   }
 
-  static ElementAnnotationImpl _requiredAnnotation(ParameterElement element) {
-    return element.metadata.firstWhere(
+  static _RequiredAnnotation _requiredAnnotation(ParameterElement element) {
+    var annotation = element.metadata.firstWhere(
       (e) => e.isRequired,
       orElse: () => null,
     );
-  }
+    if (annotation != null) {
+      return _RequiredAnnotation(annotation);
+    }
 
-  static String _requiredReason(ElementAnnotationImpl annotation) {
+    if (element.declaration.isRequiredNamed) {
+      return _RequiredAnnotation(annotation);
+    }
+
+    return null;
+  }
+}
+
+class _RequiredAnnotation {
+  /// The instance of `@required` annotation.
+  /// If `null`, then the parameter is `required` in null safety.
+  final ElementAnnotationImpl annotation;
+
+  _RequiredAnnotation(this.annotation);
+
+  String get reason {
+    if (annotation == null) {
+      return null;
+    }
+
     DartObject constantValue = annotation.computeConstantValue();
     String value = constantValue?.getField('reason')?.toStringValue();
     return (value == null || value.isEmpty) ? null : value;
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index d919f68..8bba9a1 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1800,8 +1800,7 @@
     if (executable is MethodElement ||
         executable is FunctionElement &&
             executable.enclosingElement is CompilationUnitElement) {
-      return LibraryElementImpl.hasResolutionCapability(
-          definingLibrary, LibraryResolutionCapability.constantExpressions);
+      return true;
     }
     return false;
   }
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 6f27e07..134f210 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -182,6 +182,19 @@
     expect(field.abstractKeyword, isNotNull);
   }
 
+  void test_parseField_abstract_external() {
+    createParser('abstract external int i;', featureSet: nonNullable);
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    assertErrors(errors: [
+      expectedError(ParserErrorCode.ABSTRACT_EXTERNAL_FIELD, 0, 8),
+    ]);
+    expect(member, isFieldDeclaration);
+    FieldDeclaration field = member;
+    expect(field.abstractKeyword, isNotNull);
+    expect(field.externalKeyword, isNotNull);
+  }
+
   void test_parseField_abstract_late() {
     createParser('abstract late int? i;', featureSet: nonNullable);
     ClassMember member = parser.parseClassMember('C');
@@ -254,6 +267,19 @@
     expect(field.externalKeyword, isNotNull);
   }
 
+  void test_parseField_external_abstract() {
+    createParser('external abstract int i;', featureSet: nonNullable);
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    assertErrors(errors: [
+      expectedError(ParserErrorCode.ABSTRACT_EXTERNAL_FIELD, 9, 8),
+    ]);
+    expect(member, isFieldDeclaration);
+    FieldDeclaration field = member;
+    expect(field.abstractKeyword, isNotNull);
+    expect(field.externalKeyword, isNotNull);
+  }
+
   void test_parseField_external_late() {
     createParser('external late int? i;', featureSet: nonNullable);
     ClassMember member = parser.parseClassMember('C');
@@ -2637,6 +2663,12 @@
     expect(defaultParameter.isNamed, isTrue);
   }
 
+  void test_parseFormalParameter_external() {
+    parseNNBDFormalParameter('external int i', ParameterKind.REQUIRED, errors: [
+      expectedError(ParserErrorCode.EXTRANEOUS_MODIFIER, 1, 8),
+    ]);
+  }
+
   void test_parseFormalParameter_final_required_named() {
     ParameterKind kind = ParameterKind.NAMED;
     FormalParameter parameter = parseNNBDFormalParameter(
@@ -4381,6 +4413,13 @@
     expect(forStatement.body, isNotNull);
   }
 
+  void test_parseLocalVariable_external() {
+    parseStatement('external int i;', featureSet: nonNullable);
+    assertErrors(errors: [
+      expectedError(ParserErrorCode.EXTRANEOUS_MODIFIER, 0, 8),
+    ]);
+  }
+
   void test_partial_typeArg1_34850() {
     var unit = parseCompilationUnit('<bar<', errors: [
       expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 0, 1),
diff --git a/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
index 7c3510e..236e071 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
@@ -244,7 +244,41 @@
 @reflectiveTest
 class MissingRequiredParamWithNullSafetyTest extends PubPackageResolutionTest
     with WithNullSafetyMixin {
-  test_constructor_argumentGiven() async {
+  test_constructor_legacy_argumentGiven() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A {
+  A({required int a});
+}
+''');
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import "a.dart";
+
+void f() {
+  A(a: 0);
+}
+''');
+  }
+
+  test_constructor_legacy_missingArgument() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A {
+  A({required int a});
+}
+''');
+    await assertErrorsInCode(r'''
+// @dart = 2.7
+import "a.dart";
+
+void f() {
+  A();
+}
+''', [
+      error(HintCode.MISSING_REQUIRED_PARAM, 46, 1),
+    ]);
+  }
+
+  test_constructor_nullSafe_argumentGiven() async {
     await assertNoErrorsInCode(r'''
 class C {
   C({required int a}) {}
@@ -256,7 +290,7 @@
 ''');
   }
 
-  test_constructor_missingArgument() async {
+  test_constructor_nullSafe_missingArgument() async {
     await assertErrorsInCode(r'''
 class C {
   C({required int a}) {}
@@ -269,7 +303,7 @@
     ]);
   }
 
-  test_constructor_redirectingConstructorCall() async {
+  test_constructor_nullSafe_redirectingConstructorCall() async {
     await assertErrorsInCode(r'''
 class C {
   C({required int x});
@@ -280,7 +314,7 @@
     ]);
   }
 
-  test_constructor_superCall() async {
+  test_constructor_nullSafe_superCall() async {
     await assertErrorsInCode(r'''
 class C {
   C({required int a}) {}
@@ -318,6 +352,36 @@
     ]);
   }
 
+  test_function_legacy_argumentGiven() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+void foo({required int a}) {}
+''');
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import "a.dart";
+
+void f() {
+  foo(a: 0);
+}
+''');
+  }
+
+  test_function_legacy_missingArgument() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+void foo({required int a}) {}
+''');
+    await assertErrorsInCode(r'''
+// @dart = 2.7
+import "a.dart";
+
+void f() {
+  foo();
+}
+''', [
+      error(HintCode.MISSING_REQUIRED_PARAM, 46, 3),
+    ]);
+  }
+
   test_functionInvocation() async {
     await assertErrorsInCode(r'''
 void Function({required int a}) f() => throw '';
@@ -358,7 +422,7 @@
     ]);
   }
 
-  test_method_legacy() async {
+  test_method_legacy_argumentGiven() async {
     newFile('$testPackageLibPath/a.dart', content: r'''
 class A {
   void foo({required int a}) {}
@@ -368,12 +432,30 @@
 // @dart = 2.7
 import "a.dart";
 
-f() {
-  A().foo();
+void f(A a) {
+  a.foo(a: 0);
 }
 ''');
   }
 
+  test_method_legacy_missingArgument() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A {
+  void foo({required int a}) {}
+}
+''');
+    await assertErrorsInCode(r'''
+// @dart = 2.7
+import "a.dart";
+
+void f(A a) {
+  a.foo();
+}
+''', [
+      error(HintCode.MISSING_REQUIRED_PARAM, 51, 3),
+    ]);
+  }
+
   test_typedef_function() async {
     await assertErrorsInCode(r'''
 String test(C c) => c.m()();
diff --git a/pkg/analyzer/tool/messages/generate.dart b/pkg/analyzer/tool/messages/generate.dart
index 75fd269..31d96ef 100644
--- a/pkg/analyzer/tool/messages/generate.dart
+++ b/pkg/analyzer/tool/messages/generate.dart
@@ -210,9 +210,13 @@
   void generateFormatCode() {
     messagesYaml.forEach((name, entry) {
       if (entry is Map) {
-        if (entry['index'] is int && entry['analyzerCode'] is String) {
-          translatedFastaErrorCodes.add(name);
-          translatedEntries.add(entry);
+        if (entry['index'] is int) {
+          if (entry['analyzerCode'] is String) {
+            translatedFastaErrorCodes.add(name);
+            translatedEntries.add(entry);
+          } else {
+            throw invalidAnalyzerCode;
+          }
         }
       }
     });
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index a16abd1..24385c0 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -10,7 +10,6 @@
 AbstractFieldInitializer/analyzerCode: Fail
 AbstractExtensionField/analyzerCode: Fail
 AbstractExtensionField/example: Fail
-AbstractExternalField/analyzerCode: Fail
 AbstractNotSync/example: Fail
 AbstractRedirectedClassInstantiation/example: Fail
 AccessError/analyzerCode: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index c5a9dce..9da1481 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -557,7 +557,9 @@
     - "abstract class C {abstract static var f;}"
 
 AbstractExternalField:
+  index: 110
   template: "Fields can't be declared both 'abstract' and 'external'."
+  analyzerCode: ParserErrorCode.ABSTRACT_EXTERNAL_FIELD
   tip: "Try removing the 'abstract' or 'external' keyword."
   configuration: nnbd-strong
   script:
diff --git a/pkg/vm_snapshot_analysis/CHANGELOG.md b/pkg/vm_snapshot_analysis/CHANGELOG.md
index c637854..7506f91 100644
--- a/pkg/vm_snapshot_analysis/CHANGELOG.md
+++ b/pkg/vm_snapshot_analysis/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## 0.5.5
+- Add `deps-display-depth` (`-d`) flag for `summary` command to make the display
+depth of outputted dependency trees configurable.
+- Rename `deps-collapse-depth` (formerly `-d`) flag for `summary` command to
+`deps-start-depth` (now `-s`).
+
 ## 0.5.4
 - Fix bug causing name clash for Type class.
 
diff --git a/pkg/vm_snapshot_analysis/README.md b/pkg/vm_snapshot_analysis/README.md
index 5484b91..18a7f5a 100644
--- a/pkg/vm_snapshot_analysis/README.md
+++ b/pkg/vm_snapshot_analysis/README.md
@@ -67,7 +67,7 @@
 ### `summary`
 
 ```console
-$ snapshot_analysis summary [-b granularity] [-w filter] <input.json>
+$ snapshot_analysis summary [-b granularity] [-w filter] <input-profile.json>
 ```
 
 This command shows breakdown of snapshot bytes at the given `granularity` (e.g.
@@ -98,7 +98,13 @@
 
 This command also supports _estimating_ cumulative impact of a library or a
 package together with its dependencies - which can be computed from
-a precompiler trace (`--trace-precompiler-to` options). For example:
+a precompiler trace (generated by adding
+`--trace-precompiler-to=path/to/trace.json` to `--extra-gen-snapshot-options=`).
+
+```console
+$ snapshot_analysis summary [-b granularity] [-w filter] [-s dep-tree-start-depth] [-d dep-tree-display-depth] --precompiler-trace=<input-trace.json> <input-profile.json>
+```
+For example:
 
 ```console
 $ snapshot_analysis summary -b package /tmp/profile.json
@@ -110,7 +116,7 @@
 | package:kernel              |      1443568 |  10.47% |
 | package:_fe_analyzer_shared |       944555 |   6.85% |
 ...
-$ snapshot_analysis summary -b package -d 1 --precompiler-trace=/tmp/trace.json /tmp/profile.json
+$ snapshot_analysis summary -b package -s 1 -d 3 --precompiler-trace=/tmp/trace.json /tmp/profile.json
 +------------------------------+--------------+---------+
 | Package                      | Size (Bytes) | Percent |
 +------------------------------+--------------+---------+
diff --git a/pkg/vm_snapshot_analysis/lib/src/commands/summary.dart b/pkg/vm_snapshot_analysis/lib/src/commands/summary.dart
index c45cfd0..7809aa4 100644
--- a/pkg/vm_snapshot_analysis/lib/src/commands/summary.dart
+++ b/pkg/vm_snapshot_analysis/lib/src/commands/summary.dart
@@ -59,12 +59,21 @@
 ''',
       )
       ..addOption(
-        'deps-collapse-depth',
-        abbr: 'd',
-        defaultsTo: '3',
+        'deps-start-depth',
+        abbr: 's',
+        defaultsTo: '2',
         help: '''
-Depth at which nodes in the dependency tree are collapsed together.
-Only has affect if --precompiler-trace is also passed.
+Depth at which to start the dependency tree. At this depth and above, nodes are
+collapsed together. Only has affect if --precompiler-trace is also passed.
+''',
+      )
+      ..addOption(
+        'deps-display-depth',
+        abbr: 'd',
+        defaultsTo: '4',
+        help: '''
+Display depth of the dependency tree. Nodes below this level will be displayed
+as a summary. Only has affect if --precompiler-trace is also passed.
 ''',
       )
       ..addFlag('collapse-anonymous-closures', help: '''
@@ -117,10 +126,17 @@
           'Specified column width (${columnWidth}) is not an integer');
     }
 
-    final depthCollapseDepthStr = argResults['deps-collapse-depth'];
-    final depsCollapseDepth = int.tryParse(depthCollapseDepthStr);
-    if (depsCollapseDepth == null) {
-      usageException('Specified depthCollapseDepth (${depthCollapseDepthStr})'
+    final depsStartDepthStr = argResults['deps-start-depth'];
+    final depsStartDepth = int.tryParse(depsStartDepthStr);
+    if (depsStartDepth == null) {
+      usageException('Specified depsStartDepth (${depsStartDepthStr})'
+          ' is not an integer');
+    }
+
+    final depsDisplayDepthStr = argResults['deps-display-depth'];
+    final depsDisplayDepth = int.tryParse(depsDisplayDepthStr);
+    if (depsDisplayDepth == null) {
+      usageException('Specified depsDisplayDepth (${depsStartDepthStr})'
           ' is not an integer');
     }
 
@@ -130,7 +146,8 @@
         collapseAnonymousClosures: argResults['collapse-anonymous-closures'],
         filter: argResults['where'],
         traceJson: traceJson != null ? File(traceJson) : null,
-        depsCollapseDepth: depsCollapseDepth);
+        depsStartDepth: depsStartDepth,
+        depsDisplayDepth: depsDisplayDepth);
   }
 
   static HistogramType _parseHistogramType(String value) {
@@ -154,7 +171,8 @@
     HistogramType granularity = HistogramType.bySymbol,
     String filter,
     File traceJson,
-    int depsCollapseDepth = 3,
+    int depsStartDepth = 2,
+    int depsDisplayDepth = 4,
     int topToReport = 30}) async {
   final inputJson = await loadJsonFromFile(input);
   final info = loadProgramInfoFromJson(inputJson);
@@ -162,7 +180,7 @@
   // Compute histogram.
   var histogram = computeHistogram(info, granularity, filter: filter);
 
-  // If precompiler trace is provide collapse entries based on the dependency
+  // If precompiler trace is provided, collapse entries based on the dependency
   // graph (dominator tree) extracted from the trace.
   void Function() printDependencyTrees;
   if (traceJson != null &&
@@ -182,13 +200,13 @@
     callGraph.computeDominators();
 
     // Compute name mapping from histogram buckets to new coarser buckets, by
-    // collapsing dependency tree at [depsCollapseDepth] level: node 'Foo' with
+    // collapsing dependency tree at [depsStartDepth] level: node 'Foo' with
     // k dominated children (k > 0) becomes 'Foo (+k deps)' and all its children
     // are remapped to this bucket.
     final mapping = <String, String>{};
     final collapsed = <String, CallGraphNode>{};
     callGraph.root.visitDominatorTree((n, depth) {
-      if (depth >= depsCollapseDepth) {
+      if (depth >= depsStartDepth) {
         final children = <String>[];
         n.visitDominatorTree((child, depth) {
           if (n != child && child.data is ProgramInfoNode) {
@@ -248,7 +266,9 @@
           print(
               '\n${n.data.qualifiedName} (total ${totalSizes[n.data.name]} bytes)');
           _printDominatedNodes(n,
-              totalSizes: totalSizes, totalCounts: totalCounts);
+              totalSizes: totalSizes,
+              totalCounts: totalCounts,
+              displayDepth: depsDisplayDepth);
         }
       }
     };
@@ -281,17 +301,19 @@
 /// ├── F (total ... bytes)
 /// └── G (total ... bytes)
 ///
-/// Cuts the printing off at the given depth ([cutOffDepth]) and after the
+/// Stops printing at the given depth ([displayDepth]) and after the
 /// given amount of children at each node ([maxChildrenToPrint]).
 void _printDominatedNodes(CallGraphNode node,
-    {int cutOffDepth = 2,
+    {int displayDepth = 4,
     int maxChildrenToPrint = 10,
     List<bool> isLastPerLevel,
     @required Map<String, int> totalSizes,
     @required Map<String, int> totalCounts}) {
   isLastPerLevel ??= [];
 
-  if (isLastPerLevel.length >= cutOffDepth) {
+  // Subtract one to account for the parent node that is printed before the
+  // recursive call.
+  if (isLastPerLevel.length >= displayDepth - 1) {
     maxChildrenToPrint = 0;
   }
 
@@ -311,7 +333,7 @@
     print(
         '${_treeLines(isLastPerLevel)}${n.data.qualifiedName} (total ${size} bytes)');
     _printDominatedNodes(n,
-        cutOffDepth: cutOffDepth,
+        displayDepth: displayDepth,
         isLastPerLevel: isLastPerLevel,
         totalCounts: totalCounts,
         totalSizes: totalSizes);
diff --git a/pkg/vm_snapshot_analysis/pubspec.yaml b/pkg/vm_snapshot_analysis/pubspec.yaml
index 1f7fb76..dd0da7e 100644
--- a/pkg/vm_snapshot_analysis/pubspec.yaml
+++ b/pkg/vm_snapshot_analysis/pubspec.yaml
@@ -1,6 +1,6 @@
 name: vm_snapshot_analysis
 description: Utilities for analysing AOT snapshot size.
-version: 0.5.4
+version: 0.5.5-dev.1
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_snapshot_analysis
 
diff --git a/tools/VERSION b/tools/VERSION
index 651b696..d3b9276 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 23
+PRERELEASE 24
 PRERELEASE_PATCH 0
\ No newline at end of file