let make_extensions ts =
let childmap =
List.map (
fun (name, _, t) ->
let children = List.filter (
function
| (_, _, Extension (basename, _))
when to_string basename = name -> true
| _ -> false
) ts in
let children = List.map (
function
| (childname, _, Extension (_, _)) -> childname
| _ -> assert false
) children in
((name, children) : string * string list)
) ts in
let ts =
let rec build_type extname basename exttype =
let _, _, basetype =
try List.find (
function
| (name, _, t) when name = basename -> true
| _ -> false
) ts
with Not_found -> failwith ("extension type " ^ extname ^
" refers to base type " ^ basename ^
" which cannot be found") in
let basetype =
match basetype with
| Extension (basename, exttype) ->
build_type extname (to_string basename) exttype
| t -> t in
match basetype, exttype with
| (Enumeration elements, Enumeration elements') ->
Enumeration (elements @ elements')
| (Sequence elements, Sequence elements') ->
Sequence (elements @ elements')
| _ ->
failwith ("extension type " ^ extname ^ " is/extends something " ^
"which is not an enumeration or sequence of the same " ^
"type.")
in
List.map (
function
| (name, is_abstract, Extension (basename, exttype)) ->
let t = build_type name (to_string basename) exttype in
name, is_abstract, t
| t -> t
) ts in
ts, childmap