-
Notifications
You must be signed in to change notification settings - Fork 440
Allow combining code block item lists #462
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
Allow combining code block item lists #462
Conversation
Thinking about this some more it might make sense to extend this approach to more constructs. Basically everything ending in The pattern would be really similar to the one in the PR, which makes me think it could potentially be added to the code-generation. Following this template extension {{Base}}ListBuilder {
public static func buildExpression(_ expression: {{Base}}List) -> Component {
return expression.elements
}
}
extension{{Base}}List {
public init(combining lists: [ExpressibleAs{{Base}}List]) {
self.elements = lists.flatMap {
$0.create{{Base}}().elements
}
}
} |
Thanks for your PR @anreitersimon, this sounds like a wonderful idea. I also agree that this is not only useful for As you might have already seen, we use |
@ahoppen Thanks for the pointers, i think i figured it out. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. That looks great. I’ve added a few comments inline regarding doc-comments inline. Could you also add a test case for this new behavior?
Do you have any suggestions around the tests? If yes my approach would be to actually go with the example from the description and extend it to handle all the different constructs. protocol CodeGenerator {
@CodeBlockItemListBuilder
var codeBlockItemList: CodeBlockItemList { get }
@TupleExprElementListBuilder
var tupleExprElementList: ExpressibleAsTupleExprElementList { get }
@ArrayElementListBuilder
var arrayElementList: ExpressibleAsArrayElementList { get }
....
} And then test the composition with something like this struct SimpleCodeGenerator {
var codeBlockItemList: CodeBlockItemList { ... }
var tupleExprElementList: ExpressibleAsTupleExprElementList { ... }
}
struct CodeGeneratorPipeline: CodeGenerator {
let steps: [CodeGenerator]
var codeBlockItemList: CodeBlockItemList {
for step in steps {
step.codeBlockItemList
}
}
var tupleExprElementList: ExpressibleAsTupleExprElementList {
for step in steps {
step.tupleExprElementList
}
}
} This approach is really boilerplate heavy though, so maybe this could also use I think it might actually be useful to have a "catalog" of sample data for each of the constructs, which this would provide (at least for the collection-nodes) @ahoppen Do you have any thoughts/suggestions on this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Im specifically wondering if the tests should cover all of the builders, or if it's ok to just cover a few to test that it works in general.
Just testing one builder would be totally fine. I don’t think there’s much value in testing two of them since they are all generated using the same technique.
After finishing your changes, could you squash all of your commits to keep the Git history clean?
1dc64a6
to
fb0a4ef
Compare
@ahoppen I think all the Feedback should be addressed.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good. Thanks for your contribution 🙏
@swift-ci Please test |
1 similar comment
@swift-ci Please test |
Hi!
I was trying to write a SwiftPackage to allow generating some code.
As part of my setup i tried to introduce a abstraction of a
CodeGenStep
.The idea is that i would define multiple
CodeGenStep
, each of them would generate some (top-level) codeAnd i wanted to then loop over all of them and combine their outputs.
I used
CodeBlockItemListBuilder
since that felt most appropriate to generate code in that scope.This worked great!
My problem then was combining these
CodeBlockItemList
s and generating the final result.Also manually merging (outside of the result builder) did also not work, since
CodeBlockItemList.elements
hasinternal
accessLevel so i cannot manually merge themI can imagine this being a common use case so i thought it open up a PR.
My Solution
This basically adds a
buildExpression
to theCodeBlockItemListBuilder
which makes the code snippet above legal.Additionally it provides a initializer to allow combining multiple
CodeBlockItemList
s into one.