forked from ocaml/merlin
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FEATURE] Command to provide information for OCaml syntax (ocaml#1706)
* add new command boilerplate * add identifier to syntax_doc definition * update query json to use new identifier * include new return types for query protocol * update test to check type variant declarations * syntax documentation boiler plate * poc implementation for syntax_doc command * update the test description * remove optional identifier and obsolete code * remove optional identifier * add new variant examples * handle type declarations * remove redundant parent_node matching * remove comments * Bump version for release 4.13 * delete intial testing file * add custom documentation * add language extension tests * refined node matching for better docs * add more tests * remove invalid_identifier ouput * ocamlformat, limit lines to 80 chars * add mli for syntax_doc * proper naming * update docs, move type to query_protocol, leave as record * add info type for syntax_docment command json * update to record for json output * change from string output to json * delete redundant test files * delete tests files * move tests code here and promote * remove typedtree nodes * change variable name to a more informative name * Make syntax_doc_result optional * remove redundant cases * use singular and more shorter names * dune promote name changes * lint * url builder function for syntax documentation url * lint * dune promote correct urls * concat urls before returning to query_json * make command return record option * delete test file * correct formatting to original * refactor to be more meaningful * use versbose names * test: start making more precise tests * Apply suggestions from code review Co-authored-by: Ulysse <[email protected]> * Edit descriptions to be less verbose * dune promote description changes * use syn_doc alias * merge duplicate case results * lint * reduce verboseness in test * add eof * Update src/frontend/ocamlmerlin/new/new_commands.ml Co-authored-by: Ulysse <[email protected]> * cover more test * update some match cases * remove trailing whitespaces * use plural form * refactor private and public types for same nodes into one match case * lint and seperate abstract types for public and private * better targeting first class modules * more test for first class modules and capitalization corrections * pass location position to syntaxdoc logic * use cursor position to better target locally abstract datatypes * test case where locally abstract dt shouldnt be triggered * test for first class module where it shouldnt be triggered * use 3rd person singular * add changelog * fix indentation * remove excess whitespace * proper heading --------- Co-authored-by: Ulysse Gérard <[email protected]> Co-authored-by: Ulysse <[email protected]>
- Loading branch information
1 parent
8404f96
commit 0f64255
Showing
8 changed files
with
555 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
open Browse_raw | ||
|
||
type syntax_info = Query_protocol.syntax_doc_result option | ||
|
||
let syntax_doc_url endpoint = | ||
let base_url = "https://v2.ocaml.org/releases/4.14/htmlman/" in | ||
base_url ^ endpoint | ||
|
||
let get_syntax_doc cursor_loc node : syntax_info = | ||
match node with | ||
| (_, Type_kind _) | ||
:: (_, Type_declaration _) | ||
:: (_, With_constraint (Twith_typesubst _)) | ||
:: _ -> | ||
Some | ||
{ | ||
name = "Destructive substitution"; | ||
description = | ||
"Behaves like normal signature constraints but removes the \ | ||
redefined type or module from the signature."; | ||
documentation = | ||
syntax_doc_url | ||
"signaturesubstitution.html#ss:destructive-substitution"; | ||
} | ||
| (_, Type_kind _) | ||
:: (_, Type_declaration _) | ||
:: (_, Signature_item ({ sig_desc = Tsig_typesubst _; _ }, _)) | ||
:: _ -> | ||
Some | ||
{ | ||
name = "Local substitution"; | ||
description = | ||
"Behaves like destructive substitution but is introduced during \ | ||
the specification of the signature, and will apply to all the \ | ||
items that follow."; | ||
documentation = | ||
syntax_doc_url "signaturesubstitution.html#ss:local-substitution"; | ||
} | ||
| (_, Module_type _) | ||
:: (_, Module_type _) | ||
:: ( _, | ||
Module_type_constraint | ||
(Tmodtype_explicit | ||
{ mty_desc = Tmty_with (_, [ (_, _, Twith_modtype _) ]); _ }) ) | ||
:: _ -> | ||
Some | ||
{ | ||
name = "Module substitution"; | ||
description = | ||
"Behaves like type substitutions but are useful to refine an \ | ||
abstract module type in a signature into a concrete module type,"; | ||
documentation = | ||
syntax_doc_url | ||
"signaturesubstitution.html#ss:module-type-substitution"; | ||
} | ||
| (_, Type_kind Ttype_open) :: (_, Type_declaration { typ_private; _ }) :: _ | ||
-> | ||
let e_name = "Extensible Variant Type" in | ||
let e_description = | ||
"Can be extended with new variant constructors using `+=`." | ||
in | ||
let e_url = "extensiblevariants.html" in | ||
let name, description, url = | ||
match typ_private with | ||
| Public -> (e_name, e_description, e_url) | ||
| Private -> | ||
( Format.sprintf "Private %s" e_name, | ||
Format.sprintf | ||
"%s. Prevents new constructors from being declared directly, \ | ||
but allows extension constructors to be referred to in \ | ||
interfaces." | ||
e_description, | ||
"extensiblevariants.html#ss:private-extensible" ) | ||
in | ||
Some { name; description; documentation = syntax_doc_url url } | ||
| (_, Constructor_declaration _) | ||
:: (_, Type_kind (Ttype_variant _)) | ||
:: (_, Type_declaration { typ_private; _ }) | ||
:: _ | ||
| _ | ||
:: (_, Constructor_declaration _) | ||
:: (_, Type_kind (Ttype_variant _)) | ||
:: (_, Type_declaration { typ_private; _ }) | ||
:: _ -> | ||
let v_name = "Variant Type" in | ||
let v_description = | ||
"Represent's data that may take on multiple different forms." | ||
in | ||
let v_url = "typedecl.html#ss:typedefs" in | ||
let name, description, url = | ||
match typ_private with | ||
| Public -> (v_name, v_description, v_url) | ||
| Private -> | ||
( Format.sprintf "Private %s" v_name, | ||
Format.sprintf | ||
"%s This type is private, values cannot be constructed \ | ||
directly but can be de-structured as usual." | ||
v_description, | ||
"privatetypes.html#ss:private-types-variant" ) | ||
in | ||
Some { name; description; documentation = syntax_doc_url url } | ||
| (_, Core_type _) | ||
:: (_, Core_type _) | ||
:: (_, Label_declaration _) | ||
:: (_, Type_kind (Ttype_record _)) | ||
:: (_, Type_declaration { typ_private; _ }) | ||
:: _ -> | ||
let r_name = "Record Type" in | ||
let r_description = "Defines variants with a fixed set of fields" in | ||
let r_url = "typedecl.html#ss:typedefs" in | ||
let name, description, url = | ||
match typ_private with | ||
| Public -> (r_name, r_description, r_url) | ||
| Private -> | ||
( Format.sprintf "Private %s" r_name, | ||
Format.sprintf | ||
"%s This type is private, values cannot be constructed \ | ||
directly but can be de-structured as usual." | ||
r_description, | ||
"privatetypes.html#ss:private-types-variant" ) | ||
in | ||
Some { name; description; documentation = syntax_doc_url url } | ||
| (_, Type_kind (Ttype_variant _)) | ||
:: (_, Type_declaration { typ_private = Public; _ }) | ||
:: _ -> | ||
Some | ||
{ | ||
name = "Empty Variant Type"; | ||
description = "An empty variant type."; | ||
documentation = syntax_doc_url "emptyvariants.html"; | ||
} | ||
| (_, Type_kind Ttype_abstract) | ||
:: (_, Type_declaration { typ_private = Public; typ_manifest = None; _ }) | ||
:: _ -> | ||
Some | ||
{ | ||
name = "Abstract Type"; | ||
description = | ||
"Define variants with arbitrary data structures, including other \ | ||
variants, records, and functions"; | ||
documentation = syntax_doc_url "typedecl.html#ss:typedefs"; | ||
} | ||
| (_, Type_kind Ttype_abstract) | ||
:: (_, Type_declaration { typ_private = Private; _ }) | ||
:: _ -> | ||
Some | ||
{ | ||
name = "Private Type Abbreviation"; | ||
description = | ||
"Declares a type that is distinct from its implementation type \ | ||
`typexpr`."; | ||
documentation = | ||
syntax_doc_url "privatetypes.html#ss:private-types-abbrev"; | ||
} | ||
| (_, Expression _) | ||
:: (_, Expression _) | ||
:: (_, Value_binding _) | ||
:: (_, Structure_item ({ str_desc = Tstr_value (Recursive, _); _ }, _)) | ||
:: _ -> | ||
Some | ||
{ | ||
name = "Recursive value definition"; | ||
description = | ||
"Supports a certain class of recursive definitions of \ | ||
non-functional values."; | ||
documentation = syntax_doc_url "letrecvalues.html"; | ||
} | ||
| (_, Module_expr _) :: (_, Module_type { mty_desc = Tmty_typeof _; _ }) :: _ | ||
-> | ||
Some | ||
{ | ||
name = "Recovering module type"; | ||
description = | ||
"Expands to the module type (signature or functor type) inferred \ | ||
for the module expression `module-expr`. "; | ||
documentation = syntax_doc_url "moduletypeof.html"; | ||
} | ||
| (_, Module_expr _) | ||
:: (_, Module_expr _) | ||
:: (_, Module_binding _) | ||
:: (_, Structure_item ({ str_desc = Tstr_recmodule _; _ }, _)) | ||
:: _ -> | ||
Some | ||
{ | ||
name = "Recursive module"; | ||
description = | ||
"A simultaneous definition of modules that can refer recursively \ | ||
to each others."; | ||
documentation = syntax_doc_url "recursivemodules.html"; | ||
} | ||
| (_, Expression _) | ||
:: (_, Expression _) | ||
:: (_, Case _) | ||
:: (_, Expression _) | ||
:: ( _, | ||
Value_binding | ||
{ | ||
vb_expr = | ||
{ exp_extra = [ (Texp_newtype' (_, loc), _, _) ]; exp_loc; _ }; | ||
_; | ||
} ) | ||
:: _ -> ( | ||
let in_range = | ||
cursor_loc.Lexing.pos_cnum - 1 > exp_loc.loc_start.pos_cnum | ||
&& cursor_loc.Lexing.pos_cnum <= loc.loc.loc_end.pos_cnum + 1 | ||
in | ||
match in_range with | ||
| true -> | ||
Some | ||
{ | ||
name = "Locally Abstract Type"; | ||
description = | ||
"Type constructor which is considered abstract in the scope of \ | ||
the sub-expression and replaced by a fresh type variable."; | ||
documentation = syntax_doc_url "locallyabstract.html"; | ||
} | ||
| false -> None) | ||
| (_, Module_expr _) | ||
:: (_, Module_expr _) | ||
:: (_, Expression { exp_desc = Texp_pack _; _ }) | ||
:: _ -> | ||
Some | ||
{ | ||
name = "First class module"; | ||
description = | ||
"Converts a module (structure or functor) to a value of the core \ | ||
language that encapsulates the module."; | ||
documentation = syntax_doc_url "firstclassmodules.html"; | ||
} | ||
| _ -> None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
val get_syntax_doc: Lexing.position -> (Env.t * Browse_raw.node) list -> Query_protocol.syntax_doc_result option |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.