difftreelog
refactor drop special casing of StaticBuiltin and Id functions
in: master
2 files changed
crates/jrsonnet-evaluator/src/function/builtin.rsdiffbeforeafterboth57 fn as_any(&self) -> &dyn Any;57 fn as_any(&self) -> &dyn Any;58}58}5960pub trait StaticBuiltin: Builtin + Send + Sync61where62 Self: 'static,63{64 // In impl, to make it object safe:65 // const INST: &'static Self;66}675968#[derive(Trace)]60#[derive(Trace)]69pub struct NativeCallback {61pub struct NativeCallback {crates/jrsonnet-evaluator/src/function/mod.rsdiffbeforeafterboth7pub use jrsonnet_macros::builtin;7pub use jrsonnet_macros::builtin;889use self::{9use self::{10 builtin::{Builtin, StaticBuiltin},10 builtin::Builtin,11 parse::{parse_builtin_call, parse_default_function_call, parse_function_call},11 parse::{parse_builtin_call, parse_default_function_call, parse_function_call},12 prepared::{PreparedCall, parse_prepared_builtin_call, parse_prepared_function_call},12 prepared::{parse_prepared_builtin_call, parse_prepared_function_call, PreparedCall},13};13};14use crate::{14use crate::{15 Context, Result, Thunk, Val, bail, error::ErrorKind::*, evaluate, evaluate_trivial,15 bail, error::ErrorKind::*, evaluate, evaluate_trivial, function::builtin::BuiltinFunc, Context,16 function::builtin::BuiltinFunc,16 Result, Thunk, Val,17};17};181819pub mod builtin;19pub mod builtin;97#[allow(clippy::module_name_repetitions)]97#[allow(clippy::module_name_repetitions)]98#[derive(Trace, Clone)]98#[derive(Trace, Clone)]99pub enum FuncVal {99pub enum FuncVal {100 /// Identity function, kept this way for comparsions.101 Id,102 /// Plain function implemented in jsonnet.100 /// Plain function implemented in jsonnet.103 Normal(Cc<FuncDesc>),101 Normal(Cc<FuncDesc>),104 /// Function without arguments works just as a fancy thunk value.102 /// Function without arguments works just as a fancy thunk value.105 Thunk(Thunk<Val>),103 Thunk(Thunk<Val>),106 /// Standard library function.107 StaticBuiltin(#[trace(skip)] &'static dyn StaticBuiltin),108 /// User-provided function.104 /// User-provided function.109 Builtin(BuiltinFunc),105 Builtin(BuiltinFunc),110}106}111107112impl Debug for FuncVal {108impl Debug for FuncVal {113 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {109 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {114 match self {110 match self {115 Self::Id => f.debug_tuple("Id").finish(),116 Self::Thunk(arg0) => f.debug_tuple("Thunk").field(arg0).finish(),111 Self::Thunk(arg0) => f.debug_tuple("Thunk").field(arg0).finish(),117 Self::Normal(arg0) => f.debug_tuple("Normal").field(arg0).finish(),112 Self::Normal(arg0) => f.debug_tuple("Normal").field(arg0).finish(),118 Self::StaticBuiltin(arg0) => {119 f.debug_tuple("StaticBuiltin").field(&arg0.name()).finish()120 }121 Self::Builtin(arg0) => f.debug_tuple("Builtin").field(&arg0.name()).finish(),113 Self::Builtin(arg0) => f.debug_tuple("Builtin").field(&arg0.name()).finish(),122 }114 }123 }115 }124}116}125117126#[allow(clippy::unnecessary_wraps)]118#[allow(clippy::unnecessary_wraps)]127#[builtin]119#[builtin]128const fn builtin_id(x: Val) -> Val {120pub const fn builtin_id(x: Thunk<Val>) -> Thunk<Val> {129 x121 x130}122}131static ID: &builtin_id = &builtin_id {};132123133impl FuncVal {124impl FuncVal {134 pub fn builtin(builtin: impl Builtin) -> Self {125 pub fn builtin(builtin: impl Builtin) -> Self {135 Self::Builtin(BuiltinFunc::new(builtin))126 Self::Builtin(BuiltinFunc::new(builtin))136 }127 }137 pub fn static_builtin(static_builtin: &'static dyn StaticBuiltin) -> Self {138 Self::StaticBuiltin(static_builtin)139 }140128141 pub fn params(&self) -> FunctionSignature {129 pub fn params(&self) -> FunctionSignature {142 match self {130 match self {143 Self::Id => ID.params(),144 Self::StaticBuiltin(i) => i.params(),145 Self::Builtin(i) => i.params(),131 Self::Builtin(i) => i.params(),146 Self::Normal(p) => p.params.signature.clone(),132 Self::Normal(p) => p.params.signature.clone(),147 Self::Thunk(_) => FunctionSignature::empty(),133 Self::Thunk(_) => FunctionSignature::empty(),154 /// Function name, as defined in code.140 /// Function name, as defined in code.155 pub fn name(&self) -> IStr {141 pub fn name(&self) -> IStr {156 match self {142 match self {157 Self::Id => "id".into(),158 Self::Normal(normal) => normal.name.clone(),143 Self::Normal(normal) => normal.name.clone(),159 Self::StaticBuiltin(builtin) => builtin.name().into(),160 Self::Builtin(builtin) => builtin.name().into(),144 Self::Builtin(builtin) => builtin.name().into(),161 Self::Thunk(_) => "thunk".into(),145 Self::Thunk(_) => "thunk".into(),162 }146 }182 }166 }183 thunk.evaluate()167 thunk.evaluate()184 }168 }185 Self::Id => {186 let args = parse_builtin_call(call_ctx, ID.params(), args, tailstrict)?;187 ID.call(loc, &args)188 }189 Self::StaticBuiltin(b) => {190 let args = parse_builtin_call(call_ctx, b.params(), args, tailstrict)?;191 b.call(loc, &args)192 }193 Self::Builtin(b) => {169 Self::Builtin(b) => {194 let args = parse_builtin_call(call_ctx, b.params(), args, tailstrict)?;170 let args = parse_builtin_call(call_ctx, b.params(), args, tailstrict)?;195 b.call(loc, &args)171 b.call(loc, &args)217 evaluate(body_ctx, &func.body)193 evaluate(body_ctx, &func.body)218 }194 }219 FuncVal::Thunk(t) => t.evaluate(),195 FuncVal::Thunk(t) => t.evaluate(),220 FuncVal::Id => {221 let args = parse_prepared_builtin_call(prepared, ID.params(), unnamed, named);222 ID.call(loc, &args)223 }224 FuncVal::StaticBuiltin(b) => {225 let args = parse_prepared_builtin_call(prepared, b.params(), unnamed, named);226 b.call(loc, &args)227 }228 FuncVal::Builtin(b) => {196 FuncVal::Builtin(b) => {229 let args = parse_prepared_builtin_call(prepared, b.params(), unnamed, named);197 let args = parse_prepared_builtin_call(prepared, b.params(), unnamed, named);230 b.call(loc, &args)198 b.call(loc, &args)239 /// This function should only be used for optimization, not for the conditional logic, i.e code should work with syntetic identity function too207 /// This function should only be used for optimization, not for the conditional logic, i.e code should work with syntetic identity function too240 pub fn is_identity(&self) -> bool {208 pub fn is_identity(&self) -> bool {241 match self {209 match self {242 Self::Id => true,210 Self::Builtin(b) => b.as_any().downcast_ref::<builtin_id>().is_some(),243 Self::Normal(desc) => {211 Self::Normal(desc) => {244 if desc.params.len() != 1 {212 if desc.params.len() != 1 {245 return false;213 return false;257 };225 };258 matches!(&*desc.body, Expr::Var(v) if &**v == id)226 matches!(&*desc.body, Expr::Var(v) if &**v == id)259 }227 }260 _ => false,228 Self::Thunk(_) => false,261 }229 }262 }230 }263 /// Identity function value.264 pub const fn identity() -> Self {265 Self::Id266 }267231268 pub fn evaluate_trivial(&self) -> Option<Val> {232 pub fn evaluate_trivial(&self) -> Option<Val> {269 match self {233 match self {281 Self::builtin(value)245 Self::builtin(value)282 }246 }283}247}284impl From<&'static dyn StaticBuiltin> for FuncVal {285 fn from(value: &'static dyn StaticBuiltin) -> Self {286 Self::static_builtin(value)287 }288}289248