[vm] Implement reading of parameter annotations from kernel

Fixes https://github.com/dart-lang/sdk/issues/33207

Change-Id: I201d262bb913c342b705a607b0d88ba345e759e0
Reviewed-on: https://dart-review.googlesource.com/63644
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index ff130e9..bb21e9e 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -8892,6 +8892,7 @@
     }
 
     // Read ith variable declaration.
+    intptr_t param_kernel_offset = reader_.offset();
     VariableDeclarationHelper helper(this);
     helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer);
     param_descriptor.SetAt(entry_start + Parser::kParameterIsFinalOffset,
@@ -8910,13 +8911,37 @@
                              Object::null_instance());
     }
 
-    param_descriptor.SetAt(entry_start + Parser::kParameterMetadataOffset,
-                           /* Issue(28434): Missing parameter metadata. */
-                           Object::null_instance());
+    if (FLAG_enable_mirrors && (helper.annotation_count_ > 0)) {
+      AlternativeReadingScope alt(&reader_, param_kernel_offset);
+      VariableDeclarationHelper helper(this);
+      helper.ReadUntilExcluding(VariableDeclarationHelper::kAnnotations);
+      Object& metadata = Object::ZoneHandle(Z, BuildAnnotations());
+      param_descriptor.SetAt(entry_start + Parser::kParameterMetadataOffset,
+                             metadata);
+    } else {
+      param_descriptor.SetAt(entry_start + Parser::kParameterMetadataOffset,
+                             Object::null_instance());
+    }
   }
   return param_descriptor.raw();
 }
 
+RawObject* StreamingFlowGraphBuilder::BuildAnnotations() {
+  ASSERT(active_class() != NULL);
+  intptr_t list_length = ReadListLength();  // read list length.
+  const Array& metadata_values =
+      Array::Handle(Z, Array::New(list_length, H.allocation_space()));
+  Instance& value = Instance::Handle(Z);
+  for (intptr_t i = 0; i < list_length; ++i) {
+    // this will (potentially) read the expression, but reset the position.
+    value = constant_evaluator_.EvaluateExpression(ReaderOffset());
+    SkipExpression();  // read (actual) initializer.
+    metadata_values.SetAt(i, value);
+  }
+
+  return metadata_values.raw();
+}
+
 RawObject* StreamingFlowGraphBuilder::EvaluateMetadata(intptr_t kernel_offset) {
   SetOffset(kernel_offset);
   const Tag tag = PeekTag();
@@ -8939,18 +8964,7 @@
     FATAL("No support for metadata on this type of kernel node\n");
   }
 
-  intptr_t list_length = ReadListLength();  // read list length.
-  const Array& metadata_values =
-      Array::Handle(Z, Array::New(list_length, H.allocation_space()));
-  Instance& value = Instance::Handle(Z);
-  for (intptr_t i = 0; i < list_length; ++i) {
-    // this will (potentially) read the expression, but reset the position.
-    value = constant_evaluator_.EvaluateExpression(ReaderOffset());
-    SkipExpression();  // read (actual) initializer.
-    metadata_values.SetAt(i, value);
-  }
-
-  return metadata_values.raw();
+  return BuildAnnotations();
 }
 
 void StreamingFlowGraphBuilder::CollectTokenPositionsFor(
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index f5619fd..b27d20e 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -414,6 +414,7 @@
 
   Fragment BuildStatementAt(intptr_t kernel_offset);
   RawObject* BuildParameterDescriptor(intptr_t kernel_offset);
+  RawObject* BuildAnnotations();
   RawObject* EvaluateMetadata(intptr_t kernel_offset);
   void CollectTokenPositionsFor(
       intptr_t script_index,
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index e461ae5..0811a4e 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -2096,10 +2096,14 @@
     Script& script = Script::Handle(Z, function.script());
     helper.InitFromScript(script);
 
+    const Class& owner_class = Class::Handle(Z, function.Owner());
+    ActiveClass active_class;
+    ActiveClassScope active_class_scope(&active_class, &owner_class);
+
     StreamingFlowGraphBuilder streaming_flow_graph_builder(
         &helper, Script::Handle(Z, function.script()), Z,
         ExternalTypedData::Handle(Z, function.KernelData()),
-        function.KernelDataProgramOffset(), /* active_class = */ NULL);
+        function.KernelDataProgramOffset(), &active_class);
     return streaming_flow_graph_builder.BuildParameterDescriptor(
         function.kernel_offset());
   } else {
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 5f1cf87..ac65dec 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -801,7 +801,10 @@
       if (++next_read_ == field) return;
       /* Falls through */
     case kAnnotations:
-      helper_->SkipListOfExpressions();  // read annotations.
+      annotation_count_ = helper_->ReadListLength();  // read list length.
+      for (intptr_t i = 0; i < annotation_count_; ++i) {
+        helper_->SkipExpression();  // read ith expression.
+      }
       if (++next_read_ == field) return;
       /* Falls through */
     case kFlags:
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index a3db997..342a8de 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -325,7 +325,7 @@
   };
 
   explicit VariableDeclarationHelper(KernelReaderHelper* helper)
-      : helper_(helper), next_read_(kPosition) {}
+      : annotation_count_(0), helper_(helper), next_read_(kPosition) {}
 
   void ReadUntilIncluding(Field field) {
     ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@@ -348,6 +348,7 @@
   TokenPosition equals_position_;
   uint8_t flags_;
   StringIndex name_index_;
+  intptr_t annotation_count_;
 
  private:
   KernelReaderHelper* helper_;
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index 6ea3848..6dffcc5 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -161,8 +161,6 @@
 mirrors/native_class_test: SkipByDesign # Imports dart:html
 mirrors/operator_test: CompileTimeError # Issue 31402 (Invocation arguments)
 mirrors/other_declarations_location_test: RuntimeError # Issue 33325 (no source positions for type parameters).
-mirrors/parameter_annotation_mirror_test: RuntimeError
-mirrors/parameter_metadata_test: RuntimeError
 mirrors/parameter_of_mixin_app_constructor_test: RuntimeError # Issue 31402 (Invocation arguments)
 mirrors/private_symbol_test: RuntimeError # Issue 33326 - CFE/kernel invalid typedef substitution
 mirrors/private_types_test: RuntimeError # Issue 33326 - CFE/kernel invalid typedef substitution