Skip to content

Commit 6bfde00

Browse files
committed
[Parser/libSyntax] For accessor parsing only backtrack until the accessor introducer
Previously it was backtracking for the duration of the whole property body which was preventing re-use of previously parsed nodes for incremental re-parsing.
1 parent a862f2b commit 6bfde00

File tree

6 files changed

+44
-8
lines changed

6 files changed

+44
-8
lines changed

include/swift/Parse/Parser.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -494,13 +494,7 @@ class Parser {
494494
~BacktrackingScope();
495495
bool willBacktrack() const { return Backtrack; }
496496

497-
void cancelBacktrack() {
498-
Backtrack = false;
499-
SynContext->setTransparent();
500-
SynContext.reset();
501-
DT.commit();
502-
TempReceiver.shouldTransfer = true;
503-
}
497+
void cancelBacktrack();
504498
};
505499

506500
/// RAII object that, when it is destructed, restores the parser and lexer to

include/swift/Parse/SyntaxParsingContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,9 @@ class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext {
326326
IsBacktracking = true;
327327
}
328328

329+
/// Cancels backtracking state from the top of the context stack until `this` context.
330+
void cancelBacktrack();
331+
329332
bool isBacktracking() const { return IsBacktracking; }
330333

331334
void setShouldDefer(bool Value = true) { ShouldDefer = Value; }

lib/Parse/ParseDecl.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5531,7 +5531,14 @@ ParserStatus Parser::parseGetSet(ParseDeclOptions Flags,
55315531
parseImplicitGetter();
55325532
return makeParserSuccess();
55335533
}
5534-
IsFirstAccessor = false;
5534+
if (IsFirstAccessor) {
5535+
// Continue parsing without backtracking so we can re-use previously
5536+
// parsed nodes for incremental re-parsing, but avoid destructing
5537+
// `backtrack` because its syntax context isn't at the top of the stack at
5538+
// this point.
5539+
backtrack->cancelBacktrack();
5540+
IsFirstAccessor = false;
5541+
}
55355542

55365543
// For now, immediately reject illegal accessors in protocols just to
55375544
// avoid having to deal with them everywhere.

lib/Parse/Parser.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,19 @@ swift::Parser::BacktrackingScope::~BacktrackingScope() {
222222
}
223223
}
224224

225+
void swift::Parser::BacktrackingScope::cancelBacktrack() {
226+
if (!Backtrack)
227+
return;
228+
229+
Backtrack = false;
230+
SynContext->cancelBacktrack();
231+
SynContext->setTransparent();
232+
if (SynContext->isTopOfContextStack())
233+
SynContext.reset();
234+
DT.commit();
235+
TempReceiver.shouldTransfer = true;
236+
}
237+
225238
/// Tokenizes a string literal, taking into account string interpolation.
226239
static void getStringPartTokens(const Token &Tok, const LangOptions &LangOpts,
227240
const SourceManager &SM,

lib/Parse/SyntaxParsingContext.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,17 @@ SyntaxParsingContext::SyntaxParsingContext(SyntaxParsingContext *&CtxtHolder,
4646
getStorage().reserve(128);
4747
}
4848

49+
void SyntaxParsingContext::cancelBacktrack() {
50+
SyntaxParsingContext *curr = CtxtHolder;
51+
while (true) {
52+
curr->IsBacktracking = false;
53+
if (curr == this) {
54+
break;
55+
}
56+
curr = curr->getParent();
57+
}
58+
}
59+
4960
size_t SyntaxParsingContext::lookupNode(size_t LexerOffset, SourceLoc Loc) {
5061
if (!Enabled)
5162
return 0;

test/incrParse/reuse.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
// RUN: %empty-directory(%t)
2+
// RUN: %validate-incrparse %s --test-case MODIFY_ACCESSOR
23
// RUN: %validate-incrparse %s --test-case ADD_PROPERTY
34
// RUN: %validate-incrparse %s --test-case WRAP_IN_CLASS
45
// RUN: %validate-incrparse %s --test-case UNWRAP_CLASS
56
// RUN: %validate-incrparse %s --test-case NEXT_TOKEN_CALCULATION
67

78
func start() {}
89

10+
<reparse MODIFY_ACCESSOR>var someprop: Int {</reparse MODIFY_ACCESSOR>
11+
<reparse MODIFY_ACCESSOR>get {</reparse MODIFY_ACCESSOR>
12+
return 0
13+
<reparse MODIFY_ACCESSOR>}</reparse MODIFY_ACCESSOR>
14+
<reparse MODIFY_ACCESSOR>set { print(<<MODIFY_ACCESSOR<|||0>>>) }</reparse MODIFY_ACCESSOR>
15+
<reparse MODIFY_ACCESSOR>}</reparse MODIFY_ACCESSOR>
16+
917
<reparse ADD_PROPERTY>struct Foo {</reparse ADD_PROPERTY>
1018
let a: Int
1119
let b: Int

0 commit comments

Comments
 (0)