@@ -3,6 +3,9 @@ using SciMLBase, SymbolicIndexingInterface
33struct ScopeRef{T, ST}
44 sys:: T
55 scope:: Scope{ST}
6+
7+ # (Optional) opaque data structure to facilitate faster `getproperty`.
8+ cursor
69end
710Base. Broadcast. broadcastable (ref:: ScopeRef ) = Ref (ref) # broadcast as scalar
811
@@ -135,33 +138,24 @@ function SciMLBase.sym_to_index(sr::ScopeRef, A::SciMLBase.DEIntegrator)
135138end
136139
137140function Base. getproperty (sys:: IRODESystem , name:: Symbol )
138- haskey (StructuralAnalysisResult (sys). names, name) || throw (Base. UndefRefError ())
139- return ScopeRef (sys, Scope (Scope (), name))
141+ names = StructuralAnalysisResult (sys). names
142+ cursor = get (names, name, nothing )
143+ cursor === nothing && throw (Base. UndefRefError ())
144+ return ScopeRef (sys, Scope (Scope (), name), cursor)
140145end
141146
142147function Base. propertynames (sr:: ScopeRef )
143- scope = getfield (sr, :scope )
144- stack = sym_stack (scope)
145- strct = NameLevel (StructuralAnalysisResult (IRODESystem (sr)). names)
146- for s in reverse (stack)
147- strct = strct. children[s]
148- strct. children === nothing && return keys (Dict {Symbol, Any} ())
149- end
150- return keys (strct. children)
148+ cursor = getfield (sr, :cursor )
149+ cursor. children === nothing && return keys (Dict {Symbol, Any} ())
150+ return keys (cursor. children)
151151end
152152
153153function Base. getproperty (sr:: ScopeRef{IRODESystem} , name:: Symbol )
154- scope = getfield (sr, :scope )
155- stack = sym_stack (scope)
156- strct = NameLevel (StructuralAnalysisResult (IRODESystem (sr)). names)
157- for s in reverse (stack)
158- strct = strct. children[s]
159- strct. children === nothing && throw (Base. UndefRefError ())
160- end
161- if ! haskey (strct. children, name)
162- throw (Base. UndefRefError ())
163- end
164- ScopeRef (IRODESystem (sr), Scope (getfield (sr, :scope ), name))
154+ cursor = getfield (sr, :cursor )
155+ cursor. children === nothing && return throw (Base. UndefRefError ())
156+ new_cursor = get (cursor. children, name, nothing )
157+ new_cursor === nothing && return throw (Base. UndefRefError ())
158+ return ScopeRef (IRODESystem (sr), Scope (getfield (sr, :scope ), name), new_cursor)
165159end
166160
167161function Base. show (io:: IO , scope:: Scope )
0 commit comments