@@ -89,20 +89,55 @@ isEmpty(dom::Value const& arg)
8989
9090class OverlayObjectImpl : public dom ::ObjectImpl
9191{
92+ std::vector<dom::Object> grandParents_;
9293 dom::Object parent_;
9394 dom::Object child_;
9495
9596public:
9697 ~OverlayObjectImpl () override = default ;
9798
9899 OverlayObjectImpl (dom::Object parent)
99- : parent_(std::move(parent))
100- {}
100+ {
101+ auto * parImpl = parent.impl ().get ();
102+ auto * parOverlay = dynamic_cast <OverlayObjectImpl*>(parImpl);
103+ if (parOverlay == nullptr )
104+ {
105+ parent_ = std::move (parent);
106+ }
107+ else if (parOverlay->child_ .empty ())
108+ {
109+ grandParents_ = parOverlay->grandParents_ ;
110+ parent_ = parOverlay->parent_ ;
111+ }
112+ else
113+ {
114+ grandParents_.push_back (parOverlay->parent_ );
115+ grandParents_.insert (
116+ grandParents_.end (),
117+ parOverlay->grandParents_ .begin (),
118+ parOverlay->grandParents_ .end ());
119+ parent_ = parOverlay->child_ ;
120+ }
121+ }
101122
102123 OverlayObjectImpl (dom::Object child, dom::Object parent)
103- : parent_(std::move(parent))
104- , child_(std::move(child))
105- {}
124+ : OverlayObjectImpl(std::move(parent))
125+ {
126+ child_ = std::move (child);
127+ auto * childOverlay = dynamic_cast <OverlayObjectImpl*>(child_.impl ().get ());
128+ if (childOverlay != nullptr )
129+ {
130+ grandParents_.insert (
131+ grandParents_.begin (),
132+ parent_);
133+ grandParents_.insert (
134+ grandParents_.end (),
135+ childOverlay->grandParents_ .begin (),
136+ childOverlay->grandParents_ .end ());
137+ parent_ = childOverlay->parent_ ;
138+ child_ = childOverlay->child_ ;
139+ }
140+ }
106141
107142 std::size_t size () const override
108143 {
@@ -113,6 +148,17 @@ class OverlayObjectImpl : public dom::ObjectImpl
113148 {
114149 --n;
115150 }
151+ else
152+ {
153+ for (auto const & grandParent : grandParents_)
154+ {
155+ if (grandParent.exists (key))
156+ {
157+ --n;
158+ break ;
159+ }
160+ }
161+ }
116162 });
117163 return n;
118164 };
@@ -127,6 +173,13 @@ class OverlayObjectImpl : public dom::ObjectImpl
127173 {
128174 return parent_.get (key);
129175 }
176+ for (auto const & grandParent : grandParents_)
177+ {
178+ if (grandParent.exists (key))
179+ {
180+ return grandParent.get (key);
181+ }
182+ }
130183 return dom::Kind::Undefined;
131184 }
132185
@@ -154,12 +207,55 @@ class OverlayObjectImpl : public dom::ObjectImpl
154207 {
155208 return false ;
156209 }
210+
211+ for (std::size_t i = 0 ; i < grandParents_.size (); ++i)
212+ {
213+ auto visit_if_not_in_prev = [&](
214+ dom::String const & key, dom::Value const & value)
215+ {
216+ if (child_.exists (key))
217+ {
218+ return true ;
219+ }
220+ if (parent_.exists (key))
221+ {
222+ return true ;
223+ }
224+ for (std::size_t j = 0 ; j < i; ++j)
225+ {
226+ if (grandParents_[j].exists (key))
227+ {
228+ return true ;
229+ }
230+ }
231+ return fn (key, value);
232+ };
233+ if (!grandParents_[i].visit (visit_if_not_in_prev))
234+ {
235+ return false ;
236+ }
237+ }
157238 return true ;
158239 }
159240
160241 bool exists (std::string_view key) const override
161242 {
162- return child_.exists (key) || parent_.exists (key);
243+ if (child_.exists (key))
244+ {
245+ return true ;
246+ }
247+ if (parent_.exists (key))
248+ {
249+ return true ;
250+ }
251+ for (auto const & grandParent : grandParents_)
252+ {
253+ if (grandParent.exists (key))
254+ {
255+ return true ;
256+ }
257+ }
258+ return false ;
163259 }
164260};
165261
0 commit comments