@@ -20,7 +20,23 @@ local mathEnv = {
2020 abs = math.abs
2121}
2222
23+ local function analyzeDependencies (expr )
24+ return {
25+ parent = expr :find (" parent%." ),
26+ self = expr :find (" self%." ),
27+ other = expr :find (" [^(parent)][^(self)]%." )
28+ }
29+ end
30+
2331local function parseExpression (expr , element , propName )
32+ local deps = analyzeDependencies (expr )
33+
34+ if deps .parent and not element .parent then
35+ errorManager .header = " Reactive evaluation error"
36+ errorManager .error (" Expression uses parent but no parent available" )
37+ return function () return nil end
38+ end
39+
2440 expr = expr :gsub (" ^{(.+)}$" , " %1" )
2541
2642 expr = expr :gsub (" ([%w_]+)%$([%w_]+)" , function (obj , prop )
@@ -139,6 +155,8 @@ local observerCache = setmetatable({}, {
139155})
140156
141157local function setupObservers (element , expr , propertyName )
158+ local deps = analyzeDependencies (expr )
159+
142160 if observerCache [element ][propertyName ] then
143161 for _ , observer in ipairs (observerCache [element ][propertyName ]) do
144162 observer .target :removeObserver (observer .property , observer .callback )
@@ -149,11 +167,11 @@ local function setupObservers(element, expr, propertyName)
149167 for ref , prop in expr :gmatch (" ([%w_]+)%.([%w_]+)" ) do
150168 if not protectedNames [ref ] then
151169 local target
152- if ref == " self" then
170+ if ref == " self" and deps . self then
153171 target = element
154- elseif ref == " parent" then
172+ elseif ref == " parent" and deps . parent then
155173 target = element .parent
156- else
174+ elseif deps . other then
157175 target = element :getBaseFrame ():getChild (ref )
158176 end
159177
177195PropertySystem .addSetterHook (function (element , propertyName , value , config )
178196 if type (value ) == " string" and value :match (" ^{.+}$" ) then
179197 local expr = value :gsub (" ^{(.+)}$" , " %1" )
198+ local deps = analyzeDependencies (expr )
199+
200+ if deps .parent and not element .parent then
201+ return config .default
202+ end
180203 if not validateReferences (expr , element ) then
181204 return config .default
182205 end
@@ -192,8 +215,15 @@ PropertySystem.addSetterHook(function(element, propertyName, value, config)
192215 end
193216
194217 return function (self )
218+ if element ._destroyed or (deps .parent and not element .parent ) then
219+ return config .default
220+ end
221+
195222 local success , result = pcall (functionCache [element ][value ])
196223 if not success then
224+ if result and result :match (" attempt to index.-nil value" ) then
225+ return config .default
226+ end
197227 errorManager .header = " Reactive evaluation error"
198228 if type (result ) == " string" then
199229 errorManager .error (" Error evaluating expression: " .. result )
@@ -225,6 +255,7 @@ BaseElement.hooks = {
225255 end
226256 end
227257 observerCache [self ] = nil
258+ functionCache [self ] = nil
228259 end
229260 end
230261}
0 commit comments