// Copyright (c) 2018, 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.

part of 'serialization.dart';

/// Visitor that ascribes an index to all [ir.TreeNode]s that potentially
/// needed for serialization and deserialization.
class _TreeNodeIndexerVisitor extends ir.Visitor<void> {
  int _currentIndex = 0;
  final Map<int, ir.TreeNode> _indexToNodeMap;
  final Map<ir.TreeNode, int> _nodeToIndexMap;

  _TreeNodeIndexerVisitor(this._indexToNodeMap, this._nodeToIndexMap);

  void registerNode(ir.TreeNode node) {
    _indexToNodeMap[_currentIndex] = node;
    _nodeToIndexMap[node] = _currentIndex;
    _currentIndex++;
  }

  @override
  void defaultTreeNode(ir.TreeNode node) {
    node.visitChildren(this);
  }

  @override
  void visitFunctionExpression(ir.FunctionExpression node) {
    registerNode(node);
    super.visitFunctionExpression(node);
  }

  @override
  void visitFunctionDeclaration(ir.FunctionDeclaration node) {
    registerNode(node);
    super.visitFunctionDeclaration(node);
  }

  @override
  void visitBlock(ir.Block node) {
    registerNode(node);
    super.visitBlock(node);
  }

  @override
  void visitVariableDeclaration(ir.VariableDeclaration node) {
    if (node.parent is! ir.FunctionDeclaration) {
      registerNode(node);
    }
    super.visitVariableDeclaration(node);
  }

  @override
  void visitSwitchStatement(ir.SwitchStatement node) {
    registerNode(node);
    super.visitSwitchStatement(node);
  }

  @override
  void visitForStatement(ir.ForStatement node) {
    registerNode(node);
    super.visitForStatement(node);
  }

  @override
  void visitForInStatement(ir.ForInStatement node) {
    registerNode(node);
    super.visitForInStatement(node);
  }

  @override
  void visitWhileStatement(ir.WhileStatement node) {
    registerNode(node);
    super.visitWhileStatement(node);
  }

  @override
  void visitDoStatement(ir.DoStatement node) {
    registerNode(node);
    super.visitDoStatement(node);
  }

  @override
  void visitBreakStatement(ir.BreakStatement node) {
    registerNode(node);
    super.visitBreakStatement(node);
  }

  @override
  void visitListLiteral(ir.ListLiteral node) {
    registerNode(node);
    super.visitListLiteral(node);
  }

  @override
  void visitSetLiteral(ir.SetLiteral node) {
    registerNode(node);
    super.visitSetLiteral(node);
  }

  @override
  void visitMapLiteral(ir.MapLiteral node) {
    registerNode(node);
    super.visitMapLiteral(node);
  }

  @override
  void visitPropertyGet(ir.PropertyGet node) {
    registerNode(node);
    super.visitPropertyGet(node);
  }

  @override
  void visitPropertySet(ir.PropertySet node) {
    registerNode(node);
    super.visitPropertySet(node);
  }

  @override
  void visitMethodInvocation(ir.MethodInvocation node) {
    registerNode(node);
    super.visitMethodInvocation(node);
  }

  @override
  void visitDirectPropertyGet(ir.DirectPropertyGet node) {
    registerNode(node);
    super.visitDirectPropertyGet(node);
  }

  @override
  void visitDirectPropertySet(ir.DirectPropertySet node) {
    registerNode(node);
    super.visitDirectPropertySet(node);
  }

  @override
  void visitDirectMethodInvocation(ir.DirectMethodInvocation node) {
    registerNode(node);
    super.visitDirectMethodInvocation(node);
  }

  @override
  void visitStaticInvocation(ir.StaticInvocation node) {
    registerNode(node);
    super.visitStaticInvocation(node);
  }

  @override
  void visitLabeledStatement(ir.LabeledStatement node) {
    registerNode(node);
    super.visitLabeledStatement(node);
  }

  @override
  void visitSwitchCase(ir.SwitchCase node) {
    registerNode(node);
    super.visitSwitchCase(node);
  }

  @override
  void visitContinueSwitchStatement(ir.ContinueSwitchStatement node) {
    registerNode(node);
    super.visitContinueSwitchStatement(node);
  }

  @override
  void visitConstructorInvocation(ir.ConstructorInvocation node) {
    registerNode(node);
    super.visitConstructorInvocation(node);
  }

  @override
  void visitVariableGet(ir.VariableGet node) {
    registerNode(node);
    super.visitVariableGet(node);
  }

  @override
  void visitInstantiation(ir.Instantiation node) {
    registerNode(node);
    super.visitInstantiation(node);
  }

  @override
  void visitSuperMethodInvocation(ir.SuperMethodInvocation node) {
    registerNode(node);
    super.visitSuperMethodInvocation(node);
  }

  @override
  void visitSuperPropertyGet(ir.SuperPropertyGet node) {
    registerNode(node);
    super.visitSuperPropertyGet(node);
  }

  @override
  void visitConstantExpression(ir.ConstantExpression node) {
    registerNode(node);
    super.visitConstantExpression(node);
  }
}

/// Visitor that ascribes an index to all [ir.Constant]s that we potentially
/// need to reference for serialization and deserialization.
///
/// Currently this is only list, map, and set constants, which are used as
/// allocation identities in the global inference.
class _ConstantNodeIndexerVisitor implements ir.ConstantVisitor<void> {
  int _currentIndex = 0;
  final Map<int, ir.Constant> _indexToNodeMap = {};
  final Map<ir.Constant, int> _nodeToIndexMap = {};
  final Set<ir.Constant> _visitedNonindexedNodes = {};

  /// Returns `true` if node not already registered.
  bool _register(ir.Constant node) {
    int index = _nodeToIndexMap[node];
    if (index != null) return false;
    _indexToNodeMap[_currentIndex] = node;
    _nodeToIndexMap[node] = _currentIndex;
    _currentIndex++;
    return true;
  }

  int getIndex(ir.Constant node) {
    assert(_nodeToIndexMap.containsKey(node), "Constant without index: $node");
    return _nodeToIndexMap[node];
  }

  ir.Constant getConstant(int index) {
    assert(
        _indexToNodeMap.containsKey(index), "Index without constant: $index");
    return _indexToNodeMap[index];
  }

  @override
  void visitUnevaluatedConstant(ir.UnevaluatedConstant node) {}

  @override
  void visitTypeLiteralConstant(ir.TypeLiteralConstant node) {}

  @override
  void visitTearOffConstant(ir.TearOffConstant node) {}

  @override
  void visitPartialInstantiationConstant(ir.PartialInstantiationConstant node) {
    node.tearOffConstant.accept(this);
  }

  @override
  void visitInstanceConstant(ir.InstanceConstant node) {
    if (_visitedNonindexedNodes.add(node)) {
      node.fieldValues.forEach((_, ir.Constant value) {
        value.accept(this);
      });
    }
  }

  @override
  void visitSetConstant(ir.SetConstant node) {
    if (_register(node)) {
      for (ir.Constant element in node.entries) {
        element.accept(this);
      }
    }
  }

  @override
  void visitListConstant(ir.ListConstant node) {
    if (_register(node)) {
      for (ir.Constant element in node.entries) {
        element.accept(this);
      }
    }
  }

  @override
  void visitMapConstant(ir.MapConstant node) {
    if (_register(node)) {
      for (ir.ConstantMapEntry entry in node.entries) {
        entry.key.accept(this);
        entry.value.accept(this);
      }
    }
  }

  @override
  void visitSymbolConstant(ir.SymbolConstant node) {}

  @override
  void visitStringConstant(ir.StringConstant node) {}

  @override
  void visitDoubleConstant(ir.DoubleConstant node) {}

  @override
  void visitIntConstant(ir.IntConstant node) {}

  @override
  void visitBoolConstant(ir.BoolConstant node) {}

  @override
  void visitNullConstant(ir.NullConstant node) {}

  @override
  void defaultConstant(ir.Constant node) {
    throw new UnimplementedError(
        "Unexpected constant: $node (${node.runtimeType})");
  }
}
