Skip to content

Eliminate SyntaxArena.default #1050

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

Merged
merged 1 commit into from
Nov 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions Sources/SwiftSyntax/Raw/RawSyntax.swift
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@ extension RawSyntax {
/// If the syntax tree did not contain a token and thus no trivia could be attached to it, `nil` is returned.
/// - Parameters:
/// - leadingTrivia: The trivia to attach.
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if you care about keeping parameter docstrings up to date, but if so this one’s missing.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for noticing. Updated.

func withLeadingTrivia(_ leadingTrivia: Trivia) -> RawSyntax? {
/// - arena: SyntaxArena to the result node data resides.
func withLeadingTrivia(_ leadingTrivia: Trivia, arena: SyntaxArena) -> RawSyntax? {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this actually needed? We're always using the one arena for RawSyntax anyway aren't we? You also removed these in your other PR, so there'll be a conflict (?)

switch view {
case .token(let tokenView):
return .makeMaterializedToken(
Expand All @@ -229,7 +230,7 @@ extension RawSyntax {
arena: arena)
case .layout(let layoutView):
for (index, child) in layoutView.children.enumerated() {
if let replaced = child?.withLeadingTrivia(leadingTrivia) {
if let replaced = child?.withLeadingTrivia(leadingTrivia, arena: arena) {
return layoutView.replacingChild(at: index, with: replaced, arena: arena)
}
}
Expand All @@ -241,7 +242,8 @@ extension RawSyntax {
/// If the syntax tree did not contain a token and thus no trivia could be attached to it, `nil` is returned.
/// - Parameters:
/// - trailingTrivia: The trivia to attach.
func withTrailingTrivia(_ trailingTrivia: Trivia) -> RawSyntax? {
/// - arena: SyntaxArena to the result node data resides.
func withTrailingTrivia(_ trailingTrivia: Trivia, arena: SyntaxArena) -> RawSyntax? {
switch view {
case .token(let tokenView):
return .makeMaterializedToken(
Expand All @@ -251,7 +253,7 @@ extension RawSyntax {
arena: arena)
case .layout(let layoutView):
for (index, child) in layoutView.children.enumerated().reversed() {
if let replaced = child?.withTrailingTrivia(trailingTrivia) {
if let replaced = child?.withTrailingTrivia(trailingTrivia, arena: arena) {
return layoutView.replacingChild(at: index, with: replaced, arena: arena)
}
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/SwiftSyntax/Raw/RawSyntaxTokenView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -151,24 +151,24 @@ public struct RawSyntaxTokenView {
/// Returns a `RawSyntax` node with the same source text but with the token
/// kind changed to `newValue`.
@_spi(RawSyntax)
public func withKind(_ newValue: TokenKind) -> RawSyntax {
public func withKind(_ newValue: TokenKind, arena: SyntaxArena) -> RawSyntax {
switch raw.rawData.payload {
case .parsedToken(_):
// The wholeText can't be continuous anymore. Make a materialized token.
return .makeMaterializedToken(
kind: newValue,
leadingTrivia: formLeadingTrivia(),
trailingTrivia: formTrailingTrivia(),
arena: raw.arena)
arena: arena)
case .materializedToken(var payload):
let decomposed = newValue.decomposeToRaw()
let rawKind = decomposed.rawKind
let text: SyntaxText = (decomposed.string.map({raw.arena.intern($0)}) ??
let text: SyntaxText = (decomposed.string.map({arena.intern($0)}) ??
decomposed.rawKind.defaultText ??
"")
payload.tokenKind = rawKind
payload.tokenText = text
return RawSyntax(arena: raw.arena, payload: .materializedToken(payload))
return RawSyntax(arena: arena, payload: .materializedToken(payload))
default:
preconditionFailure("'withTokenKind()' is called on non-token raw syntax")
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/SwiftSyntax/Syntax.swift
Original file line number Diff line number Diff line change
Expand Up @@ -482,13 +482,13 @@ public extension SyntaxProtocol {
/// Returns a new syntax node with its leading trivia replaced
/// by the provided trivia.
func withLeadingTrivia(_ leadingTrivia: Trivia) -> Self {
return Self(Syntax(data.withLeadingTrivia(leadingTrivia)))!
return Self(Syntax(data.withLeadingTrivia(leadingTrivia, arena: SyntaxArena())))!
}

/// Returns a new syntax node with its trailing trivia replaced
/// by the provided trivia.
func withTrailingTrivia(_ trailingTrivia: Trivia) -> Self {
return Self(Syntax(data.withTrailingTrivia(trailingTrivia)))!
return Self(Syntax(data.withTrailingTrivia(trailingTrivia, arena: SyntaxArena())))!
}

/// Returns a new syntax node with its leading trivia removed.
Expand Down
6 changes: 0 additions & 6 deletions Sources/SwiftSyntax/SyntaxArena.swift
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,6 @@ struct SyntaxArenaRef: Equatable {
}
}

extension SyntaxArena {
// FIXME: This is only for migration. All clients should move to "arena" model.
//@available(*, deprecated, message: ".default SyntaxArena is subject to remove soon")
public static let `default` = SyntaxArena()
}

private func _defaultParseTriviaFunction(_ source: SyntaxText, _ position: TriviaPosition) -> [RawTriviaPiece] {
preconditionFailure("Trivia parsing not supported")
}
17 changes: 10 additions & 7 deletions Sources/SwiftSyntax/SyntaxCollections.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,11 @@ public struct ${node.name}: SyntaxCollection, SyntaxHashable {
}

public init(_ children: [Element]) {
let raw = RawSyntax.makeLayout(kind: SyntaxKind.${node.swift_syntax_kind},
from: children.map { $0.raw }, arena: .default)
let data = SyntaxData.forRoot(raw)
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
let raw = RawSyntax.makeLayout(kind: SyntaxKind.${node.swift_syntax_kind},
from: children.map { $0.raw }, arena: arena)
return SyntaxData.forRoot(raw)
}
self.init(data)
}

Expand All @@ -135,8 +137,9 @@ public struct ${node.name}: SyntaxCollection, SyntaxHashable {
/// - Returns: A new `${node.name}` with the new layout underlying it.
internal func replacingLayout(
_ layout: [RawSyntax?]) -> ${node.name} {
let newRaw = layoutView.replacingLayout(with: layout, arena: .default)
let newData = data.replacingSelf(newRaw)
let arena = SyntaxArena()
let newRaw = layoutView.replacingLayout(with: layout, arena: arena)
let newData = data.replacingSelf(newRaw, arena: arena)
return ${node.name}(newData)
}

Expand Down Expand Up @@ -228,13 +231,13 @@ public struct ${node.name}: SyntaxCollection, SyntaxHashable {
/// Returns a new `${node.name}` with its leading trivia replaced
/// by the provided trivia.
public func withLeadingTrivia(_ leadingTrivia: Trivia) -> ${node.name} {
return ${node.name}(data.withLeadingTrivia(leadingTrivia))
return ${node.name}(data.withLeadingTrivia(leadingTrivia, arena: SyntaxArena()))
}

/// Returns a new `${node.name}` with its trailing trivia replaced
/// by the provided trivia.
public func withTrailingTrivia(_ trailingTrivia: Trivia) -> ${node.name} {
return ${node.name}(data.withTrailingTrivia(trailingTrivia))
return ${node.name}(data.withTrailingTrivia(trailingTrivia, arena: SyntaxArena()))
}

/// Returns a new `${node.name}` with its leading trivia removed.
Expand Down
30 changes: 16 additions & 14 deletions Sources/SwiftSyntax/SyntaxData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -322,15 +322,16 @@ struct SyntaxData {

/// Creates a copy of `self` and recursively creates `SyntaxData` nodes up to
/// the root.
/// - parameter newRaw: The new RawSyntax that will back the new `Data`
/// - returns: A tuple of both the new root node and the new data with the raw
/// - Parameters:
/// - newRaw: The new RawSyntax that will back the new `Data`
/// - arena: SyntaxArena to the result RawSyntax node data resides.
/// - Returns: A tuple of both the new root node and the new data with the raw
/// layout replaced.
func replacingSelf(
_ newRaw: RawSyntax) -> SyntaxData {
func replacingSelf(_ newRaw: RawSyntax, arena: SyntaxArena) -> SyntaxData {
// If we have a parent already, then ask our current parent to copy itself
// recursively up to the root.
if let parent = parent {
let parentData = parent.replacingChild(newRaw, at: indexInParent)
let parentData = parent.replacingChild(newRaw, at: indexInParent, arena: arena)
let newParent = Syntax(parentData)
return SyntaxData(absoluteRaw.replacingSelf(newRaw, newRootId: parentData.nodeId.rootId), parent: newParent)
} else {
Expand All @@ -346,25 +347,26 @@ struct SyntaxData {
/// - child: The raw syntax for the new child to replace.
/// - index: The index pointing to where in the raw layout to place this
/// child.
/// - arena: SyntaxArena to the result RawSyntax node data resides.
/// - Returns: The new root node created by this operation, and the new child
/// syntax data.
/// - SeeAlso: replacingSelf(_:)
func replacingChild(_ child: RawSyntax?, at index: Int) -> SyntaxData {
let newRaw = raw.layoutView!.replacingChild(at: index, with: child, arena: .default)
return replacingSelf(newRaw)
func replacingChild(_ child: RawSyntax?, at index: Int, arena: SyntaxArena) -> SyntaxData {
let newRaw = raw.layoutView!.replacingChild(at: index, with: child, arena: arena)
return replacingSelf(newRaw, arena: arena)
}

func withLeadingTrivia(_ leadingTrivia: Trivia) -> SyntaxData {
if let raw = raw.withLeadingTrivia(leadingTrivia) {
return replacingSelf(raw)
func withLeadingTrivia(_ leadingTrivia: Trivia, arena: SyntaxArena) -> SyntaxData {
if let raw = raw.withLeadingTrivia(leadingTrivia, arena: arena) {
return replacingSelf(raw, arena: arena)
} else {
return self
}
}

func withTrailingTrivia(_ trailingTrivia: Trivia) -> SyntaxData {
if let raw = raw.withTrailingTrivia(trailingTrivia) {
return replacingSelf(raw)
func withTrailingTrivia(_ trailingTrivia: Trivia, arena: SyntaxArena) -> SyntaxData {
if let raw = raw.withTrailingTrivia(trailingTrivia, arena: arena) {
return replacingSelf(raw, arena: arena)
} else {
return self
}
Expand Down
48 changes: 26 additions & 22 deletions Sources/SwiftSyntax/SyntaxFactory.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,16 @@ public enum SyntaxFactory {
public static func makeToken(_ kind: TokenKind, presence: SourcePresence,
leadingTrivia: Trivia = [],
trailingTrivia: Trivia = []) -> TokenSyntax {
let raw = RawSyntax.makeMaterializedToken(kind: kind, leadingTrivia: leadingTrivia,
trailingTrivia: trailingTrivia, presence: presence, arena: .default)
let data = SyntaxData.forRoot(raw)
return TokenSyntax(data)
TokenSyntax(
kind,
leadingTrivia: leadingTrivia,
trailingTrivia: trailingTrivia,
presence: presence)
}

@available(*, deprecated, message: "Use initializer on UnknownSyntax")
public static func makeUnknownSyntax(tokens: [TokenSyntax]) -> UnknownSyntax {
let raw = RawSyntax.makeLayout(kind: .unknown,
from: tokens.map { $0.raw }, arena: .default)
let data = SyntaxData.forRoot(raw)
return UnknownSyntax(data)
UnknownSyntax(tokens: tokens)
}

/// MARK: Syntax Node Creation APIs
Expand Down Expand Up @@ -78,37 +76,43 @@ public enum SyntaxFactory {
% end
% end
]
let raw = RawSyntax.makeLayout(kind: SyntaxKind.${node.swift_syntax_kind},
from: layout, arena: .default)
let data = SyntaxData.forRoot(raw)
return ${node.name}(data)
return withExtendedLifetime(SyntaxArena()) { arena in
let raw = RawSyntax.makeLayout(kind: SyntaxKind.${node.swift_syntax_kind},
from: layout, arena: arena)
let data = SyntaxData.forRoot(raw)
return ${node.name}(data)
}
}
% elif node.is_syntax_collection():
@available(*, deprecated, message: "Use initializer on ${node.name}")
public static func make${node.syntax_kind}(
_ elements: [${node.collection_element_type}]) -> ${node.name} {
let raw = RawSyntax.makeLayout(kind: SyntaxKind.${node.swift_syntax_kind},
from: elements.map { $0.raw }, arena: .default)
let data = SyntaxData.forRoot(raw)
return ${node.name}(data)
return withExtendedLifetime(SyntaxArena()) { arena in
let raw = RawSyntax.makeLayout(kind: SyntaxKind.${node.swift_syntax_kind},
from: elements.map { $0.raw }, arena: arena)
let data = SyntaxData.forRoot(raw)
return ${node.name}(data)
}
}
% end

% if not node.is_base():
% default_presence = 'missing' if node.is_missing() else 'present'
@available(*, deprecated, message: "Use initializer on ${node.name}")
public static func makeBlank${node.syntax_kind}(presence: SourcePresence = .${default_presence}) -> ${node.name} {
let data = SyntaxData.forRoot(RawSyntax.makeLayout(kind: .${node.swift_syntax_kind},
from: [
return withExtendedLifetime(SyntaxArena()) { arena in
let data = SyntaxData.forRoot(RawSyntax.makeLayout(kind: .${node.swift_syntax_kind},
from: [
% for child in node.children:
% if child.is_optional:
nil,
nil,
% else:
${make_missing_swift_child(child)},
${make_missing_swift_child(child)},
% end
% end
], arena: .default))
return ${node.name}(data)
], arena: arena))
return ${node.name}(data)
}
}
% end
% end
Expand Down
23 changes: 13 additions & 10 deletions Sources/SwiftSyntax/SyntaxNodes.swift.gyb.template
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public struct ${node.name}: ${base_type}Protocol, SyntaxHashable {
% else:
${child.swift_name}: ${param_type}${comma}
% end
% end
% end
) {
let layout: [RawSyntax?] = [
% for child in node.children:
Expand All @@ -137,9 +137,11 @@ public struct ${node.name}: ${base_type}Protocol, SyntaxHashable {
% end
% end
]
let raw = RawSyntax.makeLayout(kind: SyntaxKind.${node.swift_syntax_kind},
from: layout, arena: .default)
let data = SyntaxData.forRoot(raw)
let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in
let raw = RawSyntax.makeLayout(kind: SyntaxKind.${node.swift_syntax_kind},
from: layout, arena: arena)
return SyntaxData.forRoot(raw)
}
self.init(data)
}
% for (idx, child) in enumerate(node.children):
Expand Down Expand Up @@ -190,13 +192,14 @@ public struct ${node.name}: ${base_type}Protocol, SyntaxHashable {
/// appended to its `${child.swift_name}` collection.
public func add${child_elt}(_ element: ${child_elt_type}) -> ${node.name} {
var collection: RawSyntax
let arena = SyntaxArena()
if let col = raw.layoutView!.children[${idx}] {
collection = col.layoutView!.appending(element.raw, arena: .default)
collection = col.layoutView!.appending(element.raw, arena: arena)
} else {
collection = RawSyntax.makeLayout(kind: SyntaxKind.${child_node.swift_syntax_kind},
from: [element.raw], arena: .default)
from: [element.raw], arena: arena)
}
let newData = data.replacingChild(collection, at: ${idx})
let newData = data.replacingChild(collection, at: ${idx}, arena: arena)
return ${node.name}(newData)
}
% end
Expand All @@ -207,14 +210,14 @@ public struct ${node.name}: ${base_type}Protocol, SyntaxHashable {
/// Returns a copy of the receiver with its `${child.swift_name}` replaced.
/// - param newChild: The new `${child.swift_name}` to replace the node's
/// current `${child.swift_name}`, if present.
public func with${child.name}(
_ newChild: ${child_type}?) -> ${node.name} {
public func with${child.name}(_ newChild: ${child_type}?) -> ${node.name} {
let arena = SyntaxArena()
% if child.is_optional:
let raw = newChild?.raw
% else:
let raw = newChild?.raw ?? ${make_missing_swift_child(child)}
% end
let newData = data.replacingChild(raw, at: ${idx})
let newData = data.replacingChild(raw, at: ${idx}, arena: arena)
return ${node.name}(newData)
}
% end
Expand Down
Loading