blob: 6533926db8c3ae21ac166658104fdb39eea0491f [file] [log] [blame]
//===--- UnknownSyntax.cpp - Swift Unknown Syntax 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/TokenSyntax.h"
#include "swift/Syntax/UnknownSyntax.h"
using namespace swift;
using namespace swift::syntax;
#pragma mark - unknown-syntax Data
UnknownSyntaxData::UnknownSyntaxData(const RC<RawSyntax> Raw,
const SyntaxData *Parent,
const CursorIndex IndexInParent)
: SyntaxData(Raw, Parent, IndexInParent) {
assert(Raw->isUnknown());
for (auto RawChild : Raw->Layout) {
if (!RawChild->isToken()) {
CachedChildren.emplace_back(nullptr);
}
}
}
RC<UnknownSyntaxData> UnknownSyntaxData::make(RC<RawSyntax> Raw,
const SyntaxData *Parent,
CursorIndex IndexInParent) {
auto UnknownRaw = RawSyntax::make(SyntaxKind::Unknown, Raw->Layout,
Raw->Presence);
return RC<UnknownSyntaxData> {
new UnknownSyntaxData { UnknownRaw, Parent, IndexInParent }
};
}
#pragma mark - unknown-syntax API
UnknownSyntax::UnknownSyntax(const RC<SyntaxData> Root,
const UnknownSyntaxData *Data)
: Syntax(Root, Data) {}
size_t UnknownSyntax::getNumChildren() const {
size_t Count = 0;
for (auto Child : getRaw()->Layout) {
if (Child->isToken()) {
continue;
}
++Count;
}
return Count;
}
Syntax UnknownSyntax::getChild(const size_t N) const {
auto *MyData = getUnsafeData<UnknownSyntax>();
if (auto RealizedChild = MyData->CachedChildren[N]) {
return Syntax { Root, RealizedChild.get() };
}
assert(N < getNumChildren());
assert(N < getRaw()->Layout.size());
CursorIndex ChildLayoutIndex = 0;
for (size_t LayoutIndex = 0, Left = N;
LayoutIndex < getRaw()->Layout.size();
++LayoutIndex) {
auto Child = getRaw()->Layout[LayoutIndex];
if (Child->isToken()) {
continue;
}
ChildLayoutIndex = LayoutIndex;
if (Left == 0) {
break;
}
--Left;
}
auto RawChild = getRaw()->Layout[ChildLayoutIndex];
assert(RawChild->Kind != SyntaxKind::Token);
auto &ChildPtr = *reinterpret_cast<std::atomic<uintptr_t>*>(
MyData->CachedChildren.data() + N);
SyntaxData::realizeSyntaxNode<Syntax>(ChildPtr, RawChild, MyData,
ChildLayoutIndex);
return Syntax { Root, MyData->CachedChildren[N].get() };
}