diff --git a/include/swift/Parse/ParsedRawSyntaxNode.h b/include/swift/Parse/ParsedRawSyntaxNode.h index f67a21baead..82ca4d1f519 100644 --- a/include/swift/Parse/ParsedRawSyntaxNode.h +++ b/include/swift/Parse/ParsedRawSyntaxNode.h @@ -40,6 +40,7 @@ class SyntaxParsingContext; /// there are instances that it's not clear what will be the final syntax node /// in the current parsing context. class ParsedRawSyntaxNode { + friend class ParsedRawSyntaxRecorder; enum class DataKind: uint8_t { Null, Recorded, @@ -292,25 +293,6 @@ public: //==========================================================================// - /// Form a deferred syntax layout node. - static ParsedRawSyntaxNode makeDeferred(syntax::SyntaxKind k, - MutableArrayRef deferredNodes, - SyntaxParsingContext &ctx); - - /// Form a deferred token node. - static ParsedRawSyntaxNode makeDeferred(Token tok, StringRef leadingTrivia, - StringRef trailingTrivia, - SyntaxParsingContext &ctx); - - /// Form a deferred missing token node. - static ParsedRawSyntaxNode makeDeferredMissing(tok tokKind, SourceLoc loc) { - auto raw = ParsedRawSyntaxNode(tokKind, loc, /*tokLength=*/0, - /*leadingTrivia=*/StringRef(), - /*trailingTrivia=*/StringRef()); - raw.IsMissing = true; - return raw; - } - /// Dump this piece of syntax recursively for debugging or testing. SWIFT_DEBUG_DUMP; diff --git a/include/swift/Parse/ParsedRawSyntaxRecorder.h b/include/swift/Parse/ParsedRawSyntaxRecorder.h index 1e6b8424651..e399ba28c07 100644 --- a/include/swift/Parse/ParsedRawSyntaxRecorder.h +++ b/include/swift/Parse/ParsedRawSyntaxRecorder.h @@ -29,6 +29,7 @@ class ParsedRawSyntaxNode; struct ParsedTrivia; class ParsedTriviaPiece; class SyntaxParseActions; +class SyntaxParsingContext; class SourceLoc; class Token; enum class tok; @@ -67,6 +68,19 @@ public: ParsedRawSyntaxNode recordEmptyRawSyntaxCollection(syntax::SyntaxKind kind, SourceLoc loc); + /// Form a deferred syntax layout node. + ParsedRawSyntaxNode + makeDeferred(syntax::SyntaxKind k, + MutableArrayRef deferredNodes, + SyntaxParsingContext &ctx); + + /// Form a deferred token node. + ParsedRawSyntaxNode makeDeferred(Token tok, StringRef leadingTrivia, + StringRef trailingTrivia); + + /// Form a deferred missing token node. + ParsedRawSyntaxNode makeDeferredMissing(tok tokKind, SourceLoc loc); + /// Used for incremental re-parsing. ParsedRawSyntaxNode lookupNode(size_t lexerOffset, SourceLoc loc, syntax::SyntaxKind kind); diff --git a/lib/Parse/ParsedRawSyntaxNode.cpp b/lib/Parse/ParsedRawSyntaxNode.cpp index 5597ac054bd..283263621dd 100644 --- a/lib/Parse/ParsedRawSyntaxNode.cpp +++ b/lib/Parse/ParsedRawSyntaxNode.cpp @@ -17,50 +17,6 @@ using namespace swift; using namespace swift::syntax; using namespace llvm; -ParsedRawSyntaxNode -ParsedRawSyntaxNode::makeDeferred(SyntaxKind k, - MutableArrayRef deferredNodes, - SyntaxParsingContext &ctx) { - CharSourceRange range; - if (deferredNodes.empty()) { - return ParsedRawSyntaxNode(k, range, {}); - } - ParsedRawSyntaxNode *newPtr = - ctx.getScratchAlloc().Allocate(deferredNodes.size()); - -#ifndef NDEBUG - ParsedRawSyntaxRecorder::verifyElementRanges(deferredNodes); -#endif - auto ptr = newPtr; - for (auto &node : deferredNodes) { - // Cached range. - if (!node.isNull() && !node.isMissing()) { - auto nodeRange = node.getDeferredRange(); - if (nodeRange.isValid()) { - if (range.isInvalid()) - range = nodeRange; - else - range.widen(nodeRange); - } - } - - // uninitialized move; - :: new (static_cast(ptr++)) ParsedRawSyntaxNode(std::move(node)); - } - return ParsedRawSyntaxNode(k, range, - makeMutableArrayRef(newPtr, deferredNodes.size())); -} - -ParsedRawSyntaxNode -ParsedRawSyntaxNode::makeDeferred(Token tok, StringRef leadingTrivia, - StringRef trailingTrivia, - SyntaxParsingContext &ctx) { - CharSourceRange tokRange = tok.getRange(); - return ParsedRawSyntaxNode(tok.getKind(), tokRange.getStart(), - tokRange.getByteLength(), leadingTrivia, - trailingTrivia); -} - void ParsedRawSyntaxNode::dump() const { dump(llvm::errs(), /*Indent*/ 0); llvm::errs() << '\n'; diff --git a/lib/Parse/ParsedRawSyntaxRecorder.cpp b/lib/Parse/ParsedRawSyntaxRecorder.cpp index 12b3290ac80..a76ff4fc974 100644 --- a/lib/Parse/ParsedRawSyntaxRecorder.cpp +++ b/lib/Parse/ParsedRawSyntaxRecorder.cpp @@ -20,6 +20,7 @@ #include "swift/Parse/ParsedRawSyntaxNode.h" #include "swift/Parse/ParsedTrivia.h" #include "swift/Parse/SyntaxParseActions.h" +#include "swift/Parse/SyntaxParsingContext.h" #include "swift/Parse/Token.h" #include "swift/Syntax/SyntaxKind.h" @@ -112,6 +113,59 @@ ParsedRawSyntaxRecorder::recordEmptyRawSyntaxCollection(SyntaxKind kind, return ParsedRawSyntaxNode{kind, tok::unknown, range, n}; } +/// Create a deferred layout node. +ParsedRawSyntaxNode ParsedRawSyntaxRecorder::makeDeferred( + syntax::SyntaxKind k, MutableArrayRef deferredNodes, + SyntaxParsingContext &ctx) { + CharSourceRange range; + if (deferredNodes.empty()) { + return ParsedRawSyntaxNode(k, range, {}); + } + ParsedRawSyntaxNode *newPtr = + ctx.getScratchAlloc().Allocate(deferredNodes.size()); + +#ifndef NDEBUG + ParsedRawSyntaxRecorder::verifyElementRanges(deferredNodes); +#endif + auto ptr = newPtr; + for (auto &node : deferredNodes) { + // Cached range. + if (!node.isNull() && !node.isMissing()) { + auto nodeRange = node.getDeferredRange(); + if (nodeRange.isValid()) { + if (range.isInvalid()) + range = nodeRange; + else + range.widen(nodeRange); + } + } + + // uninitialized move; + ::new (static_cast(ptr++)) ParsedRawSyntaxNode(std::move(node)); + } + return ParsedRawSyntaxNode( + k, range, llvm::makeMutableArrayRef(newPtr, deferredNodes.size())); +} + +/// Create a deferred token node. +ParsedRawSyntaxNode +ParsedRawSyntaxRecorder::makeDeferred(Token tok, StringRef leadingTrivia, + StringRef trailingTrivia) { + CharSourceRange tokRange = tok.getRange(); + return ParsedRawSyntaxNode(tok.getKind(), tokRange.getStart(), + tokRange.getByteLength(), leadingTrivia, + trailingTrivia); +} + +ParsedRawSyntaxNode +ParsedRawSyntaxRecorder::makeDeferredMissing(tok tokKind, SourceLoc loc) { + auto raw = ParsedRawSyntaxNode(tokKind, loc, /*tokLength=*/0, + /*leadingTrivia=*/StringRef(), + /*trailingTrivia=*/StringRef()); + raw.IsMissing = true; + return raw; +} + ParsedRawSyntaxNode ParsedRawSyntaxRecorder::lookupNode(size_t lexerOffset, SourceLoc loc, SyntaxKind kind) { diff --git a/lib/Parse/ParsedSyntaxBuilders.cpp.gyb b/lib/Parse/ParsedSyntaxBuilders.cpp.gyb index 7e40e6def34..87c29ded335 100644 --- a/lib/Parse/ParsedSyntaxBuilders.cpp.gyb +++ b/lib/Parse/ParsedSyntaxBuilders.cpp.gyb @@ -67,8 +67,8 @@ Parsed${node.name}Builder::record() { Parsed${node.name} Parsed${node.name}Builder::makeDeferred() { finishLayout(/*deferred=*/true); - auto raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind}, - Layout, SPCtx); + auto raw = SPCtx.getRecorder().makeDeferred(SyntaxKind::${node.syntax_kind}, + Layout, SPCtx); return Parsed${node.name}(std::move(raw)); } @@ -91,7 +91,7 @@ void Parsed${node.name}Builder::finishLayout(bool deferred) { % if child_elt: if (!${child_elt_name}s.empty()) { if (deferred) { - Layout[${idx}] = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${child_node.syntax_kind}, + Layout[${idx}] = Rec.makeDeferred(SyntaxKind::${child_node.syntax_kind}, ${child_elt_name}s, SPCtx); } else { Layout[${idx}] = Rec.recordRawSyntax(SyntaxKind::${child_node.syntax_kind}, ${child_elt_name}s); @@ -104,13 +104,13 @@ void Parsed${node.name}Builder::finishLayout(bool deferred) { % token = child.main_token() % tok_kind = token.kind if token else "unknown" if (deferred) { - Layout[${idx}] = ParsedRawSyntaxNode::makeDeferredMissing(tok::${tok_kind}, SourceLoc()); + Layout[${idx}] = Rec.makeDeferredMissing(tok::${tok_kind}, SourceLoc()); } else { Layout[${idx}] = Rec.recordMissingToken(tok::${tok_kind}, SourceLoc()); } % elif child_elt: if (deferred) { - Layout[${idx}] = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${child_node.syntax_kind}, {}, SPCtx); + Layout[${idx}] = Rec.makeDeferred(SyntaxKind::${child_node.syntax_kind}, {}, SPCtx); } else { Layout[${idx}] = Rec.recordRawSyntax(SyntaxKind::${child_node.syntax_kind}, {}); } diff --git a/lib/Parse/ParsedSyntaxRecorder.cpp.gyb b/lib/Parse/ParsedSyntaxRecorder.cpp.gyb index 786ab529196..e3336797ab8 100644 --- a/lib/Parse/ParsedSyntaxRecorder.cpp.gyb +++ b/lib/Parse/ParsedSyntaxRecorder.cpp.gyb @@ -98,7 +98,8 @@ ParsedSyntaxRecorder::record${node.syntax_kind}(MutableArrayRef layout, SyntaxParsingContext &SPCtx) { - auto raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind}, layout, SPCtx); + auto raw = SPCtx.getRecorder().makeDeferred(SyntaxKind::${node.syntax_kind}, + layout, SPCtx); return Parsed${node.name}(std::move(raw)); } @@ -132,8 +133,8 @@ Parsed${node.name} ParsedSyntaxRecorder::defer${node.syntax_kind}( MutableArrayRef layout, SyntaxParsingContext &SPCtx) { - auto raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind}, - layout, SPCtx); + auto raw = SPCtx.getRecorder().makeDeferred(SyntaxKind::${node.syntax_kind}, + layout, SPCtx); return Parsed${node.name}(std::move(raw)); } @@ -157,7 +158,8 @@ ParsedSyntaxRecorder::makeBlank${node.syntax_kind}(SourceLoc loc, ParsedRawSyntaxNode raw; if (SPCtx.shouldDefer()) { // FIXME: 'loc' is not preserved when capturing a deferred layout. - raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind}, {}, SPCtx); + raw = SPCtx.getRecorder().makeDeferred(SyntaxKind::${node.syntax_kind}, + {}, SPCtx); } else { raw = SPCtx.getRecorder().recordEmptyRawSyntaxCollection(SyntaxKind::${node.syntax_kind}, loc); } diff --git a/lib/Parse/SyntaxParsingContext.cpp b/lib/Parse/SyntaxParsingContext.cpp index d9a46f5e952..55a3e83c076 100644 --- a/lib/Parse/SyntaxParsingContext.cpp +++ b/lib/Parse/SyntaxParsingContext.cpp @@ -98,7 +98,7 @@ SyntaxParsingContext::makeUnknownSyntax(SyntaxKind Kind, MutableArrayRef Parts) { assert(isUnknownKind(Kind)); if (shouldDefer()) - return ParsedRawSyntaxNode::makeDeferred(Kind, Parts, *this); + return getRecorder().makeDeferred(Kind, Parts, *this); else return getRecorder().recordRawSyntax(Kind, Parts); } @@ -112,7 +112,7 @@ SyntaxParsingContext::createSyntaxAs(SyntaxKind Kind, auto &rec = getRecorder(); auto formNode = [&](SyntaxKind kind, MutableArrayRef layout) { if (nodeCreateK == SyntaxNodeCreationKind::Deferred || shouldDefer()) { - rawNode = ParsedRawSyntaxNode::makeDeferred(kind, layout, *this); + rawNode = getRecorder().makeDeferred(kind, layout, *this); } else { rawNode = rec.recordRawSyntax(kind, layout); } @@ -210,8 +210,7 @@ void SyntaxParsingContext::addToken(Token &Tok, StringRef LeadingTrivia, ParsedRawSyntaxNode raw; if (shouldDefer()) { - raw = ParsedRawSyntaxNode::makeDeferred(Tok, LeadingTrivia, TrailingTrivia, - *this); + raw = getRecorder().makeDeferred(Tok, LeadingTrivia, TrailingTrivia); } else { raw = getRecorder().recordToken(Tok, LeadingTrivia, TrailingTrivia); } @@ -339,7 +338,7 @@ void SyntaxParsingContext::synthesize(tok Kind, SourceLoc Loc) { ParsedRawSyntaxNode raw; if (shouldDefer()) - raw = ParsedRawSyntaxNode::makeDeferredMissing(Kind, Loc); + raw = getRecorder().makeDeferredMissing(Kind, Loc); else raw = getRecorder().recordMissingToken(Kind, Loc); getStorage().push_back(std::move(raw));