Skip to content

Commit a356c89

Browse files
committed
[libSyntax] Don't reference count SyntaxData
Instead, reference count the SyntaxData's parent. This has a couple of advantages: 1. We eliminate a const_cast that was potentially unsafe 2. It more closely resembles the architecture on the Swift side 3. It has the potential to be optimised further if the parent can be accessed in an unsafe, non-reference-counted way
1 parent 8bb1167 commit a356c89

File tree

11 files changed

+152
-215
lines changed

11 files changed

+152
-215
lines changed

include/swift/Syntax/AbsoluteRawSyntax.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ class SyntaxIndexInTree {
4040

4141
/// Advance this index to point to its first immediate child.
4242
SyntaxIndexInTree advancedToFirstChild() const;
43+
44+
bool operator==(SyntaxIndexInTree Other) const {
45+
return IndexInTree == Other.IndexInTree;
46+
}
4347
};
4448

4549
/// A syntax identifier that globally identifies a \c Syntax node.
@@ -97,6 +101,10 @@ class SyntaxIdentifier {
97101
auto NewIndexInTree = IndexInTree.advancedToFirstChild();
98102
return SyntaxIdentifier(RootId, NewIndexInTree);
99103
}
104+
105+
bool operator==(SyntaxIdentifier Other) const {
106+
return RootId == Other.RootId && IndexInTree == Other.IndexInTree;
107+
}
100108
};
101109

102110
/// Represents a node's position in a syntax tree, described by its overal
@@ -231,6 +239,18 @@ struct AbsoluteRawSyntax {
231239
AbsoluteSyntaxPosition::IndexInParentType getIndexInParent() const {
232240
return getPosition().getIndexInParent();
233241
}
242+
243+
/// Construct a new \c AbsoluteRawSyntax node that has the same info as the
244+
/// current one, but
245+
/// - the \p NewRaw as the backing storage
246+
/// - the \p NewRootId as the RootId
247+
AbsoluteRawSyntax
248+
replacingSelf(const RC<RawSyntax> &NewRaw,
249+
SyntaxIdentifier::RootIdType NewRootId) const {
250+
SyntaxIdentifier NewNodeId(NewRootId, Info.getNodeId().getIndexInTree());
251+
AbsoluteSyntaxInfo NewInfo(Info.getPosition(), NewNodeId);
252+
return AbsoluteRawSyntax(NewRaw, NewInfo);
253+
}
234254
};
235255

236256
} // end namespace syntax

include/swift/Syntax/Syntax.h

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -41,37 +41,24 @@ class SourceFileSyntax;
4141

4242
template <typename SyntaxNode> SyntaxNode makeRoot(RC<RawSyntax> Raw) {
4343
auto Data = SyntaxData::make(AbsoluteRawSyntax::forRoot(Raw));
44-
return { Data, Data.get() };
44+
return SyntaxNode(Data);
4545
}
4646

4747
const auto NoParent = llvm::None;
4848

4949
/// The main handle for syntax nodes - subclasses contain all public
5050
/// structured editing APIs.
5151
///
52-
/// This opaque structure holds two pieces of data: a strong reference to a
53-
/// root node and a weak reference to the node itself. The node of interest can
54-
/// be weakly held because the data nodes contain strong references to
55-
/// their children.
52+
/// Essentially, this is a wrapper around \c SyntaxData that provides
53+
/// convenience methods based on the node's kind.
5654
class Syntax {
5755
friend struct SyntaxFactory;
5856

5957
protected:
60-
/// A strong reference to the root node of the tree in which this piece of
61-
/// syntax resides.
62-
const RC<SyntaxData> Root;
63-
64-
/// A raw pointer to the data representing this syntax node.
65-
///
66-
/// This is mutable for being able to set cached child members, which are
67-
/// lazily created.
68-
mutable const SyntaxData *Data;
58+
SyntaxData Data;
6959

7060
public:
71-
Syntax(const RC<SyntaxData> Root, const SyntaxData *Data)
72-
: Root(Root), Data(Data) {
73-
assert(Data != nullptr);
74-
}
61+
explicit Syntax(const SyntaxData Data) : Data(Data) {}
7562

7663
virtual ~Syntax() {}
7764

@@ -99,10 +86,6 @@ class Syntax {
9986

10087
/// Get the Data for this Syntax node.
10188
const SyntaxData &getData() const {
102-
return *Data;
103-
}
104-
105-
const SyntaxData *getDataPointer() const {
10689
return Data;
10790
}
10891

@@ -111,7 +94,7 @@ class Syntax {
11194
template <typename T>
11295
T castTo() const {
11396
assert(is<T>() && "castTo<T>() node of incompatible type!");
114-
return T { Root, Data };
97+
return T(Data);
11598
}
11699

117100
/// If this Syntax node is of the right kind, cast and return it,
@@ -127,9 +110,6 @@ class Syntax {
127110
/// Return the parent of this node, if it has one.
128111
llvm::Optional<Syntax> getParent() const;
129112

130-
/// Return the root syntax of this node.
131-
Syntax getRoot() const;
132-
133113
/// Returns the child index of this node in its parent,
134114
/// if it has one, otherwise 0.
135115
CursorIndex getIndexInParent() const { return getData().getIndexInParent(); }
@@ -176,7 +156,8 @@ class Syntax {
176156
SWIFT_DEBUG_DUMP;
177157

178158
bool hasSameIdentityAs(const Syntax &Other) const {
179-
return Root == Other.Root && Data == Other.Data;
159+
return Data.getAbsoluteRaw().getNodeId() ==
160+
Other.Data.getAbsoluteRaw().getNodeId();
180161
}
181162

182163
static bool kindof(SyntaxKind Kind) {
@@ -198,23 +179,23 @@ class Syntax {
198179

199180
/// Get the offset at which the leading trivia of this node starts.
200181
AbsoluteOffsetPosition getAbsolutePositionBeforeLeadingTrivia() const {
201-
return Data->getAbsolutePositionBeforeLeadingTrivia();
182+
return Data.getAbsolutePositionBeforeLeadingTrivia();
202183
}
203184

204185
/// Get the offset at which the actual content (i.e. non-triva) of this node
205186
/// starts.
206187
AbsoluteOffsetPosition getAbsolutePositionAfterLeadingTrivia() const {
207-
return Data->getAbsolutePositionAfterLeadingTrivia();
188+
return Data.getAbsolutePositionAfterLeadingTrivia();
208189
}
209190

210191
/// Get the offset at which the trailing trivia of this node starts.
211192
AbsoluteOffsetPosition getAbsoluteEndPositionBeforeTrailingTrivia() const {
212-
return Data->getAbsoluteEndPositionBeforeTrailingTrivia();
193+
return Data.getAbsoluteEndPositionBeforeTrailingTrivia();
213194
}
214195

215196
/// Get the offset at which the trailing trivia of this node starts.
216197
AbsoluteOffsetPosition getAbsoluteEndPositionAfterTrailingTrivia() const {
217-
return Data->getAbsoluteEndPositionAfterTrailingTrivia();
198+
return Data.getAbsoluteEndPositionAfterTrailingTrivia();
218199
}
219200

220201
// TODO: hasSameStructureAs ?

include/swift/Syntax/SyntaxCollection.h

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ class SyntaxCollection : public Syntax {
5757
friend class Syntax;
5858

5959
private:
60-
static RC<SyntaxData>
61-
makeData(std::initializer_list<Element> &Elements) {
60+
static SyntaxData makeData(std::initializer_list<Element> &Elements) {
6261
std::vector<RC<RawSyntax>> List;
6362
List.reserve(Elements.size());
6463
for (auto &Elt : Elements)
@@ -67,12 +66,9 @@ class SyntaxCollection : public Syntax {
6766
SourcePresence::Present);
6867
return SyntaxData::make(AbsoluteRawSyntax::forRoot(Raw));
6968
}
70-
SyntaxCollection(const RC<SyntaxData> Root): Syntax(Root, Root.get()) {}
7169

7270
public:
73-
74-
SyntaxCollection(const RC<SyntaxData> Root, const SyntaxData *Data)
75-
: Syntax(Root, Data) {}
71+
SyntaxCollection(const SyntaxData Data) : Syntax(Data) {}
7672

7773
SyntaxCollection(std::initializer_list<Element> list):
7874
SyntaxCollection(SyntaxCollection::makeData(list)) {}
@@ -108,7 +104,7 @@ class SyntaxCollection : public Syntax {
108104
Element operator[](const size_t Index) const {
109105
assert(Index < size());
110106
assert(!empty());
111-
return { Root, Data->getChild(Index).get() };
107+
return Element(*Data.getChild(Index));
112108
}
113109

114110
/// Return a new collection with the given element added to the end.
@@ -120,7 +116,7 @@ class SyntaxCollection : public Syntax {
120116
std::copy(OldLayout.begin(), OldLayout.end(), back_inserter(NewLayout));
121117
NewLayout.push_back(E.getRaw());
122118
auto Raw = RawSyntax::make(CollectionKind, NewLayout, getRaw()->getPresence());
123-
return Data->replacingSelf<SyntaxCollection<CollectionKind, Element>>(Raw);
119+
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
124120
}
125121

126122
/// Return a new collection with an element removed from the end.
@@ -130,7 +126,7 @@ class SyntaxCollection : public Syntax {
130126
assert(!empty());
131127
auto NewLayout = getRaw()->getLayout().drop_back();
132128
auto Raw = RawSyntax::make(CollectionKind, NewLayout, getRaw()->getPresence());
133-
return Data->replacingSelf<SyntaxCollection<CollectionKind, Element>>(Raw);
129+
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
134130
}
135131

136132
/// Return a new collection with the given element appended to the front.
@@ -141,7 +137,7 @@ class SyntaxCollection : public Syntax {
141137
std::copy(OldLayout.begin(), OldLayout.end(),
142138
std::back_inserter(NewLayout));
143139
auto Raw = RawSyntax::make(CollectionKind, NewLayout, getRaw()->getPresence());
144-
return Data->replacingSelf<SyntaxCollection<CollectionKind, Element>>(Raw);
140+
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
145141
}
146142

147143
/// Return a new collection with an element removed from the end.
@@ -151,7 +147,7 @@ class SyntaxCollection : public Syntax {
151147
assert(!empty());
152148
auto NewLayout = getRaw()->getLayout().drop_front();
153149
auto Raw = RawSyntax::make(CollectionKind, NewLayout, getRaw()->getPresence());
154-
return Data->replacingSelf<SyntaxCollection<CollectionKind, Element>>(Raw);
150+
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
155151
}
156152

157153
/// Return a new collection with the Element inserted at index i.
@@ -170,7 +166,7 @@ class SyntaxCollection : public Syntax {
170166
std::copy(OldLayout.begin() + i, OldLayout.end(),
171167
std::back_inserter(NewLayout));
172168
auto Raw = RawSyntax::make(CollectionKind, NewLayout, getRaw()->getPresence());
173-
return Data->replacingSelf<SyntaxCollection<CollectionKind, Element>>(Raw);
169+
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
174170
}
175171

176172
/// Return a new collection with the element removed at index i.
@@ -181,13 +177,13 @@ class SyntaxCollection : public Syntax {
181177
std::advance(iterator, i);
182178
NewLayout.erase(iterator);
183179
auto Raw = RawSyntax::make(CollectionKind, NewLayout, getRaw()->getPresence());
184-
return Data->replacingSelf<SyntaxCollection<CollectionKind, Element>>(Raw);
180+
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
185181
}
186182

187183
/// Return an empty syntax collection of this type.
188184
SyntaxCollection<CollectionKind, Element> cleared() const {
189185
auto Raw = RawSyntax::make(CollectionKind, {}, getRaw()->getPresence());
190-
return Data->replacingSelf<SyntaxCollection<CollectionKind, Element>>(Raw);
186+
return SyntaxCollection<CollectionKind, Element>(Data.replacingSelf(Raw));
191187
}
192188

193189
static bool kindof(SyntaxKind Kind) {

0 commit comments

Comments
 (0)