package config
Ergonomic, lightweight conditional compilation through attributes
Install
Dune Dependency
Authors
Maintainers
Sources
config-0.0.3.tbz
sha256=6dc4427cb5f6ae8f2f9d04c9897d9a606242f9e0f6eaf90fca731883cd7b6053
sha512=a3f81bf8975f6f8d69c8c1b4cc041f37be19b311797573f960afaf21beac99292e255c87ee661f40be8e5f1aaf27a64754e0a6155ef0f9785024cea0c17f8eb9
doc/src/cfg_ppx/cfg_ppx.ml.html
Source file cfg_ppx.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
open Ppxlib let tag = "cfg" let short_tag = "config" let is_config_tag str = String.equal str tag || String.equal str short_tag let user_env = Unix.environment () |> Array.to_list |> List.map (fun kv -> let[@warning "-8"] (k :: v) = String.split_on_char '=' kv in (k, String.concat "=" v)) let env = user_env @ [ ("target_os", Cfg.target_os); ("target_arch", Cfg.target_arch); ("target_env", Cfg.target_env); ] |> List.sort_uniq (fun (k1, _) (k2, _) -> String.compare k1 k2) let () = if Option.is_some (Sys.getenv_opt "CONFIG_DEBUG") then ( Format.printf "Config PPX running with environment:\n\n%!"; List.iter (fun (k, v) -> Format.printf " %s = %S\r\n" k v) env; Format.printf "\n%!") let env = List.map (fun (k, v) -> (k, Cfg_lang.Parser.String v)) env let eval_attr attr = if not (is_config_tag attr.attr_name.txt) then `keep else let loc = attr.attr_loc in (* Printf.printf "\n\nattr name: %S\n\n" attr.attr_name.txt; *) match attr.attr_payload with | PStr [ { pstr_desc = Pstr_eval (e, []); _ } ] -> (* let e_ = Pprintast.string_of_expression e in *) (* Printf.printf "\n\npayload: %S\n\n" e_; *) if Cfg_lang.eval ~loc ~env e then `keep else `drop | _ -> `keep let rec should_keep attrs = match attrs with | [] -> `keep | attr :: attrs -> if eval_attr attr = `drop then `drop else should_keep attrs let rec should_keep_many list fn = match list with | [] -> `keep | item :: list -> if should_keep (fn item) = `drop then `drop else should_keep_many list fn let apply_config_on_types (tds : type_declaration list) = List.filter_map (fun td -> match td with | { ptype_kind = Ptype_abstract; ptype_manifest = Some ({ ptyp_desc = Ptyp_variant (rows, closed_flag, labels); _ } as manifest); _; } -> let rows = List.filter_map (fun row -> if should_keep row.prf_attributes = `keep then Some row else None) rows in if rows = [] then None else Some { td with ptype_manifest = Some { manifest with ptyp_desc = Ptyp_variant (rows, closed_flag, labels); }; } | { ptype_kind = Ptype_variant cstrs; _ } -> let cstrs = List.filter_map (fun cstr -> if should_keep cstr.pcd_attributes = `keep then Some cstr else None) cstrs in if cstrs = [] then None else Some { td with ptype_kind = Ptype_variant cstrs } | { ptype_kind = Ptype_record labels; _ } -> let labels = List.filter_map (fun label -> if should_keep label.pld_attributes = `keep then Some label else None) labels in if labels = [] then None else Some { td with ptype_kind = Ptype_record labels } | _ -> Some td) tds let apply_config_on_cases (cases : cases) = List.filter (fun case -> should_keep case.pc_rhs.pexp_attributes = `keep) cases let rec apply_config_on_expression (exp : expression) = let pexp_desc = match exp.pexp_desc with | Pexp_try (exp, cases) -> let exp = apply_config_on_expression exp in let cases = apply_config_on_cases cases in Pexp_try (exp, cases) | Pexp_match (exp, cases) -> let exp = apply_config_on_expression exp in let cases = apply_config_on_cases cases in Pexp_match (exp, cases) | Pexp_fun (arg_label, exp_opt, pat, exp) -> let exp = apply_config_on_expression exp in Pexp_fun (arg_label, exp_opt, pat, exp) | Pexp_function cases -> let cases = apply_config_on_cases cases in Pexp_function cases | Pexp_let (rec_flag, vbs, exp) -> let exp = apply_config_on_expression exp in Pexp_let (rec_flag, vbs, exp) | _ -> exp.pexp_desc in { exp with pexp_desc } let apply_config_on_value_bindings (vbs : value_binding list) = List.filter_map (fun vb -> if should_keep vb.pvb_attributes = `keep then Some { vb with pvb_expr = apply_config_on_expression vb.pvb_expr } else None) vbs let apply_config_on_signature_items sig_items = List.filter_map (fun sig_item -> match sig_item.psig_desc with | Psig_value val_desc -> if should_keep val_desc.pval_attributes = `keep then Some sig_item else None | Psig_type (rec_flag, tds) -> let tds = apply_config_on_types tds in if List.length tds = 0 then None else Some { sig_item with psig_desc = Psig_type (rec_flag, tds) } | _ -> Some sig_item) sig_items let apply_config_on_module_type mod_type = match mod_type.pmty_desc with | Pmty_signature signature_items -> let signature_items = apply_config_on_signature_items signature_items in { mod_type with pmty_desc = Pmty_signature signature_items } | _ -> mod_type let rec apply_config_on_module_expr mod_expr = match mod_expr.pmod_desc with | Pmod_apply _ | Pmod_unpack _ | Pmod_extension _ | Pmod_ident _ | Pmod_functor _ -> mod_expr | Pmod_structure structs -> let new_structs = List.filter_map (fun stri -> match stri.pstr_desc with | Pstr_value (rec_flag, vbs) -> let vbs = apply_config_on_value_bindings vbs in if List.length vbs = 0 then None else Some { stri with pstr_desc = Pstr_value (rec_flag, vbs) } | _ -> Some stri) structs in { mod_expr with pmod_desc = Pmod_structure new_structs } | Pmod_constraint (module_expr, module_type) -> let module_expr = apply_config_on_module_expr module_expr in let module_type = apply_config_on_module_type module_type in { mod_expr with pmod_desc = Pmod_constraint (module_expr, module_type) } let apply_config_on_structure_item stri = try match stri.pstr_desc with | Pstr_typext { ptyext_attributes = attrs; _ } | Pstr_open { popen_attributes = attrs; _ } | Pstr_include { pincl_attributes = attrs; _ } | Pstr_exception { ptyexn_attributes = attrs; _ } | Pstr_primitive { pval_attributes = attrs; _ } | Pstr_eval (_, attrs) -> if should_keep attrs = `keep then Some stri else None | Pstr_modtype { pmtd_attributes; pmtd_name; pmtd_type; pmtd_loc } -> if should_keep pmtd_attributes = `keep then match pmtd_type with | None -> Some stri | Some pmtd_type -> let pmtd_type = Some (apply_config_on_module_type pmtd_type) in Some { stri with pstr_desc = Pstr_modtype { pmtd_attributes; pmtd_name; pmtd_type; pmtd_loc }; } else None | Pstr_module { pmb_expr; pmb_name; pmb_attributes; pmb_loc } -> if should_keep pmb_attributes = `keep then let pmb_expr = apply_config_on_module_expr pmb_expr in Some { stri with pstr_desc = Pstr_module { pmb_expr; pmb_name; pmb_attributes; pmb_loc }; } else None | Pstr_value (recflag, vbs) -> if should_keep_many vbs (fun vb -> vb.pvb_attributes) = `keep then let vbs = apply_config_on_value_bindings vbs in Some { stri with pstr_desc = Pstr_value (recflag, vbs) } else None | Pstr_type (recflag, tds) -> if should_keep_many tds (fun td -> td.ptype_attributes) = `keep then let tds = apply_config_on_types tds in Some { stri with pstr_desc = Pstr_type (recflag, tds) } else None | Pstr_recmodule md -> if should_keep_many md (fun md -> md.pmb_attributes) = `keep then Some stri else None | Pstr_class cds -> if should_keep_many cds (fun cd -> cd.pci_attributes) = `keep then Some stri else None | Pstr_class_type ctds -> if should_keep_many ctds (fun ctd -> ctd.pci_attributes) = `keep then Some stri else None | Pstr_extension _ | Pstr_attribute _ -> Some stri with Cfg_lang.Error { loc; error } -> let ext = Location.error_extensionf ~loc "%s" error in Some (Ast_builder.Default.pstr_extension ~loc ext []) let apply_config_on_signature_item sigi = try match sigi.psig_desc with | Psig_typext { ptyext_attributes = attrs; _ } | Psig_modtype { pmtd_attributes = attrs; _ } | Psig_open { popen_attributes = attrs; _ } | Psig_include { pincl_attributes = attrs; _ } | Psig_exception { ptyexn_attributes = attrs; _ } | Psig_value { pval_attributes = attrs; _ } | Psig_modtypesubst { pmtd_attributes = attrs; _ } | Psig_modsubst { pms_attributes = attrs; _ } | Psig_module { pmd_attributes = attrs; _ } -> if should_keep attrs = `keep then Some sigi else None | Psig_typesubst tds -> if should_keep_many tds (fun td -> td.ptype_attributes) = `keep then let tds = apply_config_on_types tds in Some { sigi with psig_desc = Psig_typesubst tds } else None | Psig_type (recflag, tds) -> if should_keep_many tds (fun td -> td.ptype_attributes) = `keep then let tds = apply_config_on_types tds in Some { sigi with psig_desc = Psig_type (recflag, tds) } else None | Psig_recmodule md -> if should_keep_many md (fun md -> md.pmd_attributes) = `keep then Some sigi else None | Psig_class cds -> if should_keep_many cds (fun cd -> cd.pci_attributes) = `keep then Some sigi else None | Psig_class_type ctds -> if should_keep_many ctds (fun ctd -> ctd.pci_attributes) = `keep then Some sigi else None | Psig_extension _ | Psig_attribute _ -> Some sigi with Cfg_lang.Error { loc; error } -> let ext = Location.error_extensionf ~loc "%s" error in Some (Ast_builder.Default.psig_extension ~loc ext []) let preprocess_impl str = match str with | { pstr_desc = Pstr_attribute attr; _ } :: rest when is_config_tag attr.attr_name.txt -> if eval_attr attr = `keep then rest else [] | _ -> List.filter_map apply_config_on_structure_item str let preprocess_intf sigi = match sigi with | { psig_desc = Psig_attribute attr; _ } :: rest when is_config_tag attr.attr_name.txt -> if eval_attr attr = `keep then rest else [] | _ -> List.filter_map apply_config_on_signature_item sigi let () = Driver.register_transformation tag ~aliases:[ short_tag ] ~preprocess_impl ~preprocess_intf
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>