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 @resultbuilder with SwiftSyntaxBuilder #479

Merged
merged 1 commit into from Oct 6, 2022

Conversation

kimdv
Copy link
Collaborator

@kimdv kimdv commented Jun 30, 2022

Depends on

This is still WIP, and there is still some way to go!

With gyb

@resultBuilder
public struct CodeBlockItemListBuilder {

  /// The type of individual statement expressions in the transformed function,
  /// which defaults to Component if buildExpression() is not provided.
  public typealias Expression = ExpressibleAsCodeBlockItem

  /// The type of a partial result, which will be carried through all of the
  /// build methods.
  public typealias Component = [ExpressibleAsCodeBlockItem]

  /// The type of the final returned result, which defaults to Component if
  /// buildFinalResult() is not provided.
  public typealias FinalResult = CodeBlockItemList

  /// Required by every result builder to build combined results from
  /// statement blocks.
  public static func buildBlock(_ components: Component...) -> Component {
    return components.flatMap { $0 }
  }

  /// If declared, provides contextual type information for statement
  /// expressions to translate them into partial results.
  public static func buildExpression(_ expression: Expression) -> Component {
    return [expression]
  }
  
  /// Add all the elements of `expression` to this result builder, effectively flattening them.
  public static func buildExpression(_ expression: ExpressibleAsCodeBlockItemList) -> Component {
    return expression.createCodeBlockItemList().elements
  }
  
  /// Enables support for `if` statements that do not have an `else`.
  public static func buildOptional(_ component: Component?) -> Component {
    return component ?? []
  }

  /// With buildEither(second:), enables support for 'if-else' and 'switch'
  /// statements by folding conditional results into a single result.
  public static func buildEither(first component: Component) -> Component {
    return component
  }

  /// With buildEither(first:), enables support for 'if-else' and 'switch'
  /// statements by folding conditional results into a single result.
  public static func buildEither(second component: Component) -> Component {
    return component
  }

  /// Enables support for 'for..in' loops by combining the
  /// results of all iterations into a single result.
  public static func buildArray(_ components: [Component]) -> Component {
    return components.flatMap { $0 }
  }

  /// If declared, this will be called on the partial result of an 'if
  /// #available' block to allow the result builder to erase type
  /// information.
  public static func buildLimitedAvailability(_ component: Component) -> Component {
    return component
  }

  /// If declared, this will be called on the partial result from the outermost
  /// block statement to produce the final returned result.
  public static func buildFinalResult(_ component: Component) -> FinalResult {
    return .init(component.map { $0.createCodeBlockItem() })
  }
}

With SwiftSyntaxBuilderGeneration

@resultBuilder
public struct CodeBlockItemListBuilder{
  
/// Required by every result builder to build combined results from
/// statement blocks.
public static func buildBlock(_ components: Component...)-> Component{
    return components.flatMap()
  }
  
/// If declared, provides contextual type information for statement
/// expressions to translate them into partial results.
public static func buildExpression(_ expression: Expression)-> Component{
    return [expression]
  }
  
/// Add all the elements of `expression` to this result builder, effectively flattening them.
public static func buildExpression(_ expression: ExpressibleAsCodeBlockItemList)-> Component{
    return components.flatMap()
  }
  
/// Enables support for `if` statements that do not have an `else`.
public static func buildOptional(_ component: Component?)-> Component{
    return component??[]
  }
  
/// With buildEither(second:), enables support for 'if-else' and 'switch'
/// statements by folding conditional results into a single result.
public static func buildEither(firstcomponent: Component)-> Component{
    return component
  }
  
/// With buildEither(first:), enables support for 'if-else' and 'switch'
/// statements by folding conditional results into a single result.
public static func buildEither(secondcomponent: Component)-> Component{
    return component
  }
  
/// Enables support for 'for..in' loops by combining the
/// results of all iterations into a single result.
public static func buildArray(_ components: [Component])-> Component{
    return .component
  }
  
/// If declared, this will be called on the partial result of an 'if'
/// #available' block to allow the result builder to erase type
/// information.
public static func buildLimitedAvailability(_ component: Component)-> Component{
    return component
  }
  
/// If declared, this will be called on the partial result from the outermost
/// block statement to produce the final returned result.
public static func buildFinalResult(_ component: Component)-> Component{
  }
}

@kimdv kimdv force-pushed the kimdv/generate-result-builders branch 4 times, most recently from 239cf69 to 674aa55 Compare July 2, 2022 10:40
@kimdv kimdv force-pushed the kimdv/generate-result-builders branch 3 times, most recently from 8bae013 to bfddb19 Compare July 3, 2022 12:07
@kimdv kimdv force-pushed the kimdv/generate-result-builders branch 4 times, most recently from 110ee66 to af7f529 Compare July 3, 2022 12:50
@kimdv kimdv force-pushed the kimdv/generate-result-builders branch 4 times, most recently from c5d7ecc to 3c93b41 Compare July 10, 2022 13:15
@kimdv kimdv force-pushed the kimdv/generate-result-builders branch 3 times, most recently from 89ca58c to 6e0d3e9 Compare July 18, 2022 14:57
@kimdv kimdv force-pushed the kimdv/generate-result-builders branch 3 times, most recently from d2c2965 to f392841 Compare August 4, 2022 21:16
@kimdv kimdv force-pushed the kimdv/generate-result-builders branch from f392841 to 22d6d5e Compare August 4, 2022 21:34
Copy link
Collaborator

@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.

A few style nitpicks, but otherwise this looks good! 👍

@kimdv kimdv force-pushed the kimdv/generate-result-builders branch from 22d6d5e to 520be78 Compare August 12, 2022 09:05
@kimdv kimdv force-pushed the kimdv/generate-result-builders branch 5 times, most recently from fd637f7 to 683348d Compare August 28, 2022 13:26
@kimdv kimdv force-pushed the kimdv/generate-result-builders branch 3 times, most recently from f15d0e9 to d92b600 Compare September 21, 2022 06:10
@kimdv kimdv force-pushed the kimdv/generate-result-builders branch 2 times, most recently from 0299cb3 to 7c0c02c Compare October 4, 2022 21:13
@kimdv kimdv force-pushed the kimdv/generate-result-builders branch 3 times, most recently from 2455f59 to d3b66f0 Compare October 5, 2022 11:56
@kimdv kimdv marked this pull request as ready for review October 5, 2022 11:57
@kimdv kimdv requested a review from ahoppen as a code owner October 5, 2022 11:57
@kimdv kimdv requested a review from fwcd October 5, 2022 11:57
@@ -16,73 +17,61 @@ import SwiftSyntax

@resultBuilder
public struct CodeBlockItemListBuilder {

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Is there a way with the new API to add new lines, without should adding a empty line at the beginning of each Decl

@kimdv
Copy link
Collaborator Author

kimdv commented Oct 5, 2022

@swift-ci please test

@kimdv kimdv force-pushed the kimdv/generate-result-builders branch from d3b66f0 to afcff8f Compare October 5, 2022 12:57
/// Required by every result builder to build combined results from
/// statement blocks.
public static func buildBlock(_ components: Component...) -> Component {
return components.flatMap { $0 }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since all of these functions return single expressions, we could omit the return here (and in the other builder functions).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I had the discussion with @ahoppen at some point.

We decided on going with explicit return, if remember correctly.

Not sure if that opinion have changed?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I have a general preference for explicit return, but that might be personal. I gave up actively fighting against implicit returns 😆

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Personally I also like returns in methods as it read better IMO 😬


FunctionDecl(
leadingTrivia: [
.newlines(1),
Copy link
Collaborator

Choose a reason for hiding this comment

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

.newlines(1) be shortened to .newline IIRC

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think it's on Trivia

At least I get Type 'TriviaPiece' has no member 'newline'

@kimdv kimdv force-pushed the kimdv/generate-result-builders branch 2 times, most recently from e6a4933 to 98140cb Compare October 5, 2022 16:38
Copy link
Collaborator

@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.

Wohoo. This was so easy to review.

@ahoppen
Copy link
Collaborator

ahoppen commented Oct 6, 2022

@swift-ci Please test

@kimdv kimdv force-pushed the kimdv/generate-result-builders branch from 98140cb to f3f331a Compare October 6, 2022 09:20
@kimdv
Copy link
Collaborator Author

kimdv commented Oct 6, 2022

@swift-ci please test

@kimdv kimdv merged commit b2ed797 into apple:main Oct 6, 2022
@kimdv kimdv deleted the kimdv/generate-result-builders branch December 14, 2022 14:25
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

4 participants