Skip to content

Commit e6da01b

Browse files
committed
[libSyntax] Remove getData method from ParsedRawSyntaxNode
The getData and getRecordedOrDeferredNode methods broke the move-only semantics of ParsedRawSyntaxNode because it allowed retrieving the data without resetting it. Change most uses to use takeData or takeRecordedOrDeferredNode instead of the get methods. To retrieve the children of a ParsedRawSyntaxNode, we still need a way to access the OpaqueSyntaxNode for inspection by the SyntaxParseActions without resetting it. For this, we still maintain a method with the semantics of getData, but it’s now called getUnsafeOpaqueData to make sure it’s not accidentally used.
1 parent a38dc1a commit e6da01b

File tree

3 files changed

+26
-14
lines changed

3 files changed

+26
-14
lines changed

include/swift/Parse/ParsedRawSyntaxNode.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,25 @@ class ParsedRawSyntaxNode {
106106
/// null).
107107
DataKind getDataKind() const { return Data.getKind(); }
108108

109-
/// Returns the opaque data of this node. This must be interpreted by the
110-
/// \c SyntaxParseAction, which likely also needs the node type to know
111-
/// what type of node the data represents.
112-
OpaqueSyntaxNode getData() const { return Data.getOpaque(); }
109+
/// Returns the opaque data of this node, assuming that it is deferred. This
110+
/// must be interpreted by the \c SyntaxParseAction, which likely also needs
111+
/// the node type (layout or token) to interpret the data.
112+
/// The data opaque data returned by this function *must not* be used to
113+
/// record the node, only to insepect it.
114+
OpaqueSyntaxNode getUnsafeDeferredOpaqueData() const {
115+
assert(isDeferredLayout() || isDeferredToken());
116+
return Data.getOpaque();
117+
}
113118

114-
RecordedOrDeferredNode getRecordedOrDeferredNode() const { return Data; }
119+
RecordedOrDeferredNode takeRecordedOrDeferredNode() {
120+
RecordedOrDeferredNode Data = this->Data;
121+
reset();
122+
return Data;
123+
}
115124

116125
/// Return the opaque data of this node and reset it.
117126
OpaqueSyntaxNode takeData() {
118-
OpaqueSyntaxNode Data = this->getData();
127+
OpaqueSyntaxNode Data = this->Data.getOpaque();
119128
reset();
120129
return Data;
121130
}

include/swift/Parse/ParsedRawSyntaxRecorder.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ class ParsedRawSyntaxRecorder final {
4343

4444
/// Assuming that \p node is a deferred layout or token node, record it and
4545
/// return the recorded node.
46-
ParsedRawSyntaxNode recordDeferredNode(const ParsedRawSyntaxNode &node);
46+
/// This consumes the data from \c node, which is unusable after it has been
47+
/// recorded. The returned node should be used afterwards instead.
48+
ParsedRawSyntaxNode recordDeferredNode(ParsedRawSyntaxNode &node);
4749

4850
public:
4951
explicit ParsedRawSyntaxRecorder(std::shared_ptr<SyntaxParseActions> spActions)

lib/Parse/ParsedRawSyntaxRecorder.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,19 @@ using namespace swift;
2828
using namespace swift::syntax;
2929

3030
ParsedRawSyntaxNode
31-
ParsedRawSyntaxRecorder::recordDeferredNode(const ParsedRawSyntaxNode &node) {
31+
ParsedRawSyntaxRecorder::recordDeferredNode(ParsedRawSyntaxNode &node) {
3232
switch (node.getDataKind()) {
3333
case RecordedOrDeferredNode::Kind::Null:
3434
case RecordedOrDeferredNode::Kind::Recorded:
3535
llvm_unreachable("Not deferred");
3636
case RecordedOrDeferredNode::Kind::DeferredLayout: {
37-
OpaqueSyntaxNode Data = SPActions->recordDeferredLayout(node.getData());
37+
OpaqueSyntaxNode Data = SPActions->recordDeferredLayout(node.takeData());
3838
return ParsedRawSyntaxNode(
3939
Data, node.getRange(), node.getKind(), node.getTokenKind(),
4040
ParsedRawSyntaxNode::DataKind::Recorded, node.isMissing());
4141
}
4242
case RecordedOrDeferredNode::Kind::DeferredToken: {
43-
OpaqueSyntaxNode Data = SPActions->recordDeferredToken(node.getData());
43+
OpaqueSyntaxNode Data = SPActions->recordDeferredToken(node.takeData());
4444
return ParsedRawSyntaxNode(
4545
Data, node.getRange(), node.getKind(), node.getTokenKind(),
4646
ParsedRawSyntaxNode::DataKind::Recorded, node.isMissing());
@@ -158,7 +158,7 @@ ParsedRawSyntaxNode ParsedRawSyntaxRecorder::makeDeferred(
158158
}
159159
}
160160

161-
children[i] = node.getRecordedOrDeferredNode();
161+
children[i] = node.takeRecordedOrDeferredNode();
162162
}
163163
auto data = SPActions->makeDeferredLayout(k, /*IsMissing=*/false, children);
164164
return ParsedRawSyntaxNode(data, range, k, tok::NUM_TOKENS,
@@ -213,8 +213,9 @@ ParsedRawSyntaxNode
213213
ParsedRawSyntaxRecorder::getDeferredChild(const ParsedRawSyntaxNode &parent,
214214
size_t childIndex) const {
215215
assert(parent.isDeferredLayout());
216-
auto childInfo = SPActions->getDeferredChild(parent.getData(), childIndex,
217-
parent.getRange().getStart());
216+
auto childInfo = SPActions->getDeferredChild(
217+
parent.getUnsafeDeferredOpaqueData(),
218+
childIndex, parent.getRange().getStart());
218219
return ParsedRawSyntaxNode(childInfo.Data, childInfo.Range,
219220
childInfo.SyntaxKind, childInfo.TokenKind,
220221
childInfo.SyntaxKind == syntax::SyntaxKind::Token
@@ -226,7 +227,7 @@ ParsedRawSyntaxRecorder::getDeferredChild(const ParsedRawSyntaxNode &parent,
226227
size_t ParsedRawSyntaxRecorder::getDeferredNumChildren(
227228
const ParsedRawSyntaxNode &node) const {
228229
assert(node.isDeferredLayout());
229-
return SPActions->getDeferredNumChildren(node.getData());
230+
return SPActions->getDeferredNumChildren(node.getUnsafeDeferredOpaqueData());
230231
}
231232

232233
#ifndef NDEBUG

0 commit comments

Comments
 (0)