Version 2.14.0-24.0.dev

Merge commit 'd8479de94bb5ea3eabe0560f13e6cfa3f9d543b3' into 'dev'
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 128aa38..0134b77 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -848,6 +848,8 @@
   StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
   StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
   StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION,
+  StrongModeCode.TOP_LEVEL_IDENTIFIER_NO_TYPE,
+  StrongModeCode.TOP_LEVEL_INSTANCE_GETTER,
   TodoCode.TODO,
 ];
 
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index bef21eb..9900a5e 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -14180,3 +14180,63 @@
   @override
   ErrorType get type => ErrorType.STATIC_WARNING;
 }
+
+/**
+ * This class has Strong Mode specific error codes.
+ *
+ * "Strong Mode" was the prototype for Dart 2's sound type system. Many of these
+ * errors became part of Dart 2. Some of them are optional flags, used for
+ * stricter checking.
+ *
+ * These error codes tend to use the same message across different severity
+ * levels, so they are grouped for clarity.
+ */
+class StrongModeCode extends ErrorCode {
+  /*
+   * TODO(brianwilkerson) Make the TOP_LEVEL_ error codes be errors rather than
+   * hints and then clean up the function _errorSeverity in
+   * test/src/task/strong/strong_test_helper.dart.
+   */
+  /* TODO(leafp) Delete most of these.
+   */
+
+  static const StrongModeCode TOP_LEVEL_IDENTIFIER_NO_TYPE = StrongModeCode(
+      ErrorType.HINT,
+      'TOP_LEVEL_IDENTIFIER_NO_TYPE',
+      "The type of '{0}' can't be inferred because the type of '{1}' "
+          "couldn't be inferred.",
+      correction:
+          "Try adding an explicit type to either the variable '{0}' or the "
+          "variable '{1}'.");
+
+  static const StrongModeCode TOP_LEVEL_INSTANCE_GETTER = StrongModeCode(
+      ErrorType.STATIC_WARNING,
+      'TOP_LEVEL_INSTANCE_GETTER',
+      "The type of '{0}' can't be inferred because it refers to an instance "
+          "getter, '{1}', which has an implicit type.",
+      correction: "Add an explicit type for either '{0}' or '{1}'.");
+
+  @override
+  final ErrorType type;
+
+  /**
+   * Initialize a newly created error code to have the given [type] and [name].
+   *
+   * The message associated with the error will be created from the given
+   * [message] template. The correction associated with the error will be
+   * created from the optional [correction] template.
+   */
+  const StrongModeCode(ErrorType type, String name, String message,
+      {String? correction, bool hasPublishedDocs = false})
+      : type = type,
+        super(
+          correction: correction,
+          hasPublishedDocs: hasPublishedDocs,
+          message: message,
+          name: name,
+          uniqueName: 'StrongModeCode.$name',
+        );
+
+  @override
+  ErrorSeverity get errorSeverity => type.severity;
+}
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 9f51dba..4138d99 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -376,6 +376,15 @@
     return _node.name.name;
   }
 
+  bool get isImplicitlyTypedInstanceField {
+    var variables = _node.parent as VariableDeclarationList;
+    if (variables.type == null) {
+      var parent = variables.parent;
+      return parent is FieldDeclaration && !parent.isStatic;
+    }
+    return false;
+  }
+
   PropertyInducingElementImpl get _elementImpl {
     return _node.declaredElement as PropertyInducingElementImpl;
   }
@@ -391,7 +400,19 @@
       return const <_InferenceNode>[];
     }
 
-    return collector._set.map(_walker.getNode).whereNotNull().toList();
+    var dependencies =
+        collector._set.map(_walker.getNode).whereNotNull().toList();
+
+    for (var node in dependencies) {
+      if (node is _VariableInferenceNode &&
+          node.isImplicitlyTypedInstanceField) {
+        _elementImpl.type = DynamicTypeImpl.instance;
+        isEvaluated = true;
+        return const <_InferenceNode>[];
+      }
+    }
+
+    return dependencies;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 3d179d7..bd2547c 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -17,7 +17,8 @@
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/error/codes.dart' show CompileTimeErrorCode;
+import 'package:analyzer/src/error/codes.dart'
+    show CompileTimeErrorCode, StrongModeCode;
 import 'package:analyzer/src/task/inference_error.dart';
 
 Element? _getKnownElement(Expression expression) {
@@ -496,21 +497,14 @@
 
   @override
   void visitVariableDeclaration(VariableDeclaration node) {
-    var element = node.declaredElement;
-    if (element is PropertyInducingElementImpl) {
-      var error = element.typeInferenceError;
-      if (error != null) {
-        if (error.kind == TopLevelInferenceErrorKind.dependencyCycle) {
-          // Errors on const should have been reported with
-          // [CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT].
-          if (!element.isConst) {
-            _recordMessage(
-              node.name,
-              CompileTimeErrorCode.TOP_LEVEL_CYCLE,
-              [element.name, error.arguments],
-            );
-          }
-        }
+    var variableElement = node.declaredElement;
+    var parent = node.parent;
+    if (variableElement is PropertyInducingElement &&
+        parent is VariableDeclarationList &&
+        parent.type == null) {
+      var initializer = node.initializer;
+      if (initializer != null) {
+        _validateTopLevelInitializer(variableElement.name, initializer);
       }
     }
     node.visitChildren(this);
@@ -922,6 +916,10 @@
     reporter.onError(error);
   }
 
+  void _validateTopLevelInitializer(String name, Expression n) {
+    n.accept(_TopLevelInitializerValidator(this, name));
+  }
+
   void _visitForEachParts(ForEachParts node, SimpleIdentifier loopVariable) {
     if (loopVariable.staticElement is! VariableElement) {
       return;
@@ -985,3 +983,169 @@
     throw StateError('${e.runtimeType} is unhandled type');
   }
 }
+
+class _TopLevelInitializerValidator extends RecursiveAstVisitor<void> {
+  final CodeChecker _codeChecker;
+  final String _name;
+
+  _TopLevelInitializerValidator(this._codeChecker, this._name);
+
+  void validateHasType(AstNode n, PropertyAccessorElement e) {
+    if (e.hasImplicitReturnType) {
+      var variable = e.declaration.variable as PropertyInducingElementImpl;
+      var error = variable.typeInferenceError;
+      if (error != null) {
+        if (error.kind == TopLevelInferenceErrorKind.dependencyCycle) {
+          // Errors on const should have been reported with
+          // [CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT].
+          if (!variable.isConst) {
+            _codeChecker._recordMessage(n, CompileTimeErrorCode.TOP_LEVEL_CYCLE,
+                [_name, error.arguments]);
+          }
+        } else {
+          _codeChecker._recordMessage(
+              n, StrongModeCode.TOP_LEVEL_IDENTIFIER_NO_TYPE, [_name, e.name]);
+        }
+      }
+    }
+  }
+
+  void validateIdentifierElement(AstNode n, Element? e,
+      {bool isMethodCall = false}) {
+    if (e == null) {
+      return;
+    }
+
+    var enclosing = e.enclosingElement;
+    if (enclosing is CompilationUnitElement) {
+      if (e is PropertyAccessorElement) {
+        validateHasType(n, e);
+      }
+    } else if (enclosing is ClassElement) {
+      if (e is PropertyAccessorElement) {
+        if (e.isStatic) {
+          validateHasType(n, e);
+        } else if (e.hasImplicitReturnType) {
+          _codeChecker._recordMessage(
+              n, StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, [_name, e.name]);
+        }
+      }
+    }
+  }
+
+  @override
+  visitAsExpression(AsExpression node) {
+    // Nothing to validate.
+  }
+
+  @override
+  visitBinaryExpression(BinaryExpression node) {
+    TokenType operator = node.operator.type;
+    if (operator == TokenType.AMPERSAND_AMPERSAND ||
+        operator == TokenType.BAR_BAR ||
+        operator == TokenType.EQ_EQ ||
+        operator == TokenType.BANG_EQ) {
+      // These operators give 'bool', no need to validate operands.
+    } else {
+      node.leftOperand.accept(this);
+    }
+  }
+
+  @override
+  visitCascadeExpression(CascadeExpression node) {
+    node.target.accept(this);
+  }
+
+  @override
+  visitConditionalExpression(ConditionalExpression node) {
+    // No need to validate the condition, since it can't affect type inference.
+    node.thenExpression.accept(this);
+    node.elseExpression.accept(this);
+  }
+
+  @override
+  visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    if (node.typeArguments != null) {
+      return;
+    }
+
+    var function = node.function;
+    if (function is PropertyAccess) {
+      var propertyName = function.propertyName;
+      validateIdentifierElement(propertyName, propertyName.staticElement);
+    }
+
+    var functionType = node.function.staticType;
+    if (functionType is FunctionType && functionType.typeFormals.isNotEmpty) {
+      node.argumentList.accept(this);
+    }
+  }
+
+  @override
+  visitIndexExpression(IndexExpression node) {
+    // Nothing to validate.
+  }
+
+  @override
+  visitInstanceCreationExpression(InstanceCreationExpression node) {
+    var constructor = node.constructorName.staticElement;
+    var class_ = constructor?.enclosingElement;
+    if (node.constructorName.type.typeArguments == null &&
+        class_ != null &&
+        class_.typeParameters.isNotEmpty) {
+      // Type inference might depend on the parameters
+      super.visitInstanceCreationExpression(node);
+    }
+  }
+
+  @override
+  visitIsExpression(IsExpression node) {
+    // Nothing to validate.
+  }
+
+  @override
+  visitListLiteral(ListLiteral node) {
+    if (node.typeArguments == null) {
+      super.visitListLiteral(node);
+    }
+  }
+
+  @override
+  visitMethodInvocation(MethodInvocation node) {
+    node.target?.accept(this);
+    var method = node.methodName.staticElement;
+    validateIdentifierElement(node, method, isMethodCall: true);
+    if (method is ExecutableElement) {
+      if (node.typeArguments == null && method.typeParameters.isNotEmpty) {
+        // Type inference might depend on the parameters
+        node.argumentList.accept(this);
+      }
+    }
+  }
+
+  @override
+  visitPrefixExpression(PrefixExpression node) {
+    if (node.operator.type == TokenType.BANG) {
+      // This operator gives 'bool', no need to validate operands.
+    } else {
+      node.operand.accept(this);
+    }
+  }
+
+  @override
+  visitSetOrMapLiteral(SetOrMapLiteral node) {
+    if (node.typeArguments == null) {
+      super.visitSetOrMapLiteral(node);
+    }
+  }
+
+  @override
+  visitSimpleIdentifier(SimpleIdentifier node) {
+    validateIdentifierElement(node, node.staticElement);
+  }
+
+  @override
+  visitThrowExpression(ThrowExpression node) {
+    // Nothing to validate.
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
index 85e16c6..77fa53c 100644
--- a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
@@ -34,8 +34,7 @@
 }
 final b = new A().a;
 ''', [
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 18, 1),
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 37, 1),
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 49, 1),
     ]);
 
     assertTypeDynamic(findElement.field('a').type);
diff --git a/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
index 52e2b7c..c3b6d67 100644
--- a/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
@@ -93,6 +93,7 @@
   final y = x;
 }
 ''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 37, 1),
       error(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, 37, 1),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/top_level_cycle_test.dart b/pkg/analyzer/test/src/diagnostics/top_level_cycle_test.dart
index fbe9053..0f72b33 100644
--- a/pkg/analyzer/test/src/diagnostics/top_level_cycle_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/top_level_cycle_test.dart
@@ -20,8 +20,8 @@
 var x = y + 1;
 var y = x + 1;
 ''', [
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 19, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 8, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 23, 1),
     ]);
   }
 
@@ -29,7 +29,7 @@
     await assertErrorsInCode(r'''
 var x = x;
 ''', [
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 8, 1),
     ]);
   }
 
@@ -41,7 +41,7 @@
   ],
 ];
 ''', [
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 5),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 25, 5),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart b/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
index 3a78473..8153be9 100644
--- a/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/src/error/codes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/context_collection_resolution.dart';
@@ -81,71 +82,81 @@
   }
 
   test_implicitlyTyped() async {
-    await assertNoErrorsInCode('''
+    await assertErrorsInCode('''
 class A {
   get g => 0;
 }
 var b = new A().g;
-''');
-    assertTypeDynamic(findElement.topVar('b').type);
+''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 42, 1),
+    ]);
   }
 
   test_implicitlyTyped_call() async {
-    await assertNoErrorsInCode('''
+    await assertErrorsInCode('''
 class A {
   get g => () => 0;
 }
 var a = new A();
 var b = a.g();
-''');
-    assertTypeDynamic(findElement.topVar('b').type);
+''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 59, 1),
+    ]);
   }
 
   test_implicitlyTyped_field() async {
-    await assertNoErrorsInCode('''
+    await assertErrorsInCode('''
 class A {
   var g = 0;
 }
 var b = new A().g;
-''');
-    assertType(findElement.topVar('b').type, 'int');
+''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 41, 1),
+    ]);
   }
 
   test_implicitlyTyped_field_call() async {
-    await assertNoErrorsInCode('''
+    await assertErrorsInCode('''
 class A {
   var g = () => 0;
 }
 var a = new A();
 var b = a.g();
-''');
-    assertType(findElement.topVar('b').type, 'int');
+''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 58, 1),
+    ]);
   }
 
   test_implicitlyTyped_field_prefixedIdentifier() async {
-    await assertNoErrorsInCode('''
+    await assertErrorsInCode('''
 class A {
   var g = 0;
 }
 var a = new A();
 var b = a.g;
-''');
-    assertType(findElement.topVar('b').type, 'int');
+''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 52, 1),
+    ]);
   }
 
   test_implicitlyTyped_fn() async {
-    await assertNoErrorsInCode('''
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because f is
+    // generic, so the type of a.x might affect the type of b.
+    await assertErrorsInCode('''
 class A {
   var x = 0;
 }
 int f<T>(x) => 0;
 var a = new A();
 var b = f(a.x);
-''');
-    assertType(findElement.topVar('b').type, 'int');
+''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 72, 1),
+    ]);
   }
 
   test_implicitlyTyped_fn_explicit_type_params() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -154,10 +165,11 @@
 var a = new A();
 var b = f<int>(a.x);
 ''');
-    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_fn_not_generic() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -166,10 +178,11 @@
 var a = new A();
 var b = f(a.x);
 ''');
-    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_indexExpression() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -178,21 +191,25 @@
 var a = new A();
 var b = a[a.x];
 ''');
-    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_invoke() async {
-    await assertNoErrorsInCode('''
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because the
+    // closure is generic, so the type of a.x might affect the type of b.
+    await assertErrorsInCode('''
 class A {
   var x = 0;
 }
 var a = new A();
 var b = (<T>(y) => 0)(a.x);
-''');
-    assertType(findElement.topVar('b').type, 'int');
+''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 66, 1),
+    ]);
   }
 
   test_implicitlyTyped_invoke_explicit_type_params() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -200,10 +217,11 @@
 var a = new A();
 var b = (<T>(y) => 0)<int>(a.x);
 ''');
-    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_invoke_not_generic() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -211,22 +229,26 @@
 var a = new A();
 var b = ((y) => 0)(a.x);
 ''');
-    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_method() async {
-    await assertNoErrorsInCode('''
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because f is
+    // generic, so the type of a.x might affect the type of b.
+    await assertErrorsInCode('''
 class A {
   var x = 0;
   int f<T>(int x) => 0;
 }
 var a = new A();
 var b = a.f(a.x);
-''');
-    assertType(findElement.topVar('b').type, 'int');
+''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 80, 1),
+    ]);
   }
 
   test_implicitlyTyped_method_explicit_type_params() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -235,10 +257,11 @@
 var a = new A();
 var b = a.f<int>(a.x);
 ''');
-    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_method_not_generic() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -247,24 +270,28 @@
 var a = new A();
 var b = a.f(a.x);
 ''');
-    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_new() async {
-    await assertNoErrorsInCode('''
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
+    // generic, so the type of a.x might affect the type of b.
+    await assertErrorsInCode('''
 class A {
   var x = 0;
 }
 class B<T> {
-  B(T x);
+  B(x);
 }
 var a = new A();
 var b = new B(a.x);
-''');
-    assertType(findElement.topVar('b').type, 'B<int>');
+''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 81, 1),
+    ]);
   }
 
   test_implicitlyTyped_new_explicit_type_params() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -275,10 +302,11 @@
 var a = new A();
 var b = new B<int>(a.x);
 ''');
-    assertType(findElement.topVar('b').type, 'B<int>');
   }
 
   test_implicitlyTyped_new_explicit_type_params_named() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -289,10 +317,11 @@
 var a = new A();
 var b = new B<int>.named(a.x);
 ''');
-    assertType(findElement.topVar('b').type, 'B<int>');
   }
 
   test_implicitlyTyped_new_explicit_type_params_prefixed() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
     newFile('$testPackageLibPath/lib1.dart', content: '''
 class B<T> {
   B(x);
@@ -306,24 +335,28 @@
 var a = new A();
 var b = new foo.B<int>(a.x);
 ''');
-    assertType(findElement.topVar('b').type, 'B<int>');
   }
 
   test_implicitlyTyped_new_named() async {
-    await assertNoErrorsInCode('''
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
+    // generic, so the type of a.x might affect the type of b.
+    await assertErrorsInCode('''
 class A {
   var x = 0;
 }
 class B<T> {
-  B.named(T x);
+  B.named(x);
 }
 var a = new A();
 var b = new B.named(a.x);
-''');
-    assertType(findElement.topVar('b').type, 'B<int>');
+''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 93, 1),
+    ]);
   }
 
   test_implicitlyTyped_new_not_generic() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -334,10 +367,11 @@
 var a = new A();
 var b = new B(a.x);
 ''');
-    assertType(findElement.topVar('b').type, 'B');
   }
 
   test_implicitlyTyped_new_not_generic_named() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -348,7 +382,6 @@
 var a = new A();
 var b = new B.named(a.x);
 ''');
-    assertType(findElement.topVar('b').type, 'B');
   }
 
   test_implicitlyTyped_new_not_generic_prefixed() async {
@@ -357,6 +390,8 @@
   B(x);
 }
 ''');
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 import 'lib1.dart' as foo;
 class A {
@@ -365,39 +400,44 @@
 var a = new A();
 var b = new foo.B(a.x);
 ''');
-    assertType(findElement.topVar('b').type, 'B');
   }
 
   test_implicitlyTyped_new_prefixed() async {
     newFile('$testPackageLibPath/lib1.dart', content: '''
 class B<T> {
-  B(T x);
+  B(x);
 }
 ''');
-    await assertNoErrorsInCode('''
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
+    // generic, so the type of a.x might affect the type of b.
+    await assertErrorsInCode('''
 import 'lib1.dart' as foo;
 class A {
   var x = 0;
 }
 var a = new A();
 var b = new foo.B(a.x);
-''');
-    assertType(findElement.topVar('b').type, 'B<int>');
+''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 89, 1),
+    ]);
   }
 
   test_implicitlyTyped_prefixedIdentifier() async {
-    await assertNoErrorsInCode('''
+    await assertErrorsInCode('''
 class A {
   get g => 0;
 }
 var a = new A();
 var b = a.g;
-''');
-    assertType(findElement.topVar('b').type, 'dynamic');
+''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 53, 1),
+    ]);
   }
 
   test_implicitlyTyped_propertyAccessLhs() async {
-    await assertNoErrorsInCode('''
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because the type
+    // of a.x affects the lookup of y, which in turn affects the type of b.
+    await assertErrorsInCode('''
 class A {
   var x = new B();
   int operator[](int value) => 0;
@@ -407,8 +447,9 @@
 }
 var a = new A();
 var b = (a.x).y;
-''');
-    assertType(findElement.topVar('b').type, 'int');
+''', [
+      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 118, 1),
+    ]);
   }
 
   test_prefixedIdentifier() async {
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
index d7828d1..5675f3f 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -101,8 +101,8 @@
 var a = b;
 var b = a;
 ''', [
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 15, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 8, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 19, 1),
     ]);
   }
 
@@ -718,7 +718,7 @@
 class C {
   int f;
 }
-int x;
+dynamic x;
 ''');
   }
 
@@ -735,7 +735,7 @@
 ''');
     checkElementText(library, r'''
 import 'package:test/a.dart';
-int x;
+dynamic x;
 ''');
   }
 
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index d20ec18..d77818f 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -364,8 +364,8 @@
 var x = () => y;
 var y = () => x;
 ''', [
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 21, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 14, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 31, 1),
     ]);
 
     var x = _resultUnitElement.topLevelVariables[0];
@@ -381,8 +381,8 @@
 var x = () => y;
 var y = () => x;
 ''', [
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 21, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 14, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 31, 1),
     ]);
 
     var x = _resultUnitElement.topLevelVariables[0];
diff --git a/tests/language/variable/inst_field_initializer1_test.dart b/tests/language/variable/inst_field_initializer1_test.dart
index 550a03e..edc85c8 100644
--- a/tests/language/variable/inst_field_initializer1_test.dart
+++ b/tests/language/variable/inst_field_initializer1_test.dart
@@ -10,6 +10,8 @@
   //         ^
   // [analyzer] COMPILE_TIME_ERROR.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER
   // [cfe] Can't access 'this' in a field initializer to read 'x'.
+  //         ^
+  // [analyzer] STATIC_WARNING.TOP_LEVEL_INSTANCE_GETTER
 }
 
 void main() {
diff --git a/tests/language_2/variable/inst_field_initializer1_test.dart b/tests/language_2/variable/inst_field_initializer1_test.dart
index 550a03e..edc85c8 100644
--- a/tests/language_2/variable/inst_field_initializer1_test.dart
+++ b/tests/language_2/variable/inst_field_initializer1_test.dart
@@ -10,6 +10,8 @@
   //         ^
   // [analyzer] COMPILE_TIME_ERROR.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER
   // [cfe] Can't access 'this' in a field initializer to read 'x'.
+  //         ^
+  // [analyzer] STATIC_WARNING.TOP_LEVEL_INSTANCE_GETTER
 }
 
 void main() {
diff --git a/tools/VERSION b/tools/VERSION
index b292fbb..67a7f7b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 23
+PRERELEASE 24
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/post_results_to_pubsub.dart b/tools/bots/post_results_to_pubsub.dart
index 1134188..774dec9 100644
--- a/tools/bots/post_results_to_pubsub.dart
+++ b/tools/bots/post_results_to_pubsub.dart
@@ -28,7 +28,7 @@
   exit(exitCode);
 }
 
-const resultsPerMessage = 100;
+const resultsPerMessage = 50;
 
 Uri _postUrl(String project) => Uri.https(
     'pubsub.googleapis.com', 'v1/projects/$project/topics/results:publish');
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 94d11a1..7f33648 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -2918,27 +2918,12 @@
       "steps": [
         {
           "name": "build debian package",
-          "script": "tools/run_debian_build.sh",
+          "script": "tools/linux_dist_support/run_debian_build.sh",
           "arguments": []
         },
         {
           "name": "upload debian packages",
-          "script": "tools/bots/upload_debian_packages.py",
-          "arguments": []
-        }
-      ]
-    },
-    {
-      "builders": [
-        "versionchecker-linux"
-      ],
-      "meta": {
-        "description": "This configuration is used by the versionchecker-builder."
-      },
-      "steps": [
-        {
-          "name": "check version",
-          "script": "tools/bots/version_checker.py",
+          "script": "tools/linux_dist_support/upload_debian_packages.py",
           "arguments": []
         }
       ]
diff --git a/tools/create_debian_chroot.sh b/tools/create_debian_chroot.sh
deleted file mode 100755
index 4e98093..0000000
--- a/tools/create_debian_chroot.sh
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-#
-# Script to create a Debian jessie chroot environment for building Dart
-# Debian packages.
-#
-
-function usage {
-  USAGE="Usage: $0 i386|amd64 [target dir] [be|beta|dev|<stable version>]]\n
-\n
-The first mandatory argument speciifies the CPU architecture using\n
-the Debian convention (e.g. i386 and amd64).\n
-\n
-The second optional argument specifies the destination\n
-directory. This defaults to 'debian_<architecture>'.\n
-\n
-The third optional argument specifies whether the chroot is\n
-populated with a Dart checkout. Use 'be' for bleeding edge, 'dev'\n
-for trunk/developer or the specific version number for a stable\n
-version (e.g. 1.2)."
-
-  echo -e $USAGE
-  exit 1
-}
-
-# Expect one to three arguments, architecture, optional directory and
-# optional channel.
-if [ $# -lt 1 ] || [ $# -gt 3 ]
-then
-  usage
-fi
-
-ARCH=$1
-
-if [ -n "$2" ]
-then
-  CHROOT=$2
-else
-  CHROOT=debian_$ARCH
-fi
-
-if [ -n "$3" ]
-then
-  CHANNEL=$3
-fi
-
-if [ "$ARCH" != "i386" ] && [ "$ARCH" != "amd64" ]
-then
-  usage
-fi
-
-SVN_REPRO="http://dart.googlecode.com/svn/"
-if [ -n "$CHANNEL" ]
-then
-  if [ "$CHANNEL" == "be" ]
-  then
-    SVN_PATH="branches/bleeding_edge/deps/all.deps"
-  elif [ "$CHANNEL" == "dev" ]
-  then
-    SVN_PATH="trunk/deps/all.deps"
-  else
-    SVN_PATH="branches/$CHANNEL/deps/all.deps"
-  fi
-  SRC_URI=$SVN_REPRO$SVN_PATH
-fi
-
-# Create Debian jessie chroot.
-debootstrap --arch=$ARCH --components=main,restricted,universe,multiverse \
-    jessie $CHROOT http://http.us.debian.org/debian/
-chroot $CHROOT apt-get update
-chroot $CHROOT apt-get -y install \
-    debhelper python3 git gcc sudo make
-
-# Add chrome-bot user.
-chroot $CHROOT groupadd --gid 1001 chrome-bot
-chroot $CHROOT useradd --gid 1001 --uid 1001 --create-home chrome-bot
-mkdir $CHROOT/b
-chown 1001:1001 $CHROOT/b
-
-# Create trampoline script for running the initialization as chrome-bot.
-cat << EOF > $CHROOT/b/init_chroot_trampoline.sh
-#!/bin/sh
-su -c /b/init_chroot.sh chrome-bot
-EOF
-
-# Create initialization script which does nothing.
-cat << 'EOF' > $CHROOT/b/init_chroot.sh
-#!/bin/sh
-cd /b
-EOF
-
-# If the channel is set extend the initialization script to check out
-# the Dart sources. This uses two cat commands as the first part needs
-# to bypass variable interpretation.
-if [ -n "$SRC_URI" ]
-then
-cat << 'EOF' >> $CHROOT/b/init_chroot.sh
-git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
-export PATH=$PATH:/b/depot_tools
-EOF
-
-cat << EOF >> $CHROOT/b/init_chroot.sh
-gclient config $SRC_URI
-gclient sync
-gclient runhooks
-EOF
-fi
-
-chmod 755 $CHROOT/b/init_chroot_trampoline.sh
-
-chown 1001:1001 $CHROOT/b/init_chroot.sh
-chmod 755 $CHROOT/b/init_chroot.sh
-chroot $CHROOT /bin/sh /b/init_chroot_trampoline.sh
diff --git a/tools/linux_dist_support/Debian.dockerfile b/tools/linux_dist_support/Debian.dockerfile
new file mode 100644
index 0000000..3d975c3
--- /dev/null
+++ b/tools/linux_dist_support/Debian.dockerfile
@@ -0,0 +1,11 @@
+# Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+FROM launcher.gcr.io/google/debian8:latest
+ARG depot_tools
+RUN sed -i /jessie-updates/d /etc/apt/sources.list
+RUN apt-get update \
+  && apt-get install -y build-essential debhelper git python3 \
+  && rm -rf /var/lib/apt/lists/*
+ENV PATH="$depot_tools:${PATH}"
+ENTRYPOINT python3 tools/linux_dist_support/linux_distribution_support.py
\ No newline at end of file
diff --git a/tools/create_debian_packages.py b/tools/linux_dist_support/create_debian_packages.py
similarity index 83%
rename from tools/create_debian_packages.py
rename to tools/linux_dist_support/create_debian_packages.py
index 74b8a77..94c0d53 100755
--- a/tools/create_debian_packages.py
+++ b/tools/linux_dist_support/create_debian_packages.py
@@ -14,32 +14,33 @@
 import sys
 import tarfile
 import subprocess
+from os.path import join, exists, abspath, dirname
+sys.path.append(join(dirname(__file__), '..'))
 import utils
-from os.path import join, exists, abspath
 from shutil import copyfile
 
 HOST_OS = utils.GuessOS()
 HOST_CPUS = utils.GuessCpus()
-DART_DIR = abspath(join(__file__, '..', '..'))
+DART_DIR = abspath(join(dirname(__file__), '..', '..'))
 
 
 def BuildOptions():
     result = optparse.OptionParser()
-    result.add_option(
-        "--tar_filename", default=None, help="The tar file to build from.")
-    result.add_option(
-        "--out_dir", default=None, help="Where to put the packages.")
-    result.add_option(
-        "-a",
-        "--arch",
-        help='Target architectures (comma-separated).',
-        metavar='[all,ia32,x64,armel,armhf]',
-        default='x64')
-    result.add_option(
-        "-t",
-        "--toolchain",
-        help='Cross-compilation toolchain prefix',
-        default=None)
+    result.add_option("--tar_filename",
+                      default=None,
+                      help="The tar file to build from.")
+    result.add_option("--out_dir",
+                      default=None,
+                      help="Where to put the packages.")
+    result.add_option("-a",
+                      "--arch",
+                      help='Target architectures (comma-separated).',
+                      metavar='[all,ia32,x64,armel,armhf]',
+                      default='x64')
+    result.add_option("-t",
+                      "--toolchain",
+                      help='Cross-compilation toolchain prefix',
+                      default=None)
 
     return result
 
diff --git a/tools/create_tarball.py b/tools/linux_dist_support/create_tarball.py
similarity index 83%
rename from tools/create_tarball.py
rename to tools/linux_dist_support/create_tarball.py
index 6844cad..10eb73c 100755
--- a/tools/create_tarball.py
+++ b/tools/linux_dist_support/create_tarball.py
@@ -26,12 +26,12 @@
 import sys
 import tarfile
 from os import listdir
-from os.path import join, split, abspath
-
+from os.path import join, split, abspath, dirname
+sys.path.append(join(dirname(__file__), '..'))
 import utils
 
 HOST_OS = utils.GuessOS()
-DART_DIR = abspath(join(__file__, '..', '..'))
+DART_DIR = abspath(join(dirname(__file__), '..', '..'))
 # Flags.
 verbose = False
 
@@ -40,21 +40,40 @@
 
 # Ignore Git/SVN files, checked-in binaries, backup files, etc..
 ignoredPaths = [
-    'third_party/7zip', 'third_party/android_tools', 'third_party/clang',
-    'third_party/d8', 'third_party/firefox_jsshell'
+    'buildtools/linux-x64/go',
+    'buildtools/linux-x64/rust',
+    'samples',
+    'samples_2',
+    'third_party/7zip',
+    'third_party/android_tools',
+    'third_party/clang',
+    'third_party/d8',
+    'third_party/firefox_jsshell',
+    'third_party/gsutil',
+    'third_party/llvm-build',
+    'third_party/mdn',
 ]
-ignoredDirs = ['.svn', '.git']
+ignoredDirs = [
+    '.cipd',
+    '.git',
+    'benchmarks',
+    'docs',
+    'fuchsia',
+    'parser_testcases',
+    'test',
+    'testcases',
+    'tests',
+]
 ignoredEndings = ['.mk', '.pyc', 'Makefile', '~']
 
 
 def BuildOptions():
     result = optparse.OptionParser()
-    result.add_option(
-        "-v",
-        "--verbose",
-        help='Verbose output.',
-        default=False,
-        action="store_true")
+    result.add_option("-v",
+                      "--verbose",
+                      help='Verbose output.',
+                      default=False,
+                      action="store_true")
     result.add_option("--tar_filename", default=None, help="The output file.")
 
     return result
@@ -134,9 +153,8 @@
         for f in listdir(DART_DIR):
             tar.add(join(DART_DIR, f), filter=Filter)
         for f in listdir(join(DART_DIR, debian_dir)):
-            tar.add(
-                join(DART_DIR, debian_dir, f),
-                arcname='%s/debian/%s' % (versiondir, f))
+            tar.add(join(DART_DIR, debian_dir, f),
+                    arcname='%s/debian/%s' % (versiondir, f))
 
         with utils.TempDir() as temp_dir:
             # Generate and add debian/copyright
@@ -158,9 +176,8 @@
             if utils.GetChannel() == 'be':
                 git_revision = join(temp_dir, 'GIT_REVISION')
                 GenerateGitRevision(git_revision, utils.GetGitRevision())
-                tar.add(
-                    git_revision,
-                    arcname='%s/dart/tools/GIT_REVISION' % versiondir)
+                tar.add(git_revision,
+                        arcname='%s/dart/tools/GIT_REVISION' % versiondir)
 
 
 def Main():
diff --git a/tools/linux_dist_support/debian/rules b/tools/linux_dist_support/debian/rules
index 1ccacf5..68002f5 100755
--- a/tools/linux_dist_support/debian/rules
+++ b/tools/linux_dist_support/debian/rules
@@ -57,7 +57,8 @@
 
 override_dh_auto_build:
 	cd dart; \
-	python3 tools/build.py -v -m release -a $(ARCH) $(TOOLCHAIN) create_sdk; \
+	python3 tools/build.py --no-goma --mode release \
+	  --arch $(ARCH) $(TOOLCHAIN) create_sdk; \
 	cd ..
 
 # Building the Dart SDK will already strip all binaries.
diff --git a/tools/bots/linux_distribution_support.py b/tools/linux_dist_support/linux_distribution_support.py
similarity index 88%
rename from tools/bots/linux_distribution_support.py
rename to tools/linux_dist_support/linux_distribution_support.py
index 04fb693..44c7477 100644
--- a/tools/bots/linux_distribution_support.py
+++ b/tools/linux_dist_support/linux_distribution_support.py
@@ -11,16 +11,17 @@
 """
 
 import os
-import re
 import subprocess
 import sys
 
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'bots'))
 import bot_utils
 
 utils = bot_utils.GetUtils()
 
 HOST_OS = utils.GuessOS()
 
+
 def InstallFromDep(builddir):
     for entry in os.listdir(builddir):
         if entry.endswith("_amd64.deb"):
@@ -47,9 +48,7 @@
     sys.stdout.flush()
     no_color_env = dict(os.environ)
     no_color_env['TERM'] = 'nocolor'
-    exit_code = subprocess.call(command, env=no_color_env)
-    if exit_code != 0:
-        raise OSError(exit_code)
+    subprocess.check_call(command, env=no_color_env)
 
 
 def TestInstallation(assume_installed=True):
@@ -90,13 +89,14 @@
 
     print('Building src tarball')
     Run([
-        sys.executable, './tools/create_tarball.py', '--tar_filename', tarfile
+        sys.executable, 'tools/linux_dist_support/create_tarball.py',
+        '--tar_filename', tarfile
     ])
 
     print('Building Debian packages')
     Run([
-        sys.executable, './tools/create_debian_packages.py', '--tar_filename',
-        tarfile, '--out_dir', builddir
+        sys.executable, 'tools/linux_dist_support/create_debian_packages.py',
+        '--tar_filename', tarfile, '--out_dir', builddir
     ])
 
     if os.path.exists('/usr/bin/dart') or os.path.exists(
@@ -110,7 +110,10 @@
 
     # We build the runtime target to get everything we need to test the
     # standalone target.
-    Run([sys.executable, './tools/build.py', '-mrelease', '-ax64', 'runtime'])
+    Run([
+        sys.executable, 'tools/build.py', '--no-goma', '--mode=release',
+        '--arch=x64', 'runtime'
+    ])
     # Copy in the installed binary to avoid poluting /usr/bin (and having to
     # run as root)
     Run(['cp', '/usr/bin/dart', 'out/ReleaseX64/dart'])
diff --git a/tools/linux_dist_support/run_debian_build.sh b/tools/linux_dist_support/run_debian_build.sh
new file mode 100755
index 0000000..4f09663
--- /dev/null
+++ b/tools/linux_dist_support/run_debian_build.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+set -x
+
+ninja=$(which ninja)
+depot_tools=$(dirname $ninja)
+image="debian-package:0.1"
+dockerfile=tools/linux_dist_support/Debian.dockerfile
+docker build --build-arg depot_tools=$depot_tools -t $image - < $dockerfile
+checkout=$(pwd)
+docker run -e BUILDBOT_BUILDERNAME -v $depot_tools:$depot_tools\
+    -v $checkout:$checkout -w $checkout -i --rm $image
diff --git a/tools/bots/upload_debian_packages.py b/tools/linux_dist_support/upload_debian_packages.py
similarity index 95%
rename from tools/bots/upload_debian_packages.py
rename to tools/linux_dist_support/upload_debian_packages.py
index 3fc08d4..d2f7151 100755
--- a/tools/bots/upload_debian_packages.py
+++ b/tools/linux_dist_support/upload_debian_packages.py
@@ -5,7 +5,8 @@
 # BSD-style license that can be found in the LICENSE file.
 
 import os
-
+import sys
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'bots'))
 import bot_utils
 
 utils = bot_utils.GetUtils()
diff --git a/tools/run_debian_build.sh b/tools/run_debian_build.sh
deleted file mode 100755
index 6fb1866..0000000
--- a/tools/run_debian_build.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env bash
-# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-set -x
-
-ninja=$(which ninja)
-depot_tools=$(dirname $ninja)
-cmd="sed -i /jessie-updates/d /etc/apt/sources.list \
-    && apt-get update \
-    && apt-get -y install build-essential debhelper git python3 \
-    && PATH=\"$depot_tools:\$PATH\" \
-    python3 tools/bots/linux_distribution_support.py"
-image="launcher.gcr.io/google/debian8:latest"
-docker run -e BUILDBOT_BUILDERNAME -v $depot_tools:$depot_tools\
-    -v `pwd`:`pwd` -w `pwd` -i --rm $image bash -c "$cmd"