Rework Async tree-sitter
Model, Fix Strong Ref Cycle
#225
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
DispatchQueue
and SwiftTask
s. Improving code readability and safety.SwiftTreeSitter
to0.8.0
, incorporating API changes and improvements from that package.Highlighter
class.Reworks the asynchronous tree-sitter model to correctly use Swift's structured concurrency.In more detail:
The current async tree-sitter implementation uses a mix of Swift
Task
s,pthread
locks and a custom task scheduler to perform highlight operations asynchronously. This is dangerous for a variety of reasons, so theTreeSitterClient
object has been reworked.Instead of a class, it is now anactor
. Meaning it's still a reference type, but now all asynchronous accesses are performed serially using swift's process pool. This removes the need for any custom locking mechanism, and reduces the likelihood of data races and deadlocks. This also means all operations on the client must be performed asynchronously, so the HighlightProviding protocol has been updated to use async functions in place of callbacks. Finally, the Highlighter class has been updated to keep a set of currently running tasks and provides a method to cancel them if needed.The client has been reworked to use a single
DispatchQueue
to coordinate serial access to the client. This allows the object to perform an operation either synchronously or asynchronously depending on a variety of factors. In addition to dispatching all operations to a serial queue, we enforce usage of the client from the main queue to ensure all method calls are performed serially.I did mention in my comment that I wanted to use locks, but ended up not needing any due to the use of serial queues.
This change is an improvement for two reasons:
Filter
object rather than being forced to muck around with Tasks and async calls. In addition the client will simply throw an error if a synchronous call is unsafe. It'll be up to the caller to decide if an asynchronous call should be performed afterwards.The strong reference cycle occurred in the Coordinator for CodeEditSourceEditor, which was keeping an optional (but not weak) reference to the text view controller. This has been made weak, correctly referencing the controller. There was also a strong reference cycle between
Highlighter
and the text view controller that has been corrected.Related Issues
Checklist