[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);
}