Skip to content

Commit 645aaab

Browse files
committed
[Observation] Add property definite initialization support
1 parent 2407256 commit 645aaab

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

lib/Macros/Sources/ObservationMacros/ObservableMacro.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,6 @@ extension ObservableMacro: MemberMacro {
206206
let storedInstanceVariables = declaration.definedVariables.filter { $0.isValidForObservation }
207207
for property in storedInstanceVariables {
208208
if property.hasMacroApplication(ObservableMacro.ignoredMacroName) { continue }
209-
if property.initializer == nil {
210-
context.addDiagnostics(from: DiagnosticsError(syntax: property, message: "@Observable requires property '\(property.identifier?.text ?? "")' to have an initial value", id: .missingInitializer), node: property)
211-
}
212209
let storage = DeclSyntax(property.privatePrefixed("_", addingAttribute: ObservableMacro.ignoredAttribute))
213210
declaration.addIfNeeded(storage, to: &declarations)
214211

@@ -293,6 +290,13 @@ public struct ObservationTrackedMacro: AccessorMacro {
293290
return []
294291
}
295292

293+
let initAccessor: AccessorDeclSyntax =
294+
"""
295+
init(newValue, initializes: _\(identifier)) {
296+
_\(identifier) = newValue
297+
}
298+
"""
299+
296300
let getAccessor: AccessorDeclSyntax =
297301
"""
298302
get {
@@ -310,7 +314,7 @@ public struct ObservationTrackedMacro: AccessorMacro {
310314
}
311315
"""
312316

313-
return [getAccessor, setAccessor]
317+
return [initAccessor, getAccessor, setAccessor]
314318
}
315319
}
316320

test/stdlib/Observation/Observable.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,22 @@ protocol Intermediary: Observable { }
140140
@Observable
141141
class HasIntermediaryConformance: Intermediary { }
142142

143+
@Observable
144+
class HasInitialization {
145+
var field1: String
146+
var field2: Int
147+
148+
init(field1: String, field2: Int) {
149+
self.field1 = field1
150+
self.field2 = field2
151+
}
152+
153+
init(a: String, b: Int) {
154+
field1 = a
155+
field2 = b
156+
}
157+
}
158+
143159
class CapturedState<State>: @unchecked Sendable {
144160
var state: State
145161

0 commit comments

Comments
 (0)