More positions in dart2 constant evaluator

Use positions already available in for instance AsExpressions,
also adds new offsets in the kernel format to
SuperInitializer and RedirectingInitializer.

Bug: #33216
Change-Id: I542967ddc6ec782e6513d62fce038a49239e1622
Reviewed-on: https://dart-review.googlesource.com/63883
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index eff9f14..ad5e3f1 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -131,7 +131,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 8;
+  UInt32 formatVersion = 9;
   Library[] libraries;
   UriSource sourceMap;
   List<CanonicalName> canonicalNames;
@@ -406,6 +406,7 @@
 type SuperInitializer extends Initializer {
   Byte tag = 9;
   Byte isSynthetic;
+  FileOffset fileOffset;
   ConstructorReference target;
   Arguments arguments;
 }
@@ -413,6 +414,7 @@
 type RedirectingInitializer extends Initializer {
   Byte tag = 10;
   Byte isSynthetic;
+  FileOffset fileOffset;
   ConstructorReference target;
   Arguments arguments;
 }
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index c088723..5332ba5 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -1166,13 +1166,17 @@
         return new FieldInitializer.byReference(reference, value)
           ..isSynthetic = isSynthetic;
       case Tag.SuperInitializer:
+        int offset = readOffset();
         var reference = readMemberReference();
         var arguments = readArguments();
         return new SuperInitializer.byReference(reference, arguments)
-          ..isSynthetic = isSynthetic;
+          ..isSynthetic = isSynthetic
+          ..fileOffset = offset;
       case Tag.RedirectingInitializer:
+        int offset = readOffset();
         return new RedirectingInitializer.byReference(
-            readMemberReference(), readArguments());
+            readMemberReference(), readArguments())
+          ..fileOffset = offset;
       case Tag.LocalInitializer:
         return new LocalInitializer(readAndPushVariableDeclaration());
       case Tag.AssertInitializer:
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 84a6e59..b59903b 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -917,6 +917,7 @@
   void visitSuperInitializer(SuperInitializer node) {
     writeByte(Tag.SuperInitializer);
     writeByte(node.isSynthetic ? 1 : 0);
+    writeOffset(node.fileOffset);
     writeReference(node.targetReference);
     writeNode(node.arguments);
   }
@@ -925,6 +926,7 @@
   void visitRedirectingInitializer(RedirectingInitializer node) {
     writeByte(Tag.RedirectingInitializer);
     writeByte(node.isSynthetic ? 1 : 0);
+    writeOffset(node.fileOffset);
     writeReference(node.targetReference);
     writeNode(node.arguments);
   }
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 44eb262..69a2c8fd 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -135,7 +135,7 @@
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
   /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
-  static const int BinaryFormatVersion = 8;
+  static const int BinaryFormatVersion = 9;
 }
 
 abstract class ConstantTag {
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 70d956b..9770a26 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -361,7 +361,7 @@
 }
 
 void StreamingConstantEvaluator::EvaluateMethodInvocation() {
-  builder_->ReadPosition();  // read position.
+  TokenPosition position = builder_->ReadPosition();  // read position.
   // This method call wasn't cached, so receiver et al. isn't cached either.
   const Instance& receiver = Instance::Handle(
       Z,
@@ -380,7 +380,7 @@
   ASSERT(!function.IsNull());
 
   // Read arguments, run the method and canonicalize the result.
-  const Object& result = RunMethodCall(function, &receiver);
+  const Object& result = RunMethodCall(position, function, &receiver);
   result_ ^= result.raw();
   result_ = H.Canonicalize(result_);
 
@@ -388,7 +388,7 @@
 }
 
 void StreamingConstantEvaluator::EvaluateDirectMethodInvocation() {
-  builder_->ReadPosition();  // read position.
+  TokenPosition position = builder_->ReadPosition();  // read position.
 
   const Instance& receiver = Instance::Handle(
       Z,
@@ -401,7 +401,7 @@
       Z, H.LookupMethodByMember(kernel_name, H.DartProcedureName(kernel_name)));
 
   // Read arguments, run the method and canonicalize the result.
-  const Object& result = RunMethodCall(function, &receiver);
+  const Object& result = RunMethodCall(position, function, &receiver);
   result_ ^= result.raw();
   result_ = H.Canonicalize(result_);
 }
@@ -415,7 +415,7 @@
 }
 
 void StreamingConstantEvaluator::EvaluateSuperMethodInvocation() {
-  builder_->ReadPosition();  // read position.
+  TokenPosition position = builder_->ReadPosition();  // read position.
 
   const LocalVariable* this_variable = builder_->scopes()->this_variable;
   ASSERT(this_variable->IsConst());
@@ -434,7 +434,7 @@
   ASSERT(!function.IsNull());
 
   // Read arguments, run the method and canonicalize the result.
-  const Object& result = RunMethodCall(function, &receiver);
+  const Object& result = RunMethodCall(position, function, &receiver);
   result_ ^= result.raw();
   result_ = H.Canonicalize(result_);
 
@@ -442,7 +442,7 @@
 }
 
 void StreamingConstantEvaluator::EvaluateStaticInvocation() {
-  builder_->ReadPosition();  // read position.
+  TokenPosition position = builder_->ReadPosition();  // read position.
   NameIndex procedure_reference =
       builder_->ReadCanonicalNameReference();  // read procedure reference.
 
@@ -459,13 +459,13 @@
 
   // read positional and named parameters.
   const Object& result =
-      RunFunction(function, argument_count, NULL, type_arguments);
+      RunFunction(position, function, argument_count, NULL, type_arguments);
   result_ ^= result.raw();
   result_ = H.Canonicalize(result_);
 }
 
 void StreamingConstantEvaluator::EvaluateConstructorInvocationInternal() {
-  builder_->ReadPosition();  // read position.
+  TokenPosition position = builder_->ReadPosition();  // read position.
 
   NameIndex target = builder_->ReadCanonicalNameReference();  // read target.
   const Function& constructor =
@@ -506,8 +506,8 @@
   }
 
   // read positional and named parameters.
-  const Object& result = RunFunction(constructor, argument_count, receiver,
-                                     type_arguments_argument);
+  const Object& result = RunFunction(position, constructor, argument_count,
+                                     receiver, type_arguments_argument);
 
   if (constructor.IsFactory()) {
     // Factories return the new object.
@@ -547,14 +547,14 @@
 }
 
 void StreamingConstantEvaluator::EvaluateAsExpression() {
-  builder_->ReadPosition();
+  TokenPosition position = builder_->ReadPosition();
   const uint8_t flags = builder_->ReadFlags();
   const bool is_type_error = (flags & (1 << 0)) != 0;
 
   // Check that this AsExpression was inserted by the front-end.
   if (!is_type_error) {
     H.ReportError(
-        script_, TokenPosition::kNoSource,
+        script_, position,
         "explicit as operator is not permitted in constant expression");
   }
 
@@ -564,7 +564,7 @@
   if (!type.IsInstantiated() || type.IsMalformed()) {
     const String& type_str = String::Handle(type.UserVisibleName());
     H.ReportError(
-        script_, TokenPosition::kNoSource,
+        script_, position,
         "Not a constant expression: right hand side of an implicit "
         "as-expression is expected to be an instantiated type, got %s",
         type_str.ToCString());
@@ -579,9 +579,10 @@
         AbstractType::Handle(result_.GetType(Heap::kNew));
     const String& result_str = String::Handle(rtype.UserVisibleName());
     const String& type_str = String::Handle(type.UserVisibleName());
-    H.ReportError(script_, TokenPosition::kNoSource,
-                  "Not a constant expression: %s is not an instance of %s",
-                  result_str.ToCString(), type_str.ToCString());
+    H.ReportError(
+        script_, position,
+        "Not a constant expression: Type '%s' is not a subtype of type '%s'",
+        result_str.ToCString(), type_str.ToCString());
   }
 }
 
@@ -598,7 +599,7 @@
 }
 
 void StreamingConstantEvaluator::EvaluateStringConcatenation() {
-  builder_->ReadPosition();                      // read position.
+  TokenPosition position = builder_->ReadPosition();  // read position.
   intptr_t length = builder_->ReadListLength();  // read list length.
 
   bool all_string = true;
@@ -629,7 +630,7 @@
 
     // Run and canonicalize.
     const Object& result =
-        RunFunction(func, interpolate_arg, Array::null_array());
+        RunFunction(position, func, interpolate_arg, Array::null_array());
     result_ = H.Canonicalize(String::Cast(result));
   }
 }
@@ -808,6 +809,7 @@
 
 // This depends on being about to read the list of positionals on arguments.
 const Object& StreamingConstantEvaluator::RunFunction(
+    TokenPosition position,
     const Function& function,
     intptr_t argument_count,
     const Instance* receiver,
@@ -856,12 +858,14 @@
     arguments.SetAt(pos++, result_);
   }
 
-  return RunFunction(function, arguments, names);
+  return RunFunction(position, function, arguments, names);
 }
 
-const Object& StreamingConstantEvaluator::RunFunction(const Function& function,
-                                                      const Array& arguments,
-                                                      const Array& names) {
+const Object& StreamingConstantEvaluator::RunFunction(
+    const TokenPosition position,
+    const Function& function,
+    const Array& arguments,
+    const Array& names) {
   // We do not support generic methods yet.
   const int kTypeArgsLen = 0;
   const Array& args_descriptor = Array::Handle(
@@ -869,12 +873,14 @@
   const Object& result = Object::Handle(
       Z, DartEntry::InvokeFunction(function, arguments, args_descriptor));
   if (result.IsError()) {
-    H.ReportError(Error::Cast(result), "error evaluating constant constructor");
+    H.ReportError(Error::Cast(result), script_, position,
+                  "error evaluating constant constructor");
   }
   return result;
 }
 
 const Object& StreamingConstantEvaluator::RunMethodCall(
+    const TokenPosition position,
     const Function& function,
     const Instance* receiver) {
   intptr_t argument_count = builder_->ReadUInt();  // read arguments count.
@@ -884,7 +890,7 @@
   builder_->SkipListOfDartTypes();  // read list of types.
 
   // Run the method.
-  return RunFunction(function, argument_count, receiver, NULL);
+  return RunFunction(position, function, argument_count, receiver, NULL);
 }
 
 RawObject* StreamingConstantEvaluator::EvaluateConstConstructorCall(
@@ -1151,10 +1157,12 @@
       CalculateExpressionFingerprint();  // read value.
       return;
     case kSuperInitializer:
+      ReadPosition();                       // read position.
       CalculateCanonicalNameFingerprint();  // read target_reference
       CalculateArgumentsFingerprint();      // read arguments.
       return;
     case kRedirectingInitializer:
+      ReadPosition();                       // read position.
       CalculateCanonicalNameFingerprint();  // read target_reference
       CalculateArgumentsFingerprint();      // read arguments.
       return;
@@ -1976,7 +1984,7 @@
     intptr_t list_length = ReadListLength();  // read initializers list length.
     for (intptr_t i = 0; i < list_length; ++i) {
       Tag tag = ReadTag();
-      ReadByte();  // read isSynthetic flag.
+      bool isSynthetic = ReadBool();  // read isSynthetic flag.
       switch (tag) {
         case kInvalidInitializer:
           UNIMPLEMENTED();
@@ -1992,6 +2000,7 @@
           break;
         }
         case kSuperInitializer: {
+          TokenPosition position = ReadPosition();  // read position.
           NameIndex canonical_target =
               ReadCanonicalNameReference();  // read target_reference.
 
@@ -2011,13 +2020,14 @@
           const Function& target = Function::ZoneHandle(
               Z, H.LookupConstructorByKernelConstructor(
                      parent_klass, H.CanonicalNameString(canonical_target)));
-          instructions +=
-              StaticCall(TokenPosition::kNoSource, target, argument_count,
-                         argument_names, ICData::kStatic);
+          instructions += StaticCall(
+              isSynthetic ? TokenPosition::kNoSource : position, target,
+              argument_count, argument_names, ICData::kStatic);
           instructions += Drop();
           break;
         }
         case kRedirectingInitializer: {
+          TokenPosition position = ReadPosition();  // read position.
           NameIndex canonical_target =
               ReadCanonicalNameReference();  // read target_reference.
 
@@ -2034,9 +2044,9 @@
 
           const Function& target = Function::ZoneHandle(
               Z, H.LookupConstructorByKernelConstructor(canonical_target));
-          instructions +=
-              StaticCall(TokenPosition::kNoSource, target, argument_count,
-                         argument_names, ICData::kStatic);
+          instructions += StaticCall(
+              isSynthetic ? TokenPosition::kNoSource : position, target,
+              argument_count, argument_names, ICData::kStatic);
           instructions += Drop();
           break;
         }
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index b352dea..cc258c8 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -86,16 +86,19 @@
   void EvaluateGetStringLength(intptr_t expression_offset,
                                TokenPosition position);
 
-  const Object& RunFunction(const Function& function,
+  const Object& RunFunction(const TokenPosition position,
+                            const Function& function,
                             intptr_t argument_count,
                             const Instance* receiver,
                             const TypeArguments* type_args);
 
-  const Object& RunFunction(const Function& function,
+  const Object& RunFunction(const TokenPosition position,
+                            const Function& function,
                             const Array& arguments,
                             const Array& names);
 
-  const Object& RunMethodCall(const Function& function,
+  const Object& RunMethodCall(const TokenPosition position,
+                              const Function& function,
                               const Instance* receiver);
 
   RawObject* EvaluateConstConstructorCall(const Class& type_class,
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index ac65dec..99aa61f 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -1932,10 +1932,12 @@
       SkipExpression();              // read value.
       return;
     case kSuperInitializer:
+      ReadPosition();                // read position.
       SkipCanonicalNameReference();  // read target_reference.
       SkipArguments();               // read arguments.
       return;
     case kRedirectingInitializer:
+      ReadPosition();                // read position.
       SkipCanonicalNameReference();  // read target_reference.
       SkipArguments();               // read arguments.
       return;
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index faf3885..21f2c04 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -574,10 +574,12 @@
       VisitExpression();                     // read value.
       return;
     case kSuperInitializer:
+      helper_.ReadPosition();                // read position.
       helper_.SkipCanonicalNameReference();  // read target_reference.
       VisitArguments();                      // read arguments.
       return;
     case kRedirectingInitializer:
+      helper_.ReadPosition();                // read position.
       helper_.SkipCanonicalNameReference();  // read target_reference.
       VisitArguments();                      // read arguments.
       return;
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index c0a6799..58ae9ca 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -17,7 +17,7 @@
 // package:kernel/binary.md.
 
 static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
-static const uint32_t kBinaryFormatVersion = 8;
+static const uint32_t kBinaryFormatVersion = 9;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \