Skip to content

[libSyntax] Reference count SyntaxData #36230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions include/swift/Syntax/Syntax.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ class Syntax {
friend struct SyntaxFactory;

protected:
SyntaxData Data;
RC<const SyntaxData> Data;

public:
explicit Syntax(const SyntaxData Data) : Data(Data) {}
explicit Syntax(const RC<const SyntaxData> &Data) : Data(Data) {}

virtual ~Syntax() {}

Expand All @@ -86,9 +86,7 @@ class Syntax {
}

/// Get the Data for this Syntax node.
const SyntaxData &getData() const {
return Data;
}
const RC<const SyntaxData> &getData() const { return Data; }

/// Cast this Syntax node to a more specific type, asserting it's of the
/// right kind.
Expand All @@ -113,7 +111,7 @@ class Syntax {

/// Returns the child index of this node in its parent,
/// if it has one, otherwise 0.
CursorIndex getIndexInParent() const { return getData().getIndexInParent(); }
CursorIndex getIndexInParent() const { return getData()->getIndexInParent(); }

/// Return the number of bytes this node takes when spelled out in the source
size_t getTextLength() const { return getRaw()->getTextLength(); }
Expand Down Expand Up @@ -157,8 +155,8 @@ class Syntax {
SWIFT_DEBUG_DUMP;

bool hasSameIdentityAs(const Syntax &Other) const {
return Data.getAbsoluteRaw().getNodeId() ==
Other.Data.getAbsoluteRaw().getNodeId();
return Data->getAbsoluteRaw().getNodeId() ==
Other.Data->getAbsoluteRaw().getNodeId();
}

static bool kindof(SyntaxKind Kind) {
Expand All @@ -180,23 +178,23 @@ class Syntax {

/// Get the offset at which the leading trivia of this node starts.
AbsoluteOffsetPosition getAbsolutePositionBeforeLeadingTrivia() const {
return Data.getAbsolutePositionBeforeLeadingTrivia();
return Data->getAbsolutePositionBeforeLeadingTrivia();
}

/// Get the offset at which the actual content (i.e. non-triva) of this node
/// starts.
AbsoluteOffsetPosition getAbsolutePositionAfterLeadingTrivia() const {
return Data.getAbsolutePositionAfterLeadingTrivia();
return Data->getAbsolutePositionAfterLeadingTrivia();
}

/// Get the offset at which the trailing trivia of this node starts.
AbsoluteOffsetPosition getAbsoluteEndPositionBeforeTrailingTrivia() const {
return Data.getAbsoluteEndPositionBeforeTrailingTrivia();
return Data->getAbsoluteEndPositionBeforeTrailingTrivia();
}

/// Get the offset at which the trailing trivia of this node starts.
AbsoluteOffsetPosition getAbsoluteEndPositionAfterTrailingTrivia() const {
return Data.getAbsoluteEndPositionAfterTrailingTrivia();
return Data->getAbsoluteEndPositionAfterTrailingTrivia();
}

// TODO: hasSameStructureAs ?
Expand Down
22 changes: 11 additions & 11 deletions include/swift/Syntax/SyntaxCollection.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ class SyntaxCollection : public Syntax {
friend class Syntax;

private:
static SyntaxData makeData(std::initializer_list<Element> &Elements,
const RC<SyntaxArena> &Arena) {
static RC<const SyntaxData> makeData(std::initializer_list<Element> &Elements,
const RC<SyntaxArena> &Arena) {
std::vector<const RawSyntax *> List;
List.reserve(Elements.size());
for (auto &Elt : Elements)
Expand All @@ -69,7 +69,7 @@ class SyntaxCollection : public Syntax {
}

public:
SyntaxCollection(const SyntaxData Data) : Syntax(Data) {}
SyntaxCollection(const RC<const SyntaxData> &Data) : Syntax(Data) {}

SyntaxCollection(std::initializer_list<Element> list):
SyntaxCollection(SyntaxCollection::makeData(list)) {}
Expand Down Expand Up @@ -105,7 +105,7 @@ class SyntaxCollection : public Syntax {
Element operator[](const size_t Index) const {
assert(Index < size());
assert(!empty());
return Element(*Data.getChild(Index));
return Element(Data->getChild(Index));
}

/// Return a new collection with the given element added to the end.
Expand All @@ -119,7 +119,7 @@ class SyntaxCollection : public Syntax {
auto Raw = RawSyntax::makeAndCalcLength(CollectionKind, NewLayout,
getRaw()->getPresence(),
getRaw()->getArena());
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
return SyntaxCollection<CollectionKind, Element>(Data->replacingSelf(Raw));
}

/// Return a new collection with an element removed from the end.
Expand All @@ -131,7 +131,7 @@ class SyntaxCollection : public Syntax {
auto Raw = RawSyntax::makeAndCalcLength(CollectionKind, NewLayout,
getRaw()->getPresence(),
getRaw()->getArena());
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
return SyntaxCollection<CollectionKind, Element>(Data->replacingSelf(Raw));
}

/// Return a new collection with the given element appended to the front.
Expand All @@ -144,7 +144,7 @@ class SyntaxCollection : public Syntax {
auto Raw = RawSyntax::makeAndCalcLength(CollectionKind, NewLayout,
getRaw()->getPresence(),
getRaw()->getArena());
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
return SyntaxCollection<CollectionKind, Element>(Data->replacingSelf(Raw));
}

/// Return a new collection with an element removed from the end.
Expand All @@ -156,7 +156,7 @@ class SyntaxCollection : public Syntax {
auto Raw = RawSyntax::makeAndCalcLength(CollectionKind, NewLayout,
getRaw()->getPresence(),
getRaw()->getArena());
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
return SyntaxCollection<CollectionKind, Element>(Data->replacingSelf(Raw));
}

/// Return a new collection with the Element inserted at index i.
Expand All @@ -177,7 +177,7 @@ class SyntaxCollection : public Syntax {
auto Raw = RawSyntax::makeAndCalcLength(CollectionKind, NewLayout,
getRaw()->getPresence(),
getRaw()->getArena());
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
return SyntaxCollection<CollectionKind, Element>(Data->replacingSelf(Raw));
}

/// Return a new collection with the element removed at index i.
Expand All @@ -190,14 +190,14 @@ class SyntaxCollection : public Syntax {
auto Raw = RawSyntax::makeAndCalcLength(CollectionKind, NewLayout,
getRaw()->getPresence(),
getRaw()->getArena());
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
return SyntaxCollection<CollectionKind, Element>(Data->replacingSelf(Raw));
}

/// Return an empty syntax collection of this type.
SyntaxCollection<CollectionKind, Element> cleared() const {
auto Raw = RawSyntax::makeAndCalcLength(
CollectionKind, {}, getRaw()->getPresence(), getRaw()->getArena());
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
return SyntaxCollection<CollectionKind, Element>(Data->replacingSelf(Raw));
}

static bool kindof(SyntaxKind Kind) {
Expand Down
59 changes: 19 additions & 40 deletions include/swift/Syntax/SyntaxData.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,39 +51,24 @@
namespace swift {
namespace syntax {

/// A reference counted box that can contain any type.
template <typename T>
class RefCountedBox final
: public llvm::ThreadSafeRefCountedBase<RefCountedBox<T>> {
public:
const T Data;

RefCountedBox(const T Data) : Data(Data) {}

static RC<RefCountedBox<T>> make(const T &Data) {
return RC<RefCountedBox<T>>{new RefCountedBox(Data)};
}
};

/// The class for holding parented syntax.
///
/// This structure should not contain significant public
/// API or internal modification API.
///
/// It is essentially a wrapper around \c AbsoluteRawSyntax that also keeps
/// track of the parent.
class SyntaxData {
class SyntaxData : public llvm::ThreadSafeRefCountedBase<SyntaxData> {
const AbsoluteRawSyntax AbsoluteRaw;
RC<RefCountedBox<SyntaxData>> Parent;
RC<const SyntaxData> Parent;

/// If this node is the root of a Syntax tree (i.e. \c Parent is \c nullptr ),
/// the arena in which this node's \c RawSyntax node has been allocated.
/// This keeps this \c RawSyntax nodes referenced by this tree alive.
RC<SyntaxArena> Arena;

/// Create a intermediate node with a parent.
SyntaxData(AbsoluteRawSyntax AbsoluteRaw,
const RC<RefCountedBox<SyntaxData>> &Parent)
SyntaxData(AbsoluteRawSyntax AbsoluteRaw, const RC<const SyntaxData> &Parent)
: AbsoluteRaw(AbsoluteRaw), Parent(Parent), Arena(nullptr) {}

/// Create a new root node
Expand All @@ -94,36 +79,36 @@ class SyntaxData {
public:
/// With a new \c RawSyntax node, create a new node from this one and
/// recursively rebuild the parental chain up to the root.
SyntaxData replacingSelf(const RawSyntax *NewRaw) const;
RC<const SyntaxData> replacingSelf(const RawSyntax *NewRaw) const;

/// Replace a child in the raw syntax and recursively rebuild the
/// parental chain up to the root.
template <typename CursorType>
SyntaxData replacingChild(const RawSyntax *RawChild,
CursorType ChildCursor) const {
RC<const SyntaxData> replacingChild(const RawSyntax *RawChild,
CursorType ChildCursor) const {
auto NewRaw = AbsoluteRaw.getRaw()->replacingChild(ChildCursor, RawChild);
return replacingSelf(NewRaw);
}

/// Get the node immediately before this current node that does contain a
/// non-missing token. Return \c None if we cannot find such node.
Optional<SyntaxData> getPreviousNode() const;
/// non-missing token. Return \c nullptr if we cannot find such node.
RC<const SyntaxData> getPreviousNode() const;

/// Get the node immediately after this current node that does contain a
/// non-missing token. Return \c None if we cannot find such node.
Optional<SyntaxData> getNextNode() const;
/// non-missing token. Return \c nullptr if we cannot find such node.
RC<const SyntaxData> getNextNode() const;

/// Get the first non-missing token node in this tree. Return \c None if
/// Get the first non-missing token node in this tree. Return \c nullptr if
/// this node does not contain non-missing tokens.
Optional<SyntaxData> getFirstToken() const;
RC<const SyntaxData> getFirstToken() const;

/// Get the last non-missing token node in this tree. Return \c None if
/// Get the last non-missing token node in this tree. Return \c nullptr if
/// this node does not contain non-missing tokens.
Optional<SyntaxData> getLastToken() const;
RC<const SyntaxData> getLastToken() const;

/// Make a new \c SyntaxData node for the tree's root.
static SyntaxData makeRoot(AbsoluteRawSyntax AbsoluteRaw) {
return SyntaxData(AbsoluteRaw);
static RC<const SyntaxData> makeRoot(AbsoluteRawSyntax AbsoluteRaw) {
return RC<const SyntaxData>(new SyntaxData(AbsoluteRaw));
}

const AbsoluteRawSyntax &getAbsoluteRaw() const { return AbsoluteRaw; }
Expand All @@ -135,13 +120,7 @@ class SyntaxData {
SyntaxKind getKind() const { return AbsoluteRaw.getRaw()->getKind(); }

/// Return the parent syntax if there is one.
Optional<SyntaxData> getParent() const {
if (Parent) {
return Parent->Data;
} else {
return None;
}
}
RC<const SyntaxData> getParent() const { return Parent; }

/// Returns true if this syntax node has a parent.
bool hasParent() const {
Expand All @@ -161,13 +140,13 @@ class SyntaxData {

/// Gets the child at the index specified by the provided cursor.
template <typename CursorType>
Optional<SyntaxData> getChild(CursorType Cursor) const {
RC<const SyntaxData> getChild(CursorType Cursor) const {
return getChild(
(AbsoluteSyntaxPosition::IndexInParentType)cursorIndex(Cursor));
}

/// Gets the child at the specified \p Index.
Optional<SyntaxData>
RC<const SyntaxData>
getChild(AbsoluteSyntaxPosition::IndexInParentType Index) const;

/// Get the offset at which the leading trivia of this node starts.
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Syntax/SyntaxNodes.h.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public:
};
% end

${node.name}(const SyntaxData Data) : ${node.base_type}(Data) {
${node.name}(const RC<const SyntaxData> &Data) : ${node.base_type}(Data) {
% if node.requires_validation():
this->validate();
% end
Expand Down
6 changes: 3 additions & 3 deletions include/swift/Syntax/TokenSyntax.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class TokenSyntax final : public Syntax {
assert(getRaw()->isToken());
}
public:
TokenSyntax(const SyntaxData Data) : Syntax(Data) {}
TokenSyntax(const RC<const SyntaxData> &Data) : Syntax(Data) {}

static TokenSyntax missingToken(const tok Kind, StringRef Text,
const RC<SyntaxArena> &Arena) {
Expand All @@ -50,12 +50,12 @@ class TokenSyntax final : public Syntax {

TokenSyntax withLeadingTrivia(StringRef Trivia) const {
auto NewRaw = getRaw()->withLeadingTrivia(Trivia);
return TokenSyntax(getData().replacingSelf(NewRaw));
return TokenSyntax(getData()->replacingSelf(NewRaw));
}

TokenSyntax withTrailingTrivia(StringRef Trivia) const {
auto NewRaw = getRaw()->withTrailingTrivia(Trivia);
return TokenSyntax(getData().replacingSelf(NewRaw));
return TokenSyntax(getData()->replacingSelf(NewRaw));
}

/* TODO: If we really need them.
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Syntax/UnknownSyntax.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace syntax {
class UnknownSyntax : public Syntax {
void validate() const;
public:
UnknownSyntax(const SyntaxData Data) : Syntax(Data) {}
UnknownSyntax(const RC<const SyntaxData> &Data) : Syntax(Data) {}

static bool classof(const Syntax *S) {
return S->isUnknown();
Expand Down
2 changes: 1 addition & 1 deletion lib/Parse/SyntaxParsingCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ bool SyntaxParsingCache::nodeCanBeReused(const Syntax &Node, size_t NodeStart,
// StructDecl inside and `private struc Foo {}` parses as two CodeBlockItems
// one for `private` and one for `struc Foo {}`
size_t NextLeafNodeLength = 0;
if (auto NextNode = Node.getData().getNextNode()) {
if (auto NextNode = Node.getData()->getNextNode()) {
auto NextLeafNode = NextNode->getFirstToken();
auto NextRawNode = NextLeafNode->getRaw();
assert(NextRawNode->isPresent());
Expand Down
24 changes: 12 additions & 12 deletions lib/Syntax/Syntax.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
using namespace swift;
using namespace swift::syntax;

const RawSyntax *Syntax::getRaw() const { return Data.getRaw(); }
const RawSyntax *Syntax::getRaw() const { return Data->getRaw(); }

SyntaxKind Syntax::getKind() const {
return getRaw()->getKind();
Expand All @@ -36,21 +36,21 @@ void Syntax::dump(llvm::raw_ostream &OS, unsigned Indent) const {
getRaw()->dump(OS, 0);
}

bool Syntax::isType() const { return Data.isType(); }
bool Syntax::isType() const { return Data->isType(); }

bool Syntax::isDecl() const { return Data.isDecl(); }
bool Syntax::isDecl() const { return Data->isDecl(); }

bool Syntax::isStmt() const { return Data.isStmt(); }
bool Syntax::isStmt() const { return Data->isStmt(); }

bool Syntax::isExpr() const { return Data.isExpr(); }
bool Syntax::isExpr() const { return Data->isExpr(); }

bool Syntax::isToken() const {
return getRaw()->isToken();
}

bool Syntax::isPattern() const { return Data.isPattern(); }
bool Syntax::isPattern() const { return Data->isPattern(); }

bool Syntax::isUnknown() const { return Data.isUnknown(); }
bool Syntax::isUnknown() const { return Data->isUnknown(); }

bool Syntax::isPresent() const {
return getRaw()->isPresent();
Expand All @@ -61,19 +61,19 @@ bool Syntax::isMissing() const {
}

llvm::Optional<Syntax> Syntax::getParent() const {
auto ParentData = getData().getParent();
auto ParentData = getData()->getParent();
if (!ParentData) {
return None;
}
return Syntax(*ParentData);
return Syntax(ParentData);
}

size_t Syntax::getNumChildren() const { return Data.getNumChildren(); }
size_t Syntax::getNumChildren() const { return Data->getNumChildren(); }

llvm::Optional<Syntax> Syntax::getChild(const size_t N) const {
auto ChildData = Data.getChild(N);
auto ChildData = Data->getChild(N);
if (!ChildData) {
return None;
}
return Syntax(*ChildData);
return Syntax(ChildData);
}
Loading