package merlin-lib
Merlin's libraries
Install
Dune Dependency
Authors
Maintainers
Sources
merlin-4.16-414.tbz
sha256=c5e91975f3df56849e1b306f356c31709a2b139d7d57634b8d21e473266fcf2d
sha512=1d2db379b496dc0b95874f312011cce1a48f6808e098f1aff768de0eef0caff222adc17ab61b85c7aac8d889bf9d829fb5d0211267c7a85572ce201c1cbcb990
doc/src/merlin-lib.analysis/polarity_search.ml.html
Source file polarity_search.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
open Std type t = Trie of (string * Longident.t * t list lazy_t) module PathSet = Set.Make(Path) type query = { positive: PathSet.t; pos_fun: int; negative: PathSet.t; neg_fun: int; } let remove cost set path = if PathSet.mem path !set then ( decr cost; set := PathSet.remove path !set ) let rec normalize_path env path = match Env.find_type path env with | exception Not_found -> path | decl -> match decl.Types.type_manifest with | Some body when decl.Types.type_private = Asttypes.Public || decl.Types.type_kind <> Types.Type_abstract -> begin match Types.get_desc body with | Types.Tconstr (path, _, _) -> normalize_path env path | _ -> path end | _ -> path let match_query env query t = let cost = ref 0 in let rec traverse neg neg_fun pos pos_fun t = incr cost; incr cost; match Types.get_desc t with | Types.Tconstr (path, params, _) -> remove cost pos (normalize_path env path); begin match Env.find_type path env with | exception Not_found -> () | { Types.type_variance; _ } -> List.iter2 type_variance params ~f:(fun var arg -> if Types.Variance.mem Types.Variance.Inj var then ( if Types.Variance.mem Types.Variance.Pos var then traverse neg neg_fun pos pos_fun arg; if Types.Variance.mem Types.Variance.Neg var then traverse pos pos_fun neg neg_fun arg ) ) end | Types.Tarrow (_, t1, t2, _) -> decr pos_fun; traverse neg neg_fun pos pos_fun t2; traverse pos pos_fun neg neg_fun t1 | Types.Ttuple ts -> List.iter ~f:(traverse neg neg_fun pos pos_fun) ts | Types.Tvar _ | Types.Tunivar _ -> decr cost (* Favor polymorphic defs *) | _ -> () in let neg = ref query.negative and pos = ref query.positive in let neg_fun = ref query.neg_fun and pos_fun = ref query.pos_fun in traverse neg neg_fun pos pos_fun t; if PathSet.is_empty !pos && PathSet.is_empty !neg && !neg_fun <= 0 && !pos_fun <= 0 then Some !cost else None let build_query ~positive ~negative env = let prepare r l = if l = Longident.Lident "fun" then (incr r; None) else let set, _ = Env.find_type_by_name l env in Some (normalize_path env set) in let pos_fun = ref 0 and neg_fun = ref 0 in let positive = List.filter_map positive ~f:(prepare pos_fun) in let negative = List.filter_map negative ~f:(prepare neg_fun) in { positive = PathSet.of_list positive; negative = PathSet.of_list negative; neg_fun = !neg_fun; pos_fun = !pos_fun; } let directories ~global_modules env = let rec explore lident env = let add_module name _ md l = match md.Types.md_type with | Types.Mty_alias _ -> l | _ -> let lident = Longident.Ldot (lident, name) in Trie (name, lident, lazy (explore lident env)) :: l in Env.fold_modules add_module (Some lident) env [] in List.fold_left ~f:(fun l name -> let lident = Longident.Lident name in match Env.find_module_by_name lident env with | exception _ -> l | _ -> Trie (name, lident, lazy (explore lident env)) :: l ) ~init:[] global_modules (*Env.fold_modules (fun name _ _ l -> ignore (seen name); let lident = Longident.Lident name in Trie (name, lident, lazy (explore lident env)) :: l ) None env []*) let execute_query query env dirs = let direct dir acc = Env.fold_values (fun _ path desc acc -> match match_query env query desc.Types.val_type with | Some cost -> (cost, path, desc) :: acc | None -> acc ) dir env acc in let rec recurse acc (Trie (_, dir, children)) = match ignore (Env.find_module_by_name dir env); Lazy.force children with | children -> List.fold_left ~f:recurse ~init:(direct (Some dir) acc) children | exception Not_found -> Logger.notify ~section:"polarity-search" "%S not found" (String.concat ~sep:"." (Longident.flatten dir)); acc in List.fold_left dirs ~init:(direct None []) ~f:recurse
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>