[kernel] Add ability to (de)serialize ConstructorInvocation
Change-Id: Ia25e1800c820c63a7e48818860ed3110de5473ea
Reviewed-on: https://dart-review.googlesource.com/c/90384
Reviewed-by: Daniel Hillerström <hillerstrom@google.com>
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index e6f6503..226f774 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -109,6 +109,12 @@
String visitDirectMethodInvocation(DirectMethodInvocation _) {
return "invoke-direct-method";
}
+
+ String visitConstructorInvocation(ConstructorInvocation expression) {
+ return expression.isConst
+ ? "invoke-const-constructor"
+ : "invoke-constructor";
+ }
}
TextSerializer<InvalidExpression> invalidExpressionSerializer = new Wrapped(
@@ -664,6 +670,37 @@
tuple.first, tuple.second.getReference(), tuple.third);
}
+TextSerializer<ConstructorInvocation> constructorInvocationSerializer =
+ new Wrapped(
+ unwrapConstructorInvocation,
+ wrapConstructorInvocation,
+ new Tuple2Serializer(
+ const CanonicalNameSerializer(), argumentsSerializer));
+
+Tuple2<CanonicalName, Arguments> unwrapConstructorInvocation(
+ ConstructorInvocation expression) {
+ return new Tuple2(
+ expression.targetReference.canonicalName, expression.arguments);
+}
+
+ConstructorInvocation wrapConstructorInvocation(
+ Tuple2<CanonicalName, Arguments> tuple) {
+ return new ConstructorInvocation.byReference(
+ tuple.first.getReference(), tuple.second,
+ isConst: false);
+}
+
+TextSerializer<ConstructorInvocation> constConstructorInvocationSerializer =
+ new Wrapped(unwrapConstructorInvocation, wrapConstConstructorInvocation,
+ Tuple2Serializer(const CanonicalNameSerializer(), argumentsSerializer));
+
+ConstructorInvocation wrapConstConstructorInvocation(
+ Tuple2<CanonicalName, Arguments> tuple) {
+ return new ConstructorInvocation.byReference(
+ tuple.first.getReference(), tuple.second,
+ isConst: true);
+}
+
Case<Expression> expressionSerializer =
new Case.uninitialized(const ExpressionTagger());
@@ -877,6 +914,8 @@
"invoke-static",
"invoke-const-static",
"invoke-direct-method",
+ "invoke-constructor",
+ "invoke-const-constructor",
]);
expressionSerializer.serializers.addAll([
stringLiteralSerializer,
@@ -920,6 +959,8 @@
staticInvocationSerializer,
constStaticInvocationSerializer,
directMethodInvocationSerializer,
+ constructorInvocationSerializer,
+ constConstructorInvocationSerializer,
]);
dartTypeSerializer.tags.addAll([
"invalid",
diff --git a/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart b/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
index 0976525..34f572b 100644
--- a/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
+++ b/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
@@ -256,6 +256,49 @@
new DeserializationEnvironment(null)..add("x^0", x),
component.root));
}(),
+ () {
+ Constructor constructor =
+ new Constructor(new FunctionNode(null), name: new Name("foo"));
+ Class klass =
+ new Class(name: "A", constructors: <Constructor>[constructor]);
+ Library library = new Library(
+ new Uri(scheme: "package", path: "foo/bar.dart"),
+ classes: <Class>[klass]);
+ Component component = new Component(libraries: <Library>[library]);
+ component.computeCanonicalNames();
+ return new TestCase(
+ name: "/* suppose A {A.foo();} */ new A()",
+ node: new ConstructorInvocation.byReference(
+ constructor.reference, new Arguments([])),
+ expectation: ""
+ "(invoke-constructor"
+ " \"package:foo/bar.dart::A::@constructors::foo\""
+ " () () ())",
+ serializationState: new SerializationState(null),
+ deserializationState: new DeserializationState(null, component.root));
+ }(),
+ () {
+ Constructor constructor = new Constructor(new FunctionNode(null),
+ name: new Name("foo"), isConst: true);
+ Class klass =
+ new Class(name: "A", constructors: <Constructor>[constructor]);
+ Library library = new Library(
+ new Uri(scheme: "package", path: "foo/bar.dart"),
+ classes: <Class>[klass]);
+ Component component = new Component(libraries: <Library>[library]);
+ component.computeCanonicalNames();
+ return new TestCase(
+ name: "/* suppose A {const A.foo();} */ const A()",
+ node: new ConstructorInvocation.byReference(
+ constructor.reference, new Arguments([]),
+ isConst: true),
+ expectation: ""
+ "(invoke-const-constructor"
+ " \"package:foo/bar.dart::A::@constructors::foo\""
+ " () () ())",
+ serializationState: new SerializationState(null),
+ deserializationState: new DeserializationState(null, component.root));
+ }(),
];
for (TestCase testCase in tests) {
String roundTripInput =