-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[libSyntax] Incremental Syntax Parsing #16340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libSyntax] Incremental Syntax Parsing #16340
Conversation
@@ -232,18 +232,24 @@ class RawSyntax final | |||
/// memory. | |||
unsigned ManualMemory : 1; | |||
}; | |||
enum { NumRawSyntaxBits = bitmax(NumSyntaxKindBits, 8) + 1 }; | |||
enum { NumRawSyntaxBits = bitmax(NumSyntaxKindBits, 8) + 1 + 1 }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
01d51a8
to
b53baca
Compare
lib/Parse/SyntaxParsingCache.cpp
Outdated
@@ -15,6 +15,45 @@ | |||
using namespace swift; | |||
using namespace swift::syntax; | |||
|
|||
ArrayRef<TriviaPiece> getNextChildsLeadingTrivia(const Syntax *Node) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to make this getNextChild
, because that's a traversal I've found very necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. I will keep it in mind when I refactor these methods to provide a (hopefully faster) cache based lookup.
95a5195
to
6c1434b
Compare
@swift-ci Please smoke test |
6c1434b
to
7a1b1ee
Compare
@swift-ci Please smoke test |
7a1b1ee
to
59bfeb3
Compare
@swift-ci Please smoke test |
1 similar comment
@swift-ci Please smoke test |
59bfeb3
to
a0776e6
Compare
@swift-ci Please smoke test |
@@ -434,6 +442,28 @@ class RawSyntax final | |||
return getLayout()[Index]; | |||
} | |||
|
|||
/// Return the number of bytes this node takes when spelled out in the source | |||
size_t getTextLength() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we re-use accumulateAbsolutePosition
to calculate the length?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using accumulateAbsolutePosition
now to compute the length of a token. For all other nodes I'm still computing the value while constructing the tree because it is faster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good overall! Some comments so far.
@@ -71,6 +71,8 @@ bool isTokenKind(SyntaxKind Kind); | |||
|
|||
bool isUnknownKind(SyntaxKind Kind); | |||
|
|||
bool shallBeOmittedWhenNoChildren(SyntaxKind Kind); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I presume only Parser can omit. Can we move the definition to Parser? leaving it in the node may mislead clients.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to create a gyb file in the parser for this. It is currently still nice and gyb-free.
Maybe we could add this function to the swift
namespace instead of the swift::syntax
one and call it parserShallOmitIfNoChildern
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, it works too, as long as we make it explicit that it's a parser thing rather than for syntax nodes in general.
lib/Parse/SyntaxParsingCache.cpp
Outdated
// | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: 2018
llvm::Optional<Syntax> lookUp(size_t NewPosition, SyntaxKind Kind); | ||
|
||
/// Turn recording of reused ranges on | ||
void recordReuseInformation() { RecordReuseInformation = true; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A better name is setRecordReuseInformation()
.
@@ -112,6 +113,9 @@ class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext { | |||
// Reference to the | |||
SyntaxParsingContext *&CtxtHolder; | |||
|
|||
/// A cache of nodes that can be reused when creating the current syntax tree | |||
SyntaxParsingCache *SyntaxParsingCache = nullptr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could move this instance to RootContextData
. It will make it clear that all SyntaxParsingContext
share a single cache entry. Same with Arena
.
lib/Parse/SyntaxParsingContext.cpp
Outdated
return 0; | ||
} | ||
// Disable this node and push the cached nodes into the storage | ||
disable(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of calling disable()
, can we define another AccumulationMode
called LoadedFromCache
to be more specific? Probably, we can assert LoadedFromCache
context doesn't spawn any child context.
8040453
to
8cc0d25
Compare
8cc0d25
to
e49f2b2
Compare
@swift-ci Please smoke test |
This greatly improves the ergonomics of writing tests and outweighs the ability to test which whitespaces get parsed since their parsing overhead should be minimal.
4eb19c6
to
e2e8972
Compare
@swift-ci Please smoke test |
Creating a new CodeBlockItem meant that when doing an edit in the error nodes, the prefix gets reused and thus the code is parsed as invalid although it is not.
e2e8972
to
4e44e68
Compare
@swift-ci Please smoke test |
🎉🎉🎉 |
This is a work in progress PR to add incremental syntax parsing to the Swift compiler. It accompanies the proposal here and discussion thread here.