[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:
Nathan Hawes
2019-09-24 10:00:48 -07:00
committed by Rintaro Ishizaki
parent 7b5dfd6cf6
commit 97757e4c2a
10 changed files with 129 additions and 65 deletions

View File

@@ -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};