[kernel] Implement serialization round-trip check for expressions
Change-Id: Ibf3766f5325a9bf0b1016232319e0b308eca188c
Reviewed-on: https://dart-review.googlesource.com/c/88442
Reviewed-by: Kevin Millikin <kmillikin@google.com>
diff --git a/pkg/kernel/lib/transformations/round_trip_verifier.dart b/pkg/kernel/lib/transformations/round_trip_verifier.dart
index 00c0fa0..6949ddc 100644
--- a/pkg/kernel/lib/transformations/round_trip_verifier.dart
+++ b/pkg/kernel/lib/transformations/round_trip_verifier.dart
@@ -4,8 +4,19 @@
import '../ast.dart';
+import '../text/serializer_combinators.dart' show TextSerializer;
+
+import '../text/text_reader.dart' show TextIterator;
+
+import '../text/text_serializer.dart'
+ show expressionSerializer, initializeSerializers;
+
import '../visitor.dart' show Visitor;
+const Uri noUri = null;
+
+const int noOffset = -1;
+
abstract class RoundTripFailure {
/// [Uri] of the file containing the expression that produced an error during
/// the round trip.
@@ -19,25 +30,81 @@
}
class RoundTripSerializationFailure extends RoundTripFailure {
- RoundTripSerializationFailure(Uri uri, int offset) : super(uri, offset);
+ final String message;
+
+ RoundTripSerializationFailure(this.message, Uri uri, int offset)
+ : super(uri, offset);
}
class RoundTripDeserializationFailure extends RoundTripFailure {
- RoundTripDeserializationFailure(Uri uri, int offset) : super(uri, offset);
+ final String message;
+
+ RoundTripDeserializationFailure(this.message, Uri uri, int offset)
+ : super(uri, offset);
}
class RoundTripMismatchFailure extends RoundTripFailure {
- RoundTripMismatchFailure(Uri uri, int offset) : super(uri, offset);
+ final String initial;
+ final String serialized;
+
+ RoundTripMismatchFailure(this.initial, this.serialized, Uri uri, int offset)
+ : super(uri, offset);
}
class RoundTripVerifier implements Visitor<void> {
/// List of errors produced during round trips on the visited nodes.
final List<RoundTripFailure> errors = <RoundTripFailure>[];
- RoundTripVerifier();
+ RoundTripVerifier() {
+ initializeSerializers();
+ }
+
+ T readNode<T extends Node>(
+ String input, TextSerializer<T> serializer, Uri uri, int offset) {
+ TextIterator stream = new TextIterator(input, 0);
+ stream.moveNext();
+ T result;
+ try {
+ result = serializer.readFrom(stream);
+ } catch (exception) {
+ errors.add(new RoundTripDeserializationFailure(
+ exception.toString(), uri, offset));
+ }
+ if (stream.moveNext()) {
+ errors.add(new RoundTripDeserializationFailure(
+ "unexpected trailing text", uri, offset));
+ }
+ return result;
+ }
+
+ String writeNode<T extends Node>(
+ T node, TextSerializer<T> serializer, Uri uri, int offset) {
+ StringBuffer buffer = new StringBuffer();
+ try {
+ serializer.writeTo(buffer, node);
+ } catch (exception) {
+ errors.add(
+ new RoundTripSerializationFailure(exception.toString(), uri, offset));
+ }
+ return buffer.toString();
+ }
void makeExpressionRoundTrip(Expression node) {
- throw new UnimplementedError("makeExpressionRoundTrip");
+ Uri uri = node.location.file;
+ int offset = node.fileOffset;
+
+ String initial = writeNode(node, expressionSerializer, uri, offset);
+
+ // Do the round trip.
+ Expression deserialized =
+ readNode(initial, expressionSerializer, uri, offset);
+ String serialized =
+ writeNode(deserialized, expressionSerializer, uri, offset);
+
+ if (initial != serialized) {
+ errors
+ .add(new RoundTripMismatchFailure(initial, serialized, uri, offset));
+ }
}
void makeDartTypeRoundTrip(DartType node) {