(***********************************************************************) (* *) (* OCamldoc *) (* *) (* Maxence Guesdon, projet Cristal, INRIA Rocquencourt *) (* *) (* Copyright 2001 Institut National de Recherche en Informatique et *) (* en Automatique. All rights reserved. This file is distributed *) (* under the terms of the Q Public License version 1.0. *) (* *) (***********************************************************************) (** Environment for finding complete names from relative names. *) let print_DEBUG s = print_string s ; print_newline ();; module Name = Odoc_name (** relative name * complete name *) type env_element = Name.t * Name.t type env = { env_values : env_element list ; env_types : env_element list ; env_class_types : env_element list ; env_classes : env_element list ; env_modules : env_element list ; env_module_types : env_element list ; env_exceptions : env_element list ; } let empty = { env_values = [] ; env_types = [] ; env_class_types = [] ; env_classes = [] ; env_modules = [] ; env_module_types = [] ; env_exceptions = [] ; } (** Add a signature to an environment. *) let rec add_signature env root ?rel signat = let qualify id = Name.concat root (Name.from_ident id) in let rel_name id = let n = Name.from_ident id in match rel with None -> n | Some r -> Name.concat r n in let f env item = match item with Types.Sig_value (ident, _) -> { env with env_values = (rel_name ident, qualify ident) :: env.env_values } | Types.Sig_type (ident,_,_) -> { env with env_types = (rel_name ident, qualify ident) :: env.env_types } | Types.Sig_exception (ident, _) -> { env with env_exceptions = (rel_name ident, qualify ident) :: env.env_exceptions } | Types.Sig_module (ident, modtype, _) -> let env2 = match modtype with (* A VOIR : le cas ou c'est un identificateur, dans ce cas on n'a pas de signature *) Types.Mty_signature s -> add_signature env (qualify ident) ~rel: (rel_name ident) s | _ -> env in { env2 with env_modules = (rel_name ident, qualify ident) :: env2.env_modules } | Types.Sig_modtype (ident, modtype_decl) -> let env2 = match modtype_decl with Types.Modtype_abstract -> env | Types.Modtype_manifest modtype -> match modtype with (* A VOIR : le cas ou c'est un identificateur, dans ce cas on n'a pas de signature *) Types.Mty_signature s -> add_signature env (qualify ident) ~rel: (rel_name ident) s | _ -> env in { env2 with env_module_types = (rel_name ident, qualify ident) :: env2.env_module_types } | Types.Sig_class (ident, _, _) -> { env with env_classes = (rel_name ident, qualify ident) :: env.env_classes } | Types.Sig_class_type (ident, _, _) -> { env with env_class_types = (rel_name ident, qualify ident) :: env.env_class_types } in List.fold_left f env signat let add_exception env full_name = let simple_name = Name.simple full_name in { env with env_exceptions = (simple_name, full_name) :: env.env_exceptions } let add_type env full_name = let simple_name = Name.simple full_name in { env with env_types = (simple_name, full_name) :: env.env_types } let add_value env full_name = let simple_name = Name.simple full_name in { env with env_values = (simple_name, full_name) :: env.env_values } let add_module env full_name = let simple_name = Name.simple full_name in { env with env_modules = (simple_name, full_name) :: env.env_modules } let add_module_type env full_name = let simple_name = Name.simple full_name in { env with env_module_types = (simple_name, full_name) :: env.env_module_types } let add_class env full_name = let simple_name = Name.simple full_name in { env with env_classes = (simple_name, full_name) :: env.env_classes ; (* we also add a type 'cause the class name may appear as a type *) env_types = (simple_name, full_name) :: env.env_types } let add_class_type env full_name = let simple_name = Name.simple full_name in { env with env_class_types = (simple_name, full_name) :: env.env_class_types ; (* we also add a type 'cause the class type name may appear as a type *) env_types = (simple_name, full_name) :: env.env_types } let full_module_name env n = try List.assoc n env.env_modules with Not_found -> print_DEBUG ("Module "^n^" not found with env="); List.iter (fun (sn, fn) -> print_DEBUG ("("^sn^", "^fn^")")) env.env_modules; n let full_module_type_name env n = try List.assoc n env.env_module_types with Not_found -> print_DEBUG ("Module "^n^" not found with env="); List.iter (fun (sn, fn) -> print_DEBUG ("("^sn^", "^fn^")")) env.env_modules; n let full_module_or_module_type_name env n = try List.assoc n env.env_modules with Not_found -> full_module_type_name env n let full_type_name env n = try let full = List.assoc n env.env_types in (** print_string ("type "^n^" is "^full); print_newline ();*) full with Not_found -> (** print_string ("type "^n^" not found"); print_newline ();*) n let full_value_name env n = try List.assoc n env.env_values with Not_found -> n let full_exception_name env n = try List.assoc n env.env_exceptions with Not_found -> print_DEBUG ("Exception "^n^" not found with env="); List.iter (fun (sn, fn) -> print_DEBUG ("("^sn^", "^fn^")")) env.env_exceptions; n let full_class_name env n = try List.assoc n env.env_classes with Not_found -> print_DEBUG ("Class "^n^" not found with env="); List.iter (fun (sn, fn) -> print_DEBUG ("("^sn^", "^fn^")")) env.env_classes; n let full_class_type_name env n = try List.assoc n env.env_class_types with Not_found -> print_DEBUG ("Class type "^n^" not found with env="); List.iter (fun (sn, fn) -> print_DEBUG ("("^sn^", "^fn^")")) env.env_class_types; n let full_class_or_class_type_name env n = try List.assoc n env.env_classes with Not_found -> full_class_type_name env n let print_env_types env = List.iter (fun (s1,s2) -> Printf.printf "%s = %s\n" s1 s2) env.env_types let subst_type env t = (* print_string "Odoc_env.subst_type\n"; print_env_types env ; print_newline (); *) Printtyp.mark_loops t; let deja_vu = ref [] in let rec iter t = if List.memq t !deja_vu then () else begin deja_vu := t :: !deja_vu; Btype.iter_type_expr iter t; match t.Types.desc with | Types.Tconstr (p, [ty], a) when Path.same p Predef.path_option -> () | Types.Tconstr (p, l, a) -> let new_p = Odoc_name.to_path (full_type_name env (Odoc_name.from_path p)) in t.Types.desc <- Types.Tconstr (new_p, l, a) | Types.Tpackage (p, n, l) -> let new_p = Odoc_name.to_path (full_module_type_name env (Odoc_name.from_path p)) in t.Types.desc <- Types.Tpackage (new_p, n, l) | Types.Tobject (_, ({contents=Some(p,tyl)} as r)) -> let new_p = Odoc_name.to_path (full_type_name env (Odoc_name.from_path p)) in r := Some (new_p, tyl) | Types.Tvariant ({Types.row_name=Some(p, tyl)} as row) -> let new_p = Odoc_name.to_path (full_type_name env (Odoc_name.from_path p)) in t.Types.desc <- Types.Tvariant {row with Types.row_name=Some(new_p, tyl)} | _ -> () end in iter t; t let subst_module_type env t = let rec iter t = match t with Types.Mty_ident p -> let new_p = Odoc_name.to_path (full_module_type_name env (Odoc_name.from_path p)) in Types.Mty_ident new_p | Types.Mty_signature _ -> t | Types.Mty_functor (id, mt1, mt2) -> Types.Mty_functor (id, iter mt1, iter mt2) in iter t let subst_class_type env t = let rec iter t = match t with Types.Cty_constr (p,texp_list,ct) -> let new_p = Odoc_name.to_path (full_type_name env (Odoc_name.from_path p)) in let new_texp_list = List.map (subst_type env) texp_list in let new_ct = iter ct in Types.Cty_constr (new_p, new_texp_list, new_ct) | Types.Cty_signature cs -> (* on ne s'occupe pas des vals et methods *) t | Types.Cty_fun (l, texp, ct) -> let new_texp = subst_type env texp in let new_ct = iter ct in Types.Cty_fun (l, new_texp, new_ct) in iter t