mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Parse] Assert that the children of syntax tree nodes have contiguous source ranges
This should help us catch syntax tree round-tripping issues.
This commit is contained in:
committed by
Rintaro Ishizaki
parent
7b5dfd6cf6
commit
97757e4c2a
@@ -52,6 +52,7 @@ class ParsedRawSyntaxNode {
|
||||
};
|
||||
struct DeferredLayoutNode {
|
||||
MutableArrayRef<ParsedRawSyntaxNode> Children;
|
||||
CharSourceRange Range;
|
||||
};
|
||||
struct DeferredTokenNode {
|
||||
const ParsedTriviaPiece *TriviaPieces;
|
||||
@@ -72,9 +73,9 @@ class ParsedRawSyntaxNode {
|
||||
/// Primary used for capturing a deferred missing token.
|
||||
bool IsMissing = false;
|
||||
|
||||
ParsedRawSyntaxNode(syntax::SyntaxKind k,
|
||||
ParsedRawSyntaxNode(syntax::SyntaxKind k, CharSourceRange r,
|
||||
MutableArrayRef<ParsedRawSyntaxNode> deferredNodes)
|
||||
: DeferredLayout({deferredNodes}),
|
||||
: DeferredLayout({deferredNodes, r}),
|
||||
SynKind(uint16_t(k)), TokKind(uint16_t(tok::unknown)),
|
||||
DK(DataKind::DeferredLayout) {
|
||||
assert(getKind() == k && "Syntax kind with too large value!");
|
||||
@@ -109,10 +110,12 @@ public:
|
||||
}
|
||||
|
||||
ParsedRawSyntaxNode(syntax::SyntaxKind k, tok tokKind,
|
||||
CharSourceRange r, OpaqueSyntaxNode n)
|
||||
CharSourceRange r, OpaqueSyntaxNode n,
|
||||
bool IsMissing = false)
|
||||
: RecordedData{n, r},
|
||||
SynKind(uint16_t(k)), TokKind(uint16_t(tokKind)),
|
||||
DK(DataKind::Recorded) {
|
||||
DK(DataKind::Recorded),
|
||||
IsMissing(IsMissing) {
|
||||
assert(getKind() == k && "Syntax kind with too large value!");
|
||||
assert(getTokenKind() == tokKind && "Token kind with too large value!");
|
||||
}
|
||||
@@ -209,9 +212,20 @@ public:
|
||||
return copy;
|
||||
}
|
||||
|
||||
CharSourceRange getDeferredRange() const {
|
||||
switch (DK) {
|
||||
case DataKind::DeferredLayout:
|
||||
return getDeferredLayoutRange();
|
||||
case DataKind::DeferredToken:
|
||||
return getDeferredTokenRangeWithTrivia();
|
||||
default:
|
||||
llvm_unreachable("node not deferred");
|
||||
}
|
||||
}
|
||||
|
||||
// Recorded Data ===========================================================//
|
||||
|
||||
CharSourceRange getRange() const {
|
||||
CharSourceRange getRecordedRange() const {
|
||||
assert(isRecorded());
|
||||
return RecordedData.Range;
|
||||
}
|
||||
@@ -228,6 +242,10 @@ public:
|
||||
|
||||
// Deferred Layout Data ====================================================//
|
||||
|
||||
CharSourceRange getDeferredLayoutRange() const {
|
||||
assert(DK == DataKind::DeferredLayout);
|
||||
return DeferredLayout.Range;
|
||||
}
|
||||
ArrayRef<ParsedRawSyntaxNode> getDeferredChildren() const {
|
||||
assert(DK == DataKind::DeferredLayout);
|
||||
return DeferredLayout.Children;
|
||||
@@ -259,6 +277,19 @@ public:
|
||||
|
||||
// Deferred Token Data =====================================================//
|
||||
|
||||
CharSourceRange getDeferredTokenRangeWithTrivia() const {
|
||||
assert(DK == DataKind::DeferredToken);
|
||||
auto leadTriviaPieces = getDeferredLeadingTriviaPieces();
|
||||
auto trailTriviaPieces = getDeferredTrailingTriviaPieces();
|
||||
|
||||
auto leadTriviaLen = ParsedTriviaPiece::getTotalLength(leadTriviaPieces);
|
||||
auto trailTriviaLen = ParsedTriviaPiece::getTotalLength(trailTriviaPieces);
|
||||
|
||||
SourceLoc begin = DeferredToken.TokLoc.getAdvancedLoc(-leadTriviaLen);
|
||||
unsigned len = leadTriviaLen + DeferredToken.TokLength + trailTriviaLen;
|
||||
|
||||
return CharSourceRange{begin, len};
|
||||
}
|
||||
CharSourceRange getDeferredTokenRange() const {
|
||||
assert(DK == DataKind::DeferredToken);
|
||||
return CharSourceRange{DeferredToken.TokLoc, DeferredToken.TokLength};
|
||||
|
||||
Reference in New Issue
Block a user