1999-12-16 04:25:11 -08:00
|
|
|
(*************************************************************************)
|
|
|
|
(* *)
|
|
|
|
(* Objective Caml LablTk library *)
|
|
|
|
(* *)
|
|
|
|
(* Jacques Garrigue, Kyoto University RIMS *)
|
|
|
|
(* *)
|
|
|
|
(* Copyright 1999 Institut National de Recherche en Informatique et *)
|
|
|
|
(* en Automatique and Kyoto University. All rights reserved. *)
|
|
|
|
(* This file is distributed under the terms of the GNU Library *)
|
|
|
|
(* General Public License. *)
|
|
|
|
(* *)
|
|
|
|
(*************************************************************************)
|
|
|
|
|
1999-11-30 06:59:39 -08:00
|
|
|
(* $Id$ *)
|
|
|
|
|
|
|
|
open Tk
|
|
|
|
open Jg_tk
|
|
|
|
open Parsetree
|
|
|
|
open Types
|
|
|
|
open Typedtree
|
|
|
|
open Location
|
|
|
|
open Longident
|
|
|
|
open Path
|
|
|
|
open Env
|
|
|
|
open Searchid
|
|
|
|
|
|
|
|
(* auxiliary functions *)
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
let (~!) = Jg_memo.fast ~f:Str.regexp
|
1999-12-10 01:40:51 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
let lines_to_chars n ~text:s =
|
1999-11-30 06:59:39 -08:00
|
|
|
let l = String.length s in
|
2000-04-11 20:43:25 -07:00
|
|
|
let rec ltc n ~pos =
|
1999-11-30 06:59:39 -08:00
|
|
|
if n = 1 or pos >= l then pos else
|
2000-04-11 20:43:25 -07:00
|
|
|
if s.[pos] = '\n' then ltc (n-1) ~pos:(pos+1) else ltc n ~pos:(pos+1)
|
|
|
|
in ltc n ~pos:0
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
let in_loc loc ~pos =
|
1999-11-30 06:59:39 -08:00
|
|
|
pos >= loc.loc_start & pos < loc.loc_end
|
|
|
|
|
|
|
|
let rec string_of_longident = function
|
|
|
|
Lident s -> s
|
|
|
|
| Ldot (id,s) -> string_of_longident id ^ "." ^ s
|
|
|
|
| Lapply (id1, id2) ->
|
|
|
|
string_of_longident id1 ^ "(" ^ string_of_longident id2 ^ ")"
|
|
|
|
|
|
|
|
let string_of_path p = string_of_longident (Searchid.longident_of_path p)
|
|
|
|
|
|
|
|
let parent_path = function
|
|
|
|
Pdot (path, _, _) -> Some path
|
|
|
|
| Pident _ | Papply _ -> None
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
let ident_of_path ~default = function
|
1999-11-30 06:59:39 -08:00
|
|
|
Pident i -> i
|
|
|
|
| Pdot (_, s, _) -> Ident.create s
|
|
|
|
| Papply _ -> Ident.create default
|
|
|
|
|
|
|
|
let rec head_id = function
|
|
|
|
Pident id -> id
|
|
|
|
| Pdot (path,_,_) -> head_id path
|
|
|
|
| Papply (path,_) -> head_id path (* wrong, but ... *)
|
|
|
|
|
|
|
|
let rec list_of_path = function
|
|
|
|
Pident id -> [Ident.name id]
|
|
|
|
| Pdot (path, s, _) -> list_of_path path @ [s]
|
|
|
|
| Papply (path, _) -> list_of_path path (* wrong, but ... *)
|
|
|
|
|
1999-12-07 07:01:12 -08:00
|
|
|
(* a simple wrapper *)
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
class buffer ~size = object
|
2000-04-02 18:57:52 -07:00
|
|
|
val buffer = Buffer.create size
|
2000-04-11 20:43:25 -07:00
|
|
|
method out ~buf = Buffer.add_substring buffer buf
|
1999-12-07 07:01:12 -08:00
|
|
|
method get = Buffer.contents buffer
|
1999-11-30 06:59:39 -08:00
|
|
|
end
|
|
|
|
|
|
|
|
(* Search in a signature *)
|
|
|
|
|
|
|
|
type skind = [`Type|`Class|`Module|`Modtype]
|
|
|
|
|
|
|
|
exception Found_sig of skind * Longident.t * Env.t
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
let rec search_pos_type t ~pos ~env =
|
|
|
|
if in_loc ~pos t.ptyp_loc then
|
1999-11-30 06:59:39 -08:00
|
|
|
begin (match t.ptyp_desc with
|
|
|
|
Ptyp_any
|
|
|
|
| Ptyp_var _ -> ()
|
|
|
|
| Ptyp_variant(tl, _, _) ->
|
|
|
|
List.iter tl
|
2000-04-11 20:43:25 -07:00
|
|
|
~f:(fun (_,_,tl) -> List.iter tl ~f:(search_pos_type ~pos ~env))
|
1999-11-30 06:59:39 -08:00
|
|
|
| Ptyp_arrow (_, t1, t2) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_type t1 ~pos ~env;
|
|
|
|
search_pos_type t2 ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| Ptyp_tuple tl ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter tl ~f:(search_pos_type ~pos ~env)
|
1999-11-30 06:59:39 -08:00
|
|
|
| Ptyp_constr (lid, tl) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter tl ~f:(search_pos_type ~pos ~env);
|
1999-11-30 06:59:39 -08:00
|
|
|
raise (Found_sig (`Type, lid, env))
|
|
|
|
| Ptyp_object fl ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter fl ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin function
|
2000-04-11 20:43:25 -07:00
|
|
|
| {pfield_desc = Pfield (_, ty)} -> search_pos_type ty ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| _ -> ()
|
|
|
|
end
|
|
|
|
| Ptyp_class (lid, tl, _) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter tl ~f:(search_pos_type ~pos ~env);
|
1999-11-30 06:59:39 -08:00
|
|
|
raise (Found_sig (`Type, lid, env))
|
2000-04-11 20:43:25 -07:00
|
|
|
| Ptyp_alias (t, _) -> search_pos_type ~pos ~env t);
|
1999-11-30 06:59:39 -08:00
|
|
|
raise Not_found
|
|
|
|
end
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
let rec search_pos_class_type cl ~pos ~env =
|
|
|
|
if in_loc cl.pcty_loc ~pos then begin
|
1999-11-30 06:59:39 -08:00
|
|
|
begin match cl.pcty_desc with
|
|
|
|
Pcty_constr (lid, _) ->
|
|
|
|
raise (Found_sig (`Class, lid, env))
|
|
|
|
| Pcty_signature (_, cfl) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter cfl ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin function
|
2000-04-11 20:43:25 -07:00
|
|
|
Pctf_inher cty -> search_pos_class_type cty ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| Pctf_val (_, _, Some ty, loc) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
if in_loc loc ~pos then search_pos_type ty ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| Pctf_val _ -> ()
|
|
|
|
| Pctf_virt (_, _, ty, loc) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
if in_loc loc ~pos then search_pos_type ty ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| Pctf_meth (_, _, ty, loc) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
if in_loc loc ~pos then search_pos_type ty ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| Pctf_cstr (ty1, ty2, loc) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
if in_loc loc ~pos then begin
|
|
|
|
search_pos_type ty1 ~pos ~env;
|
|
|
|
search_pos_type ty2 ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
| Pcty_fun (_, ty, cty) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_type ty ~pos ~env;
|
|
|
|
search_pos_class_type cty ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
end;
|
|
|
|
raise Not_found
|
|
|
|
end
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
let search_pos_type_decl td ~pos ~env =
|
|
|
|
if in_loc ~pos td.ptype_loc then begin
|
1999-11-30 06:59:39 -08:00
|
|
|
begin match td.ptype_manifest with
|
2000-04-11 20:43:25 -07:00
|
|
|
Some t -> search_pos_type t ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| None -> ()
|
|
|
|
end;
|
|
|
|
begin match td.ptype_kind with
|
|
|
|
Ptype_abstract -> ()
|
|
|
|
| Ptype_variant dl ->
|
|
|
|
List.iter dl
|
2000-04-11 20:43:25 -07:00
|
|
|
~f:(fun (_, tl) -> List.iter tl ~f:(search_pos_type ~pos ~env))
|
1999-11-30 06:59:39 -08:00
|
|
|
| Ptype_record dl ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter dl ~f:(fun (_, _, t) -> search_pos_type t ~pos ~env)
|
1999-11-30 06:59:39 -08:00
|
|
|
end;
|
|
|
|
raise Not_found
|
|
|
|
end
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
let rec search_pos_signature l ~pos ~env =
|
2000-02-15 02:09:55 -08:00
|
|
|
ignore (
|
2000-04-11 20:43:25 -07:00
|
|
|
List.fold_left l ~init:env ~f:
|
2000-04-02 18:57:52 -07:00
|
|
|
begin fun env pt ->
|
1999-11-30 06:59:39 -08:00
|
|
|
let env = match pt.psig_desc with
|
|
|
|
Psig_open id ->
|
|
|
|
let path, mt = lookup_module id env in
|
|
|
|
begin match mt with
|
|
|
|
Tmty_signature sign -> open_signature path sign env
|
|
|
|
| _ -> env
|
|
|
|
end
|
|
|
|
| sign_item ->
|
|
|
|
try add_signature (Typemod.transl_signature env [pt]) env
|
|
|
|
with Typemod.Error _ | Typeclass.Error _
|
|
|
|
| Typetexp.Error _ | Typedecl.Error _ -> env
|
|
|
|
in
|
2000-04-11 20:43:25 -07:00
|
|
|
if in_loc ~pos pt.psig_loc then begin
|
1999-11-30 06:59:39 -08:00
|
|
|
begin match pt.psig_desc with
|
2000-04-11 20:43:25 -07:00
|
|
|
Psig_value (_, desc) -> search_pos_type desc.pval_type ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| Psig_type l ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter l ~f:(fun (_,desc) -> search_pos_type_decl ~pos desc ~env)
|
1999-11-30 06:59:39 -08:00
|
|
|
| Psig_exception (_, l) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter l ~f:(search_pos_type ~pos ~env);
|
1999-11-30 06:59:39 -08:00
|
|
|
raise (Found_sig (`Type, Lident "exn", env))
|
|
|
|
| Psig_module (_, t) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_module t ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| Psig_modtype (_, Pmodtype_manifest t) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_module t ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| Psig_modtype _ -> ()
|
|
|
|
| Psig_class l ->
|
|
|
|
List.iter l
|
2000-04-11 20:43:25 -07:00
|
|
|
~f:(fun ci -> search_pos_class_type ci.pci_expr ~pos ~env)
|
1999-11-30 06:59:39 -08:00
|
|
|
| Psig_class_type l ->
|
|
|
|
List.iter l
|
2000-04-11 20:43:25 -07:00
|
|
|
~f:(fun ci -> search_pos_class_type ci.pci_expr ~pos ~env)
|
1999-11-30 06:59:39 -08:00
|
|
|
(* The last cases should not happen in generated interfaces *)
|
|
|
|
| Psig_open lid -> raise (Found_sig (`Module, lid, env))
|
2000-04-11 20:43:25 -07:00
|
|
|
| Psig_include t -> search_pos_module t ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
end;
|
|
|
|
raise Not_found
|
|
|
|
end;
|
|
|
|
env
|
2000-02-15 02:09:55 -08:00
|
|
|
end)
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and search_pos_module m ~pos ~env =
|
|
|
|
if in_loc m.pmty_loc ~pos then begin
|
1999-11-30 06:59:39 -08:00
|
|
|
begin match m.pmty_desc with
|
|
|
|
Pmty_ident lid -> raise (Found_sig (`Modtype, lid, env))
|
2000-04-11 20:43:25 -07:00
|
|
|
| Pmty_signature sg -> search_pos_signature sg ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| Pmty_functor (_ , m1, m2) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_module m1 ~pos ~env;
|
|
|
|
search_pos_module m2 ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| Pmty_with (m, l) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_module m ~pos ~env;
|
|
|
|
List.iter l ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin function
|
2000-04-11 20:43:25 -07:00
|
|
|
_, Pwith_type t -> search_pos_type_decl t ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| _ -> ()
|
|
|
|
end
|
|
|
|
end;
|
|
|
|
raise Not_found
|
|
|
|
end
|
|
|
|
|
|
|
|
(* the module display machinery *)
|
|
|
|
|
|
|
|
type module_widgets =
|
|
|
|
{ mw_frame: Widget.frame Widget.widget;
|
|
|
|
mw_detach: Widget.button Widget.widget;
|
|
|
|
mw_edit: Widget.button Widget.widget;
|
|
|
|
mw_intf: Widget.button Widget.widget }
|
|
|
|
|
2000-04-02 18:57:52 -07:00
|
|
|
let shown_modules = Hashtbl.create 17
|
1999-11-30 06:59:39 -08:00
|
|
|
let filter_modules () =
|
2000-04-11 20:43:25 -07:00
|
|
|
Hashtbl.iter shown_modules ~f:
|
|
|
|
begin fun ~key ~data ->
|
1999-11-30 06:59:39 -08:00
|
|
|
if not (Winfo.exists data.mw_frame) then
|
2000-04-02 18:57:52 -07:00
|
|
|
Hashtbl.remove shown_modules key
|
1999-11-30 06:59:39 -08:00
|
|
|
end
|
2000-04-11 20:43:25 -07:00
|
|
|
let add_shown_module path ~widgets =
|
|
|
|
Hashtbl.add shown_modules ~key:path ~data:widgets
|
1999-11-30 06:59:39 -08:00
|
|
|
and find_shown_module path =
|
|
|
|
filter_modules ();
|
2000-04-02 18:57:52 -07:00
|
|
|
Hashtbl.find shown_modules path
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-02-15 02:09:55 -08:00
|
|
|
let is_shown_module path =
|
|
|
|
filter_modules ();
|
2000-04-02 18:57:52 -07:00
|
|
|
Hashtbl.mem shown_modules path
|
2000-02-15 02:09:55 -08:00
|
|
|
|
1999-11-30 06:59:39 -08:00
|
|
|
(* Viewing a signature *)
|
|
|
|
|
|
|
|
(* Forward definitions of Viewer.view_defined and Editor.editor *)
|
2000-04-11 20:43:25 -07:00
|
|
|
let view_defined_ref = ref (fun lid ~env -> ())
|
|
|
|
let editor_ref = ref (fun ?file ?pos ?opendialog () -> ())
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
let edit_source ~file ~path ~sign =
|
1999-11-30 06:59:39 -08:00
|
|
|
match sign with
|
|
|
|
[item] ->
|
|
|
|
let id, kind =
|
|
|
|
match item with
|
|
|
|
Tsig_value (id, _) -> id, Pvalue
|
|
|
|
| Tsig_type (id, _) -> id, Ptype
|
|
|
|
| Tsig_exception (id, _) -> id, Pconstructor
|
|
|
|
| Tsig_module (id, _) -> id, Pmodule
|
|
|
|
| Tsig_modtype (id, _) -> id, Pmodtype
|
|
|
|
| Tsig_class (id, _) -> id, Pclass
|
|
|
|
| Tsig_cltype (id, _) -> id, Pcltype
|
|
|
|
in
|
|
|
|
let prefix = List.tl (list_of_path path) and name = Ident.name id in
|
|
|
|
let pos =
|
|
|
|
try
|
|
|
|
let chan = open_in file in
|
2000-04-02 18:57:52 -07:00
|
|
|
if Filename.check_suffix file ".ml" then
|
1999-11-30 06:59:39 -08:00
|
|
|
let parsed = Parse.implementation (Lexing.from_channel chan) in
|
|
|
|
close_in chan;
|
2000-04-11 20:43:25 -07:00
|
|
|
Searchid.search_structure parsed ~name ~kind ~prefix
|
1999-11-30 06:59:39 -08:00
|
|
|
else
|
|
|
|
let parsed = Parse.interface (Lexing.from_channel chan) in
|
|
|
|
close_in chan;
|
2000-04-11 20:43:25 -07:00
|
|
|
Searchid.search_signature parsed ~name ~kind ~prefix
|
1999-11-30 06:59:39 -08:00
|
|
|
with _ -> 0
|
2000-04-11 20:43:25 -07:00
|
|
|
in !editor_ref ~file ~pos ()
|
|
|
|
| _ -> !editor_ref ~file ()
|
1999-11-30 06:59:39 -08:00
|
|
|
|
|
|
|
(* List of windows to destroy by Close All *)
|
|
|
|
let top_widgets = ref []
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
let rec view_signature ?title ?path ?(env = !start_env) sign =
|
1999-11-30 06:59:39 -08:00
|
|
|
let env =
|
|
|
|
match path with None -> env
|
|
|
|
| Some path -> Env.open_signature path sign env in
|
|
|
|
let title =
|
|
|
|
match title, path with Some title, _ -> title
|
|
|
|
| None, Some path -> string_of_path path
|
|
|
|
| None, None -> "Signature"
|
|
|
|
in
|
|
|
|
let tl, tw, finish =
|
|
|
|
try match path with
|
|
|
|
None -> raise Not_found
|
|
|
|
| Some path ->
|
|
|
|
let widgets =
|
|
|
|
try find_shown_module path
|
|
|
|
with Not_found ->
|
2000-04-11 20:43:25 -07:00
|
|
|
view_module path ~env;
|
1999-11-30 06:59:39 -08:00
|
|
|
find_shown_module path
|
|
|
|
in
|
|
|
|
Button.configure widgets.mw_detach
|
2000-04-11 20:43:25 -07:00
|
|
|
~command:(fun () -> view_signature sign ~title ~env);
|
|
|
|
pack [widgets.mw_detach] ~side:`Left;
|
1999-11-30 06:59:39 -08:00
|
|
|
Pack.forget [widgets.mw_edit; widgets.mw_intf];
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter2 [widgets.mw_edit; widgets.mw_intf] [".ml"; ".mli"] ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin fun button ext ->
|
|
|
|
try
|
|
|
|
let id = head_id path in
|
|
|
|
let file =
|
|
|
|
Misc.find_in_path !Config.load_path
|
|
|
|
(String.uncapitalize (Ident.name id) ^ ext) in
|
|
|
|
Button.configure button
|
2000-04-11 20:43:25 -07:00
|
|
|
~command:(fun () -> edit_source ~file ~path ~sign);
|
|
|
|
pack [button] ~side:`Left
|
1999-11-30 06:59:39 -08:00
|
|
|
with Not_found -> ()
|
|
|
|
end;
|
|
|
|
let top = Winfo.toplevel widgets.mw_frame in
|
|
|
|
if not (Winfo.ismapped top) then Wm.deiconify top;
|
|
|
|
Focus.set top;
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter ~f:destroy (Winfo.children widgets.mw_frame);
|
|
|
|
Jg_message.formatted ~title ~on:widgets.mw_frame ~maxheight:15 ()
|
1999-11-30 06:59:39 -08:00
|
|
|
with Not_found ->
|
2000-04-11 20:43:25 -07:00
|
|
|
let tl, tw, finish = Jg_message.formatted ~title ~maxheight:15 () in
|
1999-11-30 06:59:39 -08:00
|
|
|
top_widgets := tl :: !top_widgets;
|
|
|
|
tl, tw, finish
|
|
|
|
in
|
|
|
|
Format.set_max_boxes 100;
|
2000-03-06 14:12:09 -08:00
|
|
|
Printtyp.signature Format.std_formatter sign;
|
1999-11-30 06:59:39 -08:00
|
|
|
finish ();
|
|
|
|
Lexical.init_tags tw;
|
|
|
|
Lexical.tag tw;
|
2000-04-11 20:43:25 -07:00
|
|
|
Text.configure tw ~state:`Disabled;
|
1999-11-30 06:59:39 -08:00
|
|
|
let text = Jg_text.get_all tw in
|
|
|
|
let pt =
|
|
|
|
try Parse.interface (Lexing.from_string text)
|
|
|
|
with Syntaxerr.Error e ->
|
|
|
|
let l =
|
|
|
|
match e with
|
|
|
|
Syntaxerr.Unclosed(l,_,_,_) -> l
|
|
|
|
| Syntaxerr.Other l -> l
|
|
|
|
in
|
2000-04-11 20:43:25 -07:00
|
|
|
Jg_text.tag_and_see tw ~start:(tpos l.loc_start)
|
|
|
|
~stop:(tpos l.loc_end) ~tag:"error"; []
|
1999-11-30 06:59:39 -08:00
|
|
|
| Lexer.Error (_, s, e) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
Jg_text.tag_and_see tw ~start:(tpos s) ~stop:(tpos e) ~tag:"error"; []
|
1999-11-30 06:59:39 -08:00
|
|
|
in
|
|
|
|
Jg_bind.enter_focus tw;
|
2000-04-11 20:43:25 -07:00
|
|
|
bind tw ~events:[`Modified([`Control], `KeyPressDetail"s")]
|
|
|
|
~action:(fun _ -> Jg_text.search_string tw);
|
|
|
|
bind tw ~events:[`Modified([`Double], `ButtonPressDetail 1)]
|
|
|
|
~fields:[`MouseX;`MouseY] ~breakable:true
|
|
|
|
~action:(fun ev ->
|
1999-11-30 06:59:39 -08:00
|
|
|
let `Linechar (l, c) =
|
2000-04-11 20:43:25 -07:00
|
|
|
Text.index tw ~index:(`Atxy(ev.ev_MouseX,ev.ev_MouseY), []) in
|
1999-11-30 06:59:39 -08:00
|
|
|
try try
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_signature pt ~pos:(lines_to_chars l ~text + c) ~env;
|
1999-11-30 06:59:39 -08:00
|
|
|
break ()
|
2000-04-11 20:43:25 -07:00
|
|
|
with Found_sig (kind, lid, env) -> view_decl lid ~kind ~env
|
1999-12-16 00:37:38 -08:00
|
|
|
with Not_found | Env.Error _ -> ());
|
2000-04-11 20:43:25 -07:00
|
|
|
bind tw ~events:[`ButtonPressDetail 3] ~fields:[`MouseX;`MouseY] ~breakable:true
|
|
|
|
~action:(fun ev ->
|
1999-11-30 06:59:39 -08:00
|
|
|
let x = ev.ev_MouseX and y = ev.ev_MouseY in
|
|
|
|
let `Linechar (l, c) =
|
2000-04-11 20:43:25 -07:00
|
|
|
Text.index tw ~index:(`Atxy(x,y), []) in
|
1999-11-30 06:59:39 -08:00
|
|
|
try try
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_signature pt ~pos:(lines_to_chars l ~text + c) ~env;
|
1999-11-30 06:59:39 -08:00
|
|
|
break ()
|
|
|
|
with Found_sig (kind, lid, env) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
let menu = view_decl_menu lid ~kind ~env ~parent:tw in
|
1999-11-30 06:59:39 -08:00
|
|
|
let x = x + Winfo.rootx tw and y = y + Winfo.rooty tw - 10 in
|
2000-04-11 20:43:25 -07:00
|
|
|
Menu.popup menu ~x ~y
|
1999-12-16 00:37:38 -08:00
|
|
|
with Not_found -> ())
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and view_signature_item sign ~path ~env =
|
|
|
|
view_signature sign ~title:(string_of_path path)
|
|
|
|
?path:(parent_path path) ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and view_module path ~env =
|
1999-11-30 06:59:39 -08:00
|
|
|
match find_module path env with
|
|
|
|
Tmty_signature sign ->
|
2000-04-11 20:43:25 -07:00
|
|
|
!view_defined_ref (Searchid.longident_of_path path) ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| modtype ->
|
2000-04-11 20:43:25 -07:00
|
|
|
let id = ident_of_path path ~default:"M" in
|
|
|
|
view_signature_item [Tsig_module (id, modtype)] ~path ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and view_module_id id ~env =
|
1999-11-30 06:59:39 -08:00
|
|
|
let path, _ = lookup_module id env in
|
2000-04-11 20:43:25 -07:00
|
|
|
view_module path ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and view_type_decl path ~env =
|
1999-11-30 06:59:39 -08:00
|
|
|
let td = find_type path env in
|
|
|
|
try match td.type_manifest with None -> raise Not_found
|
|
|
|
| Some ty -> match Ctype.repr ty with
|
|
|
|
{desc = Tobject _} ->
|
|
|
|
let clt = find_cltype path env in
|
2000-04-11 20:43:25 -07:00
|
|
|
view_signature_item ~path ~env
|
|
|
|
[Tsig_cltype(ident_of_path path ~default:"ct", clt)]
|
1999-11-30 06:59:39 -08:00
|
|
|
| _ -> raise Not_found
|
|
|
|
with Not_found ->
|
2000-04-11 20:43:25 -07:00
|
|
|
view_signature_item ~path ~env
|
|
|
|
[Tsig_type(ident_of_path path ~default:"t", td)]
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and view_type_id li ~env =
|
1999-11-30 06:59:39 -08:00
|
|
|
let path, decl = lookup_type li env in
|
2000-04-11 20:43:25 -07:00
|
|
|
view_type_decl path ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and view_class_id li ~env =
|
1999-11-30 06:59:39 -08:00
|
|
|
let path, cl = lookup_class li env in
|
2000-04-11 20:43:25 -07:00
|
|
|
view_signature_item ~path ~env
|
|
|
|
[Tsig_class(ident_of_path path ~default:"c", cl)]
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and view_cltype_id li ~env =
|
1999-11-30 06:59:39 -08:00
|
|
|
let path, clt = lookup_cltype li env in
|
2000-04-11 20:43:25 -07:00
|
|
|
view_signature_item ~path ~env
|
|
|
|
[Tsig_cltype(ident_of_path path ~default:"ct", clt)]
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and view_modtype_id li ~env =
|
1999-11-30 06:59:39 -08:00
|
|
|
let path, td = lookup_modtype li env in
|
2000-04-11 20:43:25 -07:00
|
|
|
view_signature_item ~path ~env
|
|
|
|
[Tsig_modtype(ident_of_path path ~default:"S", td)]
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and view_expr_type ?title ?path ?env ?(name="noname") t =
|
1999-11-30 06:59:39 -08:00
|
|
|
let title =
|
|
|
|
match title, path with Some title, _ -> title
|
|
|
|
| None, Some path -> string_of_path path
|
|
|
|
| None, None -> "Expression type"
|
|
|
|
and path, id =
|
|
|
|
match path with None -> None, Ident.create name
|
2000-04-11 20:43:25 -07:00
|
|
|
| Some path -> parent_path path, ident_of_path path ~default:name
|
1999-11-30 06:59:39 -08:00
|
|
|
in
|
2000-04-11 20:43:25 -07:00
|
|
|
view_signature ~title ?path ?env
|
1999-11-30 06:59:39 -08:00
|
|
|
[Tsig_value (id, {val_type = t; val_kind = Val_reg})]
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and view_decl lid ~kind ~env =
|
1999-11-30 06:59:39 -08:00
|
|
|
match kind with
|
2000-04-11 20:43:25 -07:00
|
|
|
`Type -> view_type_id lid ~env
|
|
|
|
| `Class -> view_class_id lid ~env
|
|
|
|
| `Module -> view_module_id lid ~env
|
|
|
|
| `Modtype -> view_modtype_id lid ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and view_decl_menu lid ~kind ~env ~parent =
|
1999-11-30 06:59:39 -08:00
|
|
|
let path, kname =
|
|
|
|
try match kind with
|
|
|
|
`Type -> fst (lookup_type lid env), "Type"
|
|
|
|
| `Class -> fst (lookup_class lid env), "Class"
|
|
|
|
| `Module -> fst (lookup_module lid env), "Module"
|
|
|
|
| `Modtype -> fst (lookup_modtype lid env), "Module type"
|
|
|
|
with Env.Error _ -> raise Not_found
|
|
|
|
in
|
2000-04-11 20:43:25 -07:00
|
|
|
let menu = Menu.create parent ~tearoff:false in
|
1999-11-30 06:59:39 -08:00
|
|
|
let label = kname ^ " " ^ string_of_path path in
|
|
|
|
begin match path with
|
|
|
|
Pident _ ->
|
2000-04-11 20:43:25 -07:00
|
|
|
Menu.add_command menu ~label ~state:`Disabled
|
1999-11-30 06:59:39 -08:00
|
|
|
| _ ->
|
2000-04-11 20:43:25 -07:00
|
|
|
Menu.add_command menu ~label
|
|
|
|
~command:(fun () -> view_decl lid ~kind ~env);
|
1999-11-30 06:59:39 -08:00
|
|
|
end;
|
|
|
|
if kind = `Type or kind = `Modtype then begin
|
2000-04-11 20:43:25 -07:00
|
|
|
let buf = new buffer ~size:60 in
|
1999-11-30 06:59:39 -08:00
|
|
|
let (fo,ff) = Format.get_formatter_output_functions ()
|
|
|
|
and margin = Format.get_margin () in
|
2000-04-11 20:43:25 -07:00
|
|
|
Format.set_formatter_output_functions ~out:buf#out ~flush:(fun () -> ());
|
1999-11-30 06:59:39 -08:00
|
|
|
Format.set_margin 60;
|
|
|
|
Format.open_hbox ();
|
|
|
|
if kind = `Type then
|
|
|
|
Printtyp.type_declaration
|
2000-04-11 20:43:25 -07:00
|
|
|
(ident_of_path path ~default:"t")
|
2000-03-06 14:12:09 -08:00
|
|
|
Format.std_formatter
|
1999-11-30 06:59:39 -08:00
|
|
|
(find_type path env)
|
|
|
|
else
|
|
|
|
Printtyp.modtype_declaration
|
2000-04-11 20:43:25 -07:00
|
|
|
(ident_of_path path ~default:"S")
|
2000-03-06 14:12:09 -08:00
|
|
|
Format.std_formatter
|
1999-11-30 06:59:39 -08:00
|
|
|
(find_modtype path env);
|
|
|
|
Format.close_box (); Format.print_flush ();
|
2000-04-11 20:43:25 -07:00
|
|
|
Format.set_formatter_output_functions ~out:fo ~flush:ff;
|
1999-11-30 06:59:39 -08:00
|
|
|
Format.set_margin margin;
|
2000-04-11 20:43:25 -07:00
|
|
|
let l = Str.split ~sep:~!"\n" buf#get in
|
1999-11-30 06:59:39 -08:00
|
|
|
let font =
|
|
|
|
let font =
|
2000-04-11 20:43:25 -07:00
|
|
|
Option.get Widget.default_toplevel ~name:"font" ~clas:"Font" in
|
1999-11-30 06:59:39 -08:00
|
|
|
if font = "" then "7x14" else font
|
|
|
|
in
|
|
|
|
(* Menu.add_separator menu; *)
|
|
|
|
List.iter l
|
2000-04-11 20:43:25 -07:00
|
|
|
~f:(fun label -> Menu.add_command menu ~label ~font ~state:`Disabled)
|
1999-11-30 06:59:39 -08:00
|
|
|
end;
|
|
|
|
menu
|
|
|
|
|
|
|
|
(* search and view in a structure *)
|
|
|
|
|
2000-04-02 18:57:52 -07:00
|
|
|
type fkind = [
|
|
|
|
`Exp of
|
|
|
|
[`Expr|`Pat|`Const|`Val of Path.t|`Var of Path.t|`New of Path.t]
|
1999-11-30 06:59:39 -08:00
|
|
|
* Types.type_expr
|
2000-04-02 18:57:52 -07:00
|
|
|
| `Class of Path.t * Types.class_type
|
|
|
|
| `Module of Path.t * Types.module_type
|
|
|
|
]
|
1999-11-30 06:59:39 -08:00
|
|
|
exception Found_str of fkind * Env.t
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
let view_type kind ~env =
|
1999-11-30 06:59:39 -08:00
|
|
|
match kind with
|
|
|
|
`Exp (k, ty) ->
|
|
|
|
begin match k with
|
2000-04-11 20:43:25 -07:00
|
|
|
`Expr -> view_expr_type ty ~title:"Expression type" ~env
|
|
|
|
| `Pat -> view_expr_type ty ~title:"Pattern type" ~env
|
|
|
|
| `Const -> view_expr_type ty ~title:"Constant type" ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| `Val path ->
|
|
|
|
begin try
|
|
|
|
let vd = find_value path env in
|
2000-04-11 20:43:25 -07:00
|
|
|
view_signature_item ~path ~env
|
|
|
|
[Tsig_value(ident_of_path path ~default:"v", vd)]
|
1999-11-30 06:59:39 -08:00
|
|
|
with Not_found ->
|
2000-04-11 20:43:25 -07:00
|
|
|
view_expr_type ty ~path ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
end
|
|
|
|
| `Var path ->
|
|
|
|
let vd = find_value path env in
|
2000-04-11 20:43:25 -07:00
|
|
|
view_expr_type vd.val_type ~env ~path ~title:"Variable type"
|
1999-11-30 06:59:39 -08:00
|
|
|
| `New path ->
|
|
|
|
let cl = find_class path env in
|
2000-04-11 20:43:25 -07:00
|
|
|
view_signature_item ~path ~env
|
|
|
|
[Tsig_class(ident_of_path path ~default:"c", cl)]
|
1999-11-30 06:59:39 -08:00
|
|
|
end
|
|
|
|
| `Class (path, cty) ->
|
|
|
|
let cld = { cty_params = []; cty_type = cty;
|
|
|
|
cty_path = path; cty_new = None } in
|
2000-04-11 20:43:25 -07:00
|
|
|
view_signature_item ~path ~env
|
|
|
|
[Tsig_class(ident_of_path path ~default:"c", cld)]
|
1999-11-30 06:59:39 -08:00
|
|
|
| `Module (path, mty) ->
|
|
|
|
match mty with
|
2000-04-11 20:43:25 -07:00
|
|
|
Tmty_signature sign -> view_signature sign ~path ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| modtype ->
|
2000-04-11 20:43:25 -07:00
|
|
|
view_signature_item ~path ~env
|
|
|
|
[Tsig_module(ident_of_path path ~default:"M", mty)]
|
1999-11-30 06:59:39 -08:00
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
let view_type_menu kind ~env ~parent =
|
1999-11-30 06:59:39 -08:00
|
|
|
let title =
|
|
|
|
match kind with
|
|
|
|
`Exp (`Expr,_) -> "Expression :"
|
|
|
|
| `Exp (`Pat, _) -> "Pattern :"
|
|
|
|
| `Exp (`Const, _) -> "Constant :"
|
|
|
|
| `Exp (`Val path, _) -> "Value " ^ string_of_path path ^ " :"
|
|
|
|
| `Exp (`Var path, _) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
"Variable " ^ Ident.name (ident_of_path path ~default:"noname") ^ " :"
|
1999-11-30 06:59:39 -08:00
|
|
|
| `Exp (`New path, _) -> "Class " ^ string_of_path path ^ " :"
|
|
|
|
| `Class (path, _) -> "Class " ^ string_of_path path ^ " :"
|
|
|
|
| `Module (path,_) -> "Module " ^ string_of_path path in
|
2000-04-11 20:43:25 -07:00
|
|
|
let menu = Menu.create parent ~tearoff:false in
|
1999-11-30 06:59:39 -08:00
|
|
|
begin match kind with
|
|
|
|
`Exp((`Expr | `Pat | `Const | `Val (Pident _)),_) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
Menu.add_command menu ~label:title ~state:`Disabled
|
1999-11-30 06:59:39 -08:00
|
|
|
| `Exp _ | `Class _ | `Module _ ->
|
2000-04-11 20:43:25 -07:00
|
|
|
Menu.add_command menu ~label:title
|
|
|
|
~command:(fun () -> view_type kind ~env)
|
1999-11-30 06:59:39 -08:00
|
|
|
end;
|
|
|
|
begin match kind with `Module _ | `Class _ -> ()
|
|
|
|
| `Exp(_, ty) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
let buf = new buffer ~size:60 in
|
1999-11-30 06:59:39 -08:00
|
|
|
let (fo,ff) = Format.get_formatter_output_functions ()
|
|
|
|
and margin = Format.get_margin () in
|
2000-04-11 20:43:25 -07:00
|
|
|
Format.set_formatter_output_functions ~out:buf#out ~flush:(fun () -> ());
|
1999-11-30 06:59:39 -08:00
|
|
|
Format.set_margin 60;
|
|
|
|
Format.open_hbox ();
|
|
|
|
Printtyp.reset ();
|
|
|
|
Printtyp.mark_loops ty;
|
2000-03-06 14:12:09 -08:00
|
|
|
Printtyp.type_expr Format.std_formatter ty;
|
1999-11-30 06:59:39 -08:00
|
|
|
Format.close_box (); Format.print_flush ();
|
2000-04-11 20:43:25 -07:00
|
|
|
Format.set_formatter_output_functions ~out:fo ~flush:ff;
|
1999-11-30 06:59:39 -08:00
|
|
|
Format.set_margin margin;
|
2000-04-11 20:43:25 -07:00
|
|
|
let l = Str.split ~sep:~!"\n" buf#get in
|
1999-11-30 06:59:39 -08:00
|
|
|
let font =
|
|
|
|
let font =
|
2000-04-11 20:43:25 -07:00
|
|
|
Option.get Widget.default_toplevel ~name:"font" ~clas:"Font" in
|
1999-11-30 06:59:39 -08:00
|
|
|
if font = "" then "7x14" else font
|
|
|
|
in
|
|
|
|
(* Menu.add_separator menu; *)
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter l ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin fun label -> match (Ctype.repr ty).desc with
|
|
|
|
Tconstr (path,_,_) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
Menu.add_command menu ~label ~font
|
|
|
|
~command:(fun () -> view_type_decl path ~env)
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tvariant {row_name = Some (path, _)} ->
|
2000-04-11 20:43:25 -07:00
|
|
|
Menu.add_command menu ~label ~font
|
|
|
|
~command:(fun () -> view_type_decl path ~env)
|
1999-11-30 06:59:39 -08:00
|
|
|
| _ ->
|
2000-04-11 20:43:25 -07:00
|
|
|
Menu.add_command menu ~label ~font ~state:`Disabled
|
1999-11-30 06:59:39 -08:00
|
|
|
end
|
|
|
|
end;
|
|
|
|
menu
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
let rec search_pos_structure ~pos str =
|
|
|
|
List.iter str ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin function
|
2000-04-11 20:43:25 -07:00
|
|
|
Tstr_eval exp -> search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tstr_value (rec_flag, l) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter l ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin fun (pat, exp) ->
|
|
|
|
let env =
|
|
|
|
if rec_flag = Asttypes.Recursive then exp.exp_env else Env.empty in
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_pat pat ~pos ~env;
|
|
|
|
search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
end
|
|
|
|
| Tstr_primitive (_, vd) ->()
|
|
|
|
| Tstr_type _ -> ()
|
|
|
|
| Tstr_exception _ -> ()
|
2000-03-12 05:10:29 -08:00
|
|
|
| Tstr_exn_rebind(_, _) -> ()
|
2000-04-11 20:43:25 -07:00
|
|
|
| Tstr_module (_, m) -> search_pos_module_expr m ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tstr_modtype _ -> ()
|
|
|
|
| Tstr_open _ -> ()
|
|
|
|
| Tstr_class l ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter l ~f:(fun (id, _, _, cl) -> search_pos_class_expr cl ~pos)
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tstr_cltype _ -> ()
|
|
|
|
end
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and search_pos_class_expr ~pos cl =
|
|
|
|
if in_loc cl.cl_loc ~pos then begin
|
1999-11-30 06:59:39 -08:00
|
|
|
begin match cl.cl_desc with
|
|
|
|
Tclass_ident path ->
|
|
|
|
raise (Found_str (`Class (path, cl.cl_type), !start_env))
|
|
|
|
| Tclass_structure cls ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter cls.cl_field ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin function
|
|
|
|
Cf_inher (cl, _, _) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_class_expr cl ~pos
|
|
|
|
| Cf_val (_, _, exp) -> search_pos_expr exp ~pos
|
|
|
|
| Cf_meth (_, exp) -> search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
| Cf_let (_, pel, iel) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter pel ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin fun (pat, exp) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_pat pat ~pos ~env:exp.exp_env;
|
|
|
|
search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
end;
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter iel ~f:(fun (_,exp) -> search_pos_expr exp ~pos)
|
|
|
|
| Cf_init exp -> search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
end
|
|
|
|
| Tclass_fun (pat, iel, cl, _) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_pat pat ~pos ~env:pat.pat_env;
|
|
|
|
List.iter iel ~f:(fun (_,exp) -> search_pos_expr exp ~pos);
|
|
|
|
search_pos_class_expr cl ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tclass_apply (cl, el) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_class_expr cl ~pos;
|
|
|
|
List.iter el ~f:(Misc.may (search_pos_expr ~pos))
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tclass_let (_, pel, iel, cl) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter pel ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin fun (pat, exp) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_pat pat ~pos ~env:exp.exp_env;
|
|
|
|
search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
end;
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter iel ~f:(fun (_,exp) -> search_pos_expr exp ~pos);
|
|
|
|
search_pos_class_expr cl ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tclass_constraint (cl, _, _, _) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_class_expr cl ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
end;
|
|
|
|
raise (Found_str
|
|
|
|
(`Class (Pident (Ident.create "c"), cl.cl_type), !start_env))
|
|
|
|
end
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and search_pos_expr ~pos exp =
|
|
|
|
if in_loc exp.exp_loc ~pos then begin
|
1999-11-30 06:59:39 -08:00
|
|
|
begin match exp.exp_desc with
|
|
|
|
Texp_ident (path, _) ->
|
|
|
|
raise (Found_str (`Exp(`Val path, exp.exp_type), exp.exp_env))
|
|
|
|
| Texp_constant v ->
|
|
|
|
raise (Found_str (`Exp(`Const, exp.exp_type), exp.exp_env))
|
|
|
|
| Texp_let (_, expl, exp) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter expl ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin fun (pat, exp') ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_pat pat ~pos ~env:exp.exp_env;
|
|
|
|
search_pos_expr exp' ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
end;
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
| Texp_function (l, _) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter l ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin fun (pat, exp) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_pat pat ~pos ~env:exp.exp_env;
|
|
|
|
search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
end
|
|
|
|
| Texp_apply (exp, l) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter l ~f:(Misc.may (search_pos_expr ~pos));
|
|
|
|
search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
| Texp_match (exp, l, _) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_expr exp ~pos;
|
|
|
|
List.iter l ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin fun (pat, exp) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_pat pat ~pos ~env:exp.exp_env;
|
|
|
|
search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
end
|
|
|
|
| Texp_try (exp, l) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_expr exp ~pos;
|
|
|
|
List.iter l ~f:
|
1999-11-30 06:59:39 -08:00
|
|
|
begin fun (pat, exp) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_pat pat ~pos ~env:exp.exp_env;
|
|
|
|
search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
end
|
2000-04-11 20:43:25 -07:00
|
|
|
| Texp_tuple l -> List.iter l ~f:(search_pos_expr ~pos)
|
|
|
|
| Texp_construct (_, l) -> List.iter l ~f:(search_pos_expr ~pos)
|
1999-11-30 06:59:39 -08:00
|
|
|
| Texp_variant (_, None) -> ()
|
2000-04-11 20:43:25 -07:00
|
|
|
| Texp_variant (_, Some exp) -> search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
| Texp_record (l, opt) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter l ~f:(fun (_, exp) -> search_pos_expr exp ~pos);
|
|
|
|
(match opt with None -> () | Some exp -> search_pos_expr exp ~pos)
|
|
|
|
| Texp_field (exp, _) -> search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
| Texp_setfield (a, _, b) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_expr a ~pos; search_pos_expr b ~pos
|
|
|
|
| Texp_array l -> List.iter l ~f:(search_pos_expr ~pos)
|
1999-11-30 06:59:39 -08:00
|
|
|
| Texp_ifthenelse (a, b, c) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_expr a ~pos; search_pos_expr b ~pos;
|
1999-11-30 06:59:39 -08:00
|
|
|
begin match c with None -> ()
|
2000-04-11 20:43:25 -07:00
|
|
|
| Some exp -> search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
end
|
|
|
|
| Texp_sequence (a,b) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_expr a ~pos; search_pos_expr b ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
| Texp_while (a,b) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_expr a ~pos; search_pos_expr b ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
| Texp_for (_, a, b, _, c) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter [a;b;c] ~f:(search_pos_expr ~pos)
|
1999-11-30 06:59:39 -08:00
|
|
|
| Texp_when (a, b) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_expr a ~pos; search_pos_expr b ~pos
|
|
|
|
| Texp_send (exp, _) -> search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
| Texp_new (path, _) ->
|
|
|
|
raise (Found_str (`Exp(`New path, exp.exp_type), exp.exp_env))
|
|
|
|
| Texp_instvar (_,path) ->
|
|
|
|
raise (Found_str (`Exp(`Var path, exp.exp_type), exp.exp_env))
|
|
|
|
| Texp_setinstvar (_, path, exp) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_expr exp ~pos;
|
1999-11-30 06:59:39 -08:00
|
|
|
raise (Found_str (`Exp(`Var path, exp.exp_type), exp.exp_env))
|
|
|
|
| Texp_override (_, l) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter l ~f:(fun (_, exp) -> search_pos_expr exp ~pos)
|
1999-11-30 06:59:39 -08:00
|
|
|
| Texp_letmodule (id, modexp, exp) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_module_expr modexp ~pos;
|
|
|
|
search_pos_expr exp ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
end;
|
|
|
|
raise (Found_str (`Exp(`Expr, exp.exp_type), exp.exp_env))
|
|
|
|
end
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and search_pos_pat ~pos ~env pat =
|
|
|
|
if in_loc pat.pat_loc ~pos then begin
|
1999-11-30 06:59:39 -08:00
|
|
|
begin match pat.pat_desc with
|
|
|
|
Tpat_any -> ()
|
|
|
|
| Tpat_var id ->
|
|
|
|
raise (Found_str (`Exp(`Val (Pident id), pat.pat_type), env))
|
2000-04-11 20:43:25 -07:00
|
|
|
| Tpat_alias (pat, _) -> search_pos_pat pat ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tpat_constant _ ->
|
|
|
|
raise (Found_str (`Exp(`Const, pat.pat_type), env))
|
|
|
|
| Tpat_tuple l ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter l ~f:(search_pos_pat ~pos ~env)
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tpat_construct (_, l) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter l ~f:(search_pos_pat ~pos ~env)
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tpat_variant (_, None, _) -> ()
|
2000-04-11 20:43:25 -07:00
|
|
|
| Tpat_variant (_, Some pat, _) -> search_pos_pat pat ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tpat_record l ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter l ~f:(fun (_, pat) -> search_pos_pat pat ~pos ~env)
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tpat_array l ->
|
2000-04-11 20:43:25 -07:00
|
|
|
List.iter l ~f:(search_pos_pat ~pos ~env)
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tpat_or (a, b) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_pat a ~pos ~env; search_pos_pat b ~pos ~env
|
1999-11-30 06:59:39 -08:00
|
|
|
end;
|
|
|
|
raise (Found_str (`Exp(`Pat, pat.pat_type), env))
|
|
|
|
end
|
|
|
|
|
2000-04-11 20:43:25 -07:00
|
|
|
and search_pos_module_expr ~pos m =
|
|
|
|
if in_loc m.mod_loc ~pos then begin
|
1999-11-30 06:59:39 -08:00
|
|
|
begin match m.mod_desc with
|
|
|
|
Tmod_ident path ->
|
|
|
|
raise
|
|
|
|
(Found_str (`Module (path, m.mod_type), m.mod_env))
|
2000-04-11 20:43:25 -07:00
|
|
|
| Tmod_structure str -> search_pos_structure str ~pos
|
|
|
|
| Tmod_functor (_, _, m) -> search_pos_module_expr m ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
| Tmod_apply (a, b, _) ->
|
2000-04-11 20:43:25 -07:00
|
|
|
search_pos_module_expr a ~pos; search_pos_module_expr b ~pos
|
|
|
|
| Tmod_constraint (m, _, _) -> search_pos_module_expr m ~pos
|
1999-11-30 06:59:39 -08:00
|
|
|
end;
|
|
|
|
raise (Found_str (`Module (Pident (Ident.create "M"), m.mod_type),
|
|
|
|
m.mod_env))
|
|
|
|
end
|