//===--- SyntaxData.cpp - Swift Syntax Data Implementation ----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/Syntax/SyntaxData.h"

using namespace swift;
using namespace swift::syntax;

RC<SyntaxData> SyntaxData::make(RC<RawSyntax> Raw,
                                const SyntaxData *Parent,
                                CursorIndex IndexInParent) {
  auto size = totalSizeToAlloc<AtomicCache<SyntaxData>>(Raw->getNumChildren());
  void *data = ::operator new(size);
  return RC<SyntaxData>{new (data) SyntaxData(Raw, Parent, IndexInParent)};
}

bool SyntaxData::isType() const {
  return Raw->isType();
}

bool SyntaxData::isStmt() const {
  return Raw->isStmt();
}

bool SyntaxData::isDecl() const {
  return Raw->isDecl();
}

bool SyntaxData::isExpr() const {
  return Raw->isExpr();
}

bool SyntaxData::isPattern() const {
  return Raw->isPattern();
}

bool SyntaxData::isUnknown() const {
  return Raw->isUnknown();
}

void SyntaxData::dump(llvm::raw_ostream &OS) const {
  Raw->dump(OS, 0);
  OS << '\n';
}

void SyntaxData::dump() const { dump(llvm::errs()); }

RC<SyntaxData> SyntaxData::getPreviousNode() const {
  if (size_t N = getIndexInParent()) {
    if (hasParent()) {
      for (size_t I = N - 1; ; I--) {
        if (auto C = getParent()->getChild(I)) {
          if (C->getRaw()->isPresent() && C->getFirstToken())
            return C;
        }
        if (I == 0)
          break;
      }
    }
  }
  return hasParent() ? Parent->getPreviousNode() : nullptr;
}

RC<SyntaxData> SyntaxData::getNextNode() const {
  if (hasParent()) {
    for (size_t I = getIndexInParent() + 1, N = Parent->getNumChildren();
         I != N; I++) {
      if (auto C = getParent()->getChild(I)) {
        if (C->getRaw()->isPresent() && C->getFirstToken())
          return C;
      }
    }
    return Parent->getNextNode();
  }
  return nullptr;
}

RC<SyntaxData> SyntaxData::getFirstToken() const {
  if (getRaw()->isMissing())
    return nullptr;
  if (getRaw()->isToken()) {
    // Get a reference counted version of this
    assert(hasParent() && "The syntax tree should not conisist only of the root");
    return getParent()->getChild(getIndexInParent());
  }

  for (size_t I = 0, E = getNumChildren(); I < E; ++I) {
    if (auto Child = getChild(I)) {
      if (Child->getRaw()->isMissing())
        continue;
      if (Child->getRaw()->isToken()) {
        return Child;
      } else if (auto Token = Child->getFirstToken()) {
        return Token;
      }
    }
  }
  return nullptr;
}

RC<SyntaxData> SyntaxData::getLastToken() const {
  if (getRaw()->isMissing())
    return nullptr;
  if (getRaw()->isToken()) {
    // Get a reference counted version of this
    assert(hasParent() && "The syntax tree should not conisist only of the root");
    return getParent()->getChild(getIndexInParent());
  }
  for (size_t I = getNumChildren(); I != 0; --I) {
    if (auto Child = getChild(I - 1)) {
      if (Child->getRaw()->isMissing())
        continue;
      if (Child->getRaw()->isToken()) {
        return Child;
      } else if (auto Token = Child->getLastToken()) {
        return Token;
      }
    }
  }
  return nullptr;
}

AbsolutePosition SyntaxData::getAbsolutePositionBeforeLeadingTrivia() const {
  if (PositionCache.hasValue())
    return *PositionCache;
  if (auto P = getPreviousNode()) {
    auto Result = P->getAbsolutePositionBeforeLeadingTrivia();
    P->getRaw()->accumulateAbsolutePosition(Result);
    // FIXME: avoid using const_cast.
    const_cast<SyntaxData*>(this)->PositionCache = Result;
  } else {
    const_cast<SyntaxData*>(this)->PositionCache = AbsolutePosition();
  }
  return *PositionCache;
}

AbsolutePosition SyntaxData::getAbsolutePosition() const {
  auto Result = getAbsolutePositionBeforeLeadingTrivia();
  getRaw()->accumulateLeadingTrivia(Result);
  return Result;
}

AbsolutePosition SyntaxData::getAbsoluteEndPositionAfterTrailingTrivia() const {
  if (auto N = getNextNode()) {
    return N->getAbsolutePositionBeforeLeadingTrivia();
  } else {
    auto Result = getAbsolutePositionBeforeLeadingTrivia();
    getRaw()->accumulateAbsolutePosition(Result);
    return Result;
  }
}
