-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement new syntax for type declaration #68
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -369,52 +369,48 @@ let type_declaration ~tool_name ~input_name (type_decl : Ppxlib.type_declaration | |
| { ptype_attributes | ||
; ptype_name | ||
; ptype_manifest = | ||
Some {ptyp_desc = Ptyp_extension ({txt = "import"; loc}, payload); _} | ||
; _ } -> ( | ||
match payload with | ||
| PTyp ({ptyp_desc = Ptyp_constr ({txt = lid; loc}, _); _} as manifest) -> | ||
if tool_name = "ocamldep" then | ||
(* Just put it as manifest *) | ||
if is_self_reference ~input_name lid then | ||
{type_decl with ptype_manifest = None} | ||
else {type_decl with ptype_manifest = Some manifest} | ||
else | ||
Ast_helper.with_default_loc loc (fun () -> | ||
let ttype_decl = | ||
let env = Lazy.force lazy_env in | ||
match lid with | ||
| Lapply _ -> | ||
Location.raise_errorf ~loc | ||
"[%%import] cannot import a functor application %s" | ||
(string_of_lid lid) | ||
| Lident _ as head_id -> | ||
(* In this case, we know for sure that the user intends this lident | ||
as a type name, so we use Typetexp.find_type and let the failure | ||
cases propagate to the user. *) | ||
Compat.find_type env ~loc head_id |> snd | ||
| Ldot (parent_id, elem) -> | ||
let sig_items = locate_sig ~loc env parent_id in | ||
get_type_decl ~loc sig_items parent_id elem | ||
in | ||
let m, s = | ||
if is_self_reference ~input_name lid then (None, []) | ||
else | ||
let subst = subst_of_manifest manifest in | ||
let subst = | ||
subst | ||
@ [ ( `Lid (Lident (Longident.last_exn lid)) | ||
, Ast_helper.Typ.constr | ||
{txt = Lident ptype_name.txt; loc = ptype_name.loc} | ||
[] ) ] | ||
in | ||
(Some manifest, subst) | ||
in | ||
let ptype_decl = | ||
ptype_decl_of_ttype_decl ~manifest:m ~subst:s ptype_name | ||
ttype_decl | ||
in | ||
{ptype_decl with ptype_attributes} ) | ||
| _ -> Location.raise_errorf ~loc "Invalid [%%import] syntax" ) | ||
Some ({ptyp_desc = Ptyp_constr ({txt = lid; loc}, _); _} as manifest) | ||
; _ } -> | ||
if tool_name = "ocamldep" then | ||
(* Just put it as manifest *) | ||
if is_self_reference ~input_name lid then | ||
{type_decl with ptype_manifest = None} | ||
else {type_decl with ptype_manifest = Some manifest} | ||
else | ||
Ast_helper.with_default_loc loc (fun () -> | ||
let ttype_decl = | ||
let env = Lazy.force lazy_env in | ||
match lid with | ||
| Lapply _ -> | ||
Location.raise_errorf ~loc | ||
"[%%import] cannot import a functor application %s" | ||
(string_of_lid lid) | ||
Comment on lines
+385
to
+387
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, this comment is not really related to the PR, but it is a bad practice to raise errors with ppxlib, as it prevents other rewriters to work and more importantly it prevents merlin to work... I understand that this should most certainly be part of another PR! |
||
| Lident _ as head_id -> | ||
(* In this case, we know for sure that the user intends this lident | ||
as a type name, so we use Typetexp.find_type and let the failure | ||
cases propagate to the user. *) | ||
Compat.find_type env ~loc head_id |> snd | ||
| Ldot (parent_id, elem) -> | ||
let sig_items = locate_sig ~loc env parent_id in | ||
get_type_decl ~loc sig_items parent_id elem | ||
in | ||
let m, s = | ||
if is_self_reference ~input_name lid then (None, []) | ||
else | ||
let subst = subst_of_manifest manifest in | ||
let subst = | ||
subst | ||
@ [ ( `Lid (Lident (Longident.last_exn lid)) | ||
, Ast_helper.Typ.constr | ||
{txt = Lident ptype_name.txt; loc = ptype_name.loc} | ||
[] ) ] | ||
in | ||
(Some manifest, subst) | ||
in | ||
let ptype_decl = | ||
ptype_decl_of_ttype_decl ~manifest:m ~subst:s ptype_name ttype_decl | ||
in | ||
{ptype_decl with ptype_attributes} ) | ||
| _ -> type_decl | ||
|
||
let rec cut_tsig_block_of_rec_types accu (tsig : Compat.signature_item_407 list) | ||
|
@@ -505,18 +501,38 @@ let module_type ~tool_name ~input_name (package_type : Ppxlib.package_type) = | |
| _ -> | ||
Location.raise_errorf ~loc "Imported module is indirectly defined" ) | ||
|
||
let type_declaration_expand ~ctxt type_decl = | ||
let type_declaration_expand ~ctxt rec_flag type_decl = | ||
let loc = Ppxlib.Expansion_context.Extension.extension_point_loc ctxt in | ||
let tool_name = Ppxlib.Expansion_context.Extension.tool_name ctxt in | ||
let input_name = Ppxlib.Expansion_context.Extension.input_name ctxt in | ||
type_declaration ~tool_name ~input_name type_decl | ||
let type_decl = type_declaration ~tool_name ~input_name type_decl in | ||
Ppxlib.{pstr_desc = Pstr_type (rec_flag, [type_decl]); pstr_loc = loc} | ||
|
||
let type_declaration_expand_intf ~ctxt rec_flag type_decl = | ||
let loc = Ppxlib.Expansion_context.Extension.extension_point_loc ctxt in | ||
let tool_name = Ppxlib.Expansion_context.Extension.tool_name ctxt in | ||
let input_name = Ppxlib.Expansion_context.Extension.input_name ctxt in | ||
let type_decl = type_declaration ~tool_name ~input_name type_decl in | ||
Ppxlib.{psig_desc = Psig_type (rec_flag, [type_decl]); psig_loc = loc} | ||
tatchi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
let module_declaration_expand ~ctxt package_type = | ||
let tool_name = Ppxlib.Expansion_context.Extension.tool_name ctxt in | ||
let input_name = Ppxlib.Expansion_context.Extension.input_name ctxt in | ||
module_type ~tool_name ~input_name package_type | ||
|
||
let type_declaration_extension = | ||
Ppxlib.Extension.__declare_ppx_import "import" type_declaration_expand | ||
Ppxlib.Extension.V3.declare "import" Ppxlib.Extension.Context.structure_item | ||
Ppxlib.Ast_pattern.( | ||
psig (psig_type __ (__ ^:: nil) ^:: nil) | ||
||| pstr (pstr_type __ (__ ^:: nil) ^:: nil)) | ||
tatchi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
type_declaration_expand | ||
|
||
let type_declaration_extension_intf = | ||
Ppxlib.Extension.V3.declare "import" Ppxlib.Extension.Context.signature_item | ||
Ppxlib.Ast_pattern.( | ||
psig (psig_type __ (__ ^:: nil) ^:: nil) | ||
||| pstr (pstr_type __ (__ ^:: nil) ^:: nil)) | ||
tatchi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
type_declaration_expand_intf | ||
|
||
let module_declaration_extension = | ||
Ppxlib.Extension.V3.declare "import" Ppxlib.Extension.Context.module_type | ||
|
@@ -526,10 +542,16 @@ let module_declaration_extension = | |
let type_declaration_rule = | ||
Ppxlib.Context_free.Rule.extension type_declaration_extension | ||
|
||
let type_declaration_rule_intf = | ||
Ppxlib.Context_free.Rule.extension type_declaration_extension_intf | ||
|
||
let module_declaration_rule = | ||
Ppxlib.Context_free.Rule.extension module_declaration_extension | ||
|
||
let () = | ||
Ppxlib.Driver.register_transformation | ||
~rules:[type_declaration_rule; module_declaration_rule] | ||
~rules: | ||
[ type_declaration_rule | ||
; module_declaration_rule | ||
; type_declaration_rule_intf ] | ||
"ppx_import" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
type a = [%import: Stuff.a] | ||
[%%import: type a = Stuff.a] | ||
tatchi marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
type a = [%import: Stuff.a] | ||
[%%import: type a = Stuff.a] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to explain how the other parts of the syntax work? In particular the
with foo := bar
alias.Maybe it is better just to update the readme in this PR too? Indeed, it could be a good idea to keep the documentation of the code in sync.