Skip to content

Commit bb76cdd

Browse files
authored
Adding SwiftUI View example with closures, result builders, and imports (#81)
1 parent 47d4b41 commit bb76cdd

File tree

81 files changed

+5259
-442
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+5259
-442
lines changed

.swiftlint.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ opt_in_rules:
4040
- legacy_random
4141
- literal_expression_end_indentation
4242
- lower_acl_than_parent
43-
# - missing_docs
43+
- missing_docs
4444
- modifier_order
4545
- multiline_arguments
4646
- multiline_arguments_brackets
@@ -120,7 +120,7 @@ excluded:
120120
- Mint
121121
- Examples
122122
- Macros
123-
- Sources/SyntaxKit/parser
123+
- Sources/SyntaxKit/Parser
124124
indentation_width:
125125
indentation_width: 2
126126
file_name:
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
public import SwiftUI
2+
3+
4+
public struct TodoItemRow: View {
5+
private let item: TodoItem
6+
private let onToggle: @MainActor @Sendable (Date) -> Void
7+
8+
public var body: some View {
9+
HStack {
10+
Button(action: onToggle) {
11+
Image(systemName: item.isCompleted ? "checkmark.circle.fill" : "circle")
12+
.foregroundColor(item.isCompleted ? .green : .gray)
13+
}
14+
15+
Button(action: {
16+
Task { @MainActor [weak self] in
17+
self?.onToggle(Date())
18+
}
19+
}) {
20+
Image(systemName: "trash")
21+
}
22+
}
23+
}
24+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
Import("SwiftUI").access("public")
2+
3+
Struct("TodoItemRow") {
4+
Variable(.let, name: "item", type: "TodoItem").access("private")
5+
6+
Variable(.let, name: "onToggle", type:
7+
ClosureType(returns: "Void"){
8+
ClosureParameter("Date")
9+
}
10+
.attribute("@MainActor")
11+
.attribute("@Sendable")
12+
)
13+
.access("private")
14+
15+
ComputedProperty("body", type: "some View") {
16+
Init("HStack") {
17+
ParameterExp(unlabeled: Closure{
18+
ParameterExp(unlabeled: Closure{
19+
Init("Button") {
20+
ParameterExp(name: "action", value: VariableExp("onToggle"))
21+
ParameterExp(unlabeled: Closure{
22+
Init("Image") {
23+
ParameterExp(name: "systemName", value: ConditionalOp(
24+
if: VariableExp("item").property(name: "isCompleted"),
25+
then: Literal.string("checkmark.circle.fill"),
26+
else: Literal.string("circle")
27+
))
28+
}.call("foregroundColor"){
29+
ParameterExp(unlabeled: ConditionalOp(
30+
if: VariableExp("item").property(name: "isCompleted"),
31+
then: EnumCase("green"),
32+
else: EnumCase("gray")
33+
))
34+
}
35+
})
36+
}
37+
Init("Button") {
38+
ParameterExp(name: "action", value: Closure {
39+
Init("Task") {
40+
ParameterExp(unlabeled: Closure(
41+
capture: {
42+
ParameterExp(unlabeled: VariableExp("self").reference("weak"))
43+
},
44+
body: {
45+
VariableExp("self").optional().call("onToggle") {
46+
ParameterExp(unlabeled: Init("Date"))
47+
}
48+
}
49+
).attribute("@MainActor"))
50+
}
51+
})
52+
ParameterExp(unlabeled: Closure {
53+
Init("Image") {
54+
ParameterExp(name: "systemName", value: Literal.string("trash"))
55+
}
56+
})
57+
}
58+
})
59+
})
60+
61+
}
62+
}
63+
}
64+
.inherits("View")
65+
.access("public")

Examples/Completed/swiftui/syntax.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

Examples/Remaining/swiftui/code.swift

Lines changed: 0 additions & 103 deletions
This file was deleted.

Line.swift

Lines changed: 0 additions & 58 deletions
This file was deleted.

Sources/SyntaxKit/CodeBlocks/CommentedCodeBlock.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ internal struct CommentedCodeBlock: CodeBlock {
6666
let newFirstToken = firstToken.with(\.leadingTrivia, commentTrivia + firstToken.leadingTrivia)
6767

6868
let rewriter = FirstTokenRewriter(newToken: newFirstToken)
69-
let rewritten = rewriter.visit(Syntax(base.syntax))
69+
let rewritten = rewriter.rewrite(Syntax(base.syntax))
7070
return rewritten
7171
}
7272
}

Sources/SyntaxKit/ControlFlow/If+Body.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,20 @@
3030
import SwiftSyntax
3131

3232
extension If {
33-
/// Builds the body block for the if statement.
34-
internal func buildBody() -> CodeBlockSyntax {
33+
/// Builds the body of the if expression.
34+
/// - Returns: The code block syntax for the body.
35+
public func buildBody() -> CodeBlockSyntax {
3536
CodeBlockSyntax(
3637
leftBrace: .leftBraceToken(leadingTrivia: .space, trailingTrivia: .newline),
3738
statements: buildBodyStatements(from: body),
3839
rightBrace: .rightBraceToken(leadingTrivia: .newline)
3940
)
4041
}
4142

42-
/// Builds the statements for a code block from an array of CodeBlocks.
43-
internal func buildBodyStatements(from blocks: [CodeBlock]) -> CodeBlockItemListSyntax {
43+
/// Builds the body statements from an array of code blocks.
44+
/// - Parameter blocks: The code blocks to convert to statements.
45+
/// - Returns: The code block item list syntax.
46+
public func buildBodyStatements(from blocks: [CodeBlock]) -> CodeBlockItemListSyntax {
4447
CodeBlockItemListSyntax(
4548
blocks.compactMap { block in
4649
createCodeBlockItem(from: block)?.with(\.trailingTrivia, .newline)

Sources/SyntaxKit/ControlFlow/If+CodeBlockItem.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ import SwiftSyntax
3131

3232
extension If {
3333
/// Creates a code block item from a CodeBlock.
34-
internal func createCodeBlockItem(from block: CodeBlock) -> CodeBlockItemSyntax? {
34+
/// - Parameter block: The code block to convert.
35+
/// - Returns: The code block item syntax or nil if conversion is not possible.
36+
public func createCodeBlockItem(from block: CodeBlock) -> CodeBlockItemSyntax? {
3537
if let enumCase = block as? EnumCase {
3638
// Handle EnumCase specially - use expression syntax for enum cases in expressions
3739
return CodeBlockItemSyntax(item: .expr(enumCase.exprSyntax))

Sources/SyntaxKit/ControlFlow/If+Conditions.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@
3030
import SwiftSyntax
3131

3232
extension If {
33-
/// Builds the condition elements for the if statement.
34-
internal func buildConditions() -> ConditionElementListSyntax {
33+
/// Builds the conditions for the if expression.
34+
/// - Returns: The condition element list syntax.
35+
public func buildConditions() -> ConditionElementListSyntax {
3536
ConditionElementListSyntax(
3637
conditions.enumerated().map { index, block in
3738
let needsComma = index < conditions.count - 1

0 commit comments

Comments
 (0)