[kernel] Implement serialization round-trip check for dart types

Change-Id: Ie97439e6f822eb1e94c17cc4a5f3c04f1f58a4bc
Reviewed-on: https://dart-review.googlesource.com/c/88444
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 6949ddc..9bac79f 100644
--- a/pkg/kernel/lib/transformations/round_trip_verifier.dart
+++ b/pkg/kernel/lib/transformations/round_trip_verifier.dart
@@ -9,7 +9,7 @@
 import '../text/text_reader.dart' show TextIterator;
 
 import '../text/text_serializer.dart'
-    show expressionSerializer, initializeSerializers;
+    show dartTypeSerializer, expressionSerializer, initializeSerializers;
 
 import '../visitor.dart' show Visitor;
 
@@ -55,10 +55,21 @@
   /// List of errors produced during round trips on the visited nodes.
   final List<RoundTripFailure> errors = <RoundTripFailure>[];
 
+  Uri lastSeenUri = noUri;
+
+  int lastSeenOffset = noOffset;
+
   RoundTripVerifier() {
     initializeSerializers();
   }
 
+  void storeLastSeenUriAndOffset(Node node) {
+    if (node is TreeNode && node.location != null) {
+      lastSeenUri = node.location.file;
+      lastSeenOffset = node.fileOffset;
+    }
+  }
+
   T readNode<T extends Node>(
       String input, TextSerializer<T> serializer, Uri uri, int offset) {
     TextIterator stream = new TextIterator(input, 0);
@@ -108,7 +119,20 @@
   }
 
   void makeDartTypeRoundTrip(DartType node) {
-    throw new UnimplementedError("makeDartTypeRoundTrip");
+    Uri uri = lastSeenUri;
+    int offset = lastSeenOffset;
+
+    String initial = writeNode(node, dartTypeSerializer, uri, offset);
+
+    // Do the round trip.
+    DartType deserialized = readNode(initial, dartTypeSerializer, uri, offset);
+    String serialized =
+        writeNode(deserialized, dartTypeSerializer, uri, offset);
+
+    if (initial != serialized) {
+      errors
+          .add(new RoundTripMismatchFailure(initial, serialized, uri, offset));
+    }
   }
 
   @override
@@ -168,638 +192,765 @@
 
   @override
   void visitNamedType(NamedType node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitSupertype(Supertype node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitName(Name node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitRedirectingFactoryConstructorReference(
       RedirectingFactoryConstructor node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitProcedureReference(Procedure node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitConstructorReference(Constructor node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitFieldReference(Field node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitTypeLiteralConstantReference(TypeLiteralConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitTearOffConstantReference(TearOffConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitPartialInstantiationConstantReference(
       PartialInstantiationConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitInstanceConstantReference(InstanceConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitListConstantReference(ListConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitMapConstantReference(MapConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitSymbolConstantReference(SymbolConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitStringConstantReference(StringConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitDoubleConstantReference(DoubleConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitIntConstantReference(IntConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitBoolConstantReference(BoolConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitNullConstantReference(NullConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitTypedefReference(Typedef node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitClassReference(Class node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitTypeLiteralConstant(TypeLiteralConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitTearOffConstant(TearOffConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitPartialInstantiationConstant(PartialInstantiationConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitInstanceConstant(InstanceConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitListConstant(ListConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitMapConstant(MapConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitSymbolConstant(SymbolConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitStringConstant(StringConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitDoubleConstant(DoubleConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitIntConstant(IntConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitBoolConstant(BoolConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitNullConstant(NullConstant node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitTypedefType(TypedefType node) {
+    storeLastSeenUriAndOffset(node);
     makeDartTypeRoundTrip(node);
   }
 
   @override
   void visitTypeParameterType(TypeParameterType node) {
+    storeLastSeenUriAndOffset(node);
     makeDartTypeRoundTrip(node);
   }
 
   @override
   void visitFunctionType(FunctionType node) {
+    storeLastSeenUriAndOffset(node);
     makeDartTypeRoundTrip(node);
   }
 
   @override
   void visitInterfaceType(InterfaceType node) {
+    storeLastSeenUriAndOffset(node);
     makeDartTypeRoundTrip(node);
   }
 
   @override
   void visitBottomType(BottomType node) {
+    storeLastSeenUriAndOffset(node);
     makeDartTypeRoundTrip(node);
   }
 
   @override
   void visitVoidType(VoidType node) {
+    storeLastSeenUriAndOffset(node);
     makeDartTypeRoundTrip(node);
   }
 
   @override
   void visitDynamicType(DynamicType node) {
+    storeLastSeenUriAndOffset(node);
     makeDartTypeRoundTrip(node);
   }
 
   @override
   void visitInvalidType(InvalidType node) {
+    storeLastSeenUriAndOffset(node);
     makeDartTypeRoundTrip(node);
   }
 
   @override
   void visitComponent(Component node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitMapEntry(MapEntry node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitCatch(Catch node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitSwitchCase(SwitchCase node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitNamedExpression(NamedExpression node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitArguments(Arguments node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitFunctionNode(FunctionNode node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitTypeParameter(TypeParameter node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitTypedef(Typedef node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitLibraryPart(LibraryPart node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitCombinator(Combinator node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitLibraryDependency(LibraryDependency node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitLibrary(Library node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitAssertInitializer(AssertInitializer node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitLocalInitializer(LocalInitializer node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitRedirectingInitializer(RedirectingInitializer node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitSuperInitializer(SuperInitializer node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitFieldInitializer(FieldInitializer node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitInvalidInitializer(InvalidInitializer node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitClass(Class node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitRedirectingFactoryConstructor(RedirectingFactoryConstructor node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitField(Field node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitProcedure(Procedure node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitConstructor(Constructor node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitVariableDeclaration(VariableDeclaration node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitYieldStatement(YieldStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitTryFinally(TryFinally node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitTryCatch(TryCatch node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitReturnStatement(ReturnStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitIfStatement(IfStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitContinueSwitchStatement(ContinueSwitchStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitSwitchStatement(SwitchStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitForInStatement(ForInStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitForStatement(ForStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitDoStatement(DoStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitWhileStatement(WhileStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitBreakStatement(BreakStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitLabeledStatement(LabeledStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitAssertStatement(AssertStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitEmptyStatement(EmptyStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitAssertBlock(AssertBlock node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitBlock(Block node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitExpressionStatement(ExpressionStatement node) {
+    storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
   }
 
   @override
   void visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitLoadLibrary(LoadLibrary node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitInstantiation(Instantiation node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitLet(Let node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitNullLiteral(NullLiteral node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitBoolLiteral(BoolLiteral node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitDoubleLiteral(DoubleLiteral node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitIntLiteral(IntLiteral node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitStringLiteral(StringLiteral node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitConstantExpression(ConstantExpression node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitFunctionExpression(FunctionExpression node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitAwaitExpression(AwaitExpression node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitMapLiteral(MapLiteral node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitSetLiteral(SetLiteral node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitListLiteral(ListLiteral node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitThrow(Throw node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitRethrow(Rethrow node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitThisExpression(ThisExpression node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitTypeLiteral(TypeLiteral node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitSymbolLiteral(SymbolLiteral node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitAsExpression(AsExpression node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitIsExpression(IsExpression node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitStringConcatenation(StringConcatenation node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitConditionalExpression(ConditionalExpression node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitLogicalExpression(LogicalExpression node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitNot(Not node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitConstructorInvocation(ConstructorInvocation node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitStaticInvocation(StaticInvocation node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitSuperMethodInvocation(SuperMethodInvocation node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitDirectMethodInvocation(DirectMethodInvocation node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitMethodInvocation(MethodInvocation node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitStaticSet(StaticSet node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitStaticGet(StaticGet node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitSuperPropertySet(SuperPropertySet node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitSuperPropertyGet(SuperPropertyGet node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitDirectPropertySet(DirectPropertySet node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitDirectPropertyGet(DirectPropertyGet node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitPropertySet(PropertySet node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitPropertyGet(PropertyGet node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitVariableSet(VariableSet node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitVariableGet(VariableGet node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 
   @override
   void visitInvalidExpression(InvalidExpression node) {
+    storeLastSeenUriAndOffset(node);
     makeExpressionRoundTrip(node);
   }
 }