SE-0216: User-defined dynamically callable types

My use case is @dynamicMemberLookup for the JSContext and JSValue classes (imported from Objective-C) without subclassing.

import Foundation
import JavaScriptCore

@dynamicMemberLookup
public protocol JSDynamicMemberLookup: AnyObject {}

extension JSDynamicMemberLookup where Self: JSValue {

  public subscript(dynamicMember name: String) -> JSValue {
    get {
      return objectForKeyedSubscript(name as NSString)
    }
    set {
      setObject(newValue, forKeyedSubscript: name as NSString)
    }
  }
}

extension JSValue: JSDynamicMemberLookup {}

extension JSDynamicMemberLookup where Self: JSContext {

  public subscript(dynamicMember name: String) -> JSValue {
    get {
      return globalObject![dynamicMember: name]
    }
    set {
      globalObject![dynamicMember: name] = newValue
    }
  }
}

extension JSContext: JSDynamicMemberLookup {}

let context = JSContext()!
context.Math.PI.toDouble() == .pi // true
1 Like