XCTLRuntimeSubContext.swift 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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.hasExport(name: name) {
  45. self.setValueToRootAssumeExport(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 setValueToRootAssumeExport(_ value: XCTLRuntimeVariable, forName name: String) {
  57. self.parent.setValueToRootAssumeExport(value, forName: name)
  58. }
  59. internal func setValueToRoot(_ value: XCTLRuntimeVariable, forName name: String, assumeExport export: Bool) {
  60. self.parent.setValueToRoot(value,
  61. forName: name,
  62. assumeExport: export || self.exportNames.contains(name))
  63. }
  64. internal func setValueIgnoreParent(_ value: XCTLRuntimeVariable, forName name: String) {
  65. self.values[name] = value
  66. }
  67. internal func addImport(name: String) {
  68. self.importNames.insert(name)
  69. }
  70. internal func addExport(name: String) {
  71. self.exportNames.insert(name)
  72. }
  73. internal func hasExport(name: String) -> Bool {
  74. if self.exportNames.contains(name) {
  75. return true
  76. }
  77. return self.parent.hasExport(name: name)
  78. }
  79. internal func allocateObject(name: String, args: [XCTLRuntimeVariable]) throws -> XCTLRuntimeVariable {
  80. return try self.parent.allocateObject(name: name, args: args)
  81. }
  82. internal func addLazyStatement(_ stmt: XCTLReferencedVariableStatement) {
  83. self.parent.addLazyStatement(stmt)
  84. }
  85. internal func makeSubContext() -> XCTLRuntimeAbstractContext {
  86. return XCTLRuntimeSubContext(parent: self)
  87. }
  88. private var conditionFrame: XCTLConditionParentStatementFrame?
  89. private var listFrame: XCTLListStatementFrame?
  90. private var forFrame: XCTLForStatementFrame?
  91. func findConditionFrame() -> XCTLConditionParentStatementFrame? {
  92. if let conditionFrame = self.conditionFrame {
  93. return conditionFrame
  94. }
  95. return self.parent.findConditionFrame()
  96. }
  97. func findListFrame() -> XCTLListStatementFrame? {
  98. if let listFrame = self.listFrame {
  99. return listFrame
  100. }
  101. return self.parent.findListFrame()
  102. }
  103. func recordListFrame(_ frame: XCTLListStatementFrame?) {
  104. self.listFrame = frame
  105. }
  106. func recordConditionFrame(_ frame: XCTLConditionParentStatementFrame?) {
  107. self.conditionFrame = frame
  108. }
  109. func getParentContext() -> XCTLRuntimeAbstractContext? {
  110. return self.parent
  111. }
  112. func findForFrame() -> XCTLForStatementFrame? {
  113. if let forFrame = self.forFrame {
  114. return forFrame
  115. }
  116. return self.parent.findForFrame()
  117. }
  118. func recordForFrame(_ frame: XCTLForStatementFrame?) {
  119. self.forFrame = frame
  120. }
  121. var variableStack = XCTLRuntimeVariableStackFrame()
  122. }