Skip to content

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

nathawes
Copy link

RawSyntax.init(from decoder: 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 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

@nathawes
Copy link
Author

@swift-ci please test

@nathawes nathawes requested a review from rintaro September 29, 2018 02:00
@nathawes
Copy link
Author

@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...

@rintaro
Copy link
Member

rintaro commented Sep 29, 2018

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 self = lookupNode )

@nathawes
Copy link
Author

nathawes commented Oct 1, 2018

Ah, that's neat! Thanks @rintaro – I'll update shortly.

@nathawes nathawes force-pushed the r44877860-hold-on-to-omitted-syntax-nodes-across-multiple-incremental-updates branch from 75c5504 to 9f0bb49 Compare October 1, 2018 17:42
@nathawes
Copy link
Author

nathawes commented Oct 1, 2018

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Oct 1, 2018

Build failed
Swift Test OS X Platform
Git Sha - 75c5504

@nathawes
Copy link
Author

nathawes commented Oct 1, 2018

@rintaro Does this look ok now?

Copy link
Member

@rintaro rintaro left a 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!

// 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 {}
Copy link
Member

@rintaro rintaro Oct 2, 2018

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
@nathawes nathawes force-pushed the r44877860-hold-on-to-omitted-syntax-nodes-across-multiple-incremental-updates branch from 32494c7 to c306a90 Compare October 2, 2018 02:45
@nathawes
Copy link
Author

nathawes commented Oct 2, 2018

Thanks @rintaro!

@nathawes
Copy link
Author

nathawes commented Oct 2, 2018

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Oct 2, 2018

Build failed
Swift Test OS X Platform
Git Sha - 9f0bb49

Copy link
Member

@rintaro rintaro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@nathawes nathawes merged commit 4180bb0 into swiftlang:master Oct 2, 2018
@nathawes nathawes deleted the r44877860-hold-on-to-omitted-syntax-nodes-across-multiple-incremental-updates branch October 2, 2018 16:14
adevress pushed a commit to adevress/swift-syntax that referenced this pull request Jan 14, 2024
…ules

Allow format rules to be enabled/disabled.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants