Files
swift-mirror/lib/Parse/ParsedRawSyntaxRecorder.cpp
Alex Hoppen dc8eed4279 [libSyntax] Delete discardRecordedNode
It doesn't do anything anymore and we shouldn't have it, so let's just
remove it.
2021-03-02 20:07:26 +01:00

145 lines
5.3 KiB
C++

//===--- ParsedRawSyntaxRecorder.cpp - Raw Syntax Parsing Recorder --------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the ParsedRawSyntaxRecorder, which is the interface the
// parser is using to pass parsed syntactic elements to a SyntaxParseActions
// receiver and get a ParsedRawSyntaxNode object back.
//
//===----------------------------------------------------------------------===//
#include "swift/Parse/ParsedRawSyntaxRecorder.h"
#include "swift/Parse/ParsedRawSyntaxNode.h"
#include "swift/Parse/ParsedTrivia.h"
#include "swift/Parse/SyntaxParseActions.h"
#include "swift/Parse/Token.h"
#include "swift/Syntax/SyntaxKind.h"
using namespace swift;
using namespace swift::syntax;
ParsedRawSyntaxNode
ParsedRawSyntaxRecorder::recordToken(const Token &tok, StringRef leadingTrivia,
StringRef trailingTrivia) {
return recordToken(tok.getKind(), tok.getRange(), leadingTrivia,
trailingTrivia);
}
ParsedRawSyntaxNode
ParsedRawSyntaxRecorder::recordToken(tok tokKind, CharSourceRange tokRange,
StringRef leadingTrivia,
StringRef trailingTrivia) {
SourceLoc offset = tokRange.getStart().getAdvancedLoc(-leadingTrivia.size());
unsigned length =
leadingTrivia.size() + tokRange.getByteLength() + trailingTrivia.size();
CharSourceRange range(offset, length);
OpaqueSyntaxNode n =
SPActions->recordToken(tokKind, leadingTrivia, trailingTrivia, range);
return ParsedRawSyntaxNode(SyntaxKind::Token, tokKind, range, n);
}
ParsedRawSyntaxNode
ParsedRawSyntaxRecorder::recordMissingToken(tok tokenKind, SourceLoc loc) {
CharSourceRange range{loc, 0};
OpaqueSyntaxNode n = SPActions->recordMissingToken(tokenKind, loc);
return ParsedRawSyntaxNode{SyntaxKind::Token, tokenKind, range, n,
/*isMissing=*/true};
}
static ParsedRawSyntaxNode
getRecordedNode(ParsedRawSyntaxNode node, ParsedRawSyntaxRecorder &rec) {
assert(!node.isNull() && !node.isRecorded());
if (node.isDeferredLayout())
return rec.recordRawSyntax(node.getKind(), node.getDeferredChildren());
assert(node.isDeferredToken());
CharSourceRange tokRange = node.getDeferredTokenRange();
tok tokKind = node.getTokenKind();
if (node.isMissing())
return rec.recordMissingToken(tokKind, tokRange.getStart());
return rec.recordToken(tokKind, tokRange, node.getDeferredLeadingTrivia(),
node.getDeferredTrailingTrivia());
}
ParsedRawSyntaxNode
ParsedRawSyntaxRecorder::recordRawSyntax(SyntaxKind kind,
MutableArrayRef<ParsedRawSyntaxNode> elements) {
#ifndef NDEBUG
ParsedRawSyntaxRecorder::verifyElementRanges(elements);
#endif
CharSourceRange range;
SmallVector<OpaqueSyntaxNode, 16> subnodes;
if (!elements.empty()) {
SourceLoc offset;
unsigned length = 0;
for (auto &subnode : elements) {
CharSourceRange localRange;
if (subnode.isNull()) {
subnodes.push_back(nullptr);
} else if (subnode.isRecorded()) {
localRange = subnode.getRecordedRange();
subnodes.push_back(subnode.takeOpaqueNode());
} else {
auto recorded = getRecordedNode(subnode.copyDeferred(), *this);
localRange = recorded.getRecordedRange();
subnodes.push_back(recorded.takeOpaqueNode());
}
if (localRange.isValid()) {
if (offset.isInvalid())
offset = localRange.getStart();
length += localRange.getByteLength();
}
}
range = CharSourceRange{offset, length};
}
OpaqueSyntaxNode n = SPActions->recordRawSyntax(kind, subnodes, range);
return ParsedRawSyntaxNode{kind, tok::unknown, range, n};
}
ParsedRawSyntaxNode
ParsedRawSyntaxRecorder::recordEmptyRawSyntaxCollection(SyntaxKind kind,
SourceLoc loc) {
CharSourceRange range{loc, 0};
OpaqueSyntaxNode n = SPActions->recordRawSyntax(kind, {}, range);
return ParsedRawSyntaxNode{kind, tok::unknown, range, n};
}
ParsedRawSyntaxNode
ParsedRawSyntaxRecorder::lookupNode(size_t lexerOffset, SourceLoc loc,
SyntaxKind kind) {
size_t length;
OpaqueSyntaxNode n;
std::tie(length, n) = SPActions->lookupNode(lexerOffset, kind);
if (length == 0) {
return ParsedRawSyntaxNode::null();
}
CharSourceRange range{loc, unsigned(length)};
return ParsedRawSyntaxNode{kind, tok::unknown, range, n};
}
#ifndef NDEBUG
void ParsedRawSyntaxRecorder::verifyElementRanges(ArrayRef<ParsedRawSyntaxNode> elements) {
SourceLoc prevEndLoc;
for (const auto &elem: elements) {
if (elem.isMissing() || elem.isNull())
continue;
CharSourceRange range = elem.isRecorded()
? elem.getRecordedRange()
: elem.getDeferredRange();
if (range.isValid()) {
assert((prevEndLoc.isInvalid() || range.getStart() == prevEndLoc)
&& "Non-contiguous child ranges?");
prevEndLoc = range.getEnd();
}
}
}
#endif