Skip to content

Support attributes on closures #287

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
May 24, 2021
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
2 changes: 1 addition & 1 deletion Sources/SwiftSyntax/gyb_generated/Misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1960,6 +1960,6 @@ extension Syntax {
extension SyntaxParser {
static func verifyNodeDeclarationHash() -> Bool {
return String(cString: swiftparse_syntax_structure_versioning_identifier()!) ==
"4f85168b3860f575ce60ac0d223fc89da37014df"
"a66df9d44b9128aee3da17e9b0d2aed27ce7ec61"
}
}
17 changes: 14 additions & 3 deletions Sources/SwiftSyntax/gyb_generated/SyntaxBuilders.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1917,10 +1917,21 @@ extension ClosureParamSyntax {

public struct ClosureSignatureSyntaxBuilder {
private var layout =
Array<RawSyntax?>(repeating: nil, count: 6)
Array<RawSyntax?>(repeating: nil, count: 7)

internal init() {}

public mutating func addAttribute(_ elt: Syntax) {
let idx = ClosureSignatureSyntax.Cursor.attributes.rawValue
if let list = layout[idx] {
layout[idx] = list.appending(elt.raw)
} else {
layout[idx] = RawSyntax.create(kind: SyntaxKind.attributeList,
layout: [elt.raw], length: elt.raw.totalLength,
presence: SourcePresence.present)
}
}

public mutating func useCapture(_ node: ClosureCaptureSignatureSyntax) {
let idx = ClosureSignatureSyntax.Cursor.capture.rawValue
layout[idx] = node.raw
Expand Down Expand Up @@ -1952,8 +1963,8 @@ public struct ClosureSignatureSyntaxBuilder {
}

internal mutating func buildData() -> SyntaxData {
if (layout[5] == nil) {
layout[5] = RawSyntax.missingToken(TokenKind.inKeyword)
if (layout[6] == nil) {
layout[6] = RawSyntax.missingToken(TokenKind.inKeyword)
}

return .forRoot(RawSyntax.createAndCalcLength(kind: .closureSignature,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ extension SyntaxClassification {
return (.keyword, false)
case (.arrowExpr, 0):
return (.keyword, false)
case (.closureSignature, 2):
case (.closureSignature, 3):
return (.keyword, false)
case (.expressionSegment, 2):
return (.stringInterpolationAnchor, true)
Expand Down
4 changes: 3 additions & 1 deletion Sources/SwiftSyntax/gyb_generated/SyntaxFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -996,8 +996,9 @@ public enum SyntaxFactory {
], length: .zero, presence: .present))
return ClosureParamListSyntax(data)
}
public static func makeClosureSignature(capture: ClosureCaptureSignatureSyntax?, input: Syntax?, asyncKeyword: TokenSyntax?, throwsTok: TokenSyntax?, output: ReturnClauseSyntax?, inTok: TokenSyntax) -> ClosureSignatureSyntax {
public static func makeClosureSignature(attributes: AttributeListSyntax?, capture: ClosureCaptureSignatureSyntax?, input: Syntax?, asyncKeyword: TokenSyntax?, throwsTok: TokenSyntax?, output: ReturnClauseSyntax?, inTok: TokenSyntax) -> ClosureSignatureSyntax {
let layout: [RawSyntax?] = [
attributes?.raw,
capture?.raw,
input?.raw,
asyncKeyword?.raw,
Expand All @@ -1019,6 +1020,7 @@ public enum SyntaxFactory {
nil,
nil,
nil,
nil,
RawSyntax.missingToken(TokenKind.inKeyword),
], length: .zero, presence: .present))
return ClosureSignatureSyntax(data)
Expand Down
73 changes: 62 additions & 11 deletions Sources/SwiftSyntax/gyb_generated/syntax_nodes/SyntaxNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1503,6 +1503,7 @@ extension ClosureParamSyntax: CustomReflectable {

public struct ClosureSignatureSyntax: SyntaxProtocol, SyntaxHashable {
enum Cursor: Int {
case attributes
case capture
case input
case asyncKeyword
Expand Down Expand Up @@ -1532,6 +1533,47 @@ public struct ClosureSignatureSyntax: SyntaxProtocol, SyntaxHashable {
return Swift.type(of: self)
}

public var attributes: AttributeListSyntax? {
get {
let childData = data.child(at: Cursor.attributes,
parent: Syntax(self))
if childData == nil { return nil }
return AttributeListSyntax(childData!)
}
set(value) {
self = withAttributes(value)
}
}

/// Adds the provided `Attribute` to the node's `attributes`
/// collection.
/// - param element: The new `Attribute` to add to the node's
/// `attributes` collection.
/// - returns: A copy of the receiver with the provided `Attribute`
/// appended to its `attributes` collection.
public func addAttribute(_ element: Syntax) -> ClosureSignatureSyntax {
var collection: RawSyntax
if let col = raw[Cursor.attributes] {
collection = col.appending(element.raw)
} else {
collection = RawSyntax.create(kind: SyntaxKind.attributeList,
layout: [element.raw], length: element.raw.totalLength, presence: .present)
}
let newData = data.replacingChild(collection,
at: Cursor.attributes)
return ClosureSignatureSyntax(newData)
}

/// Returns a copy of the receiver with its `attributes` replaced.
/// - param newChild: The new `attributes` to replace the node's
/// current `attributes`, if present.
public func withAttributes(
_ newChild: AttributeListSyntax?) -> ClosureSignatureSyntax {
let raw = newChild?.raw
let newData = data.replacingChild(raw, at: Cursor.attributes)
return ClosureSignatureSyntax(newData)
}

public var capture: ClosureCaptureSignatureSyntax? {
get {
let childData = data.child(at: Cursor.capture,
Expand Down Expand Up @@ -1666,30 +1708,30 @@ public struct ClosureSignatureSyntax: SyntaxProtocol, SyntaxHashable {

public func _validateLayout() {
let rawChildren = Array(RawSyntaxChildren(Syntax(self)))
assert(rawChildren.count == 6)
// Check child #0 child is ClosureCaptureSignatureSyntax or missing
assert(rawChildren.count == 7)
// Check child #0 child is AttributeListSyntax or missing
if let raw = rawChildren[0].raw {
let info = rawChildren[0].syntaxInfo
let absoluteRaw = AbsoluteRawSyntax(raw: raw, info: info)
let syntaxData = SyntaxData(absoluteRaw, parent: Syntax(self))
let syntaxChild = Syntax(syntaxData)
assert(syntaxChild.is(ClosureCaptureSignatureSyntax.self))
assert(syntaxChild.is(AttributeListSyntax.self))
}
// Check child #1 child is Syntax or missing
// Check child #1 child is ClosureCaptureSignatureSyntax or missing
if let raw = rawChildren[1].raw {
let info = rawChildren[1].syntaxInfo
let absoluteRaw = AbsoluteRawSyntax(raw: raw, info: info)
let syntaxData = SyntaxData(absoluteRaw, parent: Syntax(self))
let syntaxChild = Syntax(syntaxData)
assert(syntaxChild.is(Syntax.self))
assert(syntaxChild.is(ClosureCaptureSignatureSyntax.self))
}
// Check child #2 child is TokenSyntax or missing
// Check child #2 child is Syntax or missing
if let raw = rawChildren[2].raw {
let info = rawChildren[2].syntaxInfo
let absoluteRaw = AbsoluteRawSyntax(raw: raw, info: info)
let syntaxData = SyntaxData(absoluteRaw, parent: Syntax(self))
let syntaxChild = Syntax(syntaxData)
assert(syntaxChild.is(TokenSyntax.self))
assert(syntaxChild.is(Syntax.self))
}
// Check child #3 child is TokenSyntax or missing
if let raw = rawChildren[3].raw {
Expand All @@ -1699,21 +1741,29 @@ public struct ClosureSignatureSyntax: SyntaxProtocol, SyntaxHashable {
let syntaxChild = Syntax(syntaxData)
assert(syntaxChild.is(TokenSyntax.self))
}
// Check child #4 child is ReturnClauseSyntax or missing
// Check child #4 child is TokenSyntax or missing
if let raw = rawChildren[4].raw {
let info = rawChildren[4].syntaxInfo
let absoluteRaw = AbsoluteRawSyntax(raw: raw, info: info)
let syntaxData = SyntaxData(absoluteRaw, parent: Syntax(self))
let syntaxChild = Syntax(syntaxData)
assert(syntaxChild.is(ReturnClauseSyntax.self))
assert(syntaxChild.is(TokenSyntax.self))
}
// Check child #5 child is TokenSyntax
assert(rawChildren[5].raw != nil)
// Check child #5 child is ReturnClauseSyntax or missing
if let raw = rawChildren[5].raw {
let info = rawChildren[5].syntaxInfo
let absoluteRaw = AbsoluteRawSyntax(raw: raw, info: info)
let syntaxData = SyntaxData(absoluteRaw, parent: Syntax(self))
let syntaxChild = Syntax(syntaxData)
assert(syntaxChild.is(ReturnClauseSyntax.self))
}
// Check child #6 child is TokenSyntax
assert(rawChildren[6].raw != nil)
if let raw = rawChildren[6].raw {
let info = rawChildren[6].syntaxInfo
let absoluteRaw = AbsoluteRawSyntax(raw: raw, info: info)
let syntaxData = SyntaxData(absoluteRaw, parent: Syntax(self))
let syntaxChild = Syntax(syntaxData)
assert(syntaxChild.is(TokenSyntax.self))
}
}
Expand All @@ -1722,6 +1772,7 @@ public struct ClosureSignatureSyntax: SyntaxProtocol, SyntaxHashable {
extension ClosureSignatureSyntax: CustomReflectable {
public var customMirror: Mirror {
return Mirror(self, children: [
"attributes": attributes.map(Syntax.init)?.asProtocol(SyntaxProtocol.self) as Any,
"capture": capture.map(Syntax.init)?.asProtocol(SyntaxProtocol.self) as Any,
"input": input.map(Syntax.init)?.asProtocol(SyntaxProtocol.self) as Any,
"asyncKeyword": asyncKeyword.map(Syntax.init)?.asProtocol(SyntaxProtocol.self) as Any,
Expand Down
4 changes: 4 additions & 0 deletions Sources/SwiftSyntaxBuilder/gyb_generated/Buildables.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1879,6 +1879,7 @@ public struct ClosureParamList: SyntaxBuildable {
}

public struct ClosureSignature: SyntaxBuildable {
let attributes: AttributeList?
let capture: ClosureCaptureSignature?
let input: SyntaxBuildable?
let asyncKeyword: TokenSyntax?
Expand All @@ -1887,13 +1888,15 @@ public struct ClosureSignature: SyntaxBuildable {
let inTok: TokenSyntax

public init(
attributes: AttributeList? = nil,
capture: ClosureCaptureSignature? = nil,
input: SyntaxBuildable? = nil,
asyncKeyword: TokenSyntax? = nil,
throwsTok: TokenSyntax? = nil,
output: ReturnClause? = nil,
inTok: TokenSyntax
) {
self.attributes = attributes
self.capture = capture
self.input = input
self.asyncKeyword = asyncKeyword
Expand All @@ -1904,6 +1907,7 @@ public struct ClosureSignature: SyntaxBuildable {

func buildClosureSignature(format: Format, leadingTrivia: Trivia? = nil) -> ClosureSignatureSyntax {
let closureSignature = SyntaxFactory.makeClosureSignature(
attributes: attributes?.buildAttributeList(format: format),
capture: capture?.buildClosureCaptureSignature(format: format),
input: input?.buildSyntax(format: format),
asyncKeyword: asyncKeyword,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,28 @@ extension ClosureCaptureSignature {
}
}

extension ClosureSignature {
public init(
@AttributeListBuilder attributesBuilder: () -> AttributeList? = { nil },
capture: ClosureCaptureSignature? = nil,
input: SyntaxBuildable? = nil,
asyncKeyword: String?,
throwsTok: TokenSyntax? = nil,
output: ReturnClause? = nil,
inTok: TokenSyntax = Tokens.`in`
) {
self.init(
attributes: attributesBuilder(),
capture: capture,
input: input,
asyncKeyword: asyncKeyword.map({ SyntaxFactory.makeIdentifier($0) }),
throwsTok: throwsTok,
output: output,
inTok: inTok
)
}
}

extension ClosureExpr {
public init(
leftBrace: TokenSyntax = Tokens.`leftBrace`,
Expand Down