difftreelog
refactor no need to use CacheUnbound if there is no locals at all
in: master
1 file changed
crates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth282 Ok(())282 Ok(())283}283}284285#[derive(Trace, Clone)]286struct DirectUnbound(Context);287impl Unbound for DirectUnbound {288 type Bound = Context;289 fn bind(&self, sup_this: SupThis) -> Result<Context> {290 Ok(self291 .0292 .clone()293 .extend_bindings_sup_this(FxHashMap::new(), sup_this))294 }295}284296285#[allow(clippy::too_many_lines)]297#[allow(clippy::too_many_lines)]286pub fn evaluate_member_list_object(298pub fn evaluate_member_list_object(287 super_obj: Option<ObjValue>,299 super_obj: Option<ObjValue>,288 ctx: Context,300 ctx: Context,289 members: &ObjMembers,301 members: &ObjMembers,290) -> Result<ObjValue> {302) -> Result<ObjValue> {303 #[derive(Trace)]304 struct ObjectAssert<B: Trace> {305 uctx: B,306 asserts: Rc<Vec<AssertStmt>>,307 }308 impl<B: Unbound<Bound = Context>> ObjectAssertion for ObjectAssert<B> {309 fn run(&self, sup_this: SupThis) -> Result<()> {310 let ctx = self.uctx.bind(sup_this)?;311 for assert in &*self.asserts {312 evaluate_assert(ctx.clone(), assert)?;313 }314 Ok(())315 }316 }317291 let mut builder = ObjValueBuilder::new();318 let mut builder = ObjValueBuilder::new();292 if let Some(super_obj) = super_obj {319 if let Some(super_obj) = super_obj {293 builder.with_super(super_obj);320 builder.with_super(super_obj);294 }321 }295322296 let locals = members.locals.clone();323 if members.locals.is_empty() {297324 // We can use the same context for all field evaluation, it doesn't depends on locals, only on this/super298 // We have single context for all fields, so we can cache binds299 let uctx = CachedUnbound::new(evaluate_object_locals(ctx.clone(), locals));325 let uctx = DirectUnbound(ctx.clone());300301 for field in &members.fields {326 for field in &members.fields {302 evaluate_field_member(&mut builder, ctx.clone(), uctx.clone(), field)?;327 evaluate_field_member(&mut builder, ctx.clone(), uctx.clone(), field)?;303 }328 }304305 if !members.asserts.is_empty() {329 if !members.asserts.is_empty() {306 #[derive(Trace)]330 builder.assert(ObjectAssert {307 struct ObjectAssert<B: Trace> {331 uctx,332 asserts: members.asserts.clone(),333 });334 }335 } else {336 let locals = members.locals.clone();337 // We have single context for all fields, so we can cache them together308 uctx: B,338 let uctx = CachedUnbound::new(evaluate_object_locals(ctx.clone(), locals));309 asserts: Rc<Vec<AssertStmt>>,310 }311 impl<B: Unbound<Bound = Context>> ObjectAssertion for ObjectAssert<B> {339 for field in &members.fields {312 fn run(&self, sup_this: SupThis) -> Result<()> {340 evaluate_field_member(&mut builder, ctx.clone(), uctx.clone(), field)?;313 let ctx = self.uctx.bind(sup_this)?;314 for assert in &*self.asserts {315 evaluate_assert(ctx.clone(), assert)?;316 }317 Ok(())318 }319 }341 }342 if !members.asserts.is_empty() {320 builder.assert(ObjectAssert {343 builder.assert(ObjectAssert {321 uctx,344 uctx,322 asserts: members.asserts.clone(),345 asserts: members.asserts.clone(),323 });346 });347 }324 }348 }325349326 Ok(builder.build())350 Ok(builder.build())