-
Notifications
You must be signed in to change notification settings - Fork 440
SyntaxTreeDeserializer: Hold on to omitted nodes across multiple updates #17
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
Conversation
@swift-ci please test |
@rintaro I thought it would be better to have the new syntax tree actually use the original RawSyntax reference from the lookup table, but I couldn't work out how to do that... |
Perhaps we can use "hackish" factory initializer pattern for now. protocol _RawSyntaxFactory {}
extension _RawSyntaxFactory {
fileprivate init(_instance: Self) { self = _instance }
}
extension RawSyntax: Codable, _RawSyntaxFactory {
convenience init(from decoder: Decoder) throws {
if omitted {
/* ... */
let lookupNode = lookupFunc(id)
self.init(_instance: lookupNode)
return
} else {
/* ... */
}
}
} When https://forums.swift.org/t/allow-self-x-in-class-convenience-initializers/15924 is implemented, we probably can migrate to it (i.e. just |
Ah, that's neat! Thanks @rintaro – I'll update shortly. |
75c5504
to
9f0bb49
Compare
@swift-ci please test |
Build failed |
@rintaro Does this look ok now? |
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.
Glad it worked :)
I think we don't need init(_ other: RawSyntax)
(added in af573bf) anymore. Could you delete that?
Otherwise LGTM!
Sources/SwiftSyntax/RawSyntax.swift
Outdated
// This is needed purely to have a self assignment initializer for | ||
// RawSyntax.init(from:Decoder) so we can reuse omitted nodes, instead of | ||
// copying them. | ||
protocol _RawSyntaxFactory {} |
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.
Sorry, this can be private
, and we don't need fileprivate
in init(_instance:)
decl.
RawSyntax.init(from: Decoder) looks up omitted nodes by id from a WeakLookupTable, initializing itself as a copy. This copy is then used in the new tree, but wasn't being written back to the lookup table, leaving it with a weak reference to the original node. This was an issue because the SyntaxTreeDeserializer only holds a strong reference to the most recent syntax tree, meaning the orignal node (and table entry) could have been cleaned up, even though further incremental updates could still refer to that id. This patch changes RawSyntax.init(from: Decoder) to reuse the RawSyntax node from the WeakLookupTable, rather than copying it. Resolves rdar://problem/44877860
32494c7
to
c306a90
Compare
Thanks @rintaro! |
@swift-ci please test |
Build failed |
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.
Thanks!
…ules Allow format rules to be enabled/disabled.
RawSyntax.init(from decoder: Decoder)
looks up omitted nodes by id from aWeakLookupTable
, initializing itself as a copy. This copy is then used in the new tree, but wasn't being written back to the lookup table, leaving it with a weak reference to the original node. This was an issue because theSyntaxTreeDeserializer
only holds a strong reference to the most recent syntax tree, meaning the original node (and table entry) could have been cleaned up, even though further incremental updates could still refer to that id.Resolves rdar://problem/44877860