[kernel] Add 'const' modifier to StaticInvocation.

This is to distinguish constant calls to an external constant factory.

This changes the binary format.
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index a9083de..25b64c9 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -393,6 +393,13 @@
   Arguments arguments;
 }
 
+// Constant call to an external constant factory.
+type ConstStaticInvocation extends Expression {
+  Byte tag = 18; // Note: tag is out of order.
+  MemberReference target;
+  Arguments arguments;
+}
+
 type ConstructorInvocation extends Expression {
   Byte tag = 31;
   ConstructorReference target;
diff --git a/pkg/kernel/lib/analyzer/ast_from_analyzer.dart b/pkg/kernel/lib/analyzer/ast_from_analyzer.dart
index a8ba188..f1d881b 100644
--- a/pkg/kernel/lib/analyzer/ast_from_analyzer.dart
+++ b/pkg/kernel/lib/analyzer/ast_from_analyzer.dart
@@ -1168,10 +1168,9 @@
           return new ast.InvalidExpression();
         }
         if (element.isExternal && element.isConst && element.isFactory) {
-          // TODO: Keep track of the fact that the call site was a 'const' call.
           ast.Member target = scope.resolveMethod(element);
           return target is ast.Procedure
-              ? new ast.StaticInvocation(target, arguments)
+              ? new ast.StaticInvocation(target, arguments, isConst: true)
               : new ast.InvalidExpression();
         } else if (element.isConst && !element.enclosingElement.isAbstract) {
           ast.Constructor target = scope.resolveConstructor(element);
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 86f7c37..db3e323 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -1180,16 +1180,20 @@
   }
 }
 
-/// Expression of form `foo(x)`.
+/// Expression of form `foo(x)`, or `const foo(x)` if the target is an
+/// external constant factory.
 ///
 /// The provided arguments might not match the parameters of the target.
 class StaticInvocation extends InvocationExpression {
   Procedure target;
   Arguments arguments;
 
+  /// True if this is a constant call to an external constant factory.
+  bool isConst;
+
   Name get name => target?.name;
 
-  StaticInvocation(this.target, this.arguments) {
+  StaticInvocation(this.target, this.arguments, {this.isConst: false}) {
     arguments?.parent = this;
   }
 
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index b91990f..9ad8f1e 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -478,7 +478,11 @@
         return new SuperMethodInvocation(
             readMemberReference(), readArguments());
       case Tag.StaticInvocation:
-        return new StaticInvocation(readMemberReference(), readArguments());
+        return new StaticInvocation(readMemberReference(), readArguments(),
+            isConst: false);
+      case Tag.ConstStaticInvocation:
+        return new StaticInvocation(readMemberReference(), readArguments(),
+            isConst: true);
       case Tag.ConstructorInvocation:
         return new ConstructorInvocation(readMemberReference(), readArguments(),
             isConst: false);
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index ea6b55c..7f89fa4 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -406,7 +406,7 @@
   }
 
   visitStaticInvocation(StaticInvocation node) {
-    writeByte(Tag.StaticInvocation);
+    writeByte(node.isConst ? Tag.ConstStaticInvocation : Tag.StaticInvocation);
     writeMemberReference(node.target);
     writeNode(node.arguments);
   }
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index ae3e2f7..90d6caf 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -19,6 +19,7 @@
   static const int SuperInitializer = 9;
   static const int RedirectingInitializer = 10;
 
+  static const int ConstStaticInvocation = 18;
   static const int InvalidExpression = 19;
   static const int VariableGet = 20;
   static const int VariableSet = 21;
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index f9ae1d8..996a017 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -609,6 +609,7 @@
   }
 
   visitStaticInvocation(StaticInvocation node) {
+    writeModifier(node.isConst, 'const');
     writeMemberReference(node.target);
     writeNode(node.arguments);
   }