2002-03-27 08:20:32 -08:00
|
|
|
(***********************************************************************)
|
2012-08-01 05:09:31 -07:00
|
|
|
(* *)
|
2002-03-27 08:20:32 -08:00
|
|
|
(* 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. *)
|
|
|
|
(* *)
|
|
|
|
(***********************************************************************)
|
|
|
|
|
|
|
|
(** Analysis of implementation files. *)
|
|
|
|
open Misc
|
|
|
|
open Asttypes
|
|
|
|
open Types
|
|
|
|
open Typedtree
|
|
|
|
|
|
|
|
let print_DEBUG3 s = print_string s ; print_newline ();;
|
|
|
|
let print_DEBUG s = print_string s ; print_newline ();;
|
|
|
|
|
|
|
|
type typedtree = (Typedtree.structure * Typedtree.module_coercion)
|
|
|
|
|
|
|
|
module Name = Odoc_name
|
|
|
|
open Odoc_parameter
|
|
|
|
open Odoc_value
|
|
|
|
open Odoc_type
|
2014-05-04 16:08:45 -07:00
|
|
|
open Odoc_extension
|
2002-03-27 08:20:32 -08:00
|
|
|
open Odoc_exception
|
|
|
|
open Odoc_class
|
|
|
|
open Odoc_module
|
|
|
|
open Odoc_types
|
|
|
|
|
|
|
|
(** This variable contains the regular expression representing a blank.*)
|
|
|
|
let blank = "[ \010\013\009\012']"
|
2006-09-20 04:14:37 -07:00
|
|
|
|
2002-03-27 08:20:32 -08:00
|
|
|
(** This variable contains the regular expression representing a blank but not a '\n'.*)
|
|
|
|
let simple_blank = "[ \013\009\012]"
|
|
|
|
|
2004-11-03 01:31:19 -08:00
|
|
|
(** This module is used to search for structure items by name in a Typedtree.structure.
|
2002-04-19 09:28:08 -07:00
|
|
|
One function creates two hash tables, which can then be used to search for elements.
|
|
|
|
Class elements do not use tables.
|
|
|
|
*)
|
2002-03-27 08:20:32 -08:00
|
|
|
module Typedtree_search =
|
|
|
|
struct
|
2004-11-03 01:31:19 -08:00
|
|
|
type ele =
|
2002-07-23 07:12:03 -07:00
|
|
|
| M of string
|
|
|
|
| MT of string
|
|
|
|
| T of string
|
|
|
|
| C of string
|
|
|
|
| CT of string
|
2014-05-04 16:08:45 -07:00
|
|
|
| X of string
|
2002-07-23 07:12:03 -07:00
|
|
|
| E of string
|
|
|
|
| P of string
|
|
|
|
| IM of string
|
2002-04-19 09:28:08 -07:00
|
|
|
|
2012-05-30 07:52:37 -07:00
|
|
|
type tab = (ele, Typedtree.structure_item_desc) Hashtbl.t
|
2002-04-19 09:28:08 -07:00
|
|
|
type tab_values = (Odoc_module.Name.t, Typedtree.pattern * Typedtree.expression) Hashtbl.t
|
|
|
|
|
|
|
|
let iter_val_pattern = function
|
|
|
|
| Typedtree.Tpat_any -> None
|
2012-05-30 07:52:37 -07:00
|
|
|
| Typedtree.Tpat_var (name, _) -> Some (Name.from_ident name)
|
2002-04-19 09:28:08 -07:00
|
|
|
| Typedtree.Tpat_tuple _ -> None (* A VOIR quand on traitera les tuples *)
|
|
|
|
| _ -> None
|
|
|
|
|
2004-11-03 01:31:19 -08:00
|
|
|
let add_to_hashes table table_values tt =
|
2002-04-19 09:28:08 -07:00
|
|
|
match tt with
|
2013-03-26 01:09:26 -07:00
|
|
|
| Typedtree.Tstr_module mb ->
|
|
|
|
Hashtbl.add table (M (Name.from_ident mb.mb_id)) tt
|
2003-06-27 06:40:41 -07:00
|
|
|
| Typedtree.Tstr_recmodule mods ->
|
2006-09-20 04:14:37 -07:00
|
|
|
List.iter
|
2013-03-26 01:09:26 -07:00
|
|
|
(fun mb ->
|
|
|
|
Hashtbl.add table (M (Name.from_ident mb.mb_id))
|
|
|
|
(Typedtree.Tstr_module mb)
|
2006-09-20 04:14:37 -07:00
|
|
|
)
|
|
|
|
mods
|
2013-04-18 06:14:53 -07:00
|
|
|
| Typedtree.Tstr_modtype mtd ->
|
|
|
|
Hashtbl.add table (MT (Name.from_ident mtd.mtd_id)) tt
|
2014-05-04 16:08:45 -07:00
|
|
|
| Typedtree.Tstr_typext te -> begin
|
|
|
|
match te.tyext_constructors with
|
|
|
|
[] -> assert false
|
|
|
|
| ext :: _ -> Hashtbl.add table (X (Name.from_ident ext.ext_id)) tt
|
|
|
|
end
|
|
|
|
| Typedtree.Tstr_exception ext ->
|
|
|
|
Hashtbl.add table (E (Name.from_ident ext.ext_id)) tt
|
2002-07-23 07:12:03 -07:00
|
|
|
| Typedtree.Tstr_type ident_type_decl_list ->
|
|
|
|
List.iter
|
2013-03-25 11:20:11 -07:00
|
|
|
(fun td ->
|
|
|
|
Hashtbl.add table (T (Name.from_ident td.typ_id))
|
|
|
|
(Typedtree.Tstr_type [td]))
|
2002-07-23 07:12:03 -07:00
|
|
|
ident_type_decl_list
|
|
|
|
| Typedtree.Tstr_class info_list ->
|
|
|
|
List.iter
|
2012-05-30 07:52:37 -07:00
|
|
|
(fun (ci, m, s) ->
|
|
|
|
Hashtbl.add table (C (Name.from_ident ci.ci_id_class))
|
|
|
|
(Typedtree.Tstr_class [ci, m, s]))
|
2002-07-23 07:12:03 -07:00
|
|
|
info_list
|
2012-05-30 07:52:37 -07:00
|
|
|
| Typedtree.Tstr_class_type info_list ->
|
2002-07-23 07:12:03 -07:00
|
|
|
List.iter
|
2012-05-30 07:52:37 -07:00
|
|
|
(fun ((id,id_loc,_) as ci) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
Hashtbl.add table
|
|
|
|
(CT (Name.from_ident id))
|
2012-05-30 07:52:37 -07:00
|
|
|
(Typedtree.Tstr_class_type [ci]))
|
2002-07-23 07:12:03 -07:00
|
|
|
info_list
|
2013-06-03 08:14:19 -07:00
|
|
|
| Typedtree.Tstr_value (_, pat_exp_list) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
List.iter
|
2013-06-03 08:14:19 -07:00
|
|
|
(fun {vb_pat=pat; vb_expr=exp} ->
|
2002-07-23 07:12:03 -07:00
|
|
|
match iter_val_pattern pat.Typedtree.pat_desc with
|
|
|
|
None -> ()
|
|
|
|
| Some n -> Hashtbl.add table_values n (pat,exp)
|
|
|
|
)
|
|
|
|
pat_exp_list
|
2013-03-25 11:04:40 -07:00
|
|
|
| Typedtree.Tstr_primitive vd ->
|
|
|
|
Hashtbl.add table (P (Name.from_ident vd.val_id)) tt
|
2002-07-23 07:12:03 -07:00
|
|
|
| Typedtree.Tstr_open _ -> ()
|
|
|
|
| Typedtree.Tstr_include _ -> ()
|
|
|
|
| Typedtree.Tstr_eval _ -> ()
|
2013-03-25 07:16:07 -07:00
|
|
|
| Typedtree.Tstr_attribute _ -> ()
|
2002-04-19 09:28:08 -07:00
|
|
|
|
|
|
|
let tables typedtree =
|
|
|
|
let t = Hashtbl.create 13 in
|
|
|
|
let t_values = Hashtbl.create 13 in
|
2012-05-30 07:52:37 -07:00
|
|
|
List.iter (fun str -> add_to_hashes t t_values str.str_desc) typedtree;
|
2002-04-19 09:28:08 -07:00
|
|
|
(t, t_values)
|
|
|
|
|
|
|
|
let search_module table name =
|
|
|
|
match Hashtbl.find table (M name) with
|
2013-03-26 01:09:26 -07:00
|
|
|
(Typedtree.Tstr_module mb) -> mb.mb_expr
|
2002-07-23 07:12:03 -07:00
|
|
|
| _ -> assert false
|
2002-04-19 09:28:08 -07:00
|
|
|
|
|
|
|
let search_module_type table name =
|
|
|
|
match Hashtbl.find table (MT name) with
|
2013-04-18 06:14:53 -07:00
|
|
|
| (Typedtree.Tstr_modtype mtd) -> mtd
|
2002-04-19 09:28:08 -07:00
|
|
|
| _ -> assert false
|
|
|
|
|
2014-05-04 16:08:45 -07:00
|
|
|
let search_extension table name =
|
|
|
|
match Hashtbl.find table (X name) with
|
|
|
|
| (Typedtree.Tstr_typext tyext) -> tyext
|
2002-04-19 09:28:08 -07:00
|
|
|
| _ -> assert false
|
|
|
|
|
2014-05-04 16:08:45 -07:00
|
|
|
let search_exception table name =
|
|
|
|
match Hashtbl.find table (E name) with
|
|
|
|
| (Typedtree.Tstr_exception ext) -> ext
|
2002-07-23 07:12:03 -07:00
|
|
|
| _ -> assert false
|
2002-04-19 09:28:08 -07:00
|
|
|
|
|
|
|
let search_type_declaration table name =
|
|
|
|
match Hashtbl.find table (T name) with
|
2013-03-25 11:20:11 -07:00
|
|
|
| (Typedtree.Tstr_type [td]) -> td
|
2002-07-23 07:12:03 -07:00
|
|
|
| _ -> assert false
|
2002-04-19 09:28:08 -07:00
|
|
|
|
|
|
|
let search_class_exp table name =
|
|
|
|
match Hashtbl.find table (C name) with
|
2012-05-30 07:52:37 -07:00
|
|
|
| (Typedtree.Tstr_class [(ci, _, _ )]) ->
|
|
|
|
let ce = ci.ci_expr in
|
2002-07-23 07:12:03 -07:00
|
|
|
(
|
|
|
|
try
|
|
|
|
let type_decl = search_type_declaration table name in
|
2012-05-30 07:52:37 -07:00
|
|
|
(ce, type_decl.typ_type.Types.type_params)
|
2002-07-23 07:12:03 -07:00
|
|
|
with
|
|
|
|
Not_found ->
|
|
|
|
(ce, [])
|
|
|
|
)
|
|
|
|
| _ -> assert false
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2002-04-19 09:28:08 -07:00
|
|
|
let search_class_type_declaration table name =
|
|
|
|
match Hashtbl.find table (CT name) with
|
2012-05-30 07:52:37 -07:00
|
|
|
| (Typedtree.Tstr_class_type [(_,_,cltype_decl)]) -> cltype_decl
|
2002-07-23 07:12:03 -07:00
|
|
|
| _ -> assert false
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2004-11-03 01:31:19 -08:00
|
|
|
let search_value table name = Hashtbl.find table name
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2002-04-19 09:28:08 -07:00
|
|
|
let search_primitive table name =
|
|
|
|
match Hashtbl.find table (P name) with
|
2013-03-25 11:04:40 -07:00
|
|
|
Tstr_primitive vd -> vd.val_val.Types.val_type
|
2002-07-23 07:12:03 -07:00
|
|
|
| _ -> assert false
|
2002-03-27 08:20:32 -08:00
|
|
|
|
|
|
|
let get_nth_inherit_class_expr cls n =
|
|
|
|
let rec iter cpt = function
|
2002-07-23 07:12:03 -07:00
|
|
|
| [] ->
|
|
|
|
raise Not_found
|
2013-04-10 04:17:41 -07:00
|
|
|
| { cf_desc = Typedtree.Tcf_inherit (_, clexp, _, _, _) } :: q ->
|
2002-07-23 07:12:03 -07:00
|
|
|
if n = cpt then clexp else iter (cpt+1) q
|
|
|
|
| _ :: q ->
|
|
|
|
iter cpt q
|
2002-03-27 08:20:32 -08:00
|
|
|
in
|
2012-05-30 07:52:37 -07:00
|
|
|
iter 0 cls.Typedtree.cstr_fields
|
2002-03-27 08:20:32 -08:00
|
|
|
|
|
|
|
let search_attribute_type cls name =
|
|
|
|
let rec iter = function
|
2002-07-23 07:12:03 -07:00
|
|
|
| [] ->
|
|
|
|
raise Not_found
|
2013-04-10 04:17:41 -07:00
|
|
|
| { cf_desc = Typedtree.Tcf_val (_, _, ident, Tcfk_concrete (_, exp), _) } :: q
|
2002-07-23 07:12:03 -07:00
|
|
|
when Name.from_ident ident = name ->
|
|
|
|
exp.Typedtree.exp_type
|
2013-04-10 04:17:41 -07:00
|
|
|
| { cf_desc = Typedtree.Tcf_val (_, _, ident, Tcfk_virtual typ, _) } :: q
|
2012-09-25 00:17:11 -07:00
|
|
|
when Name.from_ident ident = name ->
|
|
|
|
typ.Typedtree.ctyp_type
|
2002-07-23 07:12:03 -07:00
|
|
|
| _ :: q ->
|
|
|
|
iter q
|
2002-03-27 08:20:32 -08:00
|
|
|
in
|
2012-05-30 07:52:37 -07:00
|
|
|
iter cls.Typedtree.cstr_fields
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2008-07-23 01:55:36 -07:00
|
|
|
let class_sig_of_cltype_decl =
|
|
|
|
let rec iter = function
|
2012-05-30 07:52:37 -07:00
|
|
|
Types.Cty_constr (_, _, cty) -> iter cty
|
|
|
|
| Types.Cty_signature s -> s
|
2013-04-16 01:59:09 -07:00
|
|
|
| Types.Cty_arrow (_,_, cty) -> iter cty
|
2008-07-23 01:55:36 -07:00
|
|
|
in
|
|
|
|
fun ct_decl -> iter ct_decl.Types.clty_type
|
|
|
|
|
2002-03-27 08:20:32 -08:00
|
|
|
let search_method_expression cls name =
|
|
|
|
let rec iter = function
|
2002-07-23 07:12:03 -07:00
|
|
|
| [] ->
|
|
|
|
raise Not_found
|
2013-04-10 04:17:41 -07:00
|
|
|
| { cf_desc = Typedtree.Tcf_method (label, _, Tcfk_concrete (_, exp)) } :: q when label.txt = name ->
|
2002-07-23 07:12:03 -07:00
|
|
|
exp
|
|
|
|
| _ :: q ->
|
|
|
|
iter q
|
2002-03-27 08:20:32 -08:00
|
|
|
in
|
2012-05-30 07:52:37 -07:00
|
|
|
iter cls.Typedtree.cstr_fields
|
2002-03-27 08:20:32 -08:00
|
|
|
end
|
|
|
|
|
2004-11-03 01:31:19 -08:00
|
|
|
module Analyser =
|
2002-03-27 08:20:32 -08:00
|
|
|
functor (My_ir : Odoc_sig.Info_retriever) ->
|
|
|
|
|
|
|
|
struct
|
|
|
|
module Sig = Odoc_sig.Analyser (My_ir)
|
|
|
|
|
|
|
|
(** This variable is used to load a file as a string and retrieve characters from it.*)
|
|
|
|
let file = Sig.file
|
|
|
|
|
|
|
|
(** The name of the analysed file. *)
|
|
|
|
let file_name = Sig.file_name
|
|
|
|
|
|
|
|
(** This function takes two indexes (start and end) and return the string
|
|
|
|
corresponding to the indexes in the file global variable. The function
|
|
|
|
prepare_file must have been called to fill the file global variable.*)
|
|
|
|
let get_string_of_file = Sig.get_string_of_file
|
|
|
|
|
|
|
|
(** This function loads the given file in the file global variable.
|
|
|
|
and sets file_name.*)
|
|
|
|
let prepare_file = Sig.prepare_file
|
|
|
|
|
|
|
|
(** The function used to get the comments in a class. *)
|
|
|
|
let get_comments_in_class = Sig.get_comments_in_class
|
|
|
|
|
|
|
|
(** The function used to get the comments in a module. *)
|
|
|
|
let get_comments_in_module = Sig.get_comments_in_module
|
|
|
|
|
2004-11-03 01:31:19 -08:00
|
|
|
(** This function takes a parameter pattern and builds the
|
2002-03-27 08:20:32 -08:00
|
|
|
corresponding [parameter] structure. The f_desc function
|
|
|
|
is used to retrieve a parameter description, if any, from
|
2002-04-02 07:16:31 -08:00
|
|
|
a parameter name.
|
2002-03-27 08:20:32 -08:00
|
|
|
*)
|
|
|
|
let tt_param_info_from_pattern env f_desc pat =
|
|
|
|
let rec iter_pattern pat =
|
2002-07-23 07:12:03 -07:00
|
|
|
match pat.pat_desc with
|
2012-05-30 07:52:37 -07:00
|
|
|
Typedtree.Tpat_var (ident, _) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let name = Name.from_ident ident in
|
|
|
|
Simple_name { sn_name = name ;
|
|
|
|
sn_text = f_desc name ;
|
|
|
|
sn_type = Odoc_env.subst_type env pat.pat_type
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
|
|
|
|
2012-05-30 07:52:37 -07:00
|
|
|
| Typedtree.Tpat_alias (pat, _, _) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
iter_pattern pat
|
|
|
|
|
|
|
|
| Typedtree.Tpat_tuple patlist ->
|
|
|
|
Tuple
|
|
|
|
(List.map iter_pattern patlist,
|
|
|
|
Odoc_env.subst_type env pat.pat_type)
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2013-04-17 02:46:52 -07:00
|
|
|
| Typedtree.Tpat_construct (_, cons_desc, _) when
|
2002-07-23 07:12:03 -07:00
|
|
|
(* we give a name to the parameter only if it unit *)
|
|
|
|
(match cons_desc.cstr_res.desc with
|
|
|
|
Tconstr (p, _, _) ->
|
2004-11-03 01:31:19 -08:00
|
|
|
Path.same p Predef.path_unit
|
2002-07-23 07:12:03 -07:00
|
|
|
| _ ->
|
|
|
|
false)
|
|
|
|
->
|
|
|
|
(* a () argument, it never has description *)
|
|
|
|
Simple_name { sn_name = "()" ;
|
|
|
|
sn_text = None ;
|
|
|
|
sn_type = Odoc_env.subst_type env pat.pat_type
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
2002-07-23 07:12:03 -07:00
|
|
|
|
|
|
|
| _ ->
|
2002-03-27 08:20:32 -08:00
|
|
|
(* implicit pattern matching -> anonymous parameter *)
|
2002-07-23 07:12:03 -07:00
|
|
|
Simple_name { sn_name = "()" ;
|
|
|
|
sn_text = None ;
|
|
|
|
sn_type = Odoc_env.subst_type env pat.pat_type
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
2002-03-27 08:20:32 -08:00
|
|
|
in
|
2004-11-03 01:31:19 -08:00
|
|
|
iter_pattern pat
|
2002-03-27 08:20:32 -08:00
|
|
|
|
|
|
|
(** Analysis of the parameter of a function. Return a list of t_parameter created from
|
|
|
|
the (pattern, expression) structures encountered. *)
|
|
|
|
let rec tt_analyse_function_parameters env current_comment_opt pat_exp_list =
|
|
|
|
match pat_exp_list with
|
2002-07-23 07:12:03 -07:00
|
|
|
[] ->
|
|
|
|
(* This case means we have a 'function' without pattern, that's impossible *)
|
|
|
|
raise (Failure "tt_analyse_function_parameters: 'function' without pattern")
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2013-04-15 09:23:22 -07:00
|
|
|
| {c_lhs=pattern_param} :: second_ele :: q ->
|
2002-03-27 08:20:32 -08:00
|
|
|
(* implicit pattern matching -> anonymous parameter and no more parameter *)
|
2002-07-23 07:12:03 -07:00
|
|
|
(* A VOIR : le label ? *)
|
|
|
|
let parameter = Odoc_parameter.Tuple ([], Odoc_env.subst_type env pattern_param.pat_type) in
|
|
|
|
[ parameter ]
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2013-04-15 09:23:22 -07:00
|
|
|
| {c_lhs=pattern_param; c_rhs=func_body} :: [] ->
|
2004-11-03 01:31:19 -08:00
|
|
|
let parameter =
|
|
|
|
tt_param_info_from_pattern
|
2002-07-23 07:12:03 -07:00
|
|
|
env
|
2004-11-03 01:31:19 -08:00
|
|
|
(Odoc_parameter.desc_from_info_opt current_comment_opt)
|
2002-07-23 07:12:03 -07:00
|
|
|
pattern_param
|
2002-04-05 03:51:15 -08:00
|
|
|
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
2002-03-27 08:20:32 -08:00
|
|
|
(* For optional parameters with a default value, a special treatment is required *)
|
|
|
|
(* we look if the name of the parameter we just add is "*opt*", which means
|
2002-07-23 07:12:03 -07:00
|
|
|
that there is a let param_name = ... in ... just right now *)
|
2004-11-03 01:31:19 -08:00
|
|
|
let (p, next_exp) =
|
2002-07-23 07:12:03 -07:00
|
|
|
match parameter with
|
|
|
|
Simple_name { sn_name = "*opt*" } ->
|
|
|
|
(
|
|
|
|
(
|
|
|
|
match func_body.exp_desc with
|
2013-06-03 08:14:19 -07:00
|
|
|
Typedtree.Texp_let (_, {vb_pat={pat_desc = Typedtree.Tpat_var (id, _) };
|
|
|
|
vb_expr=exp} :: _, func_body2) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let name = Name.from_ident id in
|
2004-11-03 01:31:19 -08:00
|
|
|
let new_param = Simple_name
|
2002-07-23 07:12:03 -07:00
|
|
|
{ sn_name = name ;
|
|
|
|
sn_text = Odoc_parameter.desc_from_info_opt current_comment_opt name ;
|
|
|
|
sn_type = Odoc_env.subst_type env exp.exp_type
|
|
|
|
}
|
|
|
|
in
|
|
|
|
(new_param, func_body2)
|
|
|
|
| _ ->
|
2010-01-20 08:26:46 -08:00
|
|
|
print_DEBUG3 "Pas le bon filtre pour le parametre optionnel avec valeur par defaut.";
|
2002-07-23 07:12:03 -07:00
|
|
|
(parameter, func_body)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
| _ ->
|
|
|
|
(parameter, func_body)
|
|
|
|
in
|
2002-03-27 08:20:32 -08:00
|
|
|
(* continue if the body is still a function *)
|
2002-07-23 07:12:03 -07:00
|
|
|
match next_exp.exp_desc with
|
2012-05-30 07:52:37 -07:00
|
|
|
Texp_function (_, pat_exp_list, _) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
p :: (tt_analyse_function_parameters env current_comment_opt pat_exp_list)
|
|
|
|
| _ ->
|
2002-03-27 08:20:32 -08:00
|
|
|
(* something else ; no more parameter *)
|
2002-07-23 07:12:03 -07:00
|
|
|
[ p ]
|
2002-03-27 08:20:32 -08:00
|
|
|
|
|
|
|
(** Analysis of a Tstr_value from the typedtree. Create and return a list of [t_value].
|
2002-07-23 07:12:03 -07:00
|
|
|
@raise Failure if an error occurs.*)
|
2002-03-27 08:20:32 -08:00
|
|
|
let tt_analyse_value env current_module_name comment_opt loc pat_exp rec_flag =
|
|
|
|
let (pat, exp) = pat_exp in
|
|
|
|
match (pat.pat_desc, exp.exp_desc) with
|
2012-05-30 07:52:37 -07:00
|
|
|
(Typedtree.Tpat_var (ident, _), Typedtree.Texp_function (_, pat_exp_list2, partial)) ->
|
2002-03-27 08:20:32 -08:00
|
|
|
(* a new function is defined *)
|
2002-07-23 07:12:03 -07:00
|
|
|
let name_pre = Name.from_ident ident in
|
|
|
|
let name = Name.parens_if_infix name_pre in
|
|
|
|
let complete_name = Name.concat current_module_name name in
|
2012-07-26 12:21:54 -07:00
|
|
|
let code =
|
|
|
|
if !Odoc_global.keep_code then
|
|
|
|
Some (get_string_of_file loc.Location.loc_start.Lexing.pos_cnum
|
|
|
|
loc.Location.loc_end.Lexing.pos_cnum)
|
|
|
|
else
|
|
|
|
None
|
|
|
|
in
|
2002-07-23 07:12:03 -07:00
|
|
|
(* create the value *)
|
|
|
|
let new_value = {
|
|
|
|
val_name = complete_name ;
|
|
|
|
val_info = comment_opt ;
|
|
|
|
val_type = Odoc_env.subst_type env pat.Typedtree.pat_type ;
|
|
|
|
val_recursive = rec_flag = Asttypes.Recursive ;
|
|
|
|
val_parameters = tt_analyse_function_parameters env comment_opt pat_exp_list2 ;
|
2012-07-26 12:21:54 -07:00
|
|
|
val_code = code ;
|
|
|
|
val_loc = { loc_impl = Some loc ; loc_inter = None } ;
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
|
|
|
[ new_value ]
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2012-05-30 07:52:37 -07:00
|
|
|
| (Typedtree.Tpat_var (ident, _), _) ->
|
2004-11-03 01:31:19 -08:00
|
|
|
(* a new value is defined *)
|
2002-07-23 07:12:03 -07:00
|
|
|
let name_pre = Name.from_ident ident in
|
|
|
|
let name = Name.parens_if_infix name_pre in
|
|
|
|
let complete_name = Name.concat current_module_name name in
|
2012-07-26 12:21:54 -07:00
|
|
|
let code =
|
|
|
|
if !Odoc_global.keep_code then
|
|
|
|
Some (get_string_of_file loc.Location.loc_start.Lexing.pos_cnum
|
|
|
|
loc.Location.loc_end.Lexing.pos_cnum)
|
|
|
|
else
|
|
|
|
None
|
|
|
|
in
|
2002-07-23 07:12:03 -07:00
|
|
|
let new_value = {
|
|
|
|
val_name = complete_name ;
|
|
|
|
val_info = comment_opt ;
|
|
|
|
val_type = Odoc_env.subst_type env pat.Typedtree.pat_type ;
|
|
|
|
val_recursive = rec_flag = Asttypes.Recursive ;
|
|
|
|
val_parameters = [] ;
|
2012-07-26 12:21:54 -07:00
|
|
|
val_code = code ;
|
|
|
|
val_loc = { loc_impl = Some loc ; loc_inter = None } ;
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
|
|
|
[ new_value ]
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2002-03-27 08:20:32 -08:00
|
|
|
| (Typedtree.Tpat_tuple lpat, _) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* new identifiers are defined *)
|
|
|
|
(* A VOIR : by now we don't accept to have global variables defined in tuples *)
|
|
|
|
[]
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2002-03-27 08:20:32 -08:00
|
|
|
| _ ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* something else, we don't care ? A VOIR *)
|
|
|
|
[]
|
2002-03-27 08:20:32 -08:00
|
|
|
|
|
|
|
(** This function takes a Typedtree.class_expr and returns a string which can stand for the class name.
|
|
|
|
The name can be "object ... end" if the class expression is not an ident or a class constraint or a class apply. *)
|
|
|
|
let rec tt_name_of_class_expr clexp =
|
2003-11-21 04:46:30 -08:00
|
|
|
(*
|
|
|
|
(
|
|
|
|
match clexp.Typedtree.cl_desc with
|
2006-09-20 04:14:37 -07:00
|
|
|
Tclass_ident _ -> prerr_endline "Tclass_ident"
|
2003-11-21 04:46:30 -08:00
|
|
|
| Tclass_structure _ -> prerr_endline "Tclass_structure"
|
|
|
|
| Tclass_fun _ -> prerr_endline "Tclass_fun"
|
|
|
|
| Tclass_apply _ -> prerr_endline "Tclass_apply"
|
|
|
|
| Tclass_let _ -> prerr_endline "Tclass_let"
|
|
|
|
| Tclass_constraint _ -> prerr_endline "Tclass_constraint"
|
|
|
|
);
|
|
|
|
*)
|
2002-03-27 08:20:32 -08:00
|
|
|
match clexp.Typedtree.cl_desc with
|
2012-05-30 07:52:37 -07:00
|
|
|
Typedtree.Tcl_ident (p, _, _) -> Name.from_path p
|
|
|
|
| Typedtree.Tcl_constraint (class_expr, _, _, _, _)
|
|
|
|
| Typedtree.Tcl_apply (class_expr, _) -> tt_name_of_class_expr class_expr
|
2002-03-27 08:20:32 -08:00
|
|
|
(*
|
2002-07-23 07:12:03 -07:00
|
|
|
| Typedtree.Tclass_fun (_, _, class_expr, _) -> tt_name_of_class_expr class_expr
|
|
|
|
| Typedtree.Tclass_let (_,_,_, class_expr) -> tt_name_of_class_expr class_expr
|
2002-03-27 08:20:32 -08:00
|
|
|
*)
|
2002-07-23 07:12:03 -07:00
|
|
|
| _ -> Odoc_messages.object_end
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2004-11-03 01:31:19 -08:00
|
|
|
(** Analysis of a method expression to get the method parameters.
|
2002-03-27 08:20:32 -08:00
|
|
|
@param first indicates if we're analysing the method for
|
|
|
|
the first time ; in that case we must not keep the first parameter,
|
|
|
|
which is "self-*", the object itself.
|
|
|
|
*)
|
|
|
|
let rec tt_analyse_method_expression env current_method_name comment_opt ?(first=true) exp =
|
|
|
|
match exp.Typedtree.exp_desc with
|
2012-05-30 07:52:37 -07:00
|
|
|
Typedtree.Texp_function (_, pat_exp_list, _) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(
|
|
|
|
match pat_exp_list with
|
|
|
|
[] ->
|
|
|
|
(* it is not a function since there are no parameters *)
|
|
|
|
(* we can't get here normally *)
|
|
|
|
raise (Failure (Odoc_messages.bad_tree^" "^(Odoc_messages.method_without_param current_method_name)))
|
|
|
|
| l ->
|
|
|
|
match l with
|
|
|
|
[] ->
|
2012-07-30 02:48:32 -07:00
|
|
|
(* cas impossible, on l'a filtre avant *)
|
2002-07-23 07:12:03 -07:00
|
|
|
assert false
|
2013-04-15 09:23:22 -07:00
|
|
|
| {c_lhs=pattern_param} :: second_ele :: q ->
|
2002-03-27 08:20:32 -08:00
|
|
|
(* implicit pattern matching -> anonymous parameter *)
|
2002-07-23 07:12:03 -07:00
|
|
|
(* Note : We can't match this pattern if it is the first call to the function. *)
|
|
|
|
let new_param = Simple_name
|
2004-11-03 01:31:19 -08:00
|
|
|
{ sn_name = "??" ; sn_text = None;
|
2002-07-23 07:12:03 -07:00
|
|
|
sn_type = Odoc_env.subst_type env pattern_param.Typedtree.pat_type }
|
|
|
|
in
|
|
|
|
[ new_param ]
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2013-04-15 09:23:22 -07:00
|
|
|
| {c_lhs=pattern_param; c_rhs=body} :: [] ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* if this is the first call to the function, this is the first parameter and we skip it *)
|
|
|
|
if not first then
|
|
|
|
(
|
2004-11-03 01:31:19 -08:00
|
|
|
let parameter =
|
2002-07-23 07:12:03 -07:00
|
|
|
tt_param_info_from_pattern
|
|
|
|
env
|
2004-11-03 01:31:19 -08:00
|
|
|
(Odoc_parameter.desc_from_info_opt comment_opt)
|
2002-07-23 07:12:03 -07:00
|
|
|
pattern_param
|
|
|
|
in
|
2002-03-27 08:20:32 -08:00
|
|
|
(* For optional parameters with a default value, a special treatment is required. *)
|
|
|
|
(* We look if the name of the parameter we just add is "*opt*", which means
|
2002-07-23 07:12:03 -07:00
|
|
|
that there is a let param_name = ... in ... just right now. *)
|
2004-11-03 01:31:19 -08:00
|
|
|
let (current_param, next_exp) =
|
2002-07-23 07:12:03 -07:00
|
|
|
match parameter with
|
|
|
|
Simple_name { sn_name = "*opt*"} ->
|
|
|
|
(
|
|
|
|
(
|
|
|
|
match body.exp_desc with
|
2013-06-03 08:14:19 -07:00
|
|
|
Typedtree.Texp_let (_, {vb_pat={pat_desc = Typedtree.Tpat_var (id, _) };
|
|
|
|
vb_expr=exp} :: _, body2) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let name = Name.from_ident id in
|
2004-11-03 01:31:19 -08:00
|
|
|
let new_param = Simple_name
|
2002-07-23 07:12:03 -07:00
|
|
|
{ sn_name = name ;
|
|
|
|
sn_text = Odoc_parameter.desc_from_info_opt comment_opt name ;
|
2004-11-03 01:31:19 -08:00
|
|
|
sn_type = Odoc_env.subst_type env exp.Typedtree.exp_type ;
|
2002-07-23 07:12:03 -07:00
|
|
|
}
|
|
|
|
in
|
|
|
|
(new_param, body2)
|
|
|
|
| _ ->
|
2010-01-20 08:26:46 -08:00
|
|
|
print_DEBUG3 "Pas le bon filtre pour le parametre optionnel avec valeur par defaut.";
|
2002-07-23 07:12:03 -07:00
|
|
|
(parameter, body)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
| _ ->
|
|
|
|
(* no *opt* parameter, we add the parameter then continue *)
|
|
|
|
(parameter, body)
|
|
|
|
in
|
|
|
|
current_param :: (tt_analyse_method_expression env current_method_name comment_opt ~first: false next_exp)
|
|
|
|
)
|
|
|
|
else
|
|
|
|
tt_analyse_method_expression env current_method_name comment_opt ~first: false body
|
|
|
|
)
|
2002-03-27 08:20:32 -08:00
|
|
|
| _ ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* no more parameter *)
|
|
|
|
[]
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2004-11-03 01:31:19 -08:00
|
|
|
(** Analysis of a [Parsetree.class_struture] and a [Typedtree.class_structure] to get a couple
|
2002-03-27 08:20:32 -08:00
|
|
|
(inherited classes, class elements). *)
|
2008-07-23 01:55:36 -07:00
|
|
|
let analyse_class_structure env current_class_name tt_class_sig last_pos pos_limit p_cls tt_cls table =
|
2002-03-27 08:20:32 -08:00
|
|
|
let rec iter acc_inher acc_fields last_pos = function
|
2004-11-03 01:31:19 -08:00
|
|
|
| [] ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let s = get_string_of_file last_pos pos_limit in
|
|
|
|
let (_, ele_coms) = My_ir.all_special !file_name s in
|
|
|
|
let ele_comments =
|
|
|
|
List.fold_left
|
|
|
|
(fun acc -> fun sc ->
|
|
|
|
match sc.Odoc_types.i_desc with
|
|
|
|
None ->
|
|
|
|
acc
|
|
|
|
| Some t ->
|
|
|
|
acc @ [Class_comment t])
|
|
|
|
[]
|
|
|
|
ele_coms
|
|
|
|
in
|
|
|
|
(acc_inher, acc_fields @ ele_comments)
|
2012-05-30 07:52:37 -07:00
|
|
|
| item :: q ->
|
|
|
|
let loc = item.Parsetree.pcf_loc in
|
|
|
|
match item.Parsetree.pcf_desc with
|
2013-04-10 04:17:41 -07:00
|
|
|
| (Parsetree.Pcf_inherit (_, p_clexp, _)) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let tt_clexp =
|
|
|
|
let n = List.length acc_inher in
|
|
|
|
try Typedtree_search.get_nth_inherit_class_expr tt_cls n
|
2010-04-07 20:58:41 -07:00
|
|
|
with Not_found ->
|
|
|
|
raise (Failure (
|
|
|
|
Odoc_messages.inherit_classexp_not_found_in_typedtree n))
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
2003-11-21 04:46:30 -08:00
|
|
|
let (info_opt, ele_comments) =
|
2006-09-20 04:14:37 -07:00
|
|
|
get_comments_in_class last_pos
|
|
|
|
p_clexp.Parsetree.pcl_loc.Location.loc_start.Lexing.pos_cnum
|
|
|
|
in
|
2010-04-07 20:58:41 -07:00
|
|
|
let text_opt =
|
|
|
|
match info_opt with None -> None
|
|
|
|
| Some i -> i.Odoc_types.i_desc in
|
2002-07-23 07:12:03 -07:00
|
|
|
let name = tt_name_of_class_expr tt_clexp in
|
2003-11-21 04:46:30 -08:00
|
|
|
let inher =
|
2006-09-20 04:14:37 -07:00
|
|
|
{
|
|
|
|
ic_name = Odoc_env.full_class_or_class_type_name env name ;
|
|
|
|
ic_class = None ;
|
|
|
|
ic_text = text_opt ;
|
|
|
|
}
|
|
|
|
in
|
2002-07-23 07:12:03 -07:00
|
|
|
iter (acc_inher @ [ inher ]) (acc_fields @ ele_comments)
|
2002-11-01 09:06:47 -08:00
|
|
|
p_clexp.Parsetree.pcl_loc.Location.loc_end.Lexing.pos_cnum
|
2002-07-23 07:12:03 -07:00
|
|
|
q
|
|
|
|
|
2013-04-10 04:17:41 -07:00
|
|
|
| Parsetree.Pcf_val ({ txt = label }, mutable_flag, k) ->
|
|
|
|
let virt = match k with Parsetree.Cfk_virtual _ -> true | Parsetree.Cfk_concrete _ -> false in
|
2002-07-23 07:12:03 -07:00
|
|
|
let complete_name = Name.concat current_class_name label in
|
2002-11-01 09:06:47 -08:00
|
|
|
let (info_opt, ele_comments) = get_comments_in_class last_pos loc.Location.loc_start.Lexing.pos_cnum in
|
2002-07-23 07:12:03 -07:00
|
|
|
let type_exp =
|
2012-10-05 08:21:35 -07:00
|
|
|
try Typedtree_search.search_attribute_type tt_cls label
|
|
|
|
with Not_found ->
|
2008-07-23 01:55:36 -07:00
|
|
|
raise (Failure (Odoc_messages.attribute_not_found_in_typedtree complete_name))
|
2012-07-26 12:21:54 -07:00
|
|
|
in
|
|
|
|
let code =
|
|
|
|
if !Odoc_global.keep_code then
|
|
|
|
Some (get_string_of_file loc.Location.loc_start.Lexing.pos_cnum
|
|
|
|
loc.Location.loc_end.Lexing.pos_cnum)
|
|
|
|
else
|
|
|
|
None
|
|
|
|
in
|
|
|
|
let att =
|
|
|
|
{
|
|
|
|
att_value = { val_name = complete_name ;
|
|
|
|
val_info = info_opt ;
|
|
|
|
val_type = Odoc_env.subst_type env type_exp ;
|
|
|
|
val_recursive = false ;
|
|
|
|
val_parameters = [] ;
|
|
|
|
val_code = code ;
|
|
|
|
val_loc = { loc_impl = Some loc ; loc_inter = None } ;
|
|
|
|
} ;
|
|
|
|
att_mutable = mutable_flag = Asttypes.Mutable ;
|
|
|
|
att_virtual = virt ;
|
|
|
|
}
|
|
|
|
in
|
|
|
|
iter acc_inher (acc_fields @ ele_comments @ [ Class_attribute att ]) loc.Location.loc_end.Lexing.pos_cnum q
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2013-04-10 04:17:41 -07:00
|
|
|
| (Parsetree.Pcf_method ({ txt = label }, private_flag, Parsetree.Cfk_virtual _)) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let complete_name = Name.concat current_class_name label in
|
2002-11-01 09:06:47 -08:00
|
|
|
let (info_opt, ele_comments) = get_comments_in_class last_pos loc.Location.loc_start.Lexing.pos_cnum in
|
2004-11-03 01:31:19 -08:00
|
|
|
let met_type =
|
|
|
|
try Odoc_sig.Signature_search.search_method_type label tt_class_sig
|
2002-07-23 07:12:03 -07:00
|
|
|
with Not_found -> raise (Failure (Odoc_messages.method_type_not_found current_class_name label))
|
|
|
|
in
|
|
|
|
let real_type =
|
|
|
|
match met_type.Types.desc with
|
2012-07-26 12:21:54 -07:00
|
|
|
Tarrow (_, _, t, _) ->
|
|
|
|
t
|
|
|
|
| _ ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* ?!? : not an arrow type ! return the original type *)
|
2012-07-26 12:21:54 -07:00
|
|
|
met_type
|
|
|
|
in
|
|
|
|
let code =
|
|
|
|
if !Odoc_global.keep_code then
|
|
|
|
Some (get_string_of_file loc.Location.loc_start.Lexing.pos_cnum
|
|
|
|
loc.Location.loc_end.Lexing.pos_cnum)
|
|
|
|
else
|
|
|
|
None
|
|
|
|
in
|
|
|
|
let met =
|
|
|
|
{
|
|
|
|
met_value = {
|
|
|
|
val_name = complete_name ;
|
|
|
|
val_info = info_opt ;
|
|
|
|
val_type = Odoc_env.subst_type env real_type ;
|
|
|
|
val_recursive = false ;
|
|
|
|
val_parameters = [] ;
|
|
|
|
val_code = code ;
|
|
|
|
val_loc = { loc_impl = Some loc ; loc_inter = None } ;
|
|
|
|
} ;
|
|
|
|
met_private = private_flag = Asttypes.Private ;
|
|
|
|
met_virtual = true ;
|
|
|
|
}
|
|
|
|
in
|
|
|
|
(* update the parameter description *)
|
|
|
|
Odoc_value.update_value_parameters_text met.met_value;
|
2002-07-23 07:12:03 -07:00
|
|
|
|
2012-07-26 12:21:54 -07:00
|
|
|
iter acc_inher (acc_fields @ ele_comments @ [ Class_method met ]) loc.Location.loc_end.Lexing.pos_cnum q
|
2002-07-23 07:12:03 -07:00
|
|
|
|
2013-04-10 04:17:41 -07:00
|
|
|
| (Parsetree.Pcf_method ({ txt = label }, private_flag, Parsetree.Cfk_concrete _)) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let complete_name = Name.concat current_class_name label in
|
2002-11-01 09:06:47 -08:00
|
|
|
let (info_opt, ele_comments) = get_comments_in_class last_pos loc.Location.loc_start.Lexing.pos_cnum in
|
2004-11-03 01:31:19 -08:00
|
|
|
let exp =
|
2002-07-23 07:12:03 -07:00
|
|
|
try Typedtree_search.search_method_expression tt_cls label
|
2012-07-26 12:21:54 -07:00
|
|
|
with Not_found -> raise (Failure (Odoc_messages.method_not_found_in_typedtree complete_name))
|
|
|
|
in
|
|
|
|
let real_type =
|
|
|
|
match exp.exp_type.desc with
|
|
|
|
Tarrow (_, _, t,_) ->
|
|
|
|
t
|
|
|
|
| _ ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* ?!? : not an arrow type ! return the original type *)
|
2012-07-26 12:21:54 -07:00
|
|
|
exp.Typedtree.exp_type
|
|
|
|
in
|
|
|
|
let code =
|
|
|
|
if !Odoc_global.keep_code then
|
|
|
|
Some (get_string_of_file loc.Location.loc_start.Lexing.pos_cnum
|
|
|
|
loc.Location.loc_end.Lexing.pos_cnum)
|
|
|
|
else
|
|
|
|
None
|
|
|
|
in
|
|
|
|
let met =
|
|
|
|
{
|
|
|
|
met_value = { val_name = complete_name ;
|
|
|
|
val_info = info_opt ;
|
|
|
|
val_type = Odoc_env.subst_type env real_type ;
|
|
|
|
val_recursive = false ;
|
|
|
|
val_parameters = tt_analyse_method_expression env complete_name info_opt exp ;
|
|
|
|
val_code = code ;
|
|
|
|
val_loc = { loc_impl = Some loc ; loc_inter = None } ;
|
|
|
|
} ;
|
|
|
|
met_private = private_flag = Asttypes.Private ;
|
|
|
|
met_virtual = false ;
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
2012-07-26 12:21:54 -07:00
|
|
|
in
|
|
|
|
(* update the parameter description *)
|
|
|
|
Odoc_value.update_value_parameters_text met.met_value;
|
2002-07-23 07:12:03 -07:00
|
|
|
|
2012-07-26 12:21:54 -07:00
|
|
|
iter acc_inher (acc_fields @ ele_comments @ [ Class_method met ]) loc.Location.loc_end.Lexing.pos_cnum q
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2013-04-10 04:17:41 -07:00
|
|
|
| Parsetree.Pcf_constraint (_, _) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* don't give a $*%@ ! *)
|
2002-11-01 09:06:47 -08:00
|
|
|
iter acc_inher acc_fields loc.Location.loc_end.Lexing.pos_cnum q
|
2002-07-23 07:12:03 -07:00
|
|
|
|
2013-04-10 04:17:41 -07:00
|
|
|
| (Parsetree.Pcf_initializer exp) ->
|
2002-11-01 09:06:47 -08:00
|
|
|
iter acc_inher acc_fields exp.Parsetree.pexp_loc.Location.loc_end.Lexing.pos_cnum q
|
2013-04-10 10:54:54 -07:00
|
|
|
|
2014-05-04 13:42:34 -07:00
|
|
|
| Parsetree.Pcf_attribute _ ->
|
|
|
|
iter acc_inher acc_fields loc.Location.loc_end.Lexing.pos_cnum q
|
|
|
|
|
2013-04-10 10:54:54 -07:00
|
|
|
| Parsetree.Pcf_extension _ -> assert false
|
2002-03-27 08:20:32 -08:00
|
|
|
in
|
2012-05-30 07:52:37 -07:00
|
|
|
iter [] [] last_pos (p_cls.Parsetree.pcstr_fields)
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2002-03-27 08:20:32 -08:00
|
|
|
(** Analysis of a [Parsetree.class_expr] and a [Typedtree.class_expr] to get a a couple (class parameters, class kind). *)
|
2008-07-23 01:55:36 -07:00
|
|
|
let rec analyse_class_kind env current_class_name comment_opt last_pos p_class_expr tt_class_exp table =
|
2002-03-27 08:20:32 -08:00
|
|
|
match (p_class_expr.Parsetree.pcl_desc, tt_class_exp.Typedtree.cl_desc) with
|
2004-11-03 01:31:19 -08:00
|
|
|
(Parsetree.Pcl_constr (lid, _), tt_class_exp_desc ) ->
|
|
|
|
let name =
|
2002-07-23 07:12:03 -07:00
|
|
|
match tt_class_exp_desc with
|
2012-05-30 07:52:37 -07:00
|
|
|
Typedtree.Tcl_ident (p,_,_) -> Name.from_path p
|
2002-07-23 07:12:03 -07:00
|
|
|
| _ ->
|
|
|
|
(* we try to get the name from the environment. *)
|
2012-07-30 02:48:32 -07:00
|
|
|
(* A VOIR : dommage qu'on n'ait pas un Tclass_ident :-( meme quand on a class tutu = toto *)
|
2012-05-30 07:52:37 -07:00
|
|
|
Name.from_longident lid.txt
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
2012-07-30 02:48:32 -07:00
|
|
|
(* On n'a pas ici les parametres de type sous forme de Types.type_expr,
|
2002-07-23 07:12:03 -07:00
|
|
|
par contre on peut les trouver dans le class_type *)
|
2004-11-03 01:31:19 -08:00
|
|
|
let params =
|
2002-07-23 07:12:03 -07:00
|
|
|
match tt_class_exp.Typedtree.cl_type with
|
2012-05-30 07:52:37 -07:00
|
|
|
Types.Cty_constr (p2, type_exp_list, cltyp) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* cltyp is the class type for [type_exp_list] p *)
|
|
|
|
type_exp_list
|
|
|
|
| _ ->
|
|
|
|
[]
|
|
|
|
in
|
2004-11-03 01:31:19 -08:00
|
|
|
([],
|
2002-07-23 07:12:03 -07:00
|
|
|
Class_constr
|
|
|
|
{
|
|
|
|
cco_name = Odoc_env.full_class_name env name ;
|
|
|
|
cco_class = None ;
|
2004-11-03 01:31:19 -08:00
|
|
|
cco_type_parameters = List.map (Odoc_env.subst_type env) params ;
|
2002-07-23 07:12:03 -07:00
|
|
|
} )
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2012-05-30 07:52:37 -07:00
|
|
|
| (Parsetree.Pcl_structure p_class_structure, Typedtree.Tcl_structure tt_class_structure) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* we need the class signature to get the type of methods in analyse_class_structure *)
|
2004-11-03 01:31:19 -08:00
|
|
|
let tt_class_sig =
|
2002-07-23 07:12:03 -07:00
|
|
|
match tt_class_exp.Typedtree.cl_type with
|
2012-05-30 07:52:37 -07:00
|
|
|
Types.Cty_signature class_sig -> class_sig
|
2002-07-23 07:12:03 -07:00
|
|
|
| _ -> raise (Failure "analyse_class_kind: no class signature for a class structure.")
|
|
|
|
in
|
2004-11-03 01:31:19 -08:00
|
|
|
let (inherited_classes, class_elements) = analyse_class_structure
|
2002-07-23 07:12:03 -07:00
|
|
|
env
|
2004-11-03 01:31:19 -08:00
|
|
|
current_class_name
|
2002-07-23 07:12:03 -07:00
|
|
|
tt_class_sig
|
|
|
|
last_pos
|
2002-11-01 09:06:47 -08:00
|
|
|
p_class_expr.Parsetree.pcl_loc.Location.loc_end.Lexing.pos_cnum
|
2002-07-23 07:12:03 -07:00
|
|
|
p_class_structure
|
|
|
|
tt_class_structure
|
2008-07-23 01:55:36 -07:00
|
|
|
table
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
|
|
|
([],
|
|
|
|
Class_structure (inherited_classes, class_elements) )
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2002-03-27 08:20:32 -08:00
|
|
|
| (Parsetree.Pcl_fun (label, expression_opt, pattern, p_class_expr2),
|
2012-05-30 07:52:37 -07:00
|
|
|
Typedtree.Tcl_fun (_, pat, ident_exp_list, tt_class_expr2, partial)) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* we check that this is not an optional parameter with
|
|
|
|
a default value. In this case, we look for the good parameter pattern *)
|
|
|
|
let (parameter, next_tt_class_exp) =
|
|
|
|
match pat.Typedtree.pat_desc with
|
2012-05-30 07:52:37 -07:00
|
|
|
Typedtree.Tpat_var (ident, _) when Name.from_ident ident = "*opt*" ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(
|
2012-05-30 07:52:37 -07:00
|
|
|
(* there must be a Tcl_let just after *)
|
2002-07-23 07:12:03 -07:00
|
|
|
match tt_class_expr2.Typedtree.cl_desc with
|
2013-06-03 08:14:19 -07:00
|
|
|
Typedtree.Tcl_let (_, {vb_pat={pat_desc = Typedtree.Tpat_var (id,_) };
|
|
|
|
vb_expr=exp} :: _, _, tt_class_expr3) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let name = Name.from_ident id in
|
|
|
|
let new_param = Simple_name
|
|
|
|
{ sn_name = name ;
|
|
|
|
sn_text = Odoc_parameter.desc_from_info_opt comment_opt name ;
|
|
|
|
sn_type = Odoc_env.subst_type env exp.exp_type
|
|
|
|
}
|
|
|
|
in
|
|
|
|
(new_param, tt_class_expr3)
|
|
|
|
| _ ->
|
|
|
|
(* strange case *)
|
|
|
|
(* we create the parameter and add it to the class *)
|
|
|
|
raise (Failure "analyse_class_kind: strange case")
|
|
|
|
)
|
2002-03-27 08:20:32 -08:00
|
|
|
| _ ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* no optional parameter with default value, we create the parameter *)
|
2004-11-03 01:31:19 -08:00
|
|
|
let new_param =
|
2002-07-23 07:12:03 -07:00
|
|
|
tt_param_info_from_pattern
|
|
|
|
env
|
|
|
|
(Odoc_parameter.desc_from_info_opt comment_opt)
|
|
|
|
pat
|
|
|
|
in
|
|
|
|
(new_param, tt_class_expr2)
|
|
|
|
in
|
2008-07-23 01:55:36 -07:00
|
|
|
let (params, k) = analyse_class_kind
|
|
|
|
env current_class_name comment_opt last_pos p_class_expr2
|
|
|
|
next_tt_class_exp table
|
|
|
|
in
|
2002-07-23 07:12:03 -07:00
|
|
|
(parameter :: params, k)
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2012-05-30 07:52:37 -07:00
|
|
|
| (Parsetree.Pcl_apply (p_class_expr2, _), Tcl_apply (tt_class_expr2, exp_opt_optional_list)) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let applied_name =
|
2002-03-27 08:20:32 -08:00
|
|
|
(* we want an ident, or else the class applied will appear in the form object ... end,
|
2002-07-23 07:12:03 -07:00
|
|
|
because if the class applied has no name, the code is kinda ugly, isn't it ? *)
|
|
|
|
match tt_class_expr2.Typedtree.cl_desc with
|
2012-05-30 07:52:37 -07:00
|
|
|
Typedtree.Tcl_ident (p,_,_) -> Name.from_path p (* A VOIR : obtenir le nom complet *)
|
2004-11-03 01:31:19 -08:00
|
|
|
| _ ->
|
2012-07-30 02:48:32 -07:00
|
|
|
(* A VOIR : dommage qu'on n'ait pas un Tclass_ident :-( meme quand on a class tutu = toto *)
|
2002-07-23 07:12:03 -07:00
|
|
|
match p_class_expr2.Parsetree.pcl_desc with
|
|
|
|
Parsetree.Pcl_constr (lid, _) ->
|
|
|
|
(* we try to get the name from the environment. *)
|
2012-05-30 07:52:37 -07:00
|
|
|
Name.from_longident lid.txt
|
2002-07-23 07:12:03 -07:00
|
|
|
| _ ->
|
|
|
|
Odoc_messages.object_end
|
|
|
|
in
|
|
|
|
let param_exps = List.fold_left
|
2012-05-30 07:52:37 -07:00
|
|
|
(fun acc -> fun (_, exp_opt, _) ->
|
2004-11-03 01:31:19 -08:00
|
|
|
match exp_opt with
|
2002-07-23 07:12:03 -07:00
|
|
|
None -> acc
|
|
|
|
| Some e -> acc @ [e])
|
|
|
|
[]
|
|
|
|
exp_opt_optional_list
|
|
|
|
in
|
|
|
|
let param_types = List.map (fun e -> e.Typedtree.exp_type) param_exps in
|
2004-11-03 01:31:19 -08:00
|
|
|
let params_code =
|
|
|
|
List.map
|
|
|
|
(fun e -> get_string_of_file
|
2002-11-01 09:06:47 -08:00
|
|
|
e.exp_loc.Location.loc_start.Lexing.pos_cnum
|
|
|
|
e.exp_loc.Location.loc_end.Lexing.pos_cnum)
|
2002-07-23 07:12:03 -07:00
|
|
|
param_exps
|
|
|
|
in
|
|
|
|
([],
|
|
|
|
Class_apply
|
|
|
|
{ capp_name = Odoc_env.full_class_name env applied_name ;
|
|
|
|
capp_class = None ;
|
|
|
|
capp_params = param_types ;
|
|
|
|
capp_params_code = params_code ;
|
|
|
|
} )
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2012-05-30 07:52:37 -07:00
|
|
|
| (Parsetree.Pcl_let (_, _, p_class_expr2), Typedtree.Tcl_let (_, _, _, tt_class_expr2)) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* we don't care about these lets *)
|
2008-07-23 01:55:36 -07:00
|
|
|
analyse_class_kind
|
|
|
|
env current_class_name comment_opt last_pos p_class_expr2
|
|
|
|
tt_class_expr2 table
|
2004-11-03 01:31:19 -08:00
|
|
|
|
|
|
|
| (Parsetree.Pcl_constraint (p_class_expr2, p_class_type2),
|
2012-05-30 07:52:37 -07:00
|
|
|
Typedtree.Tcl_constraint (tt_class_expr2, _, _, _, _)) ->
|
2008-07-23 01:55:36 -07:00
|
|
|
let (l, class_kind) = analyse_class_kind
|
|
|
|
env current_class_name comment_opt last_pos p_class_expr2
|
|
|
|
tt_class_expr2 table
|
|
|
|
in
|
|
|
|
(* A VOIR : analyse du class type ? on n'a pas toutes les infos. cf. Odoc_sig.analyse_class_type_kind *)
|
2004-11-03 01:31:19 -08:00
|
|
|
let class_type_kind =
|
2002-07-23 07:12:03 -07:00
|
|
|
(*Sig.analyse_class_type_kind
|
|
|
|
env
|
|
|
|
""
|
2002-11-01 09:06:47 -08:00
|
|
|
p_class_type2.Parsetree.pcty_loc.Location.loc_start.Lexing.pos_cnum
|
2002-07-23 07:12:03 -07:00
|
|
|
p_class_type2
|
|
|
|
tt_class_expr2.Typedtree.cl_type
|
|
|
|
*)
|
|
|
|
Class_type { cta_name = Odoc_messages.object_end ;
|
|
|
|
cta_class = None ; cta_type_parameters = [] }
|
|
|
|
in
|
|
|
|
(l, Class_constraint (class_kind, class_type_kind))
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
raise (Failure "analyse_class_kind: Parsetree and typedtree don't match.")
|
2002-03-27 08:20:32 -08:00
|
|
|
|
|
|
|
(** Analysis of a [Parsetree.class_declaration] and a [Typedtree.class_expr] to return a [t_class].*)
|
2008-07-23 01:55:36 -07:00
|
|
|
let analyse_class env current_module_name comment_opt p_class_decl tt_type_params tt_class_exp table =
|
2002-03-27 08:20:32 -08:00
|
|
|
let name = p_class_decl.Parsetree.pci_name in
|
2012-05-30 07:52:37 -07:00
|
|
|
let complete_name = Name.concat current_module_name name.txt in
|
2012-07-26 12:21:54 -07:00
|
|
|
let loc = p_class_decl.Parsetree.pci_expr.Parsetree.pcl_loc in
|
|
|
|
let pos_start = loc.Location.loc_start.Lexing.pos_cnum in
|
2002-03-27 08:20:32 -08:00
|
|
|
let type_parameters = tt_type_params in
|
|
|
|
let virt = p_class_decl.Parsetree.pci_virt = Asttypes.Virtual in
|
2002-04-05 01:20:29 -08:00
|
|
|
let cltype = Odoc_env.subst_class_type env tt_class_exp.Typedtree.cl_type in
|
2004-11-03 01:31:19 -08:00
|
|
|
let (parameters, kind) = analyse_class_kind
|
2002-07-23 07:12:03 -07:00
|
|
|
env
|
|
|
|
complete_name
|
|
|
|
comment_opt
|
|
|
|
pos_start
|
|
|
|
p_class_decl.Parsetree.pci_expr
|
|
|
|
tt_class_exp
|
2008-07-23 01:55:36 -07:00
|
|
|
table
|
2002-03-27 08:20:32 -08:00
|
|
|
in
|
|
|
|
let cl =
|
2002-07-23 07:12:03 -07:00
|
|
|
{
|
|
|
|
cl_name = complete_name ;
|
|
|
|
cl_info = comment_opt ;
|
|
|
|
cl_type = cltype ;
|
|
|
|
cl_virtual = virt ;
|
|
|
|
cl_type_parameters = type_parameters ;
|
|
|
|
cl_kind = kind ;
|
|
|
|
cl_parameters = parameters ;
|
2012-07-26 12:21:54 -07:00
|
|
|
cl_loc = { loc_impl = Some loc ; loc_inter = None } ;
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
2002-03-27 08:20:32 -08:00
|
|
|
in
|
|
|
|
cl
|
|
|
|
|
|
|
|
(** Get a name from a module expression, or "struct ... end" if the module expression
|
|
|
|
is not an ident of a constraint on an ident. *)
|
|
|
|
let rec tt_name_from_module_expr mod_expr =
|
|
|
|
match mod_expr.Typedtree.mod_desc with
|
2012-05-30 07:52:37 -07:00
|
|
|
Typedtree.Tmod_ident (p,_) -> Name.from_path p
|
|
|
|
| Typedtree.Tmod_constraint (m_exp, _, _, _) -> tt_name_from_module_expr m_exp
|
2002-03-27 08:20:32 -08:00
|
|
|
| Typedtree.Tmod_structure _
|
2004-11-03 01:31:19 -08:00
|
|
|
| Typedtree.Tmod_functor _
|
2010-01-22 04:48:24 -08:00
|
|
|
| Typedtree.Tmod_apply _
|
2009-10-26 03:53:16 -07:00
|
|
|
| Typedtree.Tmod_unpack _ ->
|
2002-07-23 07:12:03 -07:00
|
|
|
Odoc_messages.struct_end
|
2002-03-27 08:20:32 -08:00
|
|
|
|
|
|
|
(** Get the list of included modules in a module structure of a typed tree. *)
|
|
|
|
let tt_get_included_module_list tt_structure =
|
|
|
|
let f acc item =
|
2012-05-30 07:52:37 -07:00
|
|
|
match item.str_desc with
|
2014-04-15 04:26:00 -07:00
|
|
|
Typedtree.Tstr_include incl ->
|
2002-07-23 07:12:03 -07:00
|
|
|
acc @ [
|
|
|
|
{ (* A VOIR : chercher dans les modules et les module types, avec quel env ? *)
|
2014-04-15 04:26:00 -07:00
|
|
|
im_name = tt_name_from_module_expr incl.incl_mod ;
|
2002-07-23 07:12:03 -07:00
|
|
|
im_module = None ;
|
2006-09-20 04:14:37 -07:00
|
|
|
im_info = None ;
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
|
|
|
]
|
2002-07-23 07:12:03 -07:00
|
|
|
| _ ->
|
|
|
|
acc
|
2002-03-27 08:20:32 -08:00
|
|
|
in
|
2012-05-30 07:52:37 -07:00
|
|
|
List.fold_left f [] tt_structure.str_items
|
2002-03-27 08:20:32 -08:00
|
|
|
|
|
|
|
(** This function takes a [module element list] of a module and replaces the "dummy" included modules with
|
|
|
|
the ones found in typed tree structure of the module. *)
|
|
|
|
let replace_dummy_included_modules module_elements included_modules =
|
|
|
|
let rec f = function
|
2002-07-23 07:12:03 -07:00
|
|
|
| ([], _) ->
|
|
|
|
[]
|
|
|
|
| ((Element_included_module im) :: q, (im_repl :: im_q)) ->
|
2004-11-03 01:31:19 -08:00
|
|
|
(Element_included_module { im_repl with im_info = im.im_info })
|
2006-09-20 04:14:37 -07:00
|
|
|
:: (f (q, im_q))
|
2002-07-23 07:12:03 -07:00
|
|
|
| ((Element_included_module im) :: q, []) ->
|
|
|
|
(Element_included_module im) :: q
|
|
|
|
| (ele :: q, l) ->
|
|
|
|
ele :: (f (q, l))
|
2002-03-27 08:20:32 -08:00
|
|
|
in
|
|
|
|
f (module_elements, included_modules)
|
|
|
|
|
2006-09-20 04:14:37 -07:00
|
|
|
(** This function removes the elements of the module which does not
|
|
|
|
belong to the given module type, if the module type is expanded
|
|
|
|
and the module has a "structure" kind. *)
|
|
|
|
let rec filter_module_with_module_type_constraint m mt =
|
|
|
|
match m.m_kind, mt with
|
2012-05-30 07:52:37 -07:00
|
|
|
Module_struct l, Types.Mty_signature lsig ->
|
2006-09-20 04:14:37 -07:00
|
|
|
m.m_kind <- Module_struct (filter_module_elements_with_module_type_constraint l lsig);
|
|
|
|
m.m_type <- mt;
|
|
|
|
| _ -> ()
|
|
|
|
|
|
|
|
(** This function removes the elements of the module type which does not
|
|
|
|
belong to the given module type, if the module type is expanded
|
|
|
|
and the module type has a "structure" kind. *)
|
|
|
|
and filter_module_type_with_module_type_constraint mtyp mt =
|
|
|
|
match mtyp.mt_kind, mt with
|
2012-05-30 07:52:37 -07:00
|
|
|
Some Module_type_struct l, Types.Mty_signature lsig ->
|
2006-09-20 04:14:37 -07:00
|
|
|
mtyp.mt_kind <- Some (Module_type_struct (filter_module_elements_with_module_type_constraint l lsig));
|
|
|
|
mtyp.mt_type <- Some mt;
|
|
|
|
| _ -> ()
|
|
|
|
|
|
|
|
and filter_module_elements_with_module_type_constraint l lsig =
|
|
|
|
let pred ele =
|
|
|
|
let f = match ele with
|
|
|
|
Element_module m ->
|
|
|
|
(function
|
2013-09-27 10:05:39 -07:00
|
|
|
Types.Sig_module (ident,md,_) ->
|
2006-09-20 04:14:37 -07:00
|
|
|
let n1 = Name.simple m.m_name
|
|
|
|
and n2 = Ident.name ident in
|
|
|
|
(
|
|
|
|
match n1 = n2 with
|
2013-09-27 10:05:39 -07:00
|
|
|
true -> filter_module_with_module_type_constraint m md.md_type; true
|
2006-09-20 04:14:37 -07:00
|
|
|
| false -> false
|
|
|
|
)
|
|
|
|
| _ -> false)
|
|
|
|
| Element_module_type mt ->
|
|
|
|
(function
|
2013-10-01 08:14:04 -07:00
|
|
|
Types.Sig_modtype (ident,{Types.mtd_type=Some t}) ->
|
2006-09-20 04:14:37 -07:00
|
|
|
let n1 = Name.simple mt.mt_name
|
|
|
|
and n2 = Ident.name ident in
|
|
|
|
(
|
|
|
|
match n1 = n2 with
|
|
|
|
true -> filter_module_type_with_module_type_constraint mt t; true
|
|
|
|
| false -> false
|
|
|
|
)
|
|
|
|
| _ -> false)
|
|
|
|
| Element_value v ->
|
|
|
|
(function
|
2012-05-30 07:52:37 -07:00
|
|
|
Types.Sig_value (ident,_) ->
|
2006-09-20 04:14:37 -07:00
|
|
|
let n1 = Name.simple v.val_name
|
|
|
|
and n2 = Ident.name ident in
|
|
|
|
n1 = n2
|
|
|
|
| _ -> false)
|
|
|
|
| Element_type t ->
|
|
|
|
(function
|
2012-05-30 07:52:37 -07:00
|
|
|
Types.Sig_type (ident,_,_) ->
|
2012-07-30 02:48:32 -07:00
|
|
|
(* A VOIR: il est possible que le detail du type soit cache *)
|
2006-09-20 04:14:37 -07:00
|
|
|
let n1 = Name.simple t.ty_name
|
|
|
|
and n2 = Ident.name ident in
|
|
|
|
n1 = n2
|
|
|
|
| _ -> false)
|
2014-05-04 16:08:45 -07:00
|
|
|
| Element_type_extension te ->
|
|
|
|
let l =
|
|
|
|
filter_extension_constructors_with_module_type_constraint
|
|
|
|
te.te_constructors lsig
|
|
|
|
in
|
|
|
|
te.te_constructors <- l;
|
|
|
|
if l <> [] then (fun _ -> true)
|
|
|
|
else (fun _ -> false)
|
2006-09-20 04:14:37 -07:00
|
|
|
| Element_exception e ->
|
|
|
|
(function
|
2014-05-04 16:08:45 -07:00
|
|
|
Types.Sig_typext (ident,_,_) ->
|
2006-09-20 04:14:37 -07:00
|
|
|
let n1 = Name.simple e.ex_name
|
|
|
|
and n2 = Ident.name ident in
|
|
|
|
n1 = n2
|
|
|
|
| _ -> false)
|
|
|
|
| Element_class c ->
|
|
|
|
(function
|
2012-05-30 07:52:37 -07:00
|
|
|
Types.Sig_class (ident,_,_) ->
|
2006-09-20 04:14:37 -07:00
|
|
|
let n1 = Name.simple c.cl_name
|
|
|
|
and n2 = Ident.name ident in
|
|
|
|
n1 = n2
|
|
|
|
| _ -> false)
|
|
|
|
| Element_class_type ct ->
|
|
|
|
(function
|
2012-05-30 07:52:37 -07:00
|
|
|
Types.Sig_class_type (ident,_,_) ->
|
2006-09-20 04:14:37 -07:00
|
|
|
let n1 = Name.simple ct.clt_name
|
|
|
|
and n2 = Ident.name ident in
|
|
|
|
n1 = n2
|
|
|
|
| _ -> false)
|
|
|
|
| Element_module_comment _ -> fun _ -> true
|
|
|
|
| Element_included_module _ -> fun _ -> true
|
|
|
|
in
|
|
|
|
List.exists f lsig
|
|
|
|
in
|
|
|
|
List.filter pred l
|
|
|
|
|
2014-05-04 16:08:45 -07:00
|
|
|
and filter_extension_constructors_with_module_type_constraint l lsig =
|
|
|
|
let pred xt =
|
|
|
|
List.exists
|
|
|
|
(function
|
|
|
|
Types.Sig_typext (ident, _, _) ->
|
|
|
|
let n1 = Name.simple xt.xt_name
|
|
|
|
and n2 = Ident.name ident in
|
|
|
|
n1 = n2
|
|
|
|
| _ -> false)
|
|
|
|
lsig
|
|
|
|
in
|
|
|
|
List.filter pred l
|
|
|
|
|
2002-03-27 08:20:32 -08:00
|
|
|
(** Analysis of a parse tree structure with a typed tree, to return module elements.*)
|
2004-11-03 01:31:19 -08:00
|
|
|
let rec analyse_structure env current_module_name last_pos pos_limit parsetree typedtree =
|
2002-03-27 08:20:32 -08:00
|
|
|
print_DEBUG "Odoc_ast:analyse_struture";
|
2012-05-30 07:52:37 -07:00
|
|
|
let (table, table_values) = Typedtree_search.tables typedtree.str_items in
|
2002-03-27 08:20:32 -08:00
|
|
|
let rec iter env last_pos = function
|
2004-11-03 01:31:19 -08:00
|
|
|
[] ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let s = get_string_of_file last_pos pos_limit in
|
|
|
|
let (_, ele_coms) = My_ir.all_special !file_name s in
|
|
|
|
let ele_comments =
|
|
|
|
List.fold_left
|
|
|
|
(fun acc -> fun sc ->
|
|
|
|
match sc.Odoc_types.i_desc with
|
|
|
|
None ->
|
|
|
|
acc
|
|
|
|
| Some t ->
|
|
|
|
acc @ [Element_module_comment t])
|
|
|
|
[]
|
|
|
|
ele_coms
|
|
|
|
in
|
|
|
|
ele_comments
|
2004-11-03 01:31:19 -08:00
|
|
|
| item :: q ->
|
|
|
|
let (comment_opt, ele_comments) =
|
|
|
|
get_comments_in_module last_pos item.Parsetree.pstr_loc.Location.loc_start.Lexing.pos_cnum
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
|
|
|
let pos_limit2 =
|
|
|
|
match q with
|
|
|
|
[] -> pos_limit
|
2002-11-01 09:06:47 -08:00
|
|
|
| item2 :: _ -> item2.Parsetree.pstr_loc.Location.loc_start.Lexing.pos_cnum
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
|
|
|
let (maybe_more, new_env, elements) = analyse_structure_item
|
|
|
|
env
|
|
|
|
current_module_name
|
|
|
|
item.Parsetree.pstr_loc
|
|
|
|
pos_limit2
|
|
|
|
comment_opt
|
|
|
|
item.Parsetree.pstr_desc
|
|
|
|
typedtree
|
2004-11-03 01:31:19 -08:00
|
|
|
table
|
2002-07-23 07:12:03 -07:00
|
|
|
table_values
|
|
|
|
in
|
2002-11-01 09:06:47 -08:00
|
|
|
ele_comments @ elements @ (iter new_env (item.Parsetree.pstr_loc.Location.loc_end.Lexing.pos_cnum + maybe_more) q)
|
2002-03-27 08:20:32 -08:00
|
|
|
in
|
|
|
|
iter env last_pos parsetree
|
|
|
|
|
|
|
|
(** Analysis of a parse tree structure item to obtain a new environment and a list of elements.*)
|
2004-11-03 01:31:19 -08:00
|
|
|
and analyse_structure_item env current_module_name loc pos_limit comment_opt parsetree_item_desc typedtree
|
|
|
|
table table_values =
|
2002-03-27 08:20:32 -08:00
|
|
|
print_DEBUG "Odoc_ast:analyse_struture_item";
|
|
|
|
match parsetree_item_desc with
|
2002-07-23 07:12:03 -07:00
|
|
|
Parsetree.Pstr_eval _ ->
|
|
|
|
(* don't care *)
|
|
|
|
(0, env, [])
|
2013-03-06 04:27:32 -08:00
|
|
|
| Parsetree.Pstr_attribute _
|
2013-03-05 03:46:25 -08:00
|
|
|
| Parsetree.Pstr_extension _ ->
|
|
|
|
(0, env, [])
|
2013-06-03 08:14:19 -07:00
|
|
|
| Parsetree.Pstr_value (rec_flag, pat_exp_list) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* of rec_flag * (pattern * expression) list *)
|
|
|
|
(* For each value, look for the value name, then look in the
|
|
|
|
typedtree for the corresponding information,
|
|
|
|
at last analyse this information to build the value *)
|
|
|
|
let rec iter_pat = function
|
|
|
|
| Parsetree.Ppat_any -> None
|
|
|
|
| Parsetree.Ppat_var name -> Some name
|
|
|
|
| Parsetree.Ppat_tuple _ -> None (* A VOIR quand on traitera les tuples *)
|
|
|
|
| Parsetree.Ppat_constraint (pat, _) -> iter_pat pat.Parsetree.ppat_desc
|
|
|
|
| _ -> None
|
|
|
|
in
|
|
|
|
let rec iter ?(first=false) last_pos acc_env acc p_e_list =
|
|
|
|
match p_e_list with
|
|
|
|
[] ->
|
|
|
|
(acc_env, acc)
|
2013-06-03 08:14:19 -07:00
|
|
|
| {Parsetree.pvb_pat=pat; pvb_expr=exp} :: q ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let value_name_opt = iter_pat pat.Parsetree.ppat_desc in
|
2002-11-01 09:06:47 -08:00
|
|
|
let new_last_pos = exp.Parsetree.pexp_loc.Location.loc_end.Lexing.pos_cnum in
|
2002-07-23 07:12:03 -07:00
|
|
|
match value_name_opt with
|
|
|
|
None ->
|
|
|
|
iter new_last_pos acc_env acc q
|
|
|
|
| Some name ->
|
|
|
|
try
|
2012-05-30 07:52:37 -07:00
|
|
|
let pat_exp = Typedtree_search.search_value table_values name.txt in
|
2002-07-23 07:12:03 -07:00
|
|
|
let (info_opt, ele_comments) =
|
|
|
|
(* we already have the optional comment for the first value. *)
|
|
|
|
if first then
|
|
|
|
(comment_opt, [])
|
|
|
|
else
|
|
|
|
get_comments_in_module
|
2004-11-03 01:31:19 -08:00
|
|
|
last_pos
|
2002-11-01 09:06:47 -08:00
|
|
|
pat.Parsetree.ppat_loc.Location.loc_start.Lexing.pos_cnum
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
2004-11-03 01:31:19 -08:00
|
|
|
let l_values = tt_analyse_value
|
2002-07-23 07:12:03 -07:00
|
|
|
env
|
|
|
|
current_module_name
|
|
|
|
info_opt
|
|
|
|
loc
|
|
|
|
pat_exp
|
|
|
|
rec_flag
|
|
|
|
in
|
2004-11-03 01:31:19 -08:00
|
|
|
let new_env = List.fold_left
|
2002-07-23 07:12:03 -07:00
|
|
|
(fun e -> fun v ->
|
|
|
|
Odoc_env.add_value e v.val_name
|
|
|
|
)
|
|
|
|
acc_env
|
|
|
|
l_values
|
|
|
|
in
|
|
|
|
let l_ele = List.map (fun v -> Element_value v) l_values in
|
2004-11-03 01:31:19 -08:00
|
|
|
iter
|
|
|
|
new_last_pos
|
|
|
|
new_env
|
2002-07-23 07:12:03 -07:00
|
|
|
(acc @ ele_comments @ l_ele)
|
|
|
|
q
|
|
|
|
with
|
|
|
|
Not_found ->
|
|
|
|
iter new_last_pos acc_env acc q
|
|
|
|
in
|
2002-11-01 09:06:47 -08:00
|
|
|
let (new_env, l_ele) = iter ~first: true loc.Location.loc_start.Lexing.pos_cnum env [] pat_exp_list in
|
2002-07-23 07:12:03 -07:00
|
|
|
(0, new_env, l_ele)
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2013-03-06 04:00:18 -08:00
|
|
|
| Parsetree.Pstr_primitive val_desc ->
|
|
|
|
let name_pre = val_desc.Parsetree.pval_name.txt in
|
2012-07-26 12:21:54 -07:00
|
|
|
(* of string * value_description *)
|
|
|
|
print_DEBUG ("Parsetree.Pstr_primitive ("^name_pre^", ["^(String.concat ", " val_desc.Parsetree.pval_prim)^"]");
|
|
|
|
let typ = Typedtree_search.search_primitive table name_pre in
|
|
|
|
let name = Name.parens_if_infix name_pre in
|
|
|
|
let complete_name = Name.concat current_module_name name in
|
|
|
|
let code =
|
|
|
|
if !Odoc_global.keep_code then
|
|
|
|
Some (get_string_of_file loc.Location.loc_start.Lexing.pos_cnum
|
|
|
|
loc.Location.loc_end.Lexing.pos_cnum)
|
|
|
|
else
|
|
|
|
None
|
|
|
|
in
|
|
|
|
let new_value = {
|
|
|
|
val_name = complete_name ;
|
|
|
|
val_info = comment_opt ;
|
|
|
|
val_type = Odoc_env.subst_type env typ ;
|
|
|
|
val_recursive = false ;
|
|
|
|
val_parameters = [] ;
|
|
|
|
val_code = code ;
|
|
|
|
val_loc = { loc_impl = Some loc ; loc_inter = None } ;
|
|
|
|
}
|
|
|
|
in
|
|
|
|
let new_env = Odoc_env.add_value env new_value.val_name in
|
|
|
|
(0, new_env, [Element_value new_value])
|
2002-03-27 08:20:32 -08:00
|
|
|
|
|
|
|
| Parsetree.Pstr_type name_typedecl_list ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* of (string * type_declaration) list *)
|
|
|
|
(* we start by extending the environment *)
|
|
|
|
let new_env =
|
2004-11-03 01:31:19 -08:00
|
|
|
List.fold_left
|
2013-03-06 03:47:59 -08:00
|
|
|
(fun acc_env {Parsetree.ptype_name = { txt = name }} ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let complete_name = Name.concat current_module_name name in
|
|
|
|
Odoc_env.add_type acc_env complete_name
|
|
|
|
)
|
|
|
|
env
|
|
|
|
name_typedecl_list
|
|
|
|
in
|
|
|
|
let rec f ?(first=false) maybe_more_acc last_pos name_type_decl_list =
|
|
|
|
match name_type_decl_list with
|
|
|
|
[] -> (maybe_more_acc, [])
|
2013-03-06 03:47:59 -08:00
|
|
|
| type_decl :: q ->
|
|
|
|
let name = type_decl.Parsetree.ptype_name.txt in
|
2002-07-23 07:12:03 -07:00
|
|
|
let complete_name = Name.concat current_module_name name in
|
2012-07-26 12:21:54 -07:00
|
|
|
let loc = type_decl.Parsetree.ptype_loc in
|
|
|
|
let loc_start = loc.Location.loc_start.Lexing.pos_cnum in
|
|
|
|
let loc_end = loc.Location.loc_end.Lexing.pos_cnum in
|
2004-11-03 01:31:19 -08:00
|
|
|
let pos_limit2 =
|
|
|
|
match q with
|
2012-07-26 12:21:54 -07:00
|
|
|
[] -> pos_limit
|
2013-03-06 03:47:59 -08:00
|
|
|
| td :: _ -> td.Parsetree.ptype_loc.Location.loc_start.Lexing.pos_cnum
|
2012-07-26 12:21:54 -07:00
|
|
|
in
|
|
|
|
let (maybe_more, name_comment_list) =
|
2002-07-23 07:12:03 -07:00
|
|
|
Sig.name_comment_from_type_kind
|
2012-05-30 07:52:37 -07:00
|
|
|
loc_end
|
|
|
|
pos_limit2
|
|
|
|
type_decl.Parsetree.ptype_kind
|
|
|
|
in
|
|
|
|
let tt_type_decl =
|
|
|
|
try Typedtree_search.search_type_declaration table name
|
|
|
|
with Not_found -> raise (Failure (Odoc_messages.type_not_found_in_typedtree complete_name))
|
|
|
|
in
|
|
|
|
let tt_type_decl = tt_type_decl.Typedtree.typ_type in
|
|
|
|
let (com_opt, ele_comments) = (* the comment for the first type was already retrieved *)
|
|
|
|
if first then
|
|
|
|
(comment_opt , [])
|
|
|
|
else
|
|
|
|
get_comments_in_module last_pos loc_start
|
|
|
|
in
|
|
|
|
let kind = Sig.get_type_kind
|
2002-07-23 07:12:03 -07:00
|
|
|
new_env name_comment_list
|
|
|
|
tt_type_decl.Types.type_kind
|
2012-07-26 12:21:54 -07:00
|
|
|
in
|
|
|
|
let new_end = loc_end + maybe_more in
|
|
|
|
let t =
|
|
|
|
{
|
|
|
|
ty_name = complete_name ;
|
|
|
|
ty_info = com_opt ;
|
|
|
|
ty_parameters =
|
2006-09-20 04:14:37 -07:00
|
|
|
List.map2
|
2013-05-03 06:38:30 -07:00
|
|
|
(fun p v ->
|
|
|
|
let (co, cn) = Types.Variance.get_upper v in
|
|
|
|
(Odoc_env.subst_type new_env p, co, cn))
|
|
|
|
tt_type_decl.Types.type_params
|
|
|
|
tt_type_decl.Types.type_variance ;
|
2012-07-26 12:21:54 -07:00
|
|
|
ty_kind = kind ;
|
|
|
|
ty_private = tt_type_decl.Types.type_private;
|
|
|
|
ty_manifest =
|
|
|
|
(match tt_type_decl.Types.type_manifest with
|
|
|
|
None -> None
|
|
|
|
| Some t -> Some (Odoc_env.subst_type new_env t));
|
|
|
|
ty_loc = { loc_impl = Some loc ; loc_inter = None } ;
|
|
|
|
ty_code =
|
2006-09-20 04:14:37 -07:00
|
|
|
(
|
2010-08-24 02:45:45 -07:00
|
|
|
if !Odoc_global.keep_code then
|
2006-09-20 04:14:37 -07:00
|
|
|
Some (get_string_of_file loc_start new_end)
|
|
|
|
else
|
|
|
|
None
|
|
|
|
) ;
|
2012-07-26 12:21:54 -07:00
|
|
|
}
|
|
|
|
in
|
|
|
|
let (maybe_more2, info_after_opt) =
|
|
|
|
My_ir.just_after_special
|
2002-07-23 07:12:03 -07:00
|
|
|
!file_name
|
|
|
|
(get_string_of_file new_end pos_limit2)
|
2012-07-26 12:21:54 -07:00
|
|
|
in
|
|
|
|
t.ty_info <- Sig.merge_infos t.ty_info info_after_opt ;
|
|
|
|
let (maybe_more3, eles) = f (maybe_more + maybe_more2) (new_end + maybe_more2) q in
|
|
|
|
(maybe_more3, ele_comments @ ((Element_type t) :: eles))
|
|
|
|
in
|
|
|
|
let (maybe_more, eles) = f ~first: true 0 loc.Location.loc_start.Lexing.pos_cnum name_typedecl_list in
|
|
|
|
(maybe_more, new_env, eles)
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2014-05-04 16:08:45 -07:00
|
|
|
| Parsetree.Pstr_typext tyext ->
|
|
|
|
(* we get the extension declaration in the typed tree *)
|
|
|
|
let tt_tyext =
|
|
|
|
match tyext.Parsetree.ptyext_constructors with
|
|
|
|
[] -> assert false
|
|
|
|
| ext :: _ ->
|
|
|
|
try
|
|
|
|
Typedtree_search.search_extension table ext.Parsetree.pext_name.txt
|
|
|
|
with Not_found ->
|
|
|
|
raise (Failure
|
|
|
|
(Odoc_messages.extension_not_found_in_typedtree
|
|
|
|
(Name.concat current_module_name ext.Parsetree.pext_name.txt)))
|
|
|
|
in
|
|
|
|
let new_env =
|
|
|
|
List.fold_left
|
|
|
|
(fun acc_env -> fun {Parsetree.pext_name = { txt = name }} ->
|
|
|
|
let complete_name = Name.concat current_module_name name in
|
|
|
|
Odoc_env.add_extension acc_env complete_name
|
|
|
|
)
|
|
|
|
env
|
|
|
|
tyext.Parsetree.ptyext_constructors
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
2003-07-04 04:39:50 -07:00
|
|
|
let loc_start = loc.Location.loc_start.Lexing.pos_cnum in
|
|
|
|
let loc_end = loc.Location.loc_end.Lexing.pos_cnum in
|
2014-05-04 16:08:45 -07:00
|
|
|
let new_te =
|
2002-07-23 07:12:03 -07:00
|
|
|
{
|
2014-05-04 16:08:45 -07:00
|
|
|
te_info = comment_opt;
|
|
|
|
te_type_name =
|
|
|
|
Odoc_env.full_type_name new_env (Name.from_path tt_tyext.tyext_path);
|
|
|
|
te_type_parameters =
|
|
|
|
List.map (fun (ctyp, _) -> Odoc_env.subst_type new_env ctyp.ctyp_type) tt_tyext.tyext_params;
|
|
|
|
te_private = tt_tyext.tyext_private;
|
|
|
|
te_constructors = [];
|
|
|
|
te_loc = { loc_impl = Some loc ; loc_inter = None } ;
|
|
|
|
te_code =
|
2003-07-04 04:39:50 -07:00
|
|
|
(
|
2014-05-04 16:08:45 -07:00
|
|
|
if !Odoc_global.keep_code then
|
|
|
|
Some (get_string_of_file loc_start loc_end)
|
|
|
|
else
|
|
|
|
None
|
2006-09-20 04:14:37 -07:00
|
|
|
) ;
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
2014-05-04 16:08:45 -07:00
|
|
|
let rec analyse_extension_constructors maybe_more exts_acc tt_ext_list =
|
|
|
|
match tt_ext_list with
|
|
|
|
[] -> (maybe_more, List.rev exts_acc)
|
|
|
|
| tt_ext :: q ->
|
|
|
|
let complete_name = Name.concat current_module_name tt_ext.ext_name.txt in
|
|
|
|
let ext_loc_end = tt_ext.ext_loc.Location.loc_end.Lexing.pos_cnum in
|
|
|
|
let new_xt =
|
|
|
|
match tt_ext.ext_kind with
|
|
|
|
Text_decl(args, ret_type) ->
|
|
|
|
{
|
|
|
|
xt_name = complete_name;
|
|
|
|
xt_args =
|
|
|
|
List.map (fun ctyp -> Odoc_env.subst_type new_env ctyp.ctyp_type) args;
|
|
|
|
xt_ret =
|
|
|
|
may_map (fun ctyp -> Odoc_env.subst_type new_env ctyp.ctyp_type) ret_type;
|
|
|
|
xt_type_extension = new_te;
|
|
|
|
xt_alias = None;
|
|
|
|
xt_loc = { loc_impl = Some tt_ext.ext_loc ; loc_inter = None } ;
|
|
|
|
xt_text = None;
|
|
|
|
}
|
|
|
|
| Text_rebind(path, _) ->
|
|
|
|
{
|
|
|
|
xt_name = complete_name;
|
|
|
|
xt_args = [];
|
|
|
|
xt_ret = None;
|
|
|
|
xt_type_extension = new_te;
|
|
|
|
xt_alias =
|
|
|
|
Some {
|
|
|
|
xa_name = Odoc_env.full_extension_constructor_name env (Name.from_path path);
|
|
|
|
xa_xt = None;
|
|
|
|
};
|
|
|
|
xt_loc = { loc_impl = Some tt_ext.ext_loc ; loc_inter = None } ;
|
|
|
|
xt_text = None;
|
|
|
|
}
|
|
|
|
in
|
|
|
|
let pos_limit2 =
|
|
|
|
match q with
|
|
|
|
[] -> pos_limit
|
|
|
|
| next :: _ ->
|
|
|
|
next.ext_loc.Location.loc_start.Lexing.pos_cnum
|
|
|
|
in
|
|
|
|
let s = get_string_of_file ext_loc_end pos_limit2 in
|
|
|
|
let (maybe_more, comment_opt) = My_ir.just_after_special !file_name s in
|
|
|
|
new_xt.xt_text <- comment_opt;
|
|
|
|
analyse_extension_constructors maybe_more (new_xt :: exts_acc) q
|
|
|
|
in
|
|
|
|
let (maybe_more, exts) = analyse_extension_constructors 0 [] tt_tyext.tyext_constructors in
|
|
|
|
new_te.te_constructors <- exts;
|
|
|
|
(maybe_more, new_env, [ Element_type_extension new_te ])
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2014-05-04 16:08:45 -07:00
|
|
|
| Parsetree.Pstr_exception ext ->
|
|
|
|
let name = ext.Parsetree.pext_name in
|
2002-07-23 07:12:03 -07:00
|
|
|
(* a new exception is defined *)
|
2012-05-30 07:52:37 -07:00
|
|
|
let complete_name = Name.concat current_module_name name.txt in
|
2014-05-04 16:08:45 -07:00
|
|
|
(* we get the exception declaration in the typed tree *)
|
|
|
|
let tt_ext =
|
|
|
|
try Typedtree_search.search_exception table name.txt
|
2004-11-03 01:31:19 -08:00
|
|
|
with Not_found ->
|
2002-07-23 07:12:03 -07:00
|
|
|
raise (Failure (Odoc_messages.exception_not_found_in_typedtree complete_name))
|
|
|
|
in
|
2014-05-04 16:08:45 -07:00
|
|
|
let new_env = Odoc_env.add_extension env complete_name in
|
|
|
|
let new_ext =
|
|
|
|
match tt_ext.ext_kind with
|
|
|
|
Text_decl(tt_args, tt_ret_type) ->
|
|
|
|
let loc_start = loc.Location.loc_start.Lexing.pos_cnum in
|
|
|
|
let loc_end = loc.Location.loc_end.Lexing.pos_cnum in
|
|
|
|
{
|
|
|
|
ex_name = complete_name ;
|
|
|
|
ex_info = comment_opt ;
|
|
|
|
ex_args =
|
|
|
|
List.map
|
|
|
|
(fun ctyp -> Odoc_env.subst_type new_env ctyp.ctyp_type)
|
|
|
|
tt_args;
|
|
|
|
ex_ret =
|
|
|
|
Misc.may_map
|
|
|
|
(fun ctyp -> Odoc_env.subst_type new_env ctyp.ctyp_type)
|
|
|
|
tt_ret_type;
|
|
|
|
ex_alias = None ;
|
|
|
|
ex_loc = { loc_impl = Some loc ; loc_inter = None } ;
|
|
|
|
ex_code =
|
|
|
|
(
|
|
|
|
if !Odoc_global.keep_code then
|
|
|
|
Some (get_string_of_file loc_start loc_end)
|
|
|
|
else
|
|
|
|
None
|
|
|
|
) ;
|
|
|
|
}
|
|
|
|
| Text_rebind(tt_path, _) ->
|
|
|
|
{
|
|
|
|
ex_name = complete_name ;
|
|
|
|
ex_info = comment_opt ;
|
|
|
|
ex_args = [] ;
|
|
|
|
ex_ret = None ;
|
|
|
|
ex_alias =
|
|
|
|
Some { ea_name =
|
|
|
|
Odoc_env.full_extension_constructor_name
|
|
|
|
env (Name.from_path tt_path) ;
|
|
|
|
ea_ex = None ; } ;
|
|
|
|
ex_loc = { loc_impl = Some loc ; loc_inter = None } ;
|
|
|
|
ex_code = None ;
|
|
|
|
}
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
2014-05-04 16:08:45 -07:00
|
|
|
(0, new_env, [ Element_exception new_ext ])
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2013-03-06 02:12:21 -08:00
|
|
|
| Parsetree.Pstr_module {Parsetree.pmb_name=name; pmb_expr=module_expr} ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(
|
|
|
|
(* of string * module_expr *)
|
|
|
|
try
|
2012-05-30 07:52:37 -07:00
|
|
|
let tt_module_expr = Typedtree_search.search_module table name.txt in
|
2004-11-03 01:31:19 -08:00
|
|
|
let new_module_pre = analyse_module
|
2002-07-23 07:12:03 -07:00
|
|
|
env
|
|
|
|
current_module_name
|
2012-05-30 07:52:37 -07:00
|
|
|
name.txt
|
2002-07-23 07:12:03 -07:00
|
|
|
comment_opt
|
|
|
|
module_expr
|
|
|
|
tt_module_expr
|
|
|
|
in
|
2006-09-20 04:14:37 -07:00
|
|
|
let code =
|
2010-08-24 02:45:45 -07:00
|
|
|
if !Odoc_global.keep_code then
|
2006-09-20 04:14:37 -07:00
|
|
|
let loc = module_expr.Parsetree.pmod_loc in
|
|
|
|
let st = loc.Location.loc_start.Lexing.pos_cnum in
|
|
|
|
let en = loc.Location.loc_end.Lexing.pos_cnum in
|
|
|
|
Some (get_string_of_file st en)
|
|
|
|
else
|
|
|
|
None
|
|
|
|
in
|
|
|
|
let new_module =
|
|
|
|
{ new_module_pre with m_code = code }
|
|
|
|
in
|
2002-07-23 07:12:03 -07:00
|
|
|
let new_env = Odoc_env.add_module env new_module.m_name in
|
2004-11-03 01:31:19 -08:00
|
|
|
let new_env2 =
|
2002-07-23 07:12:03 -07:00
|
|
|
match new_module.m_type with
|
2012-07-30 02:48:32 -07:00
|
|
|
(* A VOIR : cela peut-il etre Tmty_ident ? dans ce cas, on aurait pas la signature *)
|
2012-05-30 07:52:37 -07:00
|
|
|
Types.Mty_signature s ->
|
2002-07-23 07:12:03 -07:00
|
|
|
Odoc_env.add_signature new_env new_module.m_name
|
|
|
|
~rel: (Name.simple new_module.m_name) s
|
2004-11-03 01:31:19 -08:00
|
|
|
| _ ->
|
2002-07-23 07:12:03 -07:00
|
|
|
new_env
|
|
|
|
in
|
|
|
|
(0, new_env2, [ Element_module new_module ])
|
|
|
|
with
|
|
|
|
Not_found ->
|
2012-05-30 07:52:37 -07:00
|
|
|
let complete_name = Name.concat current_module_name name.txt in
|
2002-07-23 07:12:03 -07:00
|
|
|
raise (Failure (Odoc_messages.module_not_found_in_typedtree complete_name))
|
|
|
|
)
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2003-06-27 06:40:41 -07:00
|
|
|
| Parsetree.Pstr_recmodule mods ->
|
2006-09-20 04:14:37 -07:00
|
|
|
(* A VOIR ICI pb: pas de lien avec les module type
|
|
|
|
dans les contraintes sur les modules *)
|
|
|
|
let new_env =
|
2004-11-03 01:31:19 -08:00
|
|
|
List.fold_left
|
2013-03-06 02:12:21 -08:00
|
|
|
(fun acc_env {Parsetree.pmb_name=name;pmb_expr=mod_exp} ->
|
2012-05-30 07:52:37 -07:00
|
|
|
let complete_name = Name.concat current_module_name name.txt in
|
2006-09-20 04:14:37 -07:00
|
|
|
let e = Odoc_env.add_module acc_env complete_name in
|
|
|
|
let tt_mod_exp =
|
2012-05-30 07:52:37 -07:00
|
|
|
try Typedtree_search.search_module table name.txt
|
2003-06-27 06:40:41 -07:00
|
|
|
with Not_found -> raise (Failure (Odoc_messages.module_not_found_in_typedtree complete_name))
|
|
|
|
in
|
2004-11-03 01:31:19 -08:00
|
|
|
let new_module = analyse_module
|
2003-06-27 06:40:41 -07:00
|
|
|
e
|
|
|
|
current_module_name
|
2012-05-30 07:52:37 -07:00
|
|
|
name.txt
|
2003-06-27 06:40:41 -07:00
|
|
|
None
|
|
|
|
mod_exp
|
|
|
|
tt_mod_exp
|
2006-09-20 04:14:37 -07:00
|
|
|
in
|
|
|
|
match new_module.m_type with
|
2012-05-30 07:52:37 -07:00
|
|
|
Types.Mty_signature s ->
|
2003-06-27 06:40:41 -07:00
|
|
|
Odoc_env.add_signature e new_module.m_name
|
2006-09-20 04:14:37 -07:00
|
|
|
~rel: (Name.simple new_module.m_name) s
|
|
|
|
| _ ->
|
2003-06-27 06:40:41 -07:00
|
|
|
e
|
|
|
|
)
|
|
|
|
env
|
|
|
|
mods
|
|
|
|
in
|
|
|
|
let rec f ?(first=false) last_pos name_mod_exp_list =
|
|
|
|
match name_mod_exp_list with
|
|
|
|
[] -> []
|
2013-03-06 02:12:21 -08:00
|
|
|
| {Parsetree.pmb_name=name;pmb_expr=mod_exp} :: q ->
|
2012-05-30 07:52:37 -07:00
|
|
|
let complete_name = Name.concat current_module_name name.txt in
|
2003-06-27 06:40:41 -07:00
|
|
|
let loc_start = mod_exp.Parsetree.pmod_loc.Location.loc_start.Lexing.pos_cnum in
|
|
|
|
let loc_end = mod_exp.Parsetree.pmod_loc.Location.loc_end.Lexing.pos_cnum in
|
2004-11-03 01:31:19 -08:00
|
|
|
let tt_mod_exp =
|
2012-05-30 07:52:37 -07:00
|
|
|
try Typedtree_search.search_module table name.txt
|
2003-06-27 06:40:41 -07:00
|
|
|
with Not_found -> raise (Failure (Odoc_messages.module_not_found_in_typedtree complete_name))
|
|
|
|
in
|
|
|
|
let (com_opt, ele_comments) = (* the comment for the first type was already retrieved *)
|
|
|
|
if first then
|
|
|
|
(comment_opt, [])
|
|
|
|
else
|
|
|
|
get_comments_in_module last_pos loc_start
|
|
|
|
in
|
2006-09-20 04:14:37 -07:00
|
|
|
let new_module = analyse_module
|
2003-06-27 06:40:41 -07:00
|
|
|
new_env
|
|
|
|
current_module_name
|
2012-05-30 07:52:37 -07:00
|
|
|
name.txt
|
2003-06-27 06:40:41 -07:00
|
|
|
com_opt
|
|
|
|
mod_exp
|
|
|
|
tt_mod_exp
|
2006-09-20 04:14:37 -07:00
|
|
|
in
|
2003-06-27 06:40:41 -07:00
|
|
|
let eles = f loc_end q in
|
|
|
|
ele_comments @ ((Element_module new_module) :: eles)
|
|
|
|
in
|
|
|
|
let eles = f ~first: true loc.Location.loc_start.Lexing.pos_cnum mods in
|
|
|
|
(0, new_env, eles)
|
2003-06-19 08:53:53 -07:00
|
|
|
|
2013-04-18 06:14:53 -07:00
|
|
|
| Parsetree.Pstr_modtype {Parsetree.pmtd_name=name; pmtd_type=modtype} ->
|
2012-05-30 07:52:37 -07:00
|
|
|
let complete_name = Name.concat current_module_name name.txt in
|
2002-07-23 07:12:03 -07:00
|
|
|
let tt_module_type =
|
2012-05-30 07:52:37 -07:00
|
|
|
try Typedtree_search.search_module_type table name.txt
|
2004-11-03 01:31:19 -08:00
|
|
|
with Not_found ->
|
2002-07-23 07:12:03 -07:00
|
|
|
raise (Failure (Odoc_messages.module_type_not_found_in_typedtree complete_name))
|
|
|
|
in
|
2013-04-18 06:14:53 -07:00
|
|
|
let kind, sig_mtype =
|
|
|
|
match modtype, tt_module_type.mtd_type with
|
|
|
|
| Some modtype, Some mty_type ->
|
|
|
|
Some (Sig.analyse_module_type_kind env complete_name
|
|
|
|
modtype mty_type.mty_type),
|
|
|
|
Some mty_type.mty_type
|
|
|
|
| _ -> None, None
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
2004-11-03 01:31:19 -08:00
|
|
|
let mt =
|
2002-07-23 07:12:03 -07:00
|
|
|
{
|
|
|
|
mt_name = complete_name ;
|
|
|
|
mt_info = comment_opt ;
|
2013-04-18 06:14:53 -07:00
|
|
|
mt_type = sig_mtype ;
|
2002-07-23 07:12:03 -07:00
|
|
|
mt_is_interface = false ;
|
|
|
|
mt_file = !file_name ;
|
2013-04-18 06:14:53 -07:00
|
|
|
mt_kind = kind ;
|
2012-07-26 12:21:54 -07:00
|
|
|
mt_loc = { loc_impl = Some loc ; loc_inter = None } ;
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
|
|
|
let new_env = Odoc_env.add_module_type env mt.mt_name in
|
|
|
|
let new_env2 =
|
2013-04-18 06:14:53 -07:00
|
|
|
match sig_mtype with
|
2012-07-30 02:48:32 -07:00
|
|
|
(* A VOIR : cela peut-il etre Tmty_ident ? dans ce cas, on n'aurait pas la signature *)
|
2013-04-18 06:14:53 -07:00
|
|
|
Some (Types.Mty_signature s) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
Odoc_env.add_signature new_env mt.mt_name ~rel: (Name.simple mt.mt_name) s
|
2004-11-03 01:31:19 -08:00
|
|
|
| _ ->
|
2002-07-23 07:12:03 -07:00
|
|
|
new_env
|
|
|
|
in
|
|
|
|
(0, new_env2, [ Element_module_type mt ])
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2014-04-15 04:26:00 -07:00
|
|
|
| Parsetree.Pstr_open _ ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* A VOIR : enrichir l'environnement quand open ? *)
|
|
|
|
let ele_comments = match comment_opt with
|
|
|
|
None -> []
|
|
|
|
| Some i ->
|
|
|
|
match i.i_desc with
|
|
|
|
None -> []
|
|
|
|
| Some t -> [Element_module_comment t]
|
|
|
|
in
|
|
|
|
(0, env, ele_comments)
|
2002-03-27 08:20:32 -08:00
|
|
|
|
|
|
|
| Parsetree.Pstr_class class_decl_list ->
|
|
|
|
(* we start by extending the environment *)
|
2002-07-23 07:12:03 -07:00
|
|
|
let new_env =
|
2004-11-03 01:31:19 -08:00
|
|
|
List.fold_left
|
2002-07-23 07:12:03 -07:00
|
|
|
(fun acc_env -> fun class_decl ->
|
2012-05-30 07:52:37 -07:00
|
|
|
let complete_name = Name.concat current_module_name class_decl.Parsetree.pci_name.txt in
|
2002-07-23 07:12:03 -07:00
|
|
|
Odoc_env.add_class acc_env complete_name
|
|
|
|
)
|
|
|
|
env
|
|
|
|
class_decl_list
|
|
|
|
in
|
|
|
|
let rec f ?(first=false) last_pos class_decl_list =
|
|
|
|
match class_decl_list with
|
|
|
|
[] ->
|
|
|
|
[]
|
|
|
|
| class_decl :: q ->
|
|
|
|
let (tt_class_exp, tt_type_params) =
|
2012-05-30 07:52:37 -07:00
|
|
|
try Typedtree_search.search_class_exp table class_decl.Parsetree.pci_name.txt
|
2002-07-23 07:12:03 -07:00
|
|
|
with Not_found ->
|
2012-05-30 07:52:37 -07:00
|
|
|
let complete_name = Name.concat current_module_name class_decl.Parsetree.pci_name.txt in
|
2002-07-23 07:12:03 -07:00
|
|
|
raise (Failure (Odoc_messages.class_not_found_in_typedtree complete_name))
|
|
|
|
in
|
|
|
|
let (com_opt, ele_comments) =
|
|
|
|
if first then
|
|
|
|
(comment_opt, [])
|
|
|
|
else
|
2004-11-03 01:31:19 -08:00
|
|
|
get_comments_in_module last_pos class_decl.Parsetree.pci_loc.Location.loc_start.Lexing.pos_cnum
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
2002-11-01 09:06:47 -08:00
|
|
|
let last_pos2 = class_decl.Parsetree.pci_loc.Location.loc_end.Lexing.pos_cnum in
|
2004-11-03 01:31:19 -08:00
|
|
|
let new_class = analyse_class
|
2002-07-23 07:12:03 -07:00
|
|
|
new_env
|
|
|
|
current_module_name
|
|
|
|
com_opt
|
|
|
|
class_decl
|
|
|
|
tt_type_params
|
|
|
|
tt_class_exp
|
2008-07-23 01:55:36 -07:00
|
|
|
table
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
|
|
|
ele_comments @ ((Element_class new_class) :: (f last_pos2 q))
|
|
|
|
in
|
2002-11-01 09:06:47 -08:00
|
|
|
(0, new_env, f ~first: true loc.Location.loc_start.Lexing.pos_cnum class_decl_list)
|
2002-03-27 08:20:32 -08:00
|
|
|
|
|
|
|
| Parsetree.Pstr_class_type class_type_decl_list ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* we start by extending the environment *)
|
|
|
|
let new_env =
|
2004-11-03 01:31:19 -08:00
|
|
|
List.fold_left
|
2002-07-23 07:12:03 -07:00
|
|
|
(fun acc_env -> fun class_type_decl ->
|
2012-05-30 07:52:37 -07:00
|
|
|
let complete_name = Name.concat current_module_name class_type_decl.Parsetree.pci_name.txt in
|
2002-07-23 07:12:03 -07:00
|
|
|
Odoc_env.add_class_type acc_env complete_name
|
|
|
|
)
|
|
|
|
env
|
|
|
|
class_type_decl_list
|
|
|
|
in
|
|
|
|
let rec f ?(first=false) last_pos class_type_decl_list =
|
|
|
|
match class_type_decl_list with
|
|
|
|
[] ->
|
|
|
|
[]
|
|
|
|
| class_type_decl :: q ->
|
|
|
|
let name = class_type_decl.Parsetree.pci_name in
|
2012-05-30 07:52:37 -07:00
|
|
|
let complete_name = Name.concat current_module_name name.txt in
|
2002-07-23 07:12:03 -07:00
|
|
|
let virt = class_type_decl.Parsetree.pci_virt = Asttypes.Virtual in
|
|
|
|
let tt_cltype_declaration =
|
2012-05-30 07:52:37 -07:00
|
|
|
try Typedtree_search.search_class_type_declaration table name.txt
|
2004-11-03 01:31:19 -08:00
|
|
|
with Not_found ->
|
2002-07-23 07:12:03 -07:00
|
|
|
raise (Failure (Odoc_messages.class_type_not_found_in_typedtree complete_name))
|
2012-05-30 07:52:37 -07:00
|
|
|
in
|
|
|
|
let tt_cltype_declaration = tt_cltype_declaration.ci_type_decl in
|
2002-07-23 07:12:03 -07:00
|
|
|
let type_params = tt_cltype_declaration.Types.clty_params in
|
|
|
|
let kind = Sig.analyse_class_type_kind
|
|
|
|
new_env
|
|
|
|
complete_name
|
2002-11-01 09:06:47 -08:00
|
|
|
class_type_decl.Parsetree.pci_loc.Location.loc_start.Lexing.pos_cnum
|
2002-07-23 07:12:03 -07:00
|
|
|
class_type_decl.Parsetree.pci_expr
|
|
|
|
tt_cltype_declaration.Types.clty_type
|
|
|
|
in
|
|
|
|
let (com_opt, ele_comments) =
|
|
|
|
if first then
|
|
|
|
(comment_opt, [])
|
|
|
|
else
|
2004-11-03 01:31:19 -08:00
|
|
|
get_comments_in_module last_pos class_type_decl.Parsetree.pci_loc.Location.loc_start.Lexing.pos_cnum
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
2002-11-01 09:06:47 -08:00
|
|
|
let last_pos2 = class_type_decl.Parsetree.pci_loc.Location.loc_end.Lexing.pos_cnum in
|
2002-07-23 07:12:03 -07:00
|
|
|
let new_ele =
|
|
|
|
Element_class_type
|
|
|
|
{
|
|
|
|
clt_name = complete_name ;
|
|
|
|
clt_info = com_opt ;
|
|
|
|
clt_type = Odoc_env.subst_class_type env tt_cltype_declaration.Types.clty_type ;
|
|
|
|
clt_type_parameters = List.map (Odoc_env.subst_type new_env) type_params ;
|
|
|
|
clt_virtual = virt ;
|
|
|
|
clt_kind = kind ;
|
2012-07-26 12:21:54 -07:00
|
|
|
clt_loc = { loc_impl = Some loc ;
|
2002-07-23 07:12:03 -07:00
|
|
|
loc_inter = None } ;
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
|
|
|
ele_comments @ (new_ele :: (f last_pos2 q))
|
|
|
|
in
|
2002-11-01 09:06:47 -08:00
|
|
|
(0, new_env, f ~first: true loc.Location.loc_start.Lexing.pos_cnum class_type_decl_list)
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2014-04-15 04:26:00 -07:00
|
|
|
| Parsetree.Pstr_include incl ->
|
2002-07-23 07:12:03 -07:00
|
|
|
(* we add a dummy included module which will be replaced by a correct
|
|
|
|
one at the end of the module analysis,
|
|
|
|
to use the Path.t of the included modules in the typdtree. *)
|
2004-11-03 01:31:19 -08:00
|
|
|
let im =
|
2002-07-23 07:12:03 -07:00
|
|
|
{
|
|
|
|
im_name = "dummy" ;
|
|
|
|
im_module = None ;
|
2006-09-20 04:14:37 -07:00
|
|
|
im_info = comment_opt ;
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
2002-07-23 07:12:03 -07:00
|
|
|
in
|
2012-07-30 02:48:32 -07:00
|
|
|
(0, env, [ Element_included_module im ]) (* A VOIR : etendre l'environnement ? avec quoi ? *)
|
2002-03-27 08:20:32 -08:00
|
|
|
|
|
|
|
(** Analysis of a [Parsetree.module_expr] and a name to return a [t_module].*)
|
|
|
|
and analyse_module env current_module_name module_name comment_opt p_module_expr tt_module_expr =
|
|
|
|
let complete_name = Name.concat current_module_name module_name in
|
2012-07-26 12:21:54 -07:00
|
|
|
let loc = p_module_expr.Parsetree.pmod_loc in
|
|
|
|
let pos_start = loc.Location.loc_start.Lexing.pos_cnum in
|
|
|
|
let pos_end = loc.Location.loc_end.Lexing.pos_cnum in
|
2004-11-03 01:31:19 -08:00
|
|
|
let modtype =
|
2004-04-17 05:36:14 -07:00
|
|
|
(* A VOIR : Odoc_env.subst_module_type env ? *)
|
2006-09-20 04:14:37 -07:00
|
|
|
tt_module_expr.Typedtree.mod_type
|
2004-04-17 05:36:14 -07:00
|
|
|
in
|
2004-03-26 01:09:50 -08:00
|
|
|
let m_code_intf =
|
2006-09-20 04:14:37 -07:00
|
|
|
match p_module_expr.Parsetree.pmod_desc with
|
|
|
|
Parsetree.Pmod_constraint (_, pmodule_type) ->
|
|
|
|
let loc_start = pmodule_type.Parsetree.pmty_loc.Location.loc_start.Lexing.pos_cnum in
|
2004-03-26 01:09:50 -08:00
|
|
|
let loc_end = pmodule_type.Parsetree.pmty_loc.Location.loc_end.Lexing.pos_cnum in
|
2006-09-20 04:14:37 -07:00
|
|
|
Some (get_string_of_file loc_start loc_end)
|
|
|
|
| _ ->
|
|
|
|
None
|
2004-03-26 01:09:50 -08:00
|
|
|
in
|
2002-03-27 08:20:32 -08:00
|
|
|
let m_base =
|
2002-07-23 07:12:03 -07:00
|
|
|
{
|
|
|
|
m_name = complete_name ;
|
2004-04-17 05:36:14 -07:00
|
|
|
m_type = modtype ;
|
2002-07-23 07:12:03 -07:00
|
|
|
m_info = comment_opt ;
|
|
|
|
m_is_interface = false ;
|
|
|
|
m_file = !file_name ;
|
|
|
|
m_kind = Module_struct [] ;
|
2012-07-26 12:21:54 -07:00
|
|
|
m_loc = { loc_impl = Some loc ; loc_inter = None } ;
|
2002-07-23 07:12:03 -07:00
|
|
|
m_top_deps = [] ;
|
2006-09-20 04:14:37 -07:00
|
|
|
m_code = None ; (* code is set by the caller, after the module is created *)
|
|
|
|
m_code_intf = m_code_intf ;
|
|
|
|
m_text_only = false ;
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
2002-03-27 08:20:32 -08:00
|
|
|
in
|
|
|
|
match (p_module_expr.Parsetree.pmod_desc, tt_module_expr.Typedtree.mod_desc) with
|
2012-05-30 07:52:37 -07:00
|
|
|
(Parsetree.Pmod_ident longident, Typedtree.Tmod_ident (path, _)) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let alias_name = Odoc_env.full_module_name env (Name.from_path path) in
|
2004-11-03 01:31:19 -08:00
|
|
|
{ m_base with m_kind = Module_alias { ma_name = alias_name ;
|
2002-07-23 07:12:03 -07:00
|
|
|
ma_module = None ; } }
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2002-03-27 08:20:32 -08:00
|
|
|
| (Parsetree.Pmod_structure p_structure, Typedtree.Tmod_structure tt_structure) ->
|
2002-07-23 07:12:03 -07:00
|
|
|
let elements = analyse_structure env complete_name pos_start pos_end p_structure tt_structure in
|
|
|
|
(* we must complete the included modules *)
|
|
|
|
let included_modules_from_tt = tt_get_included_module_list tt_structure in
|
|
|
|
let elements2 = replace_dummy_included_modules elements included_modules_from_tt in
|
|
|
|
{ m_base with m_kind = Module_struct elements2 }
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2004-11-03 01:31:19 -08:00
|
|
|
| (Parsetree.Pmod_functor (_, pmodule_type, p_module_expr2),
|
2012-05-30 07:52:37 -07:00
|
|
|
Typedtree.Tmod_functor (ident, _, mtyp, tt_module_expr2)) ->
|
2013-12-16 19:52:50 -08:00
|
|
|
let loc = match pmodule_type with None -> Location.none
|
|
|
|
| Some pmty -> pmty.Parsetree.pmty_loc in
|
|
|
|
let loc_start = loc.Location.loc_start.Lexing.pos_cnum in
|
|
|
|
let loc_end = loc.Location.loc_end.Lexing.pos_cnum in
|
2006-09-20 04:14:37 -07:00
|
|
|
let mp_type_code = get_string_of_file loc_start loc_end in
|
|
|
|
print_DEBUG (Printf.sprintf "mp_type_code=%s" mp_type_code);
|
|
|
|
let mp_name = Name.from_ident ident in
|
2013-12-16 19:52:50 -08:00
|
|
|
let mp_kind =
|
|
|
|
match pmodule_type, mtyp with
|
|
|
|
Some pmty, Some mty ->
|
|
|
|
Sig.analyse_module_type_kind env current_module_name pmty
|
|
|
|
mty.mty_type
|
|
|
|
| _ -> Module_type_struct []
|
2006-09-20 04:14:37 -07:00
|
|
|
in
|
2004-03-26 01:09:50 -08:00
|
|
|
let param =
|
|
|
|
{
|
2004-04-02 07:10:58 -08:00
|
|
|
mp_name = mp_name ;
|
2013-12-16 19:52:50 -08:00
|
|
|
mp_type = Misc.may_map
|
|
|
|
(fun m -> Odoc_env.subst_module_type env m.mty_type) mtyp ;
|
2006-09-20 04:14:37 -07:00
|
|
|
mp_type_code = mp_type_code ;
|
|
|
|
mp_kind = mp_kind ;
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
2004-03-26 01:09:50 -08:00
|
|
|
in
|
2004-04-17 05:36:14 -07:00
|
|
|
let dummy_complete_name = (*Name.concat "__"*) param.mp_name in
|
2006-09-20 04:14:37 -07:00
|
|
|
(* TODO: A VOIR CE __ *)
|
2004-03-26 01:09:50 -08:00
|
|
|
let new_env = Odoc_env.add_module env dummy_complete_name in
|
2004-11-03 01:31:19 -08:00
|
|
|
let m_base2 = analyse_module
|
2004-03-26 01:09:50 -08:00
|
|
|
new_env
|
|
|
|
current_module_name
|
|
|
|
module_name
|
|
|
|
None
|
|
|
|
p_module_expr2
|
|
|
|
tt_module_expr2
|
|
|
|
in
|
2004-04-02 07:10:58 -08:00
|
|
|
let kind = m_base2.m_kind in
|
|
|
|
{ m_base with m_kind = Module_functor (param, kind) }
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2004-11-03 01:31:19 -08:00
|
|
|
| (Parsetree.Pmod_apply (p_module_expr1, p_module_expr2),
|
2004-03-14 05:52:01 -08:00
|
|
|
Typedtree.Tmod_apply (tt_module_expr1, tt_module_expr2, _))
|
|
|
|
| (Parsetree.Pmod_apply (p_module_expr1, p_module_expr2),
|
2004-11-03 01:31:19 -08:00
|
|
|
Typedtree.Tmod_constraint
|
2012-05-30 07:52:37 -07:00
|
|
|
({ Typedtree.mod_desc = Typedtree.Tmod_apply (tt_module_expr1, tt_module_expr2, _)}, _,
|
2004-03-14 05:52:01 -08:00
|
|
|
_, _)
|
2006-09-20 04:14:37 -07:00
|
|
|
) ->
|
2004-11-03 01:31:19 -08:00
|
|
|
let m1 = analyse_module
|
2002-07-23 07:12:03 -07:00
|
|
|
env
|
|
|
|
current_module_name
|
|
|
|
module_name
|
|
|
|
None
|
|
|
|
p_module_expr1
|
|
|
|
tt_module_expr1
|
|
|
|
in
|
|
|
|
let m2 = analyse_module
|
|
|
|
env
|
|
|
|
current_module_name
|
|
|
|
module_name
|
|
|
|
None
|
|
|
|
p_module_expr2
|
|
|
|
tt_module_expr2
|
|
|
|
in
|
|
|
|
{ m_base with m_kind = Module_apply (m1.m_kind, m2.m_kind) }
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2004-11-03 01:31:19 -08:00
|
|
|
| (Parsetree.Pmod_constraint (p_module_expr2, p_modtype),
|
2012-05-30 07:52:37 -07:00
|
|
|
Typedtree.Tmod_constraint (tt_module_expr2, tt_modtype, _, _)) ->
|
2006-09-20 04:14:37 -07:00
|
|
|
print_DEBUG ("Odoc_ast: case Parsetree.Pmod_constraint + Typedtree.Tmod_constraint "^module_name);
|
2004-11-03 01:31:19 -08:00
|
|
|
let m_base2 = analyse_module
|
2002-07-23 07:12:03 -07:00
|
|
|
env
|
|
|
|
current_module_name
|
|
|
|
module_name
|
|
|
|
None
|
|
|
|
p_module_expr2
|
|
|
|
tt_module_expr2
|
|
|
|
in
|
2006-09-20 04:14:37 -07:00
|
|
|
let mtkind = Sig.analyse_module_type_kind env
|
2002-07-23 07:12:03 -07:00
|
|
|
(Name.concat current_module_name "??")
|
|
|
|
p_modtype tt_modtype
|
|
|
|
in
|
2006-09-20 04:14:37 -07:00
|
|
|
let tt_modtype = Odoc_env.subst_module_type env tt_modtype in
|
2010-08-24 02:45:45 -07:00
|
|
|
if !Odoc_global.filter_with_module_constraints then
|
2008-07-25 06:28:23 -07:00
|
|
|
filter_module_with_module_type_constraint m_base2 tt_modtype;
|
2004-11-03 01:31:19 -08:00
|
|
|
{
|
2002-07-23 07:12:03 -07:00
|
|
|
m_base with
|
2006-09-20 04:14:37 -07:00
|
|
|
m_type = tt_modtype ;
|
|
|
|
m_kind = Module_constraint (m_base2.m_kind, mtkind) ;
|
2002-07-23 07:12:03 -07:00
|
|
|
}
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2003-06-27 06:40:41 -07:00
|
|
|
| (Parsetree.Pmod_structure p_structure,
|
2004-11-03 01:31:19 -08:00
|
|
|
Typedtree.Tmod_constraint
|
2006-09-20 04:14:37 -07:00
|
|
|
({ Typedtree.mod_desc = Typedtree.Tmod_structure tt_structure},
|
2012-05-30 07:52:37 -07:00
|
|
|
tt_modtype, _, _)
|
2006-09-20 04:14:37 -07:00
|
|
|
) ->
|
|
|
|
(* needed for recursive modules *)
|
2004-04-17 05:36:14 -07:00
|
|
|
|
2006-09-20 04:14:37 -07:00
|
|
|
print_DEBUG ("Odoc_ast: case Parsetree.Pmod_structure + Typedtree.Tmod_constraint "^module_name);
|
|
|
|
let elements = analyse_structure env complete_name pos_start pos_end p_structure tt_structure in
|
2003-06-27 06:40:41 -07:00
|
|
|
(* we must complete the included modules *)
|
|
|
|
let included_modules_from_tt = tt_get_included_module_list tt_structure in
|
|
|
|
let elements2 = replace_dummy_included_modules elements included_modules_from_tt in
|
2004-11-03 01:31:19 -08:00
|
|
|
{ m_base with
|
2006-09-20 04:14:37 -07:00
|
|
|
m_type = Odoc_env.subst_module_type env tt_modtype ;
|
|
|
|
m_kind = Module_struct elements2 ;
|
|
|
|
}
|
2003-06-27 06:40:41 -07:00
|
|
|
|
2012-05-30 07:52:37 -07:00
|
|
|
| (Parsetree.Pmod_unpack p_exp,
|
2010-05-03 08:06:17 -07:00
|
|
|
Typedtree.Tmod_unpack (t_exp, tt_modtype)) ->
|
|
|
|
print_DEBUG ("Odoc_ast: case Parsetree.Pmod_unpack + Typedtree.Tmod_unpack "^module_name);
|
|
|
|
let code =
|
|
|
|
let loc = p_module_expr.Parsetree.pmod_loc in
|
|
|
|
let loc_end = loc.Location.loc_end.Lexing.pos_cnum in
|
|
|
|
let exp_loc = p_exp.Parsetree.pexp_loc in
|
|
|
|
let exp_loc_end = exp_loc.Location.loc_end.Lexing.pos_cnum in
|
|
|
|
let s = get_string_of_file exp_loc_end loc_end in
|
|
|
|
Printf.sprintf "(val ...%s" s
|
|
|
|
in
|
2010-10-21 16:59:33 -07:00
|
|
|
(* let name = Odoc_env.full_module_type_name env (Name.from_path (fst pkg_type)) in *)
|
|
|
|
let name =
|
|
|
|
match tt_modtype with
|
2012-05-30 07:52:37 -07:00
|
|
|
| Mty_ident p ->
|
2010-10-21 16:59:33 -07:00
|
|
|
Odoc_env.full_module_type_name env (Name.from_path p)
|
|
|
|
| _ -> ""
|
|
|
|
in
|
2010-05-03 08:06:17 -07:00
|
|
|
let alias = { mta_name = name ; mta_module = None } in
|
|
|
|
{ m_base with
|
|
|
|
m_type = Odoc_env.subst_module_type env tt_modtype ;
|
|
|
|
m_kind = Module_unpack (code, alias) ;
|
|
|
|
}
|
|
|
|
|
2004-03-14 05:52:01 -08:00
|
|
|
| (parsetree, typedtree) ->
|
2004-12-03 06:42:09 -08:00
|
|
|
(*DEBUG*)let s_parse =
|
|
|
|
(*DEBUG*) match parsetree with
|
|
|
|
(*DEBUG*) Parsetree.Pmod_ident _ -> "Pmod_ident"
|
2006-09-20 04:14:37 -07:00
|
|
|
(*DEBUG*) | Parsetree.Pmod_structure _ -> "Pmod_structure"
|
|
|
|
(*DEBUG*) | Parsetree.Pmod_functor _ -> "Pmod_functor"
|
|
|
|
(*DEBUG*) | Parsetree.Pmod_apply _ -> "Pmod_apply"
|
|
|
|
(*DEBUG*) | Parsetree.Pmod_constraint _ -> "Pmod_constraint"
|
2010-05-03 08:06:17 -07:00
|
|
|
(*DEBUG*) | Parsetree.Pmod_unpack _ -> "Pmod_unpack"
|
2006-09-20 04:14:37 -07:00
|
|
|
(*DEBUG*)in
|
|
|
|
(*DEBUG*)let s_typed =
|
2004-12-03 06:42:09 -08:00
|
|
|
(*DEBUG*) match typedtree with
|
|
|
|
(*DEBUG*) Typedtree.Tmod_ident _ -> "Tmod_ident"
|
2006-09-20 04:14:37 -07:00
|
|
|
(*DEBUG*) | Typedtree.Tmod_structure _ -> "Tmod_structure"
|
|
|
|
(*DEBUG*) | Typedtree.Tmod_functor _ -> "Tmod_functor"
|
|
|
|
(*DEBUG*) | Typedtree.Tmod_apply _ -> "Tmod_apply"
|
|
|
|
(*DEBUG*) | Typedtree.Tmod_constraint _ -> "Tmod_constraint"
|
2010-05-03 08:06:17 -07:00
|
|
|
(*DEBUG*) | Typedtree.Tmod_unpack _ -> "Tmod_unpack"
|
2006-09-20 04:14:37 -07:00
|
|
|
(*DEBUG*)in
|
|
|
|
(*DEBUG*)let code = get_string_of_file pos_start pos_end in
|
|
|
|
print_DEBUG (Printf.sprintf "code=%s\ns_parse=%s\ns_typed=%s\n" code s_parse s_typed);
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2002-07-23 07:12:03 -07:00
|
|
|
raise (Failure "analyse_module: parsetree and typedtree don't match.")
|
2002-03-27 08:20:32 -08:00
|
|
|
|
2004-11-03 01:31:19 -08:00
|
|
|
let analyse_typed_tree source_file input_file
|
|
|
|
(parsetree : Parsetree.structure) (typedtree : typedtree) =
|
2002-03-27 08:20:32 -08:00
|
|
|
let (tree_structure, _) = typedtree in
|
|
|
|
let complete_source_file =
|
2002-07-23 07:12:03 -07:00
|
|
|
try
|
|
|
|
let curdir = Sys.getcwd () in
|
|
|
|
let (dirname, basename) = (Filename.dirname source_file, Filename.basename source_file) in
|
|
|
|
Sys.chdir dirname ;
|
|
|
|
let complete = Filename.concat (Sys.getcwd ()) basename in
|
|
|
|
Sys.chdir curdir ;
|
|
|
|
complete
|
|
|
|
with
|
|
|
|
Sys_error s ->
|
|
|
|
prerr_endline s ;
|
|
|
|
incr Odoc_global.errors ;
|
|
|
|
source_file
|
2002-03-27 08:20:32 -08:00
|
|
|
in
|
|
|
|
prepare_file complete_source_file input_file;
|
|
|
|
(* We create the t_module for this file. *)
|
|
|
|
let mod_name = String.capitalize (Filename.basename (Filename.chop_extension source_file)) in
|
|
|
|
let (len,info_opt) = My_ir.first_special !file_name !file in
|
2004-11-03 01:31:19 -08:00
|
|
|
|
2002-06-05 05:56:09 -07:00
|
|
|
(* we must complete the included modules *)
|
|
|
|
let elements = analyse_structure Odoc_env.empty mod_name len (String.length !file) parsetree tree_structure in
|
|
|
|
let included_modules_from_tt = tt_get_included_module_list tree_structure in
|
|
|
|
let elements2 = replace_dummy_included_modules elements included_modules_from_tt in
|
|
|
|
let kind = Module_struct elements2 in
|
2004-03-26 01:09:50 -08:00
|
|
|
{
|
|
|
|
m_name = mod_name ;
|
2012-05-30 07:52:37 -07:00
|
|
|
m_type = Types.Mty_signature [] ;
|
2004-03-26 01:09:50 -08:00
|
|
|
m_info = info_opt ;
|
|
|
|
m_is_interface = false ;
|
|
|
|
m_file = !file_name ;
|
|
|
|
m_kind = kind ;
|
2012-07-26 12:21:54 -07:00
|
|
|
m_loc = { loc_impl = Some (Location.in_file !file_name) ; loc_inter = None } ;
|
2004-03-26 01:09:50 -08:00
|
|
|
m_top_deps = [] ;
|
2010-08-24 02:45:45 -07:00
|
|
|
m_code = (if !Odoc_global.keep_code then Some !file else None) ;
|
2006-09-20 04:14:37 -07:00
|
|
|
m_code_intf = None ;
|
|
|
|
m_text_only = false ;
|
2004-11-03 01:31:19 -08:00
|
|
|
}
|
2002-03-27 08:20:32 -08:00
|
|
|
end
|