// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library analyzer.src.generated.incremental_resolution_validator;

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';

/**
 * Validates that the [actual] and the [expected] units have the same structure
 * and resolution. Throws [IncrementalResolutionMismatch] otherwise.
 */
void assertSameResolution(CompilationUnit actual, CompilationUnit expected,
    {bool validateTypes: false}) {
  _SameResolutionValidator validator =
      new _SameResolutionValidator(validateTypes, expected);
  actual.accept(validator);
}

/**
 * This exception is thrown when a mismatch between actual and expected AST
 * or resolution is found.
 */
class IncrementalResolutionMismatch {
  final String message;
  IncrementalResolutionMismatch(this.message);
}

class _SameResolutionValidator implements AstVisitor {
  final bool validateTypes;
  AstNode other;

  _SameResolutionValidator(this.validateTypes, this.other);

  @override
  visitAdjacentStrings(AdjacentStrings node) {}

  @override
  visitAnnotation(Annotation node) {
    Annotation other = this.other;
    _visitNode(node.name, other.name);
    _visitNode(node.constructorName, other.constructorName);
    _visitNode(node.arguments, other.arguments);
    _verifyElement(node.element, other.element);
  }

  @override
  visitArgumentList(ArgumentList node) {
    ArgumentList other = this.other;
    _visitList(node.arguments, other.arguments);
  }

  @override
  visitAsExpression(AsExpression node) {
    AsExpression other = this.other;
    _visitExpression(node, other);
    _visitNode(node.expression, other.expression);
    _visitNode(node.type, other.type);
  }

  @override
  visitAssertStatement(AssertStatement node) {
    AssertStatement other = this.other;
    _visitNode(node.condition, other.condition);
    _visitNode(node.message, other.message);
  }

  @override
  visitAssignmentExpression(AssignmentExpression node) {
    AssignmentExpression other = this.other;
    _visitExpression(node, other);
    _verifyElement(node.staticElement, other.staticElement);
    _verifyElement(node.propagatedElement, other.propagatedElement);
    _visitNode(node.leftHandSide, other.leftHandSide);
    _visitNode(node.rightHandSide, other.rightHandSide);
  }

  @override
  visitAwaitExpression(AwaitExpression node) {
    AwaitExpression other = this.other;
    _visitExpression(node, other);
    _visitNode(node.expression, other.expression);
  }

  @override
  visitBinaryExpression(BinaryExpression node) {
    BinaryExpression other = this.other;
    _visitExpression(node, other);
    _verifyElement(node.staticElement, other.staticElement);
    _verifyElement(node.propagatedElement, other.propagatedElement);
    _visitNode(node.leftOperand, other.leftOperand);
    _visitNode(node.rightOperand, other.rightOperand);
  }

  @override
  visitBlock(Block node) {
    Block other = this.other;
    _visitList(node.statements, other.statements);
  }

  @override
  visitBlockFunctionBody(BlockFunctionBody node) {
    BlockFunctionBody other = this.other;
    _visitNode(node.block, other.block);
  }

  @override
  visitBooleanLiteral(BooleanLiteral node) {
    BooleanLiteral other = this.other;
    _visitExpression(node, other);
  }

  @override
  visitBreakStatement(BreakStatement node) {
    BreakStatement other = this.other;
    _visitNode(node.label, other.label);
  }

  @override
  visitCascadeExpression(CascadeExpression node) {
    CascadeExpression other = this.other;
    _visitExpression(node, other);
    _visitNode(node.target, other.target);
    _visitList(node.cascadeSections, other.cascadeSections);
  }

  @override
  visitCatchClause(CatchClause node) {
    CatchClause other = this.other;
    _visitNode(node.exceptionType, other.exceptionType);
    _visitNode(node.exceptionParameter, other.exceptionParameter);
    _visitNode(node.stackTraceParameter, other.stackTraceParameter);
    _visitNode(node.body, other.body);
  }

  @override
  visitClassDeclaration(ClassDeclaration node) {
    ClassDeclaration other = this.other;
    _visitDeclaration(node, other);
    _visitNode(node.name, other.name);
    _visitNode(node.typeParameters, other.typeParameters);
    _visitNode(node.extendsClause, other.extendsClause);
    _visitNode(node.implementsClause, other.implementsClause);
    _visitNode(node.withClause, other.withClause);
    _visitList(node.members, other.members);
  }

  @override
  visitClassTypeAlias(ClassTypeAlias node) {
    ClassTypeAlias other = this.other;
    _visitDeclaration(node, other);
    _visitNode(node.name, other.name);
    _visitNode(node.typeParameters, other.typeParameters);
    _visitNode(node.superclass, other.superclass);
    _visitNode(node.withClause, other.withClause);
  }

  @override
  visitComment(Comment node) {
    Comment other = this.other;
    _visitList(node.references, other.references);
  }

  @override
  visitCommentReference(CommentReference node) {
    CommentReference other = this.other;
    _visitNode(node.identifier, other.identifier);
  }

  @override
  visitCompilationUnit(CompilationUnit node) {
    CompilationUnit other = this.other;
    _verifyElement(node.element, other.element);
    _visitList(node.directives, other.directives);
    _visitList(node.declarations, other.declarations);
  }

  @override
  visitConditionalExpression(ConditionalExpression node) {
    ConditionalExpression other = this.other;
    _visitExpression(node, other);
    _visitNode(node.condition, other.condition);
    _visitNode(node.thenExpression, other.thenExpression);
    _visitNode(node.elseExpression, other.elseExpression);
  }

  @override
  visitConfiguration(Configuration node) {
    Configuration other = this.other;
    _visitNode(node.name, other.name);
    _visitNode(node.value, other.value);
    _visitNode(node.libraryUri, other.libraryUri);
  }

  @override
  visitConstructorDeclaration(ConstructorDeclaration node) {
    ConstructorDeclaration other = this.other;
    _visitDeclaration(node, other);
    _visitNode(node.returnType, other.returnType);
    _visitNode(node.name, other.name);
    _visitNode(node.parameters, other.parameters);
    _visitNode(node.redirectedConstructor, other.redirectedConstructor);
    _visitList(node.initializers, other.initializers);
  }

  @override
  visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
    ConstructorFieldInitializer other = this.other;
    _visitNode(node.fieldName, other.fieldName);
    _visitNode(node.expression, other.expression);
  }

  @override
  visitConstructorName(ConstructorName node) {
    ConstructorName other = this.other;
    _verifyElement(node.staticElement, other.staticElement);
    _visitNode(node.type, other.type);
    _visitNode(node.name, other.name);
  }

  @override
  visitContinueStatement(ContinueStatement node) {
    ContinueStatement other = this.other;
    _visitNode(node.label, other.label);
  }

  @override
  visitDeclaredIdentifier(DeclaredIdentifier node) {
    DeclaredIdentifier other = this.other;
    _visitNode(node.type, other.type);
    _visitNode(node.identifier, other.identifier);
  }

  @override
  visitDefaultFormalParameter(DefaultFormalParameter node) {
    DefaultFormalParameter other = this.other;
    _visitNode(node.parameter, other.parameter);
    _visitNode(node.defaultValue, other.defaultValue);
  }

  @override
  visitDoStatement(DoStatement node) {
    DoStatement other = this.other;
    _visitNode(node.condition, other.condition);
    _visitNode(node.body, other.body);
  }

  @override
  visitDottedName(DottedName node) {
    DottedName other = this.other;
    _visitList(node.components, other.components);
  }

  @override
  visitDoubleLiteral(DoubleLiteral node) {
    DoubleLiteral other = this.other;
    _visitExpression(node, other);
  }

  @override
  visitEmptyFunctionBody(EmptyFunctionBody node) {}

  @override
  visitEmptyStatement(EmptyStatement node) {}

  @override
  visitEnumConstantDeclaration(EnumConstantDeclaration node) {
    EnumConstantDeclaration other = this.other;
    _visitDeclaration(node, other);
    _visitNode(node.name, other.name);
  }

  @override
  visitEnumDeclaration(EnumDeclaration node) {
    EnumDeclaration other = this.other;
    _visitDeclaration(node, other);
    _visitNode(node.name, other.name);
    _visitList(node.constants, other.constants);
  }

  @override
  visitExportDirective(ExportDirective node) {
    ExportDirective other = this.other;
    _visitDirective(node, other);
  }

  @override
  visitExpressionFunctionBody(ExpressionFunctionBody node) {
    ExpressionFunctionBody other = this.other;
    _visitNode(node.expression, other.expression);
  }

  @override
  visitExpressionStatement(ExpressionStatement node) {
    ExpressionStatement other = this.other;
    _visitNode(node.expression, other.expression);
  }

  @override
  visitExtendsClause(ExtendsClause node) {
    ExtendsClause other = this.other;
    _visitNode(node.superclass, other.superclass);
  }

  @override
  visitFieldDeclaration(FieldDeclaration node) {
    FieldDeclaration other = this.other;
    _visitDeclaration(node, other);
    _visitNode(node.fields, other.fields);
  }

  @override
  visitFieldFormalParameter(FieldFormalParameter node) {
    FieldFormalParameter other = this.other;
    _visitNormalFormalParameter(node, other);
    _visitNode(node.type, other.type);
    _visitNode(node.parameters, other.parameters);
  }

  @override
  visitForEachStatement(ForEachStatement node) {
    ForEachStatement other = this.other;
    _visitNode(node.identifier, other.identifier);
    _visitNode(node.loopVariable, other.loopVariable);
    _visitNode(node.iterable, other.iterable);
  }

  @override
  visitFormalParameterList(FormalParameterList node) {
    FormalParameterList other = this.other;
    _visitList(node.parameters, other.parameters);
  }

  @override
  visitForStatement(ForStatement node) {
    ForStatement other = this.other;
    _visitNode(node.variables, other.variables);
    _visitNode(node.initialization, other.initialization);
    _visitNode(node.condition, other.condition);
    _visitList(node.updaters, other.updaters);
    _visitNode(node.body, other.body);
  }

  @override
  visitFunctionDeclaration(FunctionDeclaration node) {
    FunctionDeclaration other = this.other;
    _visitDeclaration(node, other);
    _visitNode(node.returnType, other.returnType);
    _visitNode(node.name, other.name);
    _visitNode(node.functionExpression, other.functionExpression);
  }

  @override
  visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
    FunctionDeclarationStatement other = this.other;
    _visitNode(node.functionDeclaration, other.functionDeclaration);
  }

  @override
  visitFunctionExpression(FunctionExpression node) {
    FunctionExpression other = this.other;
    _visitExpression(node, other);
    _verifyElement(node.element, other.element);
    _visitNode(node.parameters, other.parameters);
    _visitNode(node.body, other.body);
  }

  @override
  visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
    FunctionExpressionInvocation other = this.other;
    _visitExpression(node, other);
    _verifyElement(node.staticElement, other.staticElement);
    _verifyElement(node.propagatedElement, other.propagatedElement);
    _visitNode(node.function, other.function);
    _visitNode(node.argumentList, other.argumentList);
  }

  @override
  visitFunctionTypeAlias(FunctionTypeAlias node) {
    FunctionTypeAlias other = this.other;
    _visitDeclaration(node, other);
    _visitNode(node.returnType, other.returnType);
    _visitNode(node.name, other.name);
    _visitNode(node.typeParameters, other.typeParameters);
    _visitNode(node.parameters, other.parameters);
  }

  @override
  visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
    FunctionTypedFormalParameter other = this.other;
    _visitNormalFormalParameter(node, other);
    _visitNode(node.returnType, other.returnType);
    _visitNode(node.parameters, other.parameters);
  }

  @override
  visitHideCombinator(HideCombinator node) {
    HideCombinator other = this.other;
    _visitList(node.hiddenNames, other.hiddenNames);
  }

  @override
  visitIfStatement(IfStatement node) {
    IfStatement other = this.other;
    _visitNode(node.condition, other.condition);
    _visitNode(node.thenStatement, other.thenStatement);
    _visitNode(node.elseStatement, other.elseStatement);
  }

  @override
  visitImplementsClause(ImplementsClause node) {
    ImplementsClause other = this.other;
    _visitList(node.interfaces, other.interfaces);
  }

  @override
  visitImportDirective(ImportDirective node) {
    ImportDirective other = this.other;
    _visitDirective(node, other);
    _visitNode(node.prefix, other.prefix);
    _verifyElement(node.uriElement, other.uriElement);
  }

  @override
  visitIndexExpression(IndexExpression node) {
    IndexExpression other = this.other;
    _visitExpression(node, other);
    _verifyElement(node.staticElement, other.staticElement);
    _verifyElement(node.propagatedElement, other.propagatedElement);
    _visitNode(node.target, other.target);
    _visitNode(node.index, other.index);
  }

  @override
  visitInstanceCreationExpression(InstanceCreationExpression node) {
    InstanceCreationExpression other = this.other;
    _visitExpression(node, other);
    _verifyElement(node.staticElement, other.staticElement);
    _visitNode(node.constructorName, other.constructorName);
    _visitNode(node.argumentList, other.argumentList);
  }

  @override
  visitIntegerLiteral(IntegerLiteral node) {
    IntegerLiteral other = this.other;
    _visitExpression(node, other);
  }

  @override
  visitInterpolationExpression(InterpolationExpression node) {
    InterpolationExpression other = this.other;
    _visitNode(node.expression, other.expression);
  }

  @override
  visitInterpolationString(InterpolationString node) {}

  @override
  visitIsExpression(IsExpression node) {
    IsExpression other = this.other;
    _visitExpression(node, other);
    _visitNode(node.expression, other.expression);
    _visitNode(node.type, other.type);
  }

  @override
  visitLabel(Label node) {
    Label other = this.other;
    _visitNode(node.label, other.label);
  }

  @override
  visitLabeledStatement(LabeledStatement node) {
    LabeledStatement other = this.other;
    _visitList(node.labels, other.labels);
    _visitNode(node.statement, other.statement);
  }

  @override
  visitLibraryDirective(LibraryDirective node) {
    LibraryDirective other = this.other;
    _visitDirective(node, other);
    _visitNode(node.name, other.name);
  }

  @override
  visitLibraryIdentifier(LibraryIdentifier node) {
    LibraryIdentifier other = this.other;
    _visitList(node.components, other.components);
  }

  @override
  visitListLiteral(ListLiteral node) {
    ListLiteral other = this.other;
    _visitExpression(node, other);
    _visitList(node.elements, other.elements);
  }

  @override
  visitMapLiteral(MapLiteral node) {
    MapLiteral other = this.other;
    _visitExpression(node, other);
    _visitList(node.entries, other.entries);
  }

  @override
  visitMapLiteralEntry(MapLiteralEntry node) {
    MapLiteralEntry other = this.other;
    _visitNode(node.key, other.key);
    _visitNode(node.value, other.value);
  }

  @override
  visitMethodDeclaration(MethodDeclaration node) {
    MethodDeclaration other = this.other;
    _visitDeclaration(node, other);
    _visitNode(node.name, other.name);
    _visitNode(node.parameters, other.parameters);
    _visitNode(node.body, other.body);
  }

  @override
  visitMethodInvocation(MethodInvocation node) {
    MethodInvocation other = this.other;
    _visitNode(node.target, other.target);
    _visitNode(node.methodName, other.methodName);
    _visitNode(node.argumentList, other.argumentList);
  }

  @override
  visitNamedExpression(NamedExpression node) {
    NamedExpression other = this.other;
    _visitNode(node.name, other.name);
    _visitNode(node.expression, other.expression);
  }

  @override
  visitNativeClause(NativeClause node) {}

  @override
  visitNativeFunctionBody(NativeFunctionBody node) {}

  @override
  visitNullLiteral(NullLiteral node) {
    NullLiteral other = this.other;
    _visitExpression(node, other);
  }

  @override
  visitParenthesizedExpression(ParenthesizedExpression node) {
    ParenthesizedExpression other = this.other;
    _visitNode(node.expression, other.expression);
  }

  @override
  visitPartDirective(PartDirective node) {
    PartDirective other = this.other;
    _visitDirective(node, other);
  }

  @override
  visitPartOfDirective(PartOfDirective node) {
    PartOfDirective other = this.other;
    _visitDirective(node, other);
    _visitNode(node.libraryName, other.libraryName);
  }

  @override
  visitPostfixExpression(PostfixExpression node) {
    PostfixExpression other = this.other;
    _visitExpression(node, other);
    _verifyElement(node.staticElement, other.staticElement);
    _verifyElement(node.propagatedElement, other.propagatedElement);
    _visitNode(node.operand, other.operand);
  }

  @override
  visitPrefixedIdentifier(PrefixedIdentifier node) {
    PrefixedIdentifier other = this.other;
    _visitExpression(node, other);
    _visitNode(node.prefix, other.prefix);
    _visitNode(node.identifier, other.identifier);
  }

  @override
  visitPrefixExpression(PrefixExpression node) {
    PrefixExpression other = this.other;
    _visitExpression(node, other);
    _verifyElement(node.staticElement, other.staticElement);
    _verifyElement(node.propagatedElement, other.propagatedElement);
    _visitNode(node.operand, other.operand);
  }

  @override
  visitPropertyAccess(PropertyAccess node) {
    PropertyAccess other = this.other;
    _visitExpression(node, other);
    _visitNode(node.target, other.target);
    _visitNode(node.propertyName, other.propertyName);
  }

  @override
  visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
    RedirectingConstructorInvocation other = this.other;
    _verifyElement(node.staticElement, other.staticElement);
    _visitNode(node.constructorName, other.constructorName);
    _visitNode(node.argumentList, other.argumentList);
  }

  @override
  visitRethrowExpression(RethrowExpression node) {
    RethrowExpression other = this.other;
    _visitExpression(node, other);
  }

  @override
  visitReturnStatement(ReturnStatement node) {
    ReturnStatement other = this.other;
    _visitNode(node.expression, other.expression);
  }

  @override
  visitScriptTag(ScriptTag node) {}

  @override
  visitShowCombinator(ShowCombinator node) {
    ShowCombinator other = this.other;
    _visitList(node.shownNames, other.shownNames);
  }

  @override
  visitSimpleFormalParameter(SimpleFormalParameter node) {
    SimpleFormalParameter other = this.other;
    _visitNormalFormalParameter(node, other);
    _visitNode(node.type, other.type);
  }

  @override
  visitSimpleIdentifier(SimpleIdentifier node) {
    SimpleIdentifier other = this.other;
    _verifyElement(node.staticElement, other.staticElement);
    _verifyElement(node.propagatedElement, other.propagatedElement);
    _visitExpression(node, other);
  }

  @override
  visitSimpleStringLiteral(SimpleStringLiteral node) {}

  @override
  visitStringInterpolation(StringInterpolation node) {
    StringInterpolation other = this.other;
    _visitList(node.elements, other.elements);
  }

  @override
  visitSuperConstructorInvocation(SuperConstructorInvocation node) {
    SuperConstructorInvocation other = this.other;
    _verifyElement(node.staticElement, other.staticElement);
    _visitNode(node.constructorName, other.constructorName);
    _visitNode(node.argumentList, other.argumentList);
  }

  @override
  visitSuperExpression(SuperExpression node) {
    SuperExpression other = this.other;
    _visitExpression(node, other);
  }

  @override
  visitSwitchCase(SwitchCase node) {
    SwitchCase other = this.other;
    _visitList(node.labels, other.labels);
    _visitNode(node.expression, other.expression);
    _visitList(node.statements, other.statements);
  }

  @override
  visitSwitchDefault(SwitchDefault node) {
    SwitchDefault other = this.other;
    _visitList(node.statements, other.statements);
  }

  @override
  visitSwitchStatement(SwitchStatement node) {
    SwitchStatement other = this.other;
    _visitNode(node.expression, other.expression);
    _visitList(node.members, other.members);
  }

  @override
  visitSymbolLiteral(SymbolLiteral node) {}

  @override
  visitThisExpression(ThisExpression node) {
    ThisExpression other = this.other;
    _visitExpression(node, other);
  }

  @override
  visitThrowExpression(ThrowExpression node) {
    ThrowExpression other = this.other;
    _visitNode(node.expression, other.expression);
  }

  @override
  visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
    TopLevelVariableDeclaration other = this.other;
    _visitNode(node.variables, other.variables);
  }

  @override
  visitTryStatement(TryStatement node) {
    TryStatement other = this.other;
    _visitNode(node.body, other.body);
    _visitList(node.catchClauses, other.catchClauses);
    _visitNode(node.finallyBlock, other.finallyBlock);
  }

  @override
  visitTypeArgumentList(TypeArgumentList node) {
    TypeArgumentList other = this.other;
    _visitList(node.arguments, other.arguments);
  }

  @override
  visitTypeName(TypeName node) {
    TypeName other = this.other;
    _verifyType(node.type, other.type);
    _visitNode(node.name, node.name);
    _visitNode(node.typeArguments, other.typeArguments);
  }

  @override
  visitTypeParameter(TypeParameter node) {
    TypeParameter other = this.other;
    _visitNode(node.name, other.name);
    _visitNode(node.bound, other.bound);
  }

  @override
  visitTypeParameterList(TypeParameterList node) {
    TypeParameterList other = this.other;
    _visitList(node.typeParameters, other.typeParameters);
  }

  @override
  visitVariableDeclaration(VariableDeclaration node) {
    VariableDeclaration other = this.other;
    _visitDeclaration(node, other);
    _visitNode(node.name, other.name);
    _visitNode(node.initializer, other.initializer);
  }

  @override
  visitVariableDeclarationList(VariableDeclarationList node) {
    VariableDeclarationList other = this.other;
    _visitNode(node.type, other.type);
    _visitList(node.variables, other.variables);
  }

  @override
  visitVariableDeclarationStatement(VariableDeclarationStatement node) {
    VariableDeclarationStatement other = this.other;
    _visitNode(node.variables, other.variables);
  }

  @override
  visitWhileStatement(WhileStatement node) {
    WhileStatement other = this.other;
    _visitNode(node.condition, other.condition);
    _visitNode(node.body, other.body);
  }

  @override
  visitWithClause(WithClause node) {
    WithClause other = this.other;
    _visitList(node.mixinTypes, other.mixinTypes);
  }

  @override
  visitYieldStatement(YieldStatement node) {
    YieldStatement other = this.other;
    _visitNode(node.expression, other.expression);
  }

  void _assertNode(AstNode a, AstNode b) {
    _expectEquals(a.offset, b.offset);
    _expectEquals(a.length, b.length);
  }

  void _expectEquals(actual, expected) {
    if (actual != expected) {
      String message = '';
      message += 'Expected: $expected\n';
      message += '  Actual: $actual\n';
      _fail(message);
    }
  }

  void _expectIsNull(obj) {
    if (obj != null) {
      String message = '';
      message += 'Expected: null\n';
      message += '  Actual: $obj\n';
      _fail(message);
    }
  }

  void _expectLength(List actualList, int expected) {
    String message = '';
    message += 'Expected length: $expected\n';
    if (actualList == null) {
      message += 'but null found.';
      _fail(message);
    }
    int actual = actualList.length;
    if (actual != expected) {
      message += 'but $actual found\n';
      message += 'in $actualList';
      _fail(message);
    }
  }

  void _fail(String message) {
    throw new IncrementalResolutionMismatch(message);
  }

  void _verifyElement(Element a, Element b) {
    if (a is Member && b is Member) {
      a = (a as Member).baseElement;
      b = (b as Member).baseElement;
    }
    String locationA = _getElementLocationWithoutUri(a);
    String locationB = _getElementLocationWithoutUri(b);
    if (locationA != locationB) {
      int offset = other.offset;
      _fail('[$offset]\nExpected: $b ($locationB)\n  Actual: $a ($locationA)');
    }
    if (a == null && b == null) {
      return;
    }
    if (a.nameOffset != b.nameOffset) {
      _fail('Expected: ${b.nameOffset}\n  Actual: ${a.nameOffset}');
    }
    if (a is LocalElement && b is LocalElement) {
      if (a.visibleRange != b.visibleRange) {
        _fail('Expected: ${b.visibleRange}\nActual: ${a.visibleRange}');
      }
    }
  }

  void _verifyType(DartType a, DartType b) {
    if (!validateTypes) {
      return;
    }
    if (a != b) {
      int offset = other.offset;
      _fail('[$offset]\nExpected: $b\n  Actual: $a');
    }
  }

  void _visitAnnotatedNode(AnnotatedNode node, AnnotatedNode other) {
    _visitNode(node.documentationComment, other.documentationComment);
    _visitList(node.metadata, other.metadata);
  }

  _visitDeclaration(Declaration node, Declaration other) {
    _verifyElement(node.element, other.element);
    _visitAnnotatedNode(node, other);
  }

  _visitDirective(Directive node, Directive other) {
    _verifyElement(node.element, other.element);
    _visitAnnotatedNode(node, other);
  }

  void _visitExpression(Expression a, Expression b) {
//    print('[${a.offset}] |$a| vs. [${b.offset}] |$b|');
    _verifyType(a.staticType, b.staticType);
    _verifyType(a.propagatedType, b.propagatedType);
    _verifyElement(a.staticParameterElement, b.staticParameterElement);
    _verifyElement(a.propagatedParameterElement, b.propagatedParameterElement);
    _assertNode(a, b);
  }

  void _visitList(NodeList nodeList, NodeList otherList) {
    int length = nodeList.length;
    _expectLength(otherList, length);
    for (int i = 0; i < length; i++) {
      _visitNode(nodeList[i], otherList[i]);
    }
  }

  void _visitNode(AstNode node, AstNode other) {
    if (node == null) {
      _expectIsNull(other);
    } else {
      this.other = other;
      _assertNode(node, other);
      node.accept(this);
    }
  }

  void _visitNormalFormalParameter(
      NormalFormalParameter node, NormalFormalParameter other) {
    _verifyElement(node.element, other.element);
    _visitNode(node.documentationComment, other.documentationComment);
    _visitList(node.metadata, other.metadata);
    _visitNode(node.identifier, other.identifier);
  }

  /**
   * Returns an URI scheme independent version of the [element] location.
   */
  static String _getElementLocationWithoutUri(Element element) {
    if (element == null) {
      return '<null>';
    }
    if (element is UriReferencedElementImpl) {
      return '<ignored>';
    }
    ElementLocation location = element.location;
    List<String> components = location.components;
    String uriPrefix = '';
    Element unit = element is CompilationUnitElement
        ? element
        : element.getAncestor((e) => e is CompilationUnitElement);
    if (unit != null) {
      String libComponent = components[0];
      String unitComponent = components[1];
      components = components.sublist(2);
      uriPrefix = _getShortElementLocationUri(libComponent) +
          ':' +
          _getShortElementLocationUri(unitComponent);
    } else {
      String libComponent = components[0];
      components = components.sublist(1);
      uriPrefix = _getShortElementLocationUri(libComponent);
    }
    return uriPrefix + ':' + components.join(':');
  }

  /**
   * Returns a "short" version of the given [uri].
   *
   * For example:
   *     /User/me/project/lib/my_lib.dart -> my_lib.dart
   *     package:project/my_lib.dart      -> my_lib.dart
   */
  static String _getShortElementLocationUri(String uri) {
    int index = uri.lastIndexOf('/');
    if (index == -1) {
      return uri;
    }
    return uri.substring(index + 1);
  }
}
