//===--- 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::make(RC Raw, const SyntaxData *Parent, CursorIndex IndexInParent) { auto size = totalSizeToAlloc>(Raw->getNumChildren()); void *data = ::operator new(size); return RC{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::getPreviousNode() const { if (size_t N = getIndexInParent()) { if (hasParent()) { for (size_t I = N - 1; ; I--) { if (auto C = getParent()->getChild(I)) { return C; } if (I == 0) break; } } } return hasParent() ? Parent->getPreviousNode() : nullptr; } RC SyntaxData::getNextNode() const { if (hasParent()) { for (size_t I = getIndexInParent() + 1, N = Parent->getNumChildren(); I != N; I++) { if (auto C = getParent()->getChild(I)) return C; } return Parent->getNextNode(); } return nullptr; } RC SyntaxData::getFirstToken() const { for (size_t I = 0, E = getNumChildren(); I < E; ++I) { if (auto Child = getChild(I)) { if (!Child->getRaw()->isMissing()) { return Child->getFirstToken(); } } } // Get a reference counted version of this assert(getRaw()->isToken() && "Leaf node that is no token?"); assert(hasParent() && "The syntax tree should not conisist only of the root"); return getParent()->getChild(getIndexInParent()); } 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(this)->PositionCache = Result; } else { const_cast(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; } }