#include "LuaParser/Ast/LuaSyntaxNode.h"
#include "LuaParser/Ast/LuaSyntaxTree.h"
#include "LuaParser/Lexer/LuaTokenTypeDetail.h"
#include "Util/Utf8.h"
LuaSyntaxNode::LuaSyntaxNode(std::size_t index)
: _index(index) {
}
TextRange LuaSyntaxNode::GetTextRange(const LuaSyntaxTree &t) const {
if (IsToken(t)) {
return t.GetTokenRange(_index);
} else if (IsNull(t)) {
return TextRange(0, 0);
}
auto start = t.GetStartOffset(_index);
auto end = t.GetEndOffset(_index);
if (end >= start) {
return TextRange(start, end - start + 1);
}
return TextRange(start, 0);
}
std::size_t LuaSyntaxNode::GetStartLine(const LuaSyntaxTree &t) const {
return t.GetFile().GetLine(t.GetStartOffset(_index));
}
std::size_t LuaSyntaxNode::GetStartCol(const LuaSyntaxTree &t) const {
return t.GetFile().GetColumn(t.GetStartOffset(_index));
}
std::size_t LuaSyntaxNode::GetEndLine(const LuaSyntaxTree &t) const {
return t.GetFile().GetLine(t.GetEndOffset(_index));
}
std::size_t LuaSyntaxNode::GetEndCol(const LuaSyntaxTree &t) const {
return t.GetFile().GetColumn(t.GetEndOffset(_index));
}
std::string_view LuaSyntaxNode::GetText(const LuaSyntaxTree &t) const {
return t.GetFile().Slice(GetTextRange(t));
}
std::size_t LuaSyntaxNode::GetUtf8Length(const LuaSyntaxTree &t) const {
auto text = GetText(t);
return utf8::Utf8nLen(text.data(), text.size());
}
bool LuaSyntaxNode::IsNode(const LuaSyntaxTree &t) const {
return t.IsNode(_index);
}
LuaSyntaxNodeKind LuaSyntaxNode::GetSyntaxKind(const LuaSyntaxTree &t) const {
return t.GetNodeKind(_index);
}
LuaTokenKind LuaSyntaxNode::GetTokenKind(const LuaSyntaxTree &t) const {
return t.GetTokenKind(_index);
}
LuaSyntaxNode LuaSyntaxNode::GetParent(const LuaSyntaxTree &t) const {
return LuaSyntaxNode(t.GetParent(_index));
}
LuaSyntaxNode LuaSyntaxNode::GetNextSibling(const LuaSyntaxTree &t) const {
return LuaSyntaxNode(t.GetNextSibling(_index));
}
LuaSyntaxNode LuaSyntaxNode::GetPrevSibling(const LuaSyntaxTree &t) const {
return LuaSyntaxNode(t.GetPrevSibling(_index));
}
LuaSyntaxNode LuaSyntaxNode::GetFirstChild(const LuaSyntaxTree &t) const {
return LuaSyntaxNode(t.GetFirstChild(_index));
}
LuaSyntaxNode LuaSyntaxNode::GetLastChild(const LuaSyntaxTree &t) const {
return LuaSyntaxNode(t.GetLastChild(_index));
}
void LuaSyntaxNode::ToNext(const LuaSyntaxTree &t) {
_index = t.GetNextSibling(_index);
}
void LuaSyntaxNode::ToPrev(const LuaSyntaxTree &t) {
_index = t.GetPrevSibling(_index);
}
bool LuaSyntaxNode::IsNull(const LuaSyntaxTree &t) const {
return _index == 0;
}
std::vector<LuaSyntaxNode> LuaSyntaxNode::GetDescendants(const LuaSyntaxTree &t) const {
std::vector<LuaSyntaxNode> results;
if (t.GetFirstChild(_index) == 0) {
return results;
}
int accessIndex = -1;
LuaSyntaxNode node = *this;
do {
if (node.IsNode(t)) {
for (auto child = node.GetFirstChild(t); !child.IsNull(t); child.ToNext(t)) {
results.emplace_back(child);
}
}
accessIndex++;
} while (accessIndex < static_cast<int>(results.size()));
return results;
}
std::vector<LuaSyntaxNode> LuaSyntaxNode::GetChildren(const LuaSyntaxTree &t) const {
std::vector<LuaSyntaxNode> results;
for (auto child = GetFirstChild(t); !child.IsNull(t); child.ToNext(t)) {
results.push_back(child);
}
return results;
}
bool LuaSyntaxNode::IsToken(const LuaSyntaxTree &t) const {
return t.IsToken(_index);
}
std::size_t LuaSyntaxNode::GetIndex() const {
return _index;
}
LuaSyntaxNode LuaSyntaxNode::GetChildSyntaxNode(LuaSyntaxNodeKind kind, const LuaSyntaxTree &t) const {
auto child = GetFirstChild(t);
for (; !child.IsNull(t); child.ToNext(t)) {
if (child.GetSyntaxKind(t) == kind) {
break;
}
}
return child;
}
LuaSyntaxNode LuaSyntaxNode::GetChildSyntaxNode(LuaSyntaxMultiKind kind, const LuaSyntaxTree &t) const {
auto child = GetFirstChild(t);
for (; !child.IsNull(t); child.ToNext(t)) {
if (detail::multi_match::Match(kind, child.GetSyntaxKind(t))) {
break;
}
}
return child;
}
LuaSyntaxNode LuaSyntaxNode::GetLastChildSyntaxNode(LuaSyntaxNodeKind kind, const LuaSyntaxTree &t) const {
auto child = GetLastChild(t);
for (; !child.IsNull(t); child.ToPrev(t)) {
if (child.GetSyntaxKind(t) == kind) {
break;
}
}
return child;
}
LuaSyntaxNode LuaSyntaxNode::GetLastChildSyntaxNode(LuaSyntaxMultiKind kind, const LuaSyntaxTree &t) const {
auto child = GetLastChild(t);
for (; !child.IsNull(t); child.ToPrev(t)) {
if (detail::multi_match::Match(kind, child.GetSyntaxKind(t))) {
break;
}
}
return child;
}
LuaSyntaxNode LuaSyntaxNode::GetChildToken(LuaTokenKind kind, const LuaSyntaxTree &t) const {
auto child = GetFirstChild(t);
for (; !child.IsNull(t); child.ToNext(t)) {
if (child.GetTokenKind(t) == kind) {
break;
}
}
return child;
}
LuaSyntaxNode LuaSyntaxNode::GetChildToken(std::function<bool(LuaTokenKind)> predicated, const LuaSyntaxTree &t) const {
auto child = GetFirstChild(t);
for (; !child.IsNull(t); child.ToNext(t)) {
if (predicated(child.GetTokenKind(t))) {
break;
}
}
return child;
}
std::vector<LuaSyntaxNode> LuaSyntaxNode::GetChildSyntaxNodes(LuaSyntaxNodeKind kind, const LuaSyntaxTree &t) const {
std::vector<LuaSyntaxNode> results;
auto child = GetFirstChild(t);
for (; !child.IsNull(t); child.ToNext(t)) {
if (child.GetSyntaxKind(t) == kind) {
results.push_back(child);
}
}
return results;
}
std::vector<LuaSyntaxNode> LuaSyntaxNode::GetChildSyntaxNodes(LuaSyntaxMultiKind kind, const LuaSyntaxTree &t) const {
std::vector<LuaSyntaxNode> results;
auto child = GetFirstChild(t);
for (; !child.IsNull(t); child.ToNext(t)) {
if (detail::multi_match::Match(kind, child.GetSyntaxKind(t))) {
results.push_back(child);
}
}
return results;
}
std::vector<LuaSyntaxNode> LuaSyntaxNode::GetChildTokens(LuaTokenKind kind, const LuaSyntaxTree &t) const {
std::vector<LuaSyntaxNode> results;
auto child = GetFirstChild(t);
for (; !child.IsNull(t); child.ToNext(t)) {
if (child.GetTokenKind(t) == kind) {
results.push_back(child);
}
}
return results;
}
bool LuaSyntaxNode::IsSingleLineNode(const LuaSyntaxTree &t) const {
if (_index == 0) {
return false;
}
return GetStartLine(t) == GetEndLine(t);
}
LuaSyntaxNode LuaSyntaxNode::GetNextToken(const LuaSyntaxTree &t) const {
if (_index == 0) {
return *this;
}
return LuaSyntaxNode(t.GetNextToken(_index));
}
LuaSyntaxNode LuaSyntaxNode::GetNextTokenSkipComment(const LuaSyntaxTree &t) const {
if (_index == 0) {
return *this;
}
auto nextIndex = t.GetNextToken(_index);
while (t.GetTokenKind(nextIndex) == TK_SHORT_COMMENT || t.GetTokenKind(nextIndex) == TK_LONG_COMMENT) {
nextIndex = t.GetNextToken(nextIndex);
}
return LuaSyntaxNode(nextIndex);
}
LuaSyntaxNode LuaSyntaxNode::GetPrevToken(const LuaSyntaxTree &t) const {
if (_index == 0) {
return *this;
}
return LuaSyntaxNode(t.GetPrevToken(_index));
}
LuaSyntaxNode LuaSyntaxNode::GetFirstToken(const LuaSyntaxTree &t) const {
if (_index == 0) {
return *this;
}
return LuaSyntaxNode(t.GetFirstToken(_index));
}
LuaSyntaxNode LuaSyntaxNode::GetLastToken(const LuaSyntaxTree &t) const {
if (_index == 0) {
return *this;
}
return LuaSyntaxNode(t.GetLastToken(_index));
}
std::size_t LuaSyntaxNode::GetFirstLineWidth(const LuaSyntaxTree &t) const {
auto text = GetText(t);
return utf8::Utf8nLenAtFirstLine(text.data(), text.size());
}
std::size_t LuaSyntaxNode::CountTokenChild(LuaTokenKind kind, const LuaSyntaxTree &t) {
auto count = 0;
for (auto child = GetFirstChild(t); !child.IsNull(t); child.ToNext(t)) {
if (child.GetTokenKind(t) == kind) {
count++;
}
}
return count;
}
std::size_t LuaSyntaxNode::CountNodeChild(LuaSyntaxNodeKind kind, const LuaSyntaxTree &t) {
auto count = 0;
for (auto child = GetFirstChild(t); !child.IsNull(t); child.ToNext(t)) {
if (child.GetSyntaxKind(t) == kind) {
count++;
}
}
return count;
}
bool LuaSyntaxNode::IsEmpty(const LuaSyntaxTree &t) const {
return t.GetFirstChild(_index) == 0;
}