Skip to content

Allow putting garbage nodes in between any two children of a Syntax node #514

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 4 commits into from
Aug 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
3 changes: 0 additions & 3 deletions Sources/SwiftSyntax/SyntaxAnyVisitor.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@
/// }
///
open class SyntaxAnyVisitor: SyntaxVisitor {
/// Visiting `UnknownSyntax` specifically.
/// - Parameter node: the node we are visiting.
/// - Returns: how should we continue visiting.
open func visitAny(_ node: Syntax) -> SyntaxVisitorContinueKind {
return .visitChildren
}
Expand Down
4 changes: 3 additions & 1 deletion Sources/SwiftSyntax/SyntaxBuilders.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ public struct ${Builder} {
Array<RawSyntax?>(repeating: nil, count: ${len(node.children)})

internal init() {}
% for child in node.children:
% # SyntaxBuilder doesn't support adding garbage nodes at the moment
% # This could be added in the future, if needed.
% for child in node.non_garbage_children:
% child_node = NODE_MAP.get(child.syntax_kind)
% if child_node and child_node.is_syntax_collection():
% child_elt = child.collection_element_name
Expand Down
14 changes: 11 additions & 3 deletions Sources/SwiftSyntax/SyntaxFactory.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,18 @@ public enum SyntaxFactory {
% elif node.children:
% child_params = []
% for child in node.children:
% param_type = child.type_name
% if child.is_optional:
% param_type = param_type + "?"
% param_type = child.type_name
% if child.is_optional:
% param_type = param_type + "?"
% end
% if child.is_garbage_nodes():
% # It would be nice if we could label all of these arguments 'garbage'.
% # But if we do this, we hit https://github.com/apple/swift/issues/60274.
% child_params.append("_ %s: %s = nil" % (child.swift_name, param_type))
% else:
% child_params.append("%s: %s" % (child.swift_name, param_type))
% end
% end
% child_params = ', '.join(child_params)
public static func make${node.syntax_kind}(${child_params}) -> ${node.name} {
let layout: [RawSyntax?] = [
Expand Down
4 changes: 3 additions & 1 deletion Sources/SwiftSyntax/SyntaxNodes.swift.gyb.template
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ public struct ${node.name}: ${base_type}Protocol, SyntaxHashable {
% # ===============
% # Adding children
% # ===============
% if child_node and child_node.is_syntax_collection():
% # We don't currently support adding elements to a specific garbage collection.
% # If needed, this could be added in the future, but for now withGarbage should be sufficient.
% if child_node and child_node.is_syntax_collection() and not child.is_garbage_nodes():
% child_elt = child.collection_element_name
% child_elt_type = child_node.collection_element_type
% if not child_elt:
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftSyntax/SyntaxTreeViewMode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public enum SyntaxTreeViewMode {
case .sourceAccurate:
return node.presence == .present
case .fixedUp:
return true
return node.kind != .garbageNodes
case ._all:
return true
}
Expand Down
20 changes: 20 additions & 0 deletions Sources/SwiftSyntax/Trivia.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,26 @@ extension Trivia: ExpressibleByArrayLiteral {
}
}

extension Trivia: TextOutputStreamable {
/// Prints the provided trivia as they would be written in a source file.
///
/// - Parameter stream: The stream to which to print the trivia.
public func write<Target>(to target: inout Target)
where Target: TextOutputStream {
for piece in pieces {
piece.write(to: &target)
}
}
}

extension Trivia: CustomStringConvertible {
public var description: String {
var description = ""
self.write(to: &description)
return description
}
}

/// Concatenates two collections of `Trivia` into one collection.
public func +(lhs: Trivia, rhs: Trivia) -> Trivia {
return Trivia(pieces: lhs.pieces + rhs.pieces)
Expand Down
8 changes: 8 additions & 0 deletions Sources/SwiftSyntax/gyb_generated/Misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ extension SyntaxNode {
return CodeBlockSyntax(asSyntaxData)
}

public var isGarbageNodes: Bool { return raw.kind == .garbageNodes }
public var asGarbageNodes: GarbageNodesSyntax? {
guard isGarbageNodes else { return nil }
return GarbageNodesSyntax(asSyntaxData)
}

public var isInOutExpr: Bool { return raw.kind == .inOutExpr }
public var asInOutExpr: InOutExprSyntax? {
guard isInOutExpr else { return nil }
Expand Down Expand Up @@ -1601,6 +1607,8 @@ extension Syntax {
return node
case .codeBlock(let node):
return node
case .garbageNodes(let node):
return node
case .inOutExpr(let node):
return node
case .poundColumnExpr(let node):
Expand Down
10 changes: 7 additions & 3 deletions Sources/SwiftSyntax/gyb_generated/SyntaxAnyVisitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@
/// }
///
open class SyntaxAnyVisitor: SyntaxVisitor {
/// Visiting `UnknownSyntax` specifically.
/// - Parameter node: the node we are visiting.
/// - Returns: how should we continue visiting.
open func visitAny(_ node: Syntax) -> SyntaxVisitorContinueKind {
return .visitChildren
}
Expand Down Expand Up @@ -162,6 +159,13 @@ open class SyntaxAnyVisitor: SyntaxVisitor {
override open func visitPost(_ node: CodeBlockSyntax) {
visitAnyPost(node._syntaxNode)
}
override open func visit(_ node: GarbageNodesSyntax) -> SyntaxVisitorContinueKind {
return visitAny(node._syntaxNode)
}

override open func visitPost(_ node: GarbageNodesSyntax) {
visitAnyPost(node._syntaxNode)
}
override open func visit(_ node: InOutExprSyntax) -> SyntaxVisitorContinueKind {
return visitAny(node._syntaxNode)
}
Expand Down
Loading