Support for ForPartsWithExpression in binary format.

Change-Id: I69b47c6f21a2923731c91ba4d5edf8394b96408f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/179680
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index cb191c0..6a9b1ed 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -86,7 +86,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 119;
+  static const int DATA_VERSION = 120;
 
   /// The length of the list returned by [_computeDeclaredVariablesSignature].
   static const int _declaredVariablesSignatureLength = 4;
diff --git a/pkg/analyzer/lib/src/summary2/apply_resolution.dart b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
index e254ae4..f1094c6 100644
--- a/pkg/analyzer/lib/src/summary2/apply_resolution.dart
+++ b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
@@ -528,6 +528,15 @@
   }
 
   @override
+  void visitForPartsWithExpression(ForPartsWithExpression node) {
+    _expectMarker(MarkerTag.ForPartsWithExpression_initialization);
+    node.initialization?.accept(this);
+    _expectMarker(MarkerTag.ForPartsWithExpression_forParts);
+    _forParts(node);
+    _expectMarker(MarkerTag.ForPartsWithExpression_end);
+  }
+
+  @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     _assertNoLocalElements();
 
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 3bc726f..6313f8e 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -94,6 +94,8 @@
         return _readForElement();
       case Tag.ForPartsWithDeclarations:
         return _readForPartsWithDeclarations();
+      case Tag.ForPartsWithExpression:
+        return _readForPartsWithExpression();
       case Tag.FieldFormalParameter:
         return _readFieldFormalParameter();
       case Tag.FormalParameterList:
@@ -857,6 +859,19 @@
     );
   }
 
+  ForPartsWithExpression _readForPartsWithExpression() {
+    var initialization = _readOptionalNode() as Expression;
+    var condition = _readOptionalNode() as Expression;
+    var updaters = _readNodeList<Expression>();
+    return astFactory.forPartsWithExpression(
+      condition: condition,
+      initialization: initialization,
+      leftSeparator: Tokens.SEMICOLON,
+      rightSeparator: Tokens.SEMICOLON,
+      updaters: updaters,
+    );
+  }
+
   FunctionDeclaration _readFunctionDeclaration() {
     var flags = _readByte();
     var codeOffset = _readInformativeUint30();
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
index cf220f2..bcda462 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
@@ -131,6 +131,9 @@
   ForPartsWithDeclarations_variables,
   ForPartsWithDeclarations_forParts,
   ForPartsWithDeclarations_end,
+  ForPartsWithExpression_initialization,
+  ForPartsWithExpression_forParts,
+  ForPartsWithExpression_end,
   FunctionDeclaration_functionExpression,
   FunctionDeclaration_returnType,
   FunctionDeclaration_namedCompilationUnitMember,
@@ -365,6 +368,7 @@
   static const int ForEachPartsWithDeclaration = 89;
   static const int ForElement = 88;
   static const int ForPartsWithDeclarations = 91;
+  static const int ForPartsWithExpression = 99;
   static const int FormalParameterList = 17;
   static const int FunctionDeclaration = 18;
   static const int FunctionDeclaration_getter = 57;
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 6f7f8a9..c805bbd 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -752,6 +752,16 @@
   }
 
   @override
+  void visitForPartsWithExpression(ForPartsWithExpression node) {
+    _writeByte(Tag.ForPartsWithExpression);
+    _writeMarker(MarkerTag.ForPartsWithExpression_initialization);
+    _writeOptionalNode(node.initialization);
+    _writeMarker(MarkerTag.ForPartsWithExpression_forParts);
+    _storeForParts(node);
+    _writeMarker(MarkerTag.ForPartsWithExpression_end);
+  }
+
+  @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     var indexTag = Tag.FunctionDeclaration;
     if (node.isGetter) {
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index f459e36..4b043ca 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -20,6 +20,13 @@
 /// and analysis finishes without exceptions.
 @reflectiveTest
 class InvalidCodeTest extends PubPackageResolutionTest {
+  test_const_ForPartsWithExpression() async {
+    await _assertCanBeAnalyzed(r'''
+@A([for (;;) 0])
+void f() {}
+''');
+  }
+
   /// This code results in a method with the empty name, and the default
   /// constructor, which also has the empty name. The `Map` in `f` initializer
   /// references the empty name.