133d722a9Sopenharmony_ciuse crate::gen::{CfgEvaluator, CfgResult}; 233d722a9Sopenharmony_ciuse crate::syntax::cfg::CfgExpr; 333d722a9Sopenharmony_ciuse crate::syntax::report::Errors; 433d722a9Sopenharmony_ciuse crate::syntax::Api; 533d722a9Sopenharmony_ciuse quote::quote; 633d722a9Sopenharmony_ciuse std::collections::BTreeSet as Set; 733d722a9Sopenharmony_ciuse syn::Error; 833d722a9Sopenharmony_ci 933d722a9Sopenharmony_cipub(super) struct UnsupportedCfgEvaluator; 1033d722a9Sopenharmony_ci 1133d722a9Sopenharmony_ciimpl CfgEvaluator for UnsupportedCfgEvaluator { 1233d722a9Sopenharmony_ci fn eval(&self, name: &str, value: Option<&str>) -> CfgResult { 1333d722a9Sopenharmony_ci let _ = name; 1433d722a9Sopenharmony_ci let _ = value; 1533d722a9Sopenharmony_ci let msg = "cfg attribute is not supported".to_owned(); 1633d722a9Sopenharmony_ci CfgResult::Undetermined { msg } 1733d722a9Sopenharmony_ci } 1833d722a9Sopenharmony_ci} 1933d722a9Sopenharmony_ci 2033d722a9Sopenharmony_cipub(super) fn strip( 2133d722a9Sopenharmony_ci cx: &mut Errors, 2233d722a9Sopenharmony_ci cfg_errors: &mut Set<String>, 2333d722a9Sopenharmony_ci cfg_evaluator: &dyn CfgEvaluator, 2433d722a9Sopenharmony_ci apis: &mut Vec<Api>, 2533d722a9Sopenharmony_ci) { 2633d722a9Sopenharmony_ci apis.retain(|api| eval(cx, cfg_errors, cfg_evaluator, api.cfg())); 2733d722a9Sopenharmony_ci for api in apis { 2833d722a9Sopenharmony_ci match api { 2933d722a9Sopenharmony_ci Api::Struct(strct) => strct 3033d722a9Sopenharmony_ci .fields 3133d722a9Sopenharmony_ci .retain(|field| eval(cx, cfg_errors, cfg_evaluator, &field.cfg)), 3233d722a9Sopenharmony_ci Api::Enum(enm) => enm 3333d722a9Sopenharmony_ci .variants 3433d722a9Sopenharmony_ci .retain(|variant| eval(cx, cfg_errors, cfg_evaluator, &variant.cfg)), 3533d722a9Sopenharmony_ci _ => {} 3633d722a9Sopenharmony_ci } 3733d722a9Sopenharmony_ci } 3833d722a9Sopenharmony_ci} 3933d722a9Sopenharmony_ci 4033d722a9Sopenharmony_cipub(super) fn eval( 4133d722a9Sopenharmony_ci cx: &mut Errors, 4233d722a9Sopenharmony_ci cfg_errors: &mut Set<String>, 4333d722a9Sopenharmony_ci cfg_evaluator: &dyn CfgEvaluator, 4433d722a9Sopenharmony_ci expr: &CfgExpr, 4533d722a9Sopenharmony_ci) -> bool { 4633d722a9Sopenharmony_ci match try_eval(cfg_evaluator, expr) { 4733d722a9Sopenharmony_ci Ok(value) => value, 4833d722a9Sopenharmony_ci Err(errors) => { 4933d722a9Sopenharmony_ci for error in errors { 5033d722a9Sopenharmony_ci if cfg_errors.insert(error.to_string()) { 5133d722a9Sopenharmony_ci cx.push(error); 5233d722a9Sopenharmony_ci } 5333d722a9Sopenharmony_ci } 5433d722a9Sopenharmony_ci false 5533d722a9Sopenharmony_ci } 5633d722a9Sopenharmony_ci } 5733d722a9Sopenharmony_ci} 5833d722a9Sopenharmony_ci 5933d722a9Sopenharmony_cifn try_eval(cfg_evaluator: &dyn CfgEvaluator, expr: &CfgExpr) -> Result<bool, Vec<Error>> { 6033d722a9Sopenharmony_ci match expr { 6133d722a9Sopenharmony_ci CfgExpr::Unconditional => Ok(true), 6233d722a9Sopenharmony_ci CfgExpr::Eq(ident, string) => { 6333d722a9Sopenharmony_ci let key = ident.to_string(); 6433d722a9Sopenharmony_ci let value = string.as_ref().map(|string| string.value()); 6533d722a9Sopenharmony_ci match cfg_evaluator.eval(&key, value.as_deref()) { 6633d722a9Sopenharmony_ci CfgResult::True => Ok(true), 6733d722a9Sopenharmony_ci CfgResult::False => Ok(false), 6833d722a9Sopenharmony_ci CfgResult::Undetermined { msg } => { 6933d722a9Sopenharmony_ci let span = quote!(#ident #string); 7033d722a9Sopenharmony_ci Err(vec![Error::new_spanned(span, msg)]) 7133d722a9Sopenharmony_ci } 7233d722a9Sopenharmony_ci } 7333d722a9Sopenharmony_ci } 7433d722a9Sopenharmony_ci CfgExpr::All(list) => { 7533d722a9Sopenharmony_ci let mut all_errors = Vec::new(); 7633d722a9Sopenharmony_ci for subexpr in list { 7733d722a9Sopenharmony_ci match try_eval(cfg_evaluator, subexpr) { 7833d722a9Sopenharmony_ci Ok(true) => {} 7933d722a9Sopenharmony_ci Ok(false) => return Ok(false), 8033d722a9Sopenharmony_ci Err(errors) => all_errors.extend(errors), 8133d722a9Sopenharmony_ci } 8233d722a9Sopenharmony_ci } 8333d722a9Sopenharmony_ci if all_errors.is_empty() { 8433d722a9Sopenharmony_ci Ok(true) 8533d722a9Sopenharmony_ci } else { 8633d722a9Sopenharmony_ci Err(all_errors) 8733d722a9Sopenharmony_ci } 8833d722a9Sopenharmony_ci } 8933d722a9Sopenharmony_ci CfgExpr::Any(list) => { 9033d722a9Sopenharmony_ci let mut all_errors = Vec::new(); 9133d722a9Sopenharmony_ci for subexpr in list { 9233d722a9Sopenharmony_ci match try_eval(cfg_evaluator, subexpr) { 9333d722a9Sopenharmony_ci Ok(true) => return Ok(true), 9433d722a9Sopenharmony_ci Ok(false) => {} 9533d722a9Sopenharmony_ci Err(errors) => all_errors.extend(errors), 9633d722a9Sopenharmony_ci } 9733d722a9Sopenharmony_ci } 9833d722a9Sopenharmony_ci if all_errors.is_empty() { 9933d722a9Sopenharmony_ci Ok(false) 10033d722a9Sopenharmony_ci } else { 10133d722a9Sopenharmony_ci Err(all_errors) 10233d722a9Sopenharmony_ci } 10333d722a9Sopenharmony_ci } 10433d722a9Sopenharmony_ci CfgExpr::Not(subexpr) => match try_eval(cfg_evaluator, subexpr) { 10533d722a9Sopenharmony_ci Ok(value) => Ok(!value), 10633d722a9Sopenharmony_ci Err(errors) => Err(errors), 10733d722a9Sopenharmony_ci }, 10833d722a9Sopenharmony_ci } 10933d722a9Sopenharmony_ci} 11033d722a9Sopenharmony_ci 11133d722a9Sopenharmony_ciimpl Api { 11233d722a9Sopenharmony_ci fn cfg(&self) -> &CfgExpr { 11333d722a9Sopenharmony_ci match self { 11433d722a9Sopenharmony_ci Api::Include(include) => &include.cfg, 11533d722a9Sopenharmony_ci Api::Struct(strct) => &strct.cfg, 11633d722a9Sopenharmony_ci Api::Enum(enm) => &enm.cfg, 11733d722a9Sopenharmony_ci Api::CxxType(ety) | Api::RustType(ety) => &ety.cfg, 11833d722a9Sopenharmony_ci Api::CxxFunction(efn) | Api::RustFunction(efn) => &efn.cfg, 11933d722a9Sopenharmony_ci Api::TypeAlias(alias) => &alias.cfg, 12033d722a9Sopenharmony_ci Api::Impl(imp) => &imp.cfg, 12133d722a9Sopenharmony_ci } 12233d722a9Sopenharmony_ci } 12333d722a9Sopenharmony_ci} 12433d722a9Sopenharmony_ci 12533d722a9Sopenharmony_ciimpl From<bool> for CfgResult { 12633d722a9Sopenharmony_ci fn from(value: bool) -> Self { 12733d722a9Sopenharmony_ci if value { 12833d722a9Sopenharmony_ci CfgResult::True 12933d722a9Sopenharmony_ci } else { 13033d722a9Sopenharmony_ci CfgResult::False 13133d722a9Sopenharmony_ci } 13233d722a9Sopenharmony_ci } 13333d722a9Sopenharmony_ci} 134