Thanks @ahoppen for your comment regarding the proposed solution,
by Integrating the process of generating code i meant editing (build_script) to support newly added featuers (executing/running generate-swift-syntax-builder.. etc), am i understaing it correctly ?
Update: Comments implemention
i’ve started working on comments implementation as discussed in my previous comments, and here’s what i’ve reached until now, and my questions regarding the implementations,
(should this discussion about implemention placed somewhere else ? please let me know )
1- i have started by editing BuildableNodes.swift.gyb to add
var leadingTrivia: Trivia? = nil
inatilly, i found that properties of each struct is based on its childeren, and AFAIK leading trivia can't be considered as a child, so i added it manually inside the struct
public struct ${type.buildable()}: ${base_type.buildable()}, ${type.expressible_as()} {
% children = node.children()
% for child in children:
let ${child.name()}: ${child.type().buildable()}
% end
let leadingTrivia: Trivia? = nil //<- Added here
2- because leadingTrivia is added manually, i needed to reconfigure the initalizers
public init(
leadingTrivia: Trivia? = nil, //<- Can't add it as last parameter
//because trailing clousre Syntax is needed for childs
${',\n '.join(['%s: %s%s' % (
child.name(),
child.type().expressible_as(),
child.type().default_initialization()
) for child in children])}
) {
self.leadingTrivia = leadingTrivia
/* childs are intialized here */
% end
}
/// A convenience initializer that allows:
/// - Initializing syntax collections using result builders
/// - Initializing tokens without default text using strings
public init(
leadingTrivia: Trivia? = nil, //< Added here,
${',\n '.join(convenience_init_normal_parameters + convenience_init_result_builder_parameters)}
) {
self.init(
leadingTrivia: leadingTrivia,
${',\n '.join(delegated_init_args)}
)
}
% end
3- at buildFunctionDecl(format: leadingTrivia:)
func buildFunctionDecl(format: Format, leadingTrivia: Trivia? = nil) -> FunctionDeclSyntax {
var result = SyntaxFactory.makeFunctionDecl(
attributes: attributes?.buildAttributeList(format: format, leadingTrivia: nil),
modifiers: modifiers?.buildModifierList(format: format, leadingTrivia: nil),
funcKeyword: funcKeyword,
identifier: identifier,
genericParameterClause: genericParameterClause?.buildGenericParameterClause(format: format, leadingTrivia: nil),
signature: signature.buildFunctionSignature(format: format, leadingTrivia: nil),
genericWhereClause: genericWhereClause?.buildGenericWhereClause(format: format, leadingTrivia: nil),
body: body?.buildCodeBlock(format: format, leadingTrivia: nil)
)
if let leadingTrivia = self.leadingTrivia {
result = result.withLeadingTrivia(leadingTrivia)
}
if let leadingTrivia = leadingTrivia {
return result.withLeadingTrivia(leadingTrivia + (result.leadingTrivia ?? []))
} else {
return result
}
}
And finally,the modifier should be something like this
extension FunctionDecl {
/// Adds Line Comment to FunctionDecl
/// - Parameter text: comment to be added as lineComment
/// - Returns: FunctionDecl
public func withLineDocument(_ text: String) -> FunctionDecl {
return FunctionDecl(leadingTrivia: .lineComment("// \(text)\n"),
attributes: self.attributes,
modifiers: self.modifiers,
funcKeyword: self.funcKeyword,
identifier: self.identifier,
genericParameterClause: self.genericParameterClause,
signature: self.signature,
genericWhereClause: self.genericWhereClause,
body: self.body)
}
}
while this's sufficient to make it work, i have comments and questions regarding this approach:
1- i dont think that leadingTrivia should be first parameter in the initalizer, so
- adding leadingTrivia to the childs, would remove the headach of configuring the initializers, but i don't think it's correct to add it to the childs, since it's not a child of a syntax.
- adding leadingTrivia initazliation parameter after
init_normal_parameters
and beforeresult_builder_parameters
would fix the initalizaion issue. - adding leadingTrivia as an optional with default value to be nil, and making it only accessiable/initazlied via a
mutating
function should be enpugh, but i think that clients would need to access it dierctly from initalizer, also this will intrduce mutating changes which might affect the performance
i think that adding leadingTrivia initazliation parameter after init_normal_parameters
would provide enough balance
2- using self.leadingTrivia
name inside buildFunctionDecl
isn't clear IMO, should i consider betting naming ?
please let me know what do you think about this approach, and how we can i make things better.
Update 1: i've made a very small berief about building generate-swift-syntax-builder
using SwiftPM, based on the work of @kimdv
would like to hear opinions about that ! :)
thanks.