Skip to content

Commit ce587f0

Browse files
authored
Merge pull request #35517 from ahoppen/libsyntax-restructuring
[libSyntax] Restructure to more closely resemble the SwiftSyntax data structure
2 parents 8a96fcb + 8a6b8b8 commit ce587f0

31 files changed

+833
-861
lines changed

include/swift/Parse/Parser.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ namespace swift {
5959
struct EnumElementInfo;
6060

6161
namespace syntax {
62-
class AbsolutePosition;
6362
class RawSyntax;
6463
enum class SyntaxKind;
6564
}// end of syntax namespace
@@ -1817,14 +1816,10 @@ bool isKeywordPossibleDeclStart(const Token &Tok);
18171816

18181817
/// Lex and return a vector of `TokenSyntax` tokens, which include
18191818
/// leading and trailing trivia.
1820-
std::vector<std::pair<RC<syntax::RawSyntax>,
1821-
syntax::AbsolutePosition>>
1822-
tokenizeWithTrivia(const LangOptions &LangOpts,
1823-
const SourceManager &SM,
1824-
unsigned BufferID,
1825-
unsigned Offset = 0,
1826-
unsigned EndOffset = 0,
1827-
DiagnosticEngine *Diags = nullptr);
1819+
std::vector<std::pair<RC<syntax::RawSyntax>, syntax::AbsoluteOffsetPosition>>
1820+
tokenizeWithTrivia(const LangOptions &LangOpts, const SourceManager &SM,
1821+
unsigned BufferID, unsigned Offset = 0,
1822+
unsigned EndOffset = 0, DiagnosticEngine *Diags = nullptr);
18281823
} // end namespace swift
18291824

18301825
#endif

include/swift/Parse/SyntaxParsingCache.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ struct SourceEdit {
4848
};
4949

5050
struct SyntaxReuseRegion {
51-
AbsolutePosition Start;
52-
AbsolutePosition End;
51+
AbsoluteOffsetPosition Start;
52+
AbsoluteOffsetPosition End;
5353
};
5454

5555
class SyntaxParsingCache {
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
//===--- AbsoluteRawSyntax.h ------------------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_SYNTAX_ABSOLUTERAWSYNTAX_H
14+
#define SWIFT_SYNTAX_ABSOLUTERAWSYNTAX_H
15+
16+
#include "swift/Basic/SourceLoc.h"
17+
#include "swift/Syntax/RawSyntax.h"
18+
19+
namespace swift {
20+
namespace syntax {
21+
22+
/// Type-safe wrapper around a \c size_t that describes a node's index in its
23+
/// tree. This represents the index at which the node will be encountered during
24+
/// a depth-first traversal of the tree.
25+
class SyntaxIndexInTree {
26+
size_t IndexInTree;
27+
28+
explicit SyntaxIndexInTree(size_t IndexInTree) : IndexInTree(IndexInTree) {}
29+
30+
public:
31+
static SyntaxIndexInTree zero() { return SyntaxIndexInTree(0); }
32+
33+
/// Assuming that this index points to the start of \p Raw, advance it so that
34+
/// it points to the next sibling of \p Raw.
35+
SyntaxIndexInTree advancedBy(const RC<RawSyntax> &Raw) const;
36+
37+
/// Assuming that this index points to the next sibling of \p Raw, reverse it
38+
/// so that it points to the start of \p Raw.
39+
SyntaxIndexInTree reversedBy(const RC<RawSyntax> &Raw) const;
40+
41+
/// Advance this index to point to its first immediate child.
42+
SyntaxIndexInTree advancedToFirstChild() const;
43+
44+
bool operator==(SyntaxIndexInTree Other) const {
45+
return IndexInTree == Other.IndexInTree;
46+
}
47+
};
48+
49+
/// A syntax identifier that globally identifies a \c Syntax node.
50+
/// In contrast to \c NodeId of \c RawSyntax, this also takes into account the
51+
/// node's position in the tree. For example, a source file may contain two
52+
/// int literals with value 0. The corresponding \c RawSyntax nodes can share
53+
/// the same \c NodeId. However, because the literals occur in different
54+
/// locations of the syntax tree, their \c SyntaxIdentifiers are different.
55+
class SyntaxIdentifier {
56+
public:
57+
using RootIdType = size_t;
58+
59+
private:
60+
static std::atomic<RootIdType> NextUnusedRootId;
61+
62+
/// An integer that identifies the tree in which the node represented by this
63+
/// identifier lives.
64+
RootIdType RootId;
65+
66+
/// The position of the node represented by this identifier in the syntax
67+
/// tree.
68+
SyntaxIndexInTree IndexInTree;
69+
70+
public:
71+
SyntaxIdentifier(RootIdType RootId, SyntaxIndexInTree IndexInTree)
72+
: RootId(RootId), IndexInTree(IndexInTree) {
73+
assert(RootId < NextUnusedRootId && "New RootIds should only be created "
74+
"using the newRoot constructor.");
75+
}
76+
77+
/// Create a SyntaxIdentifier that refers to the root of a new syntax tree.
78+
static SyntaxIdentifier newRoot() {
79+
return SyntaxIdentifier(NextUnusedRootId++, SyntaxIndexInTree::zero());
80+
}
81+
82+
RootIdType getRootId() const { return RootId; }
83+
SyntaxIndexInTree getIndexInTree() const { return IndexInTree; }
84+
85+
/// Assuming that this identifier points to the start of \p Raw, advance it so
86+
/// that it points to the next sibling of \p Raw.
87+
SyntaxIdentifier advancedBy(const RC<RawSyntax> &Raw) const {
88+
auto NewIndexInTree = IndexInTree.advancedBy(Raw);
89+
return SyntaxIdentifier(RootId, NewIndexInTree);
90+
}
91+
92+
/// Assuming that this identifier points to the next sibling of \p Raw,
93+
/// reverse it so that it points to the start of \p Raw.
94+
SyntaxIdentifier reversedBy(const RC<RawSyntax> &Raw) const {
95+
auto NewIndexInTree = IndexInTree.reversedBy(Raw);
96+
return SyntaxIdentifier(RootId, NewIndexInTree);
97+
}
98+
99+
/// Get the identifier of the first immediate child.
100+
SyntaxIdentifier advancedToFirstChild() const {
101+
auto NewIndexInTree = IndexInTree.advancedToFirstChild();
102+
return SyntaxIdentifier(RootId, NewIndexInTree);
103+
}
104+
105+
bool operator==(SyntaxIdentifier Other) const {
106+
return RootId == Other.RootId && IndexInTree == Other.IndexInTree;
107+
}
108+
};
109+
110+
/// Represents a node's position in a syntax tree, described by its overal
111+
/// textual offset and the position within its parent.
112+
class AbsoluteSyntaxPosition {
113+
public:
114+
using OffsetType = uint32_t;
115+
using IndexInParentType = uint32_t;
116+
117+
private:
118+
/// The text offset where this node starts within its syntax tree, counted in
119+
/// UTF-8 bytes.
120+
OffsetType Offset;
121+
122+
/// The node's index within its parent, i.e.
123+
/// `node.parent.childAt(IndexInParent) = node`.
124+
IndexInParentType IndexInParent;
125+
126+
public:
127+
AbsoluteSyntaxPosition(OffsetType Offset, IndexInParentType IndexInParent)
128+
: Offset(Offset), IndexInParent(IndexInParent) {}
129+
130+
/// Create a new \c AbsoluteSyntaxPosition that refers to the root of a syntax
131+
/// tree.
132+
static AbsoluteSyntaxPosition forRoot() {
133+
return AbsoluteSyntaxPosition(0, 0);
134+
}
135+
136+
OffsetType getOffset() const { return Offset; }
137+
IndexInParentType getIndexInParent() const { return IndexInParent; }
138+
139+
/// Assuming that this position points to the start of \p Raw, advance it so
140+
/// that it points to the next sibling of \p Raw.
141+
AbsoluteSyntaxPosition advancedBy(const RC<RawSyntax> &Raw) const;
142+
143+
/// Assuming that this position points to the next sibling of \p Raw, reverse
144+
/// it so that it points to the start of \p Raw.
145+
AbsoluteSyntaxPosition reversedBy(const RC<RawSyntax> &Raw) const;
146+
147+
/// Get the position of the node's first immediate child.
148+
AbsoluteSyntaxPosition advancedToFirstChild() const {
149+
return AbsoluteSyntaxPosition(Offset, 0);
150+
}
151+
};
152+
153+
/// A type-safe wrapper that describes a node's textual position within a source
154+
/// file, represented by its UTF-8 byte offset from the start.
155+
class AbsoluteOffsetPosition {
156+
AbsoluteSyntaxPosition::OffsetType Offset;
157+
158+
public:
159+
explicit AbsoluteOffsetPosition(AbsoluteSyntaxPosition::OffsetType Offset)
160+
: Offset(Offset) {}
161+
AbsoluteOffsetPosition(AbsoluteSyntaxPosition Position)
162+
: Offset(Position.getOffset()) {}
163+
164+
AbsoluteSyntaxPosition::OffsetType getOffset() const { return Offset; }
165+
166+
/// Return a position that has been advanced by \p Advance UTF-8 bytes.s
167+
AbsoluteOffsetPosition advancedBy(int Advance) {
168+
return AbsoluteOffsetPosition(Offset + Advance);
169+
}
170+
};
171+
172+
/// Various information that enrich a \c RawSyntax node with information on how
173+
/// it's located within the syntax tree.
174+
class AbsoluteSyntaxInfo {
175+
AbsoluteSyntaxPosition Position;
176+
SyntaxIdentifier NodeId;
177+
178+
public:
179+
AbsoluteSyntaxInfo(AbsoluteSyntaxPosition Position, SyntaxIdentifier NodeId)
180+
: Position(Position), NodeId(NodeId) {}
181+
182+
static AbsoluteSyntaxInfo forRoot() {
183+
return AbsoluteSyntaxInfo(AbsoluteSyntaxPosition::forRoot(),
184+
SyntaxIdentifier::newRoot());
185+
}
186+
187+
AbsoluteSyntaxPosition getPosition() const { return Position; }
188+
SyntaxIdentifier getNodeId() const { return NodeId; }
189+
190+
/// Assuming that this info points to the start of \p Raw, advance it so
191+
/// that it points to the next sibling of \p Raw.
192+
AbsoluteSyntaxInfo advancedBy(const RC<RawSyntax> &Raw) const {
193+
auto NewNodeId = NodeId.advancedBy(Raw);
194+
auto NewPosition = Position.advancedBy(Raw);
195+
return AbsoluteSyntaxInfo(NewPosition, NewNodeId);
196+
}
197+
198+
/// Assuming that this info points to the next sibling of \p Raw, reverse
199+
/// it so that it points to the start of \p Raw.
200+
AbsoluteSyntaxInfo reversedBy(const RC<RawSyntax> &Raw) const {
201+
auto NewNodeId = NodeId.reversedBy(Raw);
202+
auto NewPosition = Position.reversedBy(Raw);
203+
return AbsoluteSyntaxInfo(NewPosition, NewNodeId);
204+
}
205+
206+
/// Get the information of the node's first immediate child.
207+
AbsoluteSyntaxInfo advancedToFirstChild() const {
208+
auto NewNodeId = NodeId.advancedToFirstChild();
209+
auto NewPosition = Position.advancedToFirstChild();
210+
return AbsoluteSyntaxInfo(NewPosition, NewNodeId);
211+
}
212+
};
213+
214+
/// A \c RawSyntax node that is enrichted with information of its position
215+
/// within the syntax tree it lives in.
216+
struct AbsoluteRawSyntax {
217+
const RC<RawSyntax> Raw;
218+
const AbsoluteSyntaxInfo Info;
219+
220+
public:
221+
AbsoluteRawSyntax(const RC<RawSyntax> &Raw, AbsoluteSyntaxInfo Info)
222+
: Raw(Raw), Info(Info) {}
223+
224+
/// Construct a \c AbsoluteRawSyntax for a \c RawSyntax node that represents
225+
/// the syntax tree's root.
226+
static AbsoluteRawSyntax forRoot(const RC<RawSyntax> &Raw) {
227+
return AbsoluteRawSyntax(Raw, AbsoluteSyntaxInfo::forRoot());
228+
}
229+
230+
const RC<RawSyntax> &getRaw() const { return Raw; }
231+
232+
AbsoluteSyntaxInfo getInfo() const { return Info; }
233+
234+
/// Get the position at which the leading triva of this node starts.
235+
AbsoluteSyntaxPosition getPosition() const { return Info.getPosition(); };
236+
237+
SyntaxIdentifier getNodeId() const { return Info.getNodeId(); };
238+
239+
AbsoluteSyntaxPosition::IndexInParentType getIndexInParent() const {
240+
return getPosition().getIndexInParent();
241+
}
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+
}
254+
};
255+
256+
} // end namespace syntax
257+
} // end namespace swift
258+
259+
namespace llvm {
260+
raw_ostream &operator<<(raw_ostream &OS,
261+
swift::syntax::AbsoluteOffsetPosition Pos);
262+
} // end namespace llvm
263+
264+
#endif // SWIFT_SYNTAX_ABSOLUTERAWSYNTAX_H

0 commit comments

Comments
 (0)