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

Generate BuildableNodes with SwiftSyntaxBuilderGeneration #555

Merged
merged 4 commits into from
Aug 16, 2022

Conversation

fwcd
Copy link
Member

@fwcd fwcd commented Aug 4, 2022

This PR ports the currently gyb-generated BuildableNodes to SwiftSyntaxBuilder's DSL as part of the ongoing effort to bootstrap SwiftSyntaxBuilder with SwiftSyntaxBuilderGeneration.

Currently blocked on

To do:

  • Generate BuildableNodes using SwiftSyntaxBuilderGeneration
  • Remove the current gyb-generation (and its associated exclude from the Package.swift)

Copy link
Member Author

@fwcd fwcd left a comment

Choose a reason for hiding this comment

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

Two notes on the implementation below. Another thing that we might want to look into is producing nicer formatting for very long parameter lists, for example by inserting .newline trivias:

func someFunction(
  first: First,
  second: Second,
  third: Third
)

instead of

func someFunction(first: First, second: Second, third: Third)

This would, if handled generically, be out-of-scope for this PR, but ideas or thoughts on this are of course welcome.

Comment on lines 85 to 108

/// Generate the `create...` function for an `ExpressibleAs...` conformance.
func createExpressibleAsCreateFunction(type: SyntaxBuildableType, additionalDocComments: [String] = []) -> FunctionDecl {
FunctionDecl(
leadingTrivia: ([
"/// Conformance to `\(type.expressibleAsBaseName)`.",
] + additionalDocComments).map { .docLineComment($0) + .newline }.reduce([], +),
modifiers: [TokenSyntax.public],
identifier: .identifier("create\(type.buildableBaseName)"),
signature: FunctionSignature(
input: ParameterClause(),
output: type.buildable
)
) {
ReturnStmt(expression: "self")
}
}

/// Generate the `create...` function for an `ExpressibleAs...` conformance
/// that includes an explanation as to how the function disambiguates a conformance.
func createDisambiguatingExpressibleAsCreateFunction(type: SyntaxBuildableType, baseType: SyntaxBuildableType) -> FunctionDecl {
createExpressibleAsCreateFunction(type: baseType, additionalDocComments: [
"/// `\(type.buildableBaseName)` may conform to `\(baseType.expressibleAsBaseName)` via different `ExpressibleAs*` paths.",
"/// Thus, there are multiple default implementations of `create\(baseType.buildableBaseName)`, some of which perform conversions",
"/// through `ExpressibleAs*` protocols. To resolve the ambiguity, provie a fixed implementation that doesn't perform any conversions.",
])
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This PR factors out the create... functions generated for the ExpressibleAs... conformances. This is particularly nice since we can share a lot of logic between BuildableNodes and BuildableCollectionNodes, including this lengthy doc comment that explains how the function disambiguates the implementation.

@fwcd
Copy link
Member Author

fwcd commented Aug 15, 2022

@swift-ci please test

Copy link
Contributor

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

Some minor stylistic comments inline. Otherwise LGTM.

- Set up BuildableNodesFile
- Generate BuildableNodes members
- Use ...BaseName where needed in BuildableNodesFile
- Generate default initializer in BuildableNodes fully
- Disable assert stmt generation until swiftlang#549 is fixed
- Generate convenience initializer parameters
- Generate convenience initializer declaration
- Use ParameterClause builder initializer
- Generate initializer delegations
- Generate build method in BuildableNodes
- Generate build base type method in BuildableNodes
- Generate expressible-as conformance in BuildableNodes
- Generate base type ExpressibleAs conformance
- Generate disambiguating conformances in BuildableNodes
- Generate withTrailingComma function in BuildableNodes
- Escape token names in backticks
- Bootstrap BuildableNodes
- Replace deprecated SyntaxFactory in BuildableNodesFile
- Resolve style issues
@fwcd fwcd force-pushed the buildable-nodes-swift-syntax-gen branch from b006e6e to e16cb8b Compare August 16, 2022 14:16
@fwcd
Copy link
Member Author

fwcd commented Aug 16, 2022

@swift-ci please test

@fwcd fwcd merged commit 23d38a1 into swiftlang:main Aug 16, 2022
@fwcd fwcd deleted the buildable-nodes-swift-syntax-gen branch August 16, 2022 16:09
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.

None yet

2 participants