Version 2.10.0-69.0.dev

Merge commit 'b29aebbc8d96b26da4a98c9d5d09870cb22640c2' into 'dev'
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index c2b13cc..3a0b9e7 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -25,7 +25,7 @@
 
   void _addCommentRanges() {
     var token = _unit.beginToken;
-    while (token != null && token.type != TokenType.EOF) {
+    do {
       Token commentToken = token.precedingComments;
       while (commentToken != null) {
         HighlightRegionType highlightType;
@@ -45,7 +45,7 @@
         commentToken = commentToken.next;
       }
       token = token.next;
-    }
+    } while (token != null && token.type != TokenType.EOF);
   }
 
   void _addIdentifierRegion(SimpleIdentifier node) {
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
index 6f59807..3be6bae 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
@@ -25,7 +25,7 @@
 
   void _addCommentRanges() {
     var token = _unit.beginToken;
-    while (token != null && token.type != TokenType.EOF) {
+    do {
       Token commentToken = token.precedingComments;
       while (commentToken != null) {
         HighlightRegionType highlightType;
@@ -45,7 +45,7 @@
         commentToken = commentToken.next;
       }
       token = token.next;
-    }
+    } while (token != null && token.type != TokenType.EOF);
   }
 
   void _addIdentifierRegion(SimpleIdentifier node) {
diff --git a/pkg/analysis_server/test/src/computer/highlights2_computer_test.dart b/pkg/analysis_server/test/src/computer/highlights2_computer_test.dart
index 5ae859f..1102320 100644
--- a/pkg/analysis_server/test/src/computer/highlights2_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/highlights2_computer_test.dart
@@ -62,6 +62,13 @@
     _check(HighlightRegionType.KEYWORD, 'throw');
   }
 
+  Future<void> test_trailingComment() async {
+    await _computeHighlights('''
+// A trailing comment
+''');
+    _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
+  }
+
   void _check(HighlightRegionType expectedType, String expectedText) {
     for (var region in highlights) {
       if (region.type == expectedType) {
diff --git a/pkg/analysis_server/test/src/computer/highlights_computer_test.dart b/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
index e6c5879..d853b1e 100644
--- a/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
@@ -48,6 +48,13 @@
     _check(HighlightRegionType.IDENTIFIER_DEFAULT, 'foo');
   }
 
+  Future<void> test_trailingComment() async {
+    await _computeHighlights('''
+// A trailing comment
+''');
+    _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
+  }
+
   void _check(HighlightRegionType expectedType, String expectedText) {
     for (var region in highlights) {
       if (region.type == expectedType) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
index a3b4f35..1de4308 100644
--- a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
@@ -101,10 +101,9 @@
   ///
   /// TODO(scheglov) this is duplicate
   void _analyzeLeastUpperBound(
-      Expression node, Expression expr1, Expression expr2,
-      {bool read = false}) {
-    DartType staticType1 = _getExpressionType(expr1, read: read);
-    DartType staticType2 = _getExpressionType(expr2, read: read);
+      Expression node, Expression expr1, Expression expr2) {
+    DartType staticType1 = getReadType(expr1);
+    DartType staticType2 = getReadType(expr2);
 
     _analyzeLeastUpperBoundTypes(node, staticType1, staticType2);
   }
@@ -130,57 +129,6 @@
     _inferenceHelper.recordStaticType(node, staticType);
   }
 
-  /// Gets the definite type of expression, which can be used in cases where
-  /// the most precise type is desired, for example computing the least upper
-  /// bound.
-  ///
-  /// See [getExpressionType] for more information. Without strong mode, this is
-  /// equivalent to [_getStaticType].
-  ///
-  /// TODO(scheglov) this is duplicate
-  DartType _getExpressionType(Expression expr, {bool read = false}) =>
-      getExpressionType(expr, _typeSystem, _typeProvider, read: read);
-
-  /// Return the static type of the given [expression] that is to be used for
-  /// type analysis.
-  ///
-  /// TODO(scheglov) this is duplicate
-  DartType _getStaticType1(Expression expression, {bool read = false}) {
-    if (expression is NullLiteral) {
-      return _typeProvider.nullType;
-    }
-    DartType type = read ? getReadType(expression) : expression.staticType;
-    return _resolveTypeParameter(type);
-  }
-
-  /// Return the static type of the given [expression].
-  ///
-  /// TODO(scheglov) this is duplicate
-  DartType _getStaticType2(Expression expression, {bool read = false}) {
-    DartType type;
-    if (read) {
-      type = getReadType(expression);
-    } else {
-      if (expression is SimpleIdentifier && expression.inSetterContext()) {
-        var element = expression.staticElement;
-        if (element is PromotableElement) {
-          // We're writing to the element so ignore promotions.
-          type = element.type;
-        } else {
-          type = expression.staticType;
-        }
-      } else {
-        type = expression.staticType;
-      }
-    }
-    if (type == null) {
-      // TODO(brianwilkerson) Determine the conditions for which the static type
-      // is null.
-      return DynamicTypeImpl.instance;
-    }
-    return type;
-  }
-
   /// Return the non-nullable variant of the [type] if null safety is enabled,
   /// otherwise return the type itself.
   ///
@@ -222,9 +170,11 @@
     Token operator = node.operator;
     TokenType operatorType = operator.type;
     Expression leftHandSide = node.leftHandSide;
-    DartType staticType = _getStaticType1(leftHandSide, read: true);
 
-    if (identical(staticType, NeverTypeImpl.instance)) {
+    var leftType = getReadType(leftHandSide);
+    leftType = _resolveTypeParameter(leftType);
+
+    if (identical(leftType, NeverTypeImpl.instance)) {
       return;
     }
 
@@ -233,7 +183,7 @@
     // For any compound assignments to a void or nullable variable, report it.
     // Example: `y += voidFn()`, not allowed.
     if (operatorType != TokenType.EQ) {
-      if (staticType != null && staticType.isVoid) {
+      if (leftType != null && leftType.isVoid) {
         _errorReporter.reportErrorForToken(
           CompileTimeErrorCode.USE_OF_VOID_RESULT,
           operator,
@@ -253,17 +203,17 @@
         //  side to the operator.
         var result = _typePropertyResolver.resolve(
           receiver: leftHandSide,
-          receiverType: staticType,
+          receiverType: leftType,
           name: methodName,
           receiverErrorNode: leftHandSide,
           nameErrorNode: leftHandSide,
         );
         node.staticElement = result.getter;
-        if (_shouldReportInvalidMember(staticType, result)) {
+        if (_shouldReportInvalidMember(leftType, result)) {
           _errorReporter.reportErrorForToken(
             CompileTimeErrorCode.UNDEFINED_OPERATOR,
             operator,
-            [methodName, staticType],
+            [methodName, leftType],
           );
         }
       }
@@ -273,9 +223,8 @@
   void _resolve2(AssignmentExpressionImpl node) {
     TokenType operator = node.operator.type;
     if (operator == TokenType.EQ) {
-      Expression rightHandSide = node.rightHandSide;
-      DartType staticType = _getStaticType2(rightHandSide);
-      _inferenceHelper.recordStaticType(node, staticType);
+      var rightType = node.rightHandSide.staticType;
+      _inferenceHelper.recordStaticType(node, rightType);
     } else if (operator == TokenType.QUESTION_QUESTION_EQ) {
       if (_isNonNullableByDefault) {
         // The static type of a compound assignment using ??= with NNBD is the
@@ -284,14 +233,12 @@
         // if null)
         _analyzeLeastUpperBoundTypes(
             node,
-            _typeSystem.promoteToNonNull(
-                _getExpressionType(node.leftHandSide, read: true)),
-            _getExpressionType(node.rightHandSide, read: true));
+            _typeSystem.promoteToNonNull(getReadType(node.leftHandSide)),
+            getReadType(node.rightHandSide));
       } else {
         // The static type of a compound assignment using ??= before NNBD is the
         // least upper bound of the static types of the LHS and RHS.
-        _analyzeLeastUpperBound(node, node.leftHandSide, node.rightHandSide,
-            read: true);
+        _analyzeLeastUpperBound(node, node.leftHandSide, node.rightHandSide);
       }
     } else if (operator == TokenType.AMPERSAND_AMPERSAND_EQ ||
         operator == TokenType.BAR_BAR_EQ) {
@@ -300,7 +247,7 @@
     } else {
       var rightType = node.rightHandSide.staticType;
 
-      var leftReadType = _getStaticType2(node.leftHandSide, read: true);
+      var leftReadType = getReadType(node.leftHandSide);
       if (identical(leftReadType, NeverTypeImpl.instance)) {
         _inferenceHelper.recordStaticType(node, rightType);
         return;
@@ -317,7 +264,7 @@
       );
       _inferenceHelper.recordStaticType(node, type);
 
-      var leftWriteType = _getStaticType2(node.leftHandSide);
+      var leftWriteType = _getWriteType(node.leftHandSide);
       if (!_typeSystem.isAssignableTo2(type, leftWriteType)) {
         _resolver.errorReporter.reportErrorForNode(
           CompileTimeErrorCode.INVALID_ASSIGNMENT,
@@ -413,6 +360,19 @@
     }
     return false;
   }
+
+  /// The type of the RHS assigned to [left] must be subtype of the return.
+  static DartType _getWriteType(Expression left) {
+    // We are writing, so ignore promotions.
+    if (left is SimpleIdentifier) {
+      var element = left.staticElement;
+      if (element is PromotableElement) {
+        return element.type;
+      }
+    }
+
+    return left.staticType;
+  }
 }
 
 class AssignmentExpressionShared {
diff --git a/runtime/include/dart_tools_api.h b/runtime/include/dart_tools_api.h
index 4c86a82..2b47365 100644
--- a/runtime/include/dart_tools_api.h
+++ b/runtime/include/dart_tools_api.h
@@ -5,7 +5,7 @@
 #ifndef RUNTIME_INCLUDE_DART_TOOLS_API_H_
 #define RUNTIME_INCLUDE_DART_TOOLS_API_H_
 
-#include "dart_api.h"
+#include "dart_api.h" /* NOLINT */
 
 /** \mainpage Dart Tools Embedding API Reference
  *
diff --git a/tools/VERSION b/tools/VERSION
index 29d04b0..7c8ae1a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 68
+PRERELEASE 69
 PRERELEASE_PATCH 0
\ No newline at end of file