Skip to content

Commit 7338cc0

Browse files
authored
Cleaning up Documentation (#84)
1 parent c622583 commit 7338cc0

86 files changed

Lines changed: 1294 additions & 524 deletions

File tree

Some content is hidden

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

.swiftlint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ opt_in_rules:
7777
- strong_iboutlet
7878
- toggle_bool
7979
# - trailing_closure
80-
- type_contents_order
80+
# - type_contents_order
8181
- unavailable_function
8282
- unneeded_parentheses_in_closure_argument
8383
- unowned_variable_capture
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
import Foundation
2+
3+
// MARK: - Macro Tutorial Examples
4+
// This file demonstrates the concepts from the "Creating Macros with SyntaxKit" tutorial
5+
6+
// MARK: - Example 1: Extension Macro Usage
7+
// This shows how the @MyMacro would be used (as defined in the tutorial)
8+
9+
protocol MyProtocol {
10+
var description: String { get }
11+
}
12+
13+
// Example of what the macro would generate:
14+
@MyMacro
15+
enum Color: String {
16+
case red = "red"
17+
case green = "green"
18+
case blue = "blue"
19+
}
20+
21+
// The macro would generate:
22+
// extension Color: MyProtocol {
23+
// typealias MyType = String
24+
// static let myProperty = ["red", "green", "blue"]
25+
// var description: String {
26+
// return myProperty.joined(separator: ", ")
27+
// }
28+
// }
29+
//
30+
// struct ColorWrapper {
31+
// let value: Color
32+
// init(value: Color) {
33+
// self.value = value
34+
// }
35+
// var description: String {
36+
// return value.description
37+
// }
38+
// }
39+
40+
// MARK: - Example 2: Freestanding Expression Macro Usage
41+
// This shows how the #stringify macro would be used
42+
43+
// let result = #stringify(42 + 8)
44+
// result would be (50, "42 + 8")
45+
46+
// MARK: - Example 3: Complex Macro Generation
47+
// This shows what a complex macro might generate
48+
49+
struct User {
50+
var status: UserStatus
51+
var name: String
52+
}
53+
54+
enum UserStatus: String {
55+
case active = "active"
56+
case inactive = "inactive"
57+
case pending = "pending"
58+
}
59+
60+
// A complex macro might generate an extension like this:
61+
extension User {
62+
enum Status: String {
63+
case active = "active"
64+
case inactive = "inactive"
65+
case pending = "pending"
66+
}
67+
68+
var isValid: Bool {
69+
if status == .active {
70+
return true
71+
} else {
72+
return false
73+
}
74+
}
75+
76+
func updateStatus(newStatus: Status) {
77+
status = newStatus
78+
print("Status updated to \(newStatus)")
79+
}
80+
81+
static func createDefault() -> User {
82+
return User(status: .pending, name: "Default")
83+
}
84+
}
85+
86+
// MARK: - Example 4: SyntaxKit Code Generation
87+
// This shows how SyntaxKit would be used to generate the above code
88+
89+
import SyntaxKit
90+
91+
// Example of generating the User extension using SyntaxKit
92+
let userExtension = Extension("User") {
93+
// Add a nested enum
94+
Enum("Status") {
95+
EnumCase("active").equals("active")
96+
EnumCase("inactive").equals("inactive")
97+
EnumCase("pending").equals("pending")
98+
}.inherits("String")
99+
100+
// Add a computed property with complex logic
101+
ComputedProperty("isValid") {
102+
If(VariableExp("status == .active"), then: {
103+
Return { Literal.boolean(true) }
104+
}, else: {
105+
Return { Literal.boolean(false) }
106+
})
107+
}
108+
109+
// Add a method with parameters
110+
Function("updateStatus", parameters: [Parameter("newStatus", type: "Status")]) {
111+
Assignment("status", VariableExp("newStatus"))
112+
Call("print") {
113+
ParameterExp(unlabeled: "\"Status updated to \\(newStatus)\"")
114+
}
115+
}
116+
117+
// Add a static method
118+
Function("createDefault", parameters: []) {
119+
Return {
120+
Init("User") {
121+
Parameter(name: "status", value: ".pending")
122+
Parameter(name: "name", value: "\"Default\"")
123+
}
124+
}
125+
}.static()
126+
127+
}.inherits("Identifiable", "Codable")
128+
129+
// MARK: - Example 5: Error Handling in Macros
130+
// This shows how macros should handle errors
131+
132+
enum MacroError: Error, CustomStringConvertible {
133+
case onlyWorksWithEnums
134+
case invalidCaseName(String)
135+
case missingRawValue
136+
137+
var description: String {
138+
switch self {
139+
case .onlyWorksWithEnums:
140+
return "This macro can only be applied to enums"
141+
case .invalidCaseName(let name):
142+
return "Invalid case name: \(name)"
143+
case .missingRawValue:
144+
return "Enum cases must have raw values"
145+
}
146+
}
147+
}
148+
149+
// MARK: - Example 6: Testing Macros
150+
// This shows how macros should be tested
151+
152+
/*
153+
// Example test for the MyMacro
154+
func testExtensionMacro() throws {
155+
assertMacroExpansion(
156+
"""
157+
@MyMacro
158+
enum Color: String {
159+
case red = "red"
160+
case blue = "blue"
161+
}
162+
""",
163+
expandedSource: """
164+
enum Color: String {
165+
case red = "red"
166+
case blue = "blue"
167+
}
168+
169+
extension Color: MyProtocol {
170+
typealias MyType = String
171+
static let myProperty = ["red", "blue"]
172+
var description: String {
173+
return myProperty.joined(separator: ", ")
174+
}
175+
}
176+
177+
struct ColorWrapper {
178+
let value: Color
179+
init(value: Color) {
180+
self.value = value
181+
}
182+
var description: String {
183+
return value.description
184+
}
185+
}
186+
""",
187+
macros: ["MyMacro": MyMacro.self]
188+
)
189+
}
190+
*/
191+
192+
// MARK: - Example 7: Integration with SwiftSyntax
193+
// This shows how SyntaxKit can be mixed with raw SwiftSyntax
194+
195+
/*
196+
// You can mix SyntaxKit with raw SwiftSyntax
197+
let syntaxKitStruct = Struct("Generated") {
198+
Variable(.let, name: "value", type: "String")
199+
}
200+
201+
// Convert to SwiftSyntax and modify
202+
var structDecl = syntaxKitStruct.syntax.as(StructDeclSyntax.self)!
203+
structDecl = structDecl.with(\.modifiers, DeclModifierListSyntax {
204+
DeclModifierSyntax(name: .keyword(.public))
205+
})
206+
207+
// Convert back to SyntaxKit if needed
208+
let modifiedStruct = Struct(structDecl)
209+
*/
210+
211+
// MARK: - Usage Examples
212+
213+
// Example usage of the generated code
214+
let color = Color.red
215+
print(color.description) // Would print: "red, green, blue"
216+
217+
let user = User(status: .pending, name: "John")
218+
print(user.isValid) // Would print: false
219+
220+
user.updateStatus(newStatus: .active)
221+
print(user.isValid) // Would print: true
222+
223+
let defaultUser = User.createDefault()
224+
print(defaultUser.name) // Would print: "Default"
225+
print(defaultUser.status) // Would print: .pending

0 commit comments

Comments
 (0)