XCTLRuntimeSubContext.swift 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. //
  2. // XCTLRuntimeSubContext.swift
  3. // notebook
  4. //
  5. // Created by 邢铖 on 2023/5/25.
  6. //
  7. import Foundation
  8. internal class XCTLRuntimeSubContext: XCTLRuntimeAbstractContext {
  9. private let parent: XCTLRuntimeAbstractContext
  10. internal var nativeObjectInstance: NSObject {
  11. self.parent.nativeObjectInstance
  12. }
  13. private var values = [String : XCTLRuntimeVariable]()
  14. internal init(parent: XCTLRuntimeAbstractContext) {
  15. self.parent = parent
  16. }
  17. private var importNames = Set<String>()
  18. private var exportNames = Set<String>()
  19. internal func valueDefined(_ name: String) -> Bool {
  20. if self.values[name] != nil {
  21. return true
  22. }
  23. if self.importNames.contains(name) {
  24. return true
  25. }
  26. return self.parent.valueDefined(name)
  27. }
  28. internal func value(forName name: String) -> XCTLRuntimeVariable? {
  29. if name == "self" {
  30. return XCTLRuntimeVariable(rawObject: self.nativeObjectInstance)
  31. }
  32. if let value = self.values[name] {
  33. return value
  34. }
  35. if importNames.contains(name),
  36. let valueFromNative = self.nativeObjectInstance.value(forKey: name) as? NSObject {
  37. let object = XCTLRuntimeVariable(rawObject: valueFromNative)
  38. self.values[name] = object
  39. return object
  40. }
  41. return self.parent.value(forName: name)
  42. }
  43. internal func setValue(_ value: XCTLRuntimeVariable, forName name: String) {
  44. if self.exportNames.contains(name) {
  45. self.setValueToRoot(value, forName: name)
  46. return
  47. }
  48. if self.values[name] == nil {
  49. if self.valueDefined(name) {
  50. self.parent.setValue(value, forName: name)
  51. return
  52. }
  53. }
  54. self.values[name] = value
  55. }
  56. internal func setValueToRoot(_ value: XCTLRuntimeVariable, forName name: String) {
  57. self.parent.setValueToRoot(value, forName: name)
  58. }
  59. internal func addImport(name: String) {
  60. self.importNames.insert(name)
  61. }
  62. internal func addExport(name: String) {
  63. self.exportNames.insert(name)
  64. }
  65. internal func allocateObject(name: String, args: [XCTLRuntimeVariable]) throws -> XCTLRuntimeVariable {
  66. return try self.parent.allocateObject(name: name, args: args)
  67. }
  68. internal func addLazyStatement(_ stmt: XCTLStatement) {
  69. self.parent.addLazyStatement(stmt)
  70. }
  71. internal func makeSubContext() -> XCTLRuntimeAbstractContext {
  72. return XCTLRuntimeSubContext(parent: self)
  73. }
  74. private var conditionFrame: XCTLConditionParentStatementFrame?
  75. private var listFrame: XCTLListStatementFrame?
  76. func findConditionFrame() -> XCTLConditionParentStatementFrame? {
  77. if let conditionFrame = self.conditionFrame {
  78. return self.conditionFrame
  79. }
  80. return self.parent.findConditionFrame()
  81. }
  82. func findListFrame() -> XCTLListStatementFrame? {
  83. if let listFrame = self.listFrame {
  84. return self.listFrame
  85. }
  86. return self.parent.findListFrame()
  87. }
  88. func recordListFrame(_ frame: XCTLListStatementFrame?) {
  89. self.listFrame = frame
  90. }
  91. func recordConditionFrame(_ frame: XCTLConditionParentStatementFrame?) {
  92. self.conditionFrame = frame
  93. }
  94. }