Skip to content
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

Add result builder support to SubscriptDeclSyntax #2949

Open
thafner0 opened this issue Jan 21, 2025 · 1 comment
Open

Add result builder support to SubscriptDeclSyntax #2949

thafner0 opened this issue Jan 21, 2025 · 1 comment
Labels
enhancement New feature or request

Comments

@thafner0
Copy link

Description

Currently a SubscriptDeclSyntax can only be initialized using a string or the different parts that make it up. Adding the capability for result builders to create accessors would greatly increase the ease of use in generating subscripts. It would be ideal for the result builders to support both the shortened syntax that only provides a getter and the longer syntax providing the ability to declare multiple accessors. Similar to the issue I just opened with the VariableDeclSyntax type not having the ability to declare multiple accessors using result builders (issue #2948), this extension could also use a private shared initializer incorporating the work done by both types and then each specific implementation incorporating the differences specific to that kind of result builder.

Comparison Between Current and Proposed methods

Note that after this change, the existing methods to create subscripts will still be supported. Also, all modifications of this code is to go into the SwiftSyntaxBuilder target since it deals with the result builders. The following usage of the currently available API assumes that SwiftSyntax and SwiftSyntaxBuilder are both imported.

Protocol Requirements

Protocol requirements aren't affected by this change since they have no body. In these cases, continuing to use the SwiftSyntaxBuilder SubscriptDeclSyntax(_:) is sufficient. See the example below:

try! SubscriptDeclSyntax("subscript(_ index: Index) -> Element")

Single Accessor

This code:

SubscriptDeclSyntax(parameterClause: FunctionParameterClauseSyntax(parametersBuilder: {
"_ index: Index"
}),
returnClause: ReturnClauseSyntax(arrow: .arrowToken(leadingTrivia: .space, trailingTrivia: .space), type: TypeSyntax("Element")),
accessorBlock: .getter(CodeBlockItemSyntax {
// code in getter, represented as SwiftSyntax types
})
)

is currently required to generate (the lack of tabs is currently due to it appearing that there isn't a way to tabulate code in GitHub markdown):

subscript(_ index: Index) -> Element {
// code in getter
}

Using result builders, the above code can be simplified to:

try! SubscriptDeclSyntax("subscript(_ index: Index) -> Element") {
// code in getter represented as SwiftSyntax types
}

Multiple Accessors

Similarly we can apply the above code with an additional set accessor generated using the currently available API:

SubscriptDeclSyntax(parameterClause: FunctionParameterClauseSyntax(parametersBuilder: {
"_ index: Index"
}),
returnClause: ReturnClauseSyntax(arrow: .arrowToken(leadingTrivia: .space, trailingTrivia: .space), type: TypeSyntax("Element")),
accessorBlock: .accessors(AccessorDeclListSyntax {
try! AccessorDeclSyntax("get") {
// code in getter represented as SwiftSyntax types
}
try! AccessorDeclSyntax("set") {
// code in setter represented as SwiftSyntax types
}
})
)

which generates:

subscript(_ index: Index) -> Element {
get {
// code in getter
}
set {
// code in setter
}
}

and would be expressible as the following if this feature is adopted:

SubscriptDeclSyntax("subscript(_ index: Index) -> Element") {
try! AccessorDeclSyntax("get") {
// code in getter represented as SwiftSyntax types
}
try! AccessorDeclSyntax("set") {
// code in setter represented as SwiftSyntax types
}
}

Declarations

The method headers that would be added would likely be similar to:

// single getter
public init(_ header: SyntaxNodeString, @CodeBlockItemListBuilder accessor: () throws -> CodeBlockItemListSyntax) throws {
try self.init(header, accessorBlock: .getter(accessor()))
}

// multiple accessors
public init(_ header: SyntaxNodeString, @AccessorDeclListBuilder accessors: () throws -> AccessorDeclListSyntax) throws {
try self.init(header, accessorBlock: .accessors(accessors()))
}

// shared initializer doing any required work that would be common to both of the above public methods, receiving the formatted accessor from the appropriate public method declared above.
private init(_ header: SyntaxNodeString, accessorBlock: AccessorBlockSyntax) throws
@thafner0 thafner0 added the enhancement New feature or request label Jan 21, 2025
@ahoppen
Copy link
Member

ahoppen commented Jan 21, 2025

Synced to Apple’s issue tracker as rdar://143343559

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants