Skip to content

Commit a448a73

Browse files
authored
libSyntax: parse codeblock syntax node. (#12771)
This commit teaches parser to generate code block syntax node. As a support for this, SyntaxParsingContext can be created by a single syntax kind, indicating the whole context should be parsed into a node of that given syntax. Another change is to bridge created syntax node with the given context kind. For instance, if a statement context results into an expression node, the expression node will be bridged to a statement by wrapping it with a ExpressionStmt node.
1 parent 01f4b51 commit a448a73

File tree

6 files changed

+162
-72
lines changed

6 files changed

+162
-72
lines changed

include/swift/Syntax/SyntaxParsingContext.h

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
#ifndef SWIFT_SYNTAX_PARSING_CONTEXT_H
1414
#define SWIFT_SYNTAX_PARSING_CONTEXT_H
1515

16-
#include "swift/Syntax/Syntax.h"
16+
#include "swift/Basic/SourceLoc.h"
17+
#include "swift/Syntax/Syntax.h"
1718

1819
namespace swift {
1920
class SourceLoc;
@@ -25,19 +26,28 @@ namespace syntax {
2526
struct RawSyntax;
2627
enum class SyntaxKind;
2728

29+
enum class SyntaxContextKind: uint8_t{
30+
Expr,
31+
Decl,
32+
Stmt,
33+
};
34+
2835
/// The handler for parser to generate libSyntax entities.
2936
struct RawSyntaxInfo {
30-
/// Start location of this syntax node.
31-
SourceLoc StartLoc;
32-
33-
/// The number of tokens belong to the syntax node.
34-
unsigned TokCount;
37+
/// Start and end location of this syntax node.
38+
SourceRange SyntaxRange;
3539

3640
/// The raw node.
3741
RC<RawSyntax> RawNode;
42+
RawSyntaxInfo(RC<RawSyntax> RawNode): RawNode(RawNode) {}
3843
RawSyntaxInfo(SourceLoc StartLoc, RC<RawSyntax> RawNode):
39-
RawSyntaxInfo(StartLoc, 1, RawNode) {}
40-
RawSyntaxInfo(SourceLoc StartLoc, unsigned TokCount, RC<RawSyntax> RawNode);
44+
SyntaxRange(StartLoc), RawNode(RawNode) {}
45+
RawSyntaxInfo(SourceRange SyntaxRange, RC<RawSyntax> RawNode):
46+
SyntaxRange(SyntaxRange), RawNode(RawNode) {}
47+
48+
bool isImplicit() const { return SyntaxRange.isInvalid(); }
49+
SourceLoc getStartLoc() const { return SyntaxRange.Start; }
50+
SourceLoc getEndLoc() const { return SyntaxRange.End; }
4151

4252
template <typename SyntaxNode>
4353
SyntaxNode makeSyntax() const { return make<SyntaxNode>(RawNode); }
@@ -46,6 +56,7 @@ struct RawSyntaxInfo {
4656
RC<RawSyntaxNode> getRaw() const {
4757
return RC<RawSyntaxNode>(cast<RawSyntaxNode>(RawNode));
4858
}
59+
void brigeWithContext(SyntaxContextKind Kind);
4960
};
5061

5162
enum class SyntaxParsingContextKind: uint8_t {
@@ -96,22 +107,28 @@ class SyntaxParsingContextRoot: public SyntaxParsingContext {
96107
};
97108
};
98109

99-
enum class SyntaxContextKind: uint8_t{
100-
Expr,
101-
Decl,
102-
};
103-
104110
// The base class for contexts that are created from a parent context.
105111
// The stack instance will set the context holder when the context
106112
// is firstly created and reset the context holder to the parent when
107113
// it's destructed.
108114
class SyntaxParsingContextChild: public SyntaxParsingContext {
109115
SyntaxParsingContext *Parent;
110116
SyntaxParsingContext *&ContextHolder;
111-
const SyntaxContextKind Kind;
117+
Optional<SyntaxContextKind> Kind;
118+
Optional<SyntaxKind> KnownSyntax;
119+
void makeNodeWhole(SyntaxKind Kind);
120+
SyntaxParsingContextChild(SyntaxParsingContext *&ContextHolder,
121+
Optional<SyntaxContextKind> Kind,
122+
Optional<SyntaxKind> KnownSyntax);
112123
public:
113124
SyntaxParsingContextChild(SyntaxParsingContext *&ContextHolder,
114-
SyntaxContextKind Kind);
125+
SyntaxContextKind Kind): SyntaxParsingContextChild(ContextHolder,
126+
Kind, None) {}
127+
128+
SyntaxParsingContextChild(SyntaxParsingContext *&ContextHolder,
129+
SyntaxKind KnownSyntax): SyntaxParsingContextChild(ContextHolder,
130+
None, KnownSyntax) {};
131+
115132
~SyntaxParsingContextChild();
116133
void makeNode(SyntaxKind Kind) override;
117134
void addTokenSyntax(SourceLoc Loc) override;

lib/Parse/ParseStmt.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,15 @@
2222
#include "swift/Parse/Lexer.h"
2323
#include "swift/Parse/CodeCompletionCallbacks.h"
2424
#include "swift/Subsystems.h"
25+
#include "swift/Syntax/TokenSyntax.h"
26+
#include "swift/Syntax/SyntaxParsingContext.h"
2527
#include "llvm/ADT/PointerUnion.h"
2628
#include "llvm/ADT/Twine.h"
2729
#include "llvm/Support/Compiler.h"
2830
#include "llvm/Support/SaveAndRestore.h"
2931

3032
using namespace swift;
33+
using namespace swift::syntax;
3134

3235
/// isStartOfStmt - Return true if the current token starts a statement.
3336
///
@@ -223,7 +226,7 @@ void Parser::consumeTopLevelDecl(ParserPosition BeginParserPosition,
223226
ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
224227
BraceItemListKind Kind,
225228
BraceItemListKind ConditionalBlockKind) {
226-
229+
SyntaxParsingContextChild StmtListContext(SyntaxContext, SyntaxKind::StmtList);
227230
bool IsTopLevel = (Kind == BraceItemListKind::TopLevelCode) ||
228231
(Kind == BraceItemListKind::TopLevelLibrary);
229232
bool isActiveConditionalBlock =
@@ -259,6 +262,7 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
259262
Tok.isNot(tok::kw_sil_default_witness_table) &&
260263
(isConditionalBlock ||
261264
!isTerminatorForBraceItemListKind(Kind, Entries))) {
265+
SyntaxParsingContextChild StmtContext(SyntaxContext, SyntaxContextKind::Stmt);
262266
if (Kind == BraceItemListKind::TopLevelLibrary &&
263267
skipExtraTopLevelRBraces())
264268
continue;
@@ -489,7 +493,7 @@ static ParserResult<Stmt> recoverFromInvalidCase(Parser &P) {
489493
}
490494

491495
ParserResult<Stmt> Parser::parseStmt() {
492-
496+
SyntaxParsingContextChild LocalContext(SyntaxContext, SyntaxContextKind::Stmt);
493497
// Note that we're parsing a statement.
494498
StructureMarkerRAII ParsingStmt(*this, Tok.getLoc(),
495499
StructureMarkerKind::Statement);
@@ -586,15 +590,19 @@ ParserResult<BraceStmt> Parser::parseBraceItemList(Diag<> ID) {
586590
if (Tok.isNot(tok::l_brace))
587591
return nullptr;
588592
}
593+
SyntaxParsingContextChild LocalContext(SyntaxContext, SyntaxKind::CodeBlock);
589594
SourceLoc LBLoc = consumeToken(tok::l_brace);
595+
LocalContext.addTokenSyntax(LBLoc);
590596

591597
SmallVector<ASTNode, 16> Entries;
592598
SourceLoc RBLoc;
593599

594600
ParserStatus Status = parseBraceItems(Entries, BraceItemListKind::Brace,
595601
BraceItemListKind::Brace);
596-
parseMatchingToken(tok::r_brace, RBLoc,
597-
diag::expected_rbrace_in_brace_stmt, LBLoc);
602+
if (!parseMatchingToken(tok::r_brace, RBLoc,
603+
diag::expected_rbrace_in_brace_stmt, LBLoc)) {
604+
LocalContext.addTokenSyntax(RBLoc);
605+
}
598606

599607
return makeParserResult(Status,
600608
BraceStmt::create(Context, LBLoc, Entries, RBLoc));

lib/Parse/Parser.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class ParseDelayedFunctionBodies : public ASTWalker {
6868
SourceManager &SourceMgr = SF.getASTContext().SourceMgr;
6969
unsigned BufferID = SourceMgr.findBufferContainingLoc(AFD->getLoc());
7070
Parser TheParser(BufferID, SF, nullptr, &ParserState);
71-
71+
TheParser.SyntaxContext->disable();
7272
std::unique_ptr<CodeCompletionCallbacks> CodeCompletion;
7373
if (CodeCompletionFactory) {
7474
CodeCompletion.reset(
@@ -102,6 +102,9 @@ static void parseDelayedDecl(
102102
SourceMgr.findBufferContainingLoc(ParserState.getDelayedDeclLoc());
103103
Parser TheParser(BufferID, SF, nullptr, &ParserState);
104104

105+
// Disable libSyntax creation in the delayed parsing.
106+
TheParser.SyntaxContext->disable();
107+
105108
std::unique_ptr<CodeCompletionCallbacks> CodeCompletion;
106109
if (CodeCompletionFactory) {
107110
CodeCompletion.reset(

lib/Syntax/RawSyntax.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ static bool isTrivialSyntaxKind(SyntaxKind Kind) {
2929
case SyntaxKind::SourceFile:
3030
case SyntaxKind::TopLevelCodeDecl:
3131
case SyntaxKind::ExpressionStmt:
32+
case SyntaxKind::DeclarationStmt:
3233
return true;
3334
default:
3435
return false;

0 commit comments

Comments
 (0)