Skip to content

Commit eb413b2

Browse files
authored
Merge pull request #2053 from voodoos/te-classes-test
Improve type enclosing behavior on various class and object related items
2 parents d8fee0e + 606fa86 commit eb413b2

8 files changed

Lines changed: 269 additions & 14 deletions

File tree

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ unreleased
1010
- Fix bugs on signature help about labelled and optional parameters (#2032)
1111
- Add `-end-position` parameter for `enclosing` (#2029)
1212
- Signature help should appear even if the 'in' is not written (#2036)
13+
- Improve type enclosing behavior on various class and object related items
14+
(#2053)
1315
+ merlin binary
1416
- Define PATH_MAX to 4096 if undefined (eg. hurd) (#2039)
1517
+ tests

src/analysis/completion.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ let classify_node = function
133133
| Module_binding_name _ -> `Module
134134
| Module_declaration_name _ -> `Module
135135
| Module_type_declaration_name _ -> `Module_type
136+
| Class_declaration_name _ -> `Expression
137+
| Class_type_declaration_name _ -> `Type
138+
| Class_description_name _ -> `Type
139+
| Class_field_name _ -> `Expression
140+
| Exp_new_class_name _ -> `Expression
136141
| Open_description _ -> `Module
137142
| Open_declaration _ -> `Module
138143
| Include_declaration _ -> `Module

src/analysis/type_enclosing.ml

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ let { Logger.log } = Logger.for_section log_section
66

77
type type_info =
88
| Modtype of Env.t * Types.module_type
9+
| Classtype of Env.t * Types.class_type
910
| Type of Env.t * Types.type_expr
1011
| Type_decl of Env.t * Ident.t * Types.type_declaration
1112
| Type_constr of Env.t * Data_types.constructor_description
@@ -22,6 +23,10 @@ let print_type ~verbosity type_info =
2223
wrap_printing_env env (fun () ->
2324
print_type_with_decl ~verbosity env ppf t;
2425
Format.flush_str_formatter ())
26+
| Classtype (env, t) ->
27+
wrap_printing_env env (fun () ->
28+
Printtyp.class_type ppf t;
29+
Format.flush_str_formatter ())
2530
| Type_decl (env, id, t) ->
2631
wrap_printing_env env (fun () ->
2732
Printtyp.type_declaration env id ppf t;
@@ -40,6 +45,14 @@ let from_nodes ~path =
4045
let aux (env, node, tail) =
4146
let open Browse_raw in
4247
let ret x = Some (Mbrowse.node_loc node, x, tail) in
48+
let filter_method_arrow exp_type =
49+
(* Method types show the class as first parameter:
50+
[#c -> unit]
51+
We remove it from the type shown to he user *)
52+
match Types.get_desc exp_type with
53+
| Tarrow (_, _, t, _) -> t
54+
| _ -> exp_type
55+
in
4356
match[@ocaml.warning "-9"] node with
4457
| Expression { exp_type = t }
4558
| Pattern { pat_type = t }
@@ -57,12 +70,20 @@ let from_nodes ~path =
5770
| Module_declaration_name { md_type = { mty_type = m } }
5871
| Module_type_declaration_name { mtd_type = Some { mty_type = m } } ->
5972
ret (Modtype (env, m))
73+
| Class_declaration_name { ci_expr = { cl_type = t; _ }; _ } ->
74+
ret (Classtype (env, t))
75+
| Class_description_name { ci_expr = { cltyp_type = t; _ }; _ } ->
76+
ret (Classtype (env, t))
77+
| Class_expr { cl_desc = Tcl_ident (_, _, _); cl_type = t; _ } ->
78+
ret (Classtype (env, t))
79+
| Class_field_name
80+
{ cf_desc = Tcf_val (_, _, _, Tcfk_concrete (_, { exp_type = t }), _) }
81+
-> ret (Type (env, t))
6082
| Class_field
83+
{ cf_desc = Tcf_method (_, _, Tcfk_concrete (_, { exp_type })) }
84+
| Class_field_name
6185
{ cf_desc = Tcf_method (_, _, Tcfk_concrete (_, { exp_type })) } ->
62-
begin match Types.get_desc exp_type with
63-
| Tarrow (_, _, t, _) -> ret (Type (env, t))
64-
| _ -> None
65-
end
86+
ret (Type (env, filter_method_arrow exp_type))
6687
| Class_field
6788
{ cf_desc = Tcf_val (_, _, _, Tcfk_concrete (_, { exp_type = t }), _) }
6889
-> ret (Type (env, t))
@@ -72,6 +93,11 @@ let from_nodes ~path =
7293
| Class_field
7394
{ cf_desc = Tcf_val (_, _, _, Tcfk_virtual { ctyp_type = t }, _) } ->
7495
ret (Type (env, t))
96+
| Exp_new_class_name (_, decl) ->
97+
begin match decl.cty_new with
98+
| Some ty -> ret (Type (env, ty))
99+
| None -> None
100+
end
75101
| Binding_op { bop_op_type; _ } -> ret (Type (env, bop_op_type))
76102
| _ -> None
77103
in

src/analysis/type_enclosing.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ val log_section : string
3636

3737
type type_info =
3838
| Modtype of Env.t * Types.module_type
39+
| Classtype of Env.t * Types.class_type
3940
| Type of Env.t * Types.type_expr
4041
| Type_decl of Env.t * Ident.t * Types.type_declaration
4142
| Type_constr of Env.t * Data_types.constructor_description

src/ocaml/merlin_specific/browse_raw.ml

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ type node =
8484
| Module_binding_name of module_binding
8585
| Module_declaration_name of module_declaration
8686
| Module_type_declaration_name of module_type_declaration
87+
| Class_declaration_name of class_declaration
88+
| Class_type_declaration_name of class_type_declaration
89+
| Class_description_name of class_description
90+
| Class_field_name of class_field
91+
| Exp_new_class_name of Longident.t Location.loc * Types.class_declaration
8792

8893
let node_update_env env0 = function
8994
| Pattern { pat_env = env }
@@ -104,6 +109,11 @@ let node_update_env env0 = function
104109
| Class_signature _
105110
| Class_field _
106111
| Class_field_kind _
112+
| Class_declaration_name _
113+
| Class_type_declaration_name _
114+
| Class_description_name _
115+
| Class_field_name _
116+
| Exp_new_class_name _
107117
| Type_extension _
108118
| Extension_constructor _
109119
| Package_type _
@@ -159,6 +169,12 @@ let node_real_loc loc0 = function
159169
| Class_declaration { ci_loc = loc }
160170
| Class_description { ci_loc = loc }
161171
| Class_type_declaration { ci_loc = loc }
172+
| Class_declaration_name { ci_id_name = { loc } }
173+
| Class_type_declaration_name { ci_id_name = { loc } }
174+
| Class_description_name { ci_id_name = { loc } }
175+
| Class_field_name
176+
{ cf_desc = Tcf_val ({ loc }, _, _, _, _) | Tcf_method ({ loc }, _, _) }
177+
| Exp_new_class_name ({ loc }, _)
162178
| Extension_constructor { ext_loc = loc }
163179
| Include_description { incl_loc = loc }
164180
| Include_declaration { incl_loc = loc }
@@ -180,6 +196,7 @@ let node_real_loc loc0 = function
180196
| Type_kind _
181197
| Class_signature _
182198
| Package_type _
199+
| Class_field_name _
183200
| Dummy -> loc0
184201

185202
let node_attributes = function
@@ -351,7 +368,8 @@ let of_method_call obj meth loc env (f : _ f0) acc =
351368
let rec of_expression_desc loc = function
352369
| Texp_ident _ | Texp_constant _ | Texp_instvar _
353370
| Texp_variant (_, None)
354-
| Texp_new _ | Texp_typed_hole -> id_fold
371+
| Texp_typed_hole -> id_fold
372+
| Texp_new (_, lid, decl) -> app (Exp_new_class_name (lid, decl))
355373
| Texp_let (_, vbs, e) -> of_expression e ** list_fold of_value_binding vbs
356374
| Texp_function (params, body) ->
357375
list_fold of_function_param params ** of_function_body body
@@ -586,7 +604,8 @@ let of_node = function
586604
| Class_expr { cl_desc } -> of_class_expr_desc cl_desc
587605
| Class_structure { cstr_self; cstr_fields } ->
588606
of_pattern cstr_self ** list_fold (fun f -> app (Class_field f)) cstr_fields
589-
| Class_field { cf_desc } -> of_class_field_desc cf_desc
607+
| Class_field ({ cf_desc } as cf) ->
608+
of_class_field_desc cf_desc ** app (Class_field_name cf)
590609
| Class_field_kind (Tcfk_virtual ct) -> of_core_type ct
591610
| Class_field_kind (Tcfk_concrete (_, e)) -> of_expression e
592611
| Module_expr { mod_desc } -> of_module_expr_desc mod_desc
@@ -656,17 +675,28 @@ let of_node = function
656675
of_core_type csig_self
657676
** list_fold (fun x -> app (Class_type_field x)) csig_fields
658677
| Class_type_field { ctf_desc } -> of_class_type_field_desc ctf_desc
659-
| Class_declaration { ci_params; ci_expr } ->
660-
app (Class_expr ci_expr) ** list_fold of_typ_param ci_params
661-
| Class_description { ci_params; ci_expr } ->
662-
app (Class_type ci_expr) ** list_fold of_typ_param ci_params
663-
| Class_type_declaration { ci_params; ci_expr } ->
664-
app (Class_type ci_expr) ** list_fold of_typ_param ci_params
678+
| Class_declaration ({ ci_params; ci_expr } as cd) ->
679+
app (Class_expr ci_expr)
680+
** list_fold of_typ_param ci_params
681+
** app (Class_declaration_name cd)
682+
| Class_description ({ ci_params; ci_expr } as cd) ->
683+
app (Class_type ci_expr)
684+
** list_fold of_typ_param ci_params
685+
** app (Class_description_name cd)
686+
| Class_type_declaration ({ ci_params; ci_expr } as ctd) ->
687+
app (Class_type ci_expr)
688+
** list_fold of_typ_param ci_params
689+
** app (Class_type_declaration_name ctd)
665690
| Method_call _ -> id_fold
666691
| Record_field _ -> id_fold
667692
| Module_binding_name _ -> id_fold
668693
| Module_declaration_name _ -> id_fold
669694
| Module_type_declaration_name _ -> id_fold
695+
| Class_declaration_name _ -> id_fold
696+
| Class_type_declaration_name _ -> id_fold
697+
| Class_description_name _ -> id_fold
698+
| Class_field_name _ -> id_fold
699+
| Exp_new_class_name _ -> id_fold
670700
| Open_description _ -> id_fold
671701
| Open_declaration od -> app (Module_expr od.open_expr)
672702
| Include_declaration i -> of_module_expr i.incl_mod
@@ -723,6 +753,11 @@ let string_of_node = function
723753
| Module_binding_name _ -> "module_binding_name"
724754
| Module_declaration_name _ -> "module_declaration_name"
725755
| Module_type_declaration_name _ -> "module_type_declaration_name"
756+
| Class_declaration_name _ -> "class_declaration_name"
757+
| Class_type_declaration_name _ -> "class_type_declaration_name"
758+
| Class_description_name _ -> "class_description_name"
759+
| Class_field_name _ -> "class_field_name"
760+
| Exp_new_class_name _ -> "exp_new_class_name"
726761
| Open_description _ -> "open_description"
727762
| Open_declaration _ -> "open_declaration"
728763
| Include_description _ -> "include_description"

src/ocaml/merlin_specific/browse_raw.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ type node =
9797
| Module_binding_name of module_binding
9898
| Module_declaration_name of module_declaration
9999
| Module_type_declaration_name of module_type_declaration
100+
| Class_declaration_name of class_declaration
101+
| Class_type_declaration_name of class_type_declaration
102+
| Class_description_name of class_description
103+
| Class_field_name of class_field
104+
| Exp_new_class_name of Longident.t Location.loc * Types.class_declaration
100105

101106
val fold_node : (Env.t -> node -> 'a -> 'a) -> Env.t -> node -> 'a -> 'a
102107

tests/test-dirs/type-enclosing/objects.t/run.t

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,20 @@
1616
]
1717

1818
$ $MERLIN single type-enclosing -position 2:14 -verbosity 1 \
19-
> -filename ./test.ml < ./test.ml | tr '\r\n' ' ' | jq ".value[0:2]"
19+
> -filename ./test.ml < ./test.ml | tr '\r\n' ' ' | jq ".value[0:3]"
2020
[
21+
{
22+
"start": {
23+
"line": 2,
24+
"col": 14
25+
},
26+
"end": {
27+
"line": 2,
28+
"col": 15
29+
},
30+
"type": "int list type 'a list = [] | (::) of 'a * 'a list",
31+
"tail": "no"
32+
},
2133
{
2234
"start": {
2335
"line": 2,
@@ -45,8 +57,20 @@
4557
]
4658

4759
$ $MERLIN single type-enclosing -position 11:10 -verbosity 1 \
48-
> -filename ./test.ml < ./test.ml | jq ".value[0:2]"
60+
> -filename ./test.ml < ./test.ml | jq ".value[0:3]"
4961
[
62+
{
63+
"start": {
64+
"line": 11,
65+
"col": 9
66+
},
67+
"end": {
68+
"line": 11,
69+
"col": 13
70+
},
71+
"type": "int -> unit",
72+
"tail": "no"
73+
},
5074
{
5175
"start": {
5276
"line": 11,

0 commit comments

Comments
 (0)