Add support for >>> in summaries

Change-Id: I92092085d9a12093f15ae86783327aade8b4ac4b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97605
Commit-Queue: Mike Fairhurst <mfairhurst@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/summary/expr_builder.dart b/pkg/analyzer/lib/src/summary/expr_builder.dart
index 2fe2012..77bcdd9 100644
--- a/pkg/analyzer/lib/src/summary/expr_builder.dart
+++ b/pkg/analyzer/lib/src/summary/expr_builder.dart
@@ -146,6 +146,9 @@
         case UnlinkedExprOperation.bitShiftRight:
           _pushBinary(TokenType.GT_GT);
           break;
+        case UnlinkedExprOperation.bitShiftRightLogical:
+          _pushBinary(TokenType.GT_GT_GT);
+          break;
         case UnlinkedExprOperation.add:
           _pushBinary(TokenType.PLUS);
           break;
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 8b52c07..ae0cab1 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1060,7 +1060,11 @@
   /// `Type name in expression`, where `name` is obtained from
   /// [UnlinkedExpr.strings], and `Type` is obtained from
   /// [UnlinkedExpr.references].
-  forEachPartsWithTypedDeclaration
+  forEachPartsWithTypedDeclaration,
+
+  /// Pop the top 2 values from the stack, compute `v1 >>> v2`, and push the
+  /// result back onto the stack.
+  bitShiftRightLogical
 }
 
 /// Enum used to indicate the kind of a parameter.
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index e406e0c..821de47 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -3996,6 +3996,10 @@
   /// [UnlinkedExpr.strings], and `Type` is obtained from
   /// [UnlinkedExpr.references].
   forEachPartsWithTypedDeclaration,
+
+  /// Pop the top 2 values from the stack, compute `v1 >>> v2`, and push the
+  /// result back onto the stack.
+  bitShiftRightLogical,
 }
 
 /// Unlinked summary information about an import declaration.
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
index 8727ef2..79f9c9a 100644
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -517,6 +517,8 @@
       operations.add(UnlinkedExprOperation.bitOr);
     } else if (operator == TokenType.GT_GT) {
       operations.add(UnlinkedExprOperation.bitShiftRight);
+    } else if (operator == TokenType.GT_GT_GT) {
+      operations.add(UnlinkedExprOperation.bitShiftRightLogical);
     } else if (operator == TokenType.LT_LT) {
       operations.add(UnlinkedExprOperation.bitShiftLeft);
     } else if (operator == TokenType.PLUS) {
diff --git a/pkg/analyzer/test/src/summary/expr_builder_test.dart b/pkg/analyzer/test/src/summary/expr_builder_test.dart
index 00979aa..d2c9611 100644
--- a/pkg/analyzer/test/src/summary/expr_builder_test.dart
+++ b/pkg/analyzer/test/src/summary/expr_builder_test.dart
@@ -24,6 +24,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ExprBuilderTest);
+    defineReflectiveTests(ExprBuilderWithConstantUpdateTest);
     defineReflectiveTests(TokensToStringTest);
   });
 }
@@ -768,6 +769,18 @@
 }
 
 @reflectiveTest
+class ExprBuilderWithConstantUpdateTest extends ResynthesizeTestStrategyTwoPhase
+    with ExprBuilderTestHelpers {
+  @override
+  ExperimentStatus get experimentStatus =>
+      new ExperimentStatus.fromStrings([EnableString.constant_update_2018]);
+
+  void test_bitShiftRightLogical() {
+    checkSimpleExpression('0 >>> 1');
+  }
+}
+
+@reflectiveTest
 class TokensToStringTest {
   void test_empty_list_no_space() {
     // This is an interesting test case because "[]" is scanned as a single
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index f594ee2..e4043ad 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -805,6 +805,19 @@
     return findVariable(variableName, failIfAbsent: true);
   }
 
+  test_constExpr_binary_bitShiftRightLogical() {
+    experimentStatus = ExperimentStatus(constant_update_2018: true);
+    UnlinkedVariable variable = serializeVariableText('const v = 1 >>> 2;');
+    assertUnlinkedConst(variable.initializer.bodyExpr, '1 >>> 2', operators: [
+      UnlinkedExprOperation.pushInt,
+      UnlinkedExprOperation.pushInt,
+      UnlinkedExprOperation.bitShiftRightLogical
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
   test_apiSignature() {
     List<int> signature1;
     List<int> signature2;
@@ -11632,7 +11645,8 @@
     var errorListener = AnalysisErrorListener.NULL_LISTENER;
     var reader = new CharSequenceReader(sourceText);
     var stringSource = new StringSource(sourceText, null);
-    var scanner = new Scanner(stringSource, reader, errorListener);
+    var scanner = new Scanner(stringSource, reader, errorListener)
+      ..enableGtGtGt = true;
     var startToken = scanner.tokenize();
     var parser = new Parser(stringSource, errorListener)
       ..enableNonNullable = experimentStatus.non_nullable;
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index eed8b58..566c62c 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -41,7 +41,8 @@
   experimentStatus ??= ExperimentStatus();
   CharSequenceReader reader = new CharSequenceReader(text);
   Scanner scanner =
-      new Scanner(null, reader, AnalysisErrorListener.NULL_LISTENER);
+      new Scanner(null, reader, AnalysisErrorListener.NULL_LISTENER)
+        ..enableGtGtGt = experimentStatus.constant_update_2018;
   Token token = scanner.tokenize();
   Parser parser = new Parser(
       NonExistingSource.unknown, AnalysisErrorListener.NULL_LISTENER)