Merge pull request #27230 from rintaro/syntaxparsse-rdar55421369

[SyntaxParse] Re-apply move-only ParsedRawSyntaxNode
This commit is contained in:
Rintaro Ishizaki
2019-09-19 07:36:14 +02:00
committed by GitHub
27 changed files with 503 additions and 331 deletions

View File

@@ -55,13 +55,14 @@ size_t SyntaxParsingContext::lookupNode(size_t LexerOffset, SourceLoc Loc) {
return 0;
}
Mode = AccumulationMode::SkippedForIncrementalUpdate;
getStorage().push_back(foundNode);
return foundNode.getRecordedRange().getByteLength();
auto length = foundNode.getRecordedRange().getByteLength();
getStorage().push_back(std::move(foundNode));
return length;
}
ParsedRawSyntaxNode
SyntaxParsingContext::makeUnknownSyntax(SyntaxKind Kind,
ArrayRef<ParsedRawSyntaxNode> Parts) {
MutableArrayRef<ParsedRawSyntaxNode> Parts) {
assert(isUnknownKind(Kind));
if (shouldDefer())
return ParsedRawSyntaxNode::makeDeferred(Kind, Parts, *this);
@@ -71,12 +72,12 @@ SyntaxParsingContext::makeUnknownSyntax(SyntaxKind Kind,
ParsedRawSyntaxNode
SyntaxParsingContext::createSyntaxAs(SyntaxKind Kind,
ArrayRef<ParsedRawSyntaxNode> Parts,
MutableArrayRef<ParsedRawSyntaxNode> Parts,
SyntaxNodeCreationKind nodeCreateK) {
// Try to create the node of the given syntax.
ParsedRawSyntaxNode rawNode;
auto &rec = getRecorder();
auto formNode = [&](SyntaxKind kind, ArrayRef<ParsedRawSyntaxNode> layout) {
auto formNode = [&](SyntaxKind kind, MutableArrayRef<ParsedRawSyntaxNode> layout) {
if (nodeCreateK == SyntaxNodeCreationKind::Deferred || shouldDefer()) {
rawNode = ParsedRawSyntaxNode::makeDeferred(kind, layout, *this);
} else {
@@ -92,9 +93,9 @@ SyntaxParsingContext::createSyntaxAs(SyntaxKind Kind,
Optional<ParsedRawSyntaxNode>
SyntaxParsingContext::bridgeAs(SyntaxContextKind Kind,
ArrayRef<ParsedRawSyntaxNode> Parts) {
MutableArrayRef<ParsedRawSyntaxNode> Parts) {
if (Parts.size() == 1) {
auto RawNode = Parts.front();
auto &RawNode = Parts.front();
SyntaxKind RawNodeKind = RawNode.getKind();
switch (Kind) {
case SyntaxContextKind::Stmt:
@@ -121,7 +122,7 @@ SyntaxParsingContext::bridgeAs(SyntaxContextKind Kind,
// We don't need to coerce in this case.
break;
}
return RawNode;
return std::move(RawNode);
} else if (Parts.empty()) {
// Just omit the unknown node if it does not have any children
return None;
@@ -164,7 +165,8 @@ const SyntaxParsingContext *SyntaxParsingContext::getRoot() const {
}
ParsedTokenSyntax SyntaxParsingContext::popToken() {
return popIf<ParsedTokenSyntax>().getValue();
auto tok = popIf<ParsedTokenSyntax>();
return std::move(tok.getValue());
}
/// Add Token with Trivia to the parts.
@@ -182,7 +184,7 @@ void SyntaxParsingContext::addToken(Token &Tok,
/// Add Syntax to the parts.
void SyntaxParsingContext::addSyntax(ParsedSyntax Node) {
addRawSyntax(Node.getRaw());
addRawSyntax(Node.takeRaw());
}
void SyntaxParsingContext::createNodeInPlace(SyntaxKind Kind, size_t N,
@@ -193,12 +195,10 @@ void SyntaxParsingContext::createNodeInPlace(SyntaxKind Kind, size_t N,
return;
}
auto I = getStorage().end() - N;
*I = createSyntaxAs(Kind, getParts().take_back(N), nodeCreateK);
// Remove consumed parts.
if (N != 1)
getStorage().erase(I + 1, getStorage().end());
auto node = createSyntaxAs(Kind, getParts().take_back(N), nodeCreateK);
auto &storage = getStorage();
getStorage().erase(storage.end() - N, getStorage().end());
getStorage().emplace_back(std::move(node));
}
void SyntaxParsingContext::createNodeInPlace(SyntaxKind Kind,
@@ -251,32 +251,24 @@ void SyntaxParsingContext::collectNodesInPlace(SyntaxKind ColletionKind,
ParsedRawSyntaxNode SyntaxParsingContext::finalizeSourceFile() {
ParsedRawSyntaxRecorder &Recorder = getRecorder();
ArrayRef<ParsedRawSyntaxNode> Parts = getParts();
std::vector<ParsedRawSyntaxNode> AllTopLevel;
auto Parts = getParts();
ParsedRawSyntaxNode Layout[2];
assert(!Parts.empty() && Parts.back().isToken(tok::eof));
ParsedRawSyntaxNode EOFToken = Parts.back();
Layout[1] = std::move(Parts.back());
Parts = Parts.drop_back();
for (auto RawNode : Parts) {
if (RawNode.getKind() != SyntaxKind::CodeBlockItem) {
// FIXME: Skip toplevel garbage nodes for now. we shouldn't emit them in
// the first place.
if (RawNode.isRecorded())
getSyntaxCreator().finalizeNode(RawNode.getOpaqueNode());
continue;
}
assert(llvm::all_of(Parts, [](const ParsedRawSyntaxNode& node) {
return node.getKind() == SyntaxKind::CodeBlockItem;
}) && "all top level element must be 'CodeBlockItem'");
AllTopLevel.push_back(RawNode);
}
Layout[0] = Recorder.recordRawSyntax(SyntaxKind::CodeBlockItemList, Parts);
auto itemList = Recorder.recordRawSyntax(SyntaxKind::CodeBlockItemList,
Parts);
return Recorder.recordRawSyntax(SyntaxKind::SourceFile,
{ itemList, EOFToken });
llvm::makeMutableArrayRef(Layout, 2));
}
OpaqueSyntaxNode SyntaxParsingContext::finalizeRoot() {
OpaqueSyntaxNode SyntaxParsingContext::finalizeRoot() {
assert(isTopOfContextStack() && "some sub-contexts are not destructed");
assert(isRoot() && "only root context can finalize the tree");
assert(Mode == AccumulationMode::Root);
@@ -284,7 +276,7 @@ ParsedRawSyntaxNode SyntaxParsingContext::finalizeSourceFile() {
return nullptr; // already finalized.
}
ParsedRawSyntaxNode root = finalizeSourceFile();
auto opaqueRoot = getSyntaxCreator().finalizeNode(root.getOpaqueNode());
auto opaqueRoot = getSyntaxCreator().finalizeNode(root.takeOpaqueNode());
// Clear the parts because we will call this function again when destroying
// the root context.
@@ -304,9 +296,12 @@ void SyntaxParsingContext::synthesize(tok Kind, SourceLoc Loc) {
void SyntaxParsingContext::dumpStorage() const {
llvm::errs() << "======================\n";
for (auto Node : getStorage()) {
Node.dump(llvm::errs());
llvm::errs() << "\n--------------\n";
auto &storage = getStorage();
for (unsigned i = 0; i != storage.size(); ++i) {
storage[i].dump(llvm::errs());
llvm::errs() << "\n";
if (i + 1 == Offset)
llvm::errs() << "--------------\n";
}
}
@@ -338,14 +333,12 @@ SyntaxParsingContext::~SyntaxParsingContext() {
assert(!isRoot());
if (Storage.size() == Offset) {
if (auto BridgedNode = bridgeAs(CtxtKind, {})) {
Storage.push_back(BridgedNode.getValue());
Storage.push_back(std::move(BridgedNode.getValue()));
}
} else {
auto I = Storage.begin() + Offset;
*I = bridgeAs(CtxtKind, getParts()).getValue();
// Remove used parts.
if (Storage.size() > Offset + 1)
Storage.erase(Storage.begin() + (Offset + 1), Storage.end());
auto node(std::move(bridgeAs(CtxtKind, getParts()).getValue()));
Storage.erase(Storage.begin() + Offset, Storage.end());
Storage.emplace_back(std::move(node));
}
break;
}
@@ -358,10 +351,12 @@ SyntaxParsingContext::~SyntaxParsingContext() {
// Remove all parts in this context.
case AccumulationMode::Discard: {
auto &nodes = getStorage();
for (auto i = nodes.begin()+Offset, e = nodes.end(); i != e; ++i)
for (auto i = nodes.begin()+Offset, e = nodes.end(); i != e; ++i) {
// FIXME: This should not be needed. This breaks invariant that any
// recorded node must be a part of result souce syntax tree.
if (i->isRecorded())
getSyntaxCreator().finalizeNode(i->getOpaqueNode());
getRecorder().discardRecordedNode(*i);
}
nodes.erase(nodes.begin()+Offset, nodes.end());
break;
}