Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,13 @@ if enablePrivateImports {
sharedSwiftSettings.append(.unsafeFlags(["-Xfrontend", "-enable-private-imports"]))
}

// MARK: - [env] OPENSWIFTUI_ENABLE_RUNTIME_CONCURRENCY_CHECK

let enableRuntimeConcurrencyCheck = envEnable("OPENSWIFTUI_ENABLE_RUNTIME_CONCURRENCY_CHECK", default: false)
if enableRuntimeConcurrencyCheck {
sharedSwiftSettings.append(.define("OPENSWIFTUI_ENABLE_RUNTIME_CONCURRENCY_CHECK"))
}

// MARK: - OpenSwiftUISPI Target

let openSwiftUISPITarget = Target.target(
Expand Down
416 changes: 339 additions & 77 deletions Sources/OpenSwiftUICore/Data/Binding/Binding.swift

Large diffs are not rendered by default.

166 changes: 143 additions & 23 deletions Sources/OpenSwiftUICore/Data/Binding/BindingOperations.swift
Original file line number Diff line number Diff line change
@@ -1,52 +1,172 @@
//
// BindingOperations.swift
// OpenSwiftUI
// OpenSwiftUICore
//
// Audited for 3.5.2
// Audited for 6.5.4
// Status: Complete
// ID: 1B4A0A6DD72E915E1D833753C43AC6E0 (SwiftUICore)

enum BindingOperations {}
@available(OpenSwiftUI_v1_0, *)
extension Binding {

extension BindingOperations {
struct ForceUnwrapping<Value>: Projection {
func get(base: Value?) -> Value { base! }
func set(base: inout Value?, newValue: Value) { base = newValue }
/// Creates a binding by projecting the base value to an optional value.
///
/// - Parameter base: A value to project to an optional value.
public init<V>(_ base: Binding<V>) where Value == V? {
self = base.projecting(BindingOperations.ToOptional())
}

struct NilCoalescing<Value>: Projection {
/// Creates a binding by projecting the base value to an unwrapped value.
///
/// - Parameter base: A value to project to an unwrapped value.
///
/// - Returns: A new binding or `nil` when `base` is `nil`.
public init?(_ base: Binding<Value?>) {
guard let _ = base.wrappedValue else {
return nil
}
self = base.projecting(BindingOperations.ForceUnwrapping())
}

/// Creates a binding by projecting the base value to a hashable value.
///
/// - Parameters:
/// - base: A `Hashable` value to project to an `AnyHashable` value.
public init<V>(_ base: Binding<V>) where Value == AnyHashable, V: Hashable {
self = base.projecting(BindingOperations.ToAnyHashable())
}

package init<V>(_ base: Binding<V>) where Value == Double, V: BinaryFloatingPoint {
self = base.projecting(BindingOperations.ToDouble())
}

package init<V>(_ base: Binding<V>) where Value == Double, V: BinaryInteger {
self = base.projecting(BindingOperations.ToDoubleFromInteger())
}

package static func == (lhs: Binding<Value>, rhs: Value) -> Binding<Bool> where Value: Hashable {
lhs.projecting(BindingOperations.Equals(value: rhs))
}
}

private let _constantFalse: Binding<Bool> = .constant(false)

extension Binding where Value == Bool {
package static var `false`: Binding<Bool> {
_constantFalse
}
}

private var nilCoalescingGenerationCounter: Int = 0

package enum BindingOperations {
// MARK: - ToOptional

package struct ToOptional<Value>: Projection {
package func get(base: Value) -> Value? {
base
}

package func set(base: inout Value, newValue: Value?) {
guard let newValue else {
return
}
base = newValue
}
}

// MARK: - ToAnyHashable

package struct ToAnyHashable<Value: Hashable>: Projection {
package func get(base: Value) -> AnyHashable {
AnyHashable(base)
}
package func set(base: inout Value, newValue: AnyHashable) {
base = newValue.base as! Value
}
}

package struct ForceUnwrapping<Value>: Projection {
package func get(base: Value?) -> Value {
base!
}

package func set(base: inout Value?, newValue: Value) {
base = newValue
}

package init() {
_openSwiftUIEmptyStub()
}
}

package struct NilCoalescing<Value>: Projection {
let defaultValue: Value
let generation: Int

func get(base: Value?) -> Value { base ?? defaultValue }
func set(base: inout Value?, newValue: Value) { base = newValue }
package init(defaultValue: Value) {
self.defaultValue = defaultValue
self.generation = nilCoalescingGenerationCounter
nilCoalescingGenerationCounter += 1
}

package func get(base: Value?) -> Value {
base ?? defaultValue
}

package func set(base: inout Value?, newValue: Value) {
base = newValue
}

static func == (lhs: BindingOperations.NilCoalescing<Value>, rhs: BindingOperations.NilCoalescing<Value>) -> Bool {
package static func == (lhs: BindingOperations.NilCoalescing<Value>, rhs: BindingOperations.NilCoalescing<Value>) -> Bool {
lhs.generation == rhs.generation
}

func hash(into hasher: inout Hasher) {
package func hash(into hasher: inout Hasher) {
hasher.combine(generation)
}
}

struct ToAnyHashable<Value: Hashable>: Projection {
func get(base: Value) -> AnyHashable { AnyHashable(base) }
func set(base: inout Value, newValue: AnyHashable) { base = newValue.base as! Value }
package struct ToDouble<Base>: Projection where Base: BinaryFloatingPoint {
package func get(base: Base) -> Double {
Double(base)
}

package func set(base: inout Base, newValue: Double) {
base = Base(newValue)
}

package init() {
_openSwiftUIEmptyStub()
}
}

struct ToDouble<Value: BinaryFloatingPoint>: Projection {
func get(base: Value) -> Double { Double(base) }
func set(base: inout Value, newValue: Double) { base = Value(newValue) }
package struct ToDoubleFromInteger<Base>: Projection where Base: BinaryInteger {
package func get(base: Base) -> Double {
Double(base)
}

package func set(base: inout Base, newValue: Double) {
base = Base(newValue)
}

package init() {
_openSwiftUIEmptyStub()
}
}

struct ToOptional<Value>: Projection {
func get(base: Value) -> Value? { base }
fileprivate struct Equals<Value>: Projection where Value: Hashable {
var value: Value

func set(base: inout Value, newValue: Value?) {
guard let newValue else {
func get(base: Value) -> Bool {
base == value
}

func set(base: inout Value, newValue: Bool) {
guard newValue else {
return
}
base = newValue
base = value
}
}
}
Loading
Loading