Skip to content

Commit 900bcfe

Browse files
committed
Add mangling utilities from ppx_deriving (issue ocaml-ppx#317)
Signed-off-by: Simmo Saan <[email protected]>
1 parent 1baaa0b commit 900bcfe

File tree

6 files changed

+106
-0
lines changed

6 files changed

+106
-0
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
unreleased
22
-------------------
33

4+
- Add `Ppxlib.Mangle` with name mangling utilities from ppx_deriving (#<PR_NUMBER>, @sim642)
5+
46
- Make `esequence` right-associative. (#366, @ceastlund)
57

68
- Deprecate unused attributes in `Deriving.Generator` (#368, @sim642)

src/mangle.ml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
open Import
2+
3+
type affix =
4+
[ `Prefix of string | `Suffix of string | `PrefixSuffix of string * string ]
5+
6+
let mangle ?(fixpoint = "t") affix name =
7+
match (String.(name = fixpoint), affix) with
8+
| true, (`Prefix x | `Suffix x) -> x
9+
| true, `PrefixSuffix (p, s) -> p ^ "_" ^ s
10+
| false, `PrefixSuffix (p, s) -> p ^ "_" ^ name ^ "_" ^ s
11+
| false, `Prefix x -> x ^ "_" ^ name
12+
| false, `Suffix x -> name ^ "_" ^ x
13+
14+
let mangle_type_decl ?fixpoint affix { ptype_name = { txt = name; _ }; _ } =
15+
mangle ?fixpoint affix name
16+
17+
let mangle_lid ?fixpoint affix lid =
18+
match lid with
19+
| Lident s -> Lident (mangle ?fixpoint affix s)
20+
| Ldot (p, s) -> Ldot (p, mangle ?fixpoint affix s)
21+
| Lapply _ -> invalid_arg "Ppxlib.Mangle.mangle_lid: Lapply"

src/mangle.mli

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
(** Derive mangled names from type names in a deriver. *)
2+
3+
open Import
4+
5+
type affix =
6+
[ `Prefix of string (** [`Prefix p] adds prefix [p]. *)
7+
| `Suffix of string (** [`Suffix s] adds suffix [s]. *)
8+
| `PrefixSuffix of string * string
9+
(** [`PrefixSuffix (p, s)] adds both prefix [p] and suffix [s]. *) ]
10+
(** Specification for name mangling. *)
11+
12+
val mangle : ?fixpoint:string -> affix -> string -> string
13+
(** [mangle ~fixpoint affix s] derives a mangled name from [s] with the mangling
14+
specified by [affix]. If [s] is equal to [fixpoint] (["t"] by default), then
15+
[s] is omitted from the mangled name. *)
16+
17+
val mangle_type_decl : ?fixpoint:string -> affix -> type_declaration -> string
18+
(** [mangle_type_decl ~fixpoint affix td] does the same as {!mangle}, but for
19+
the name of [td]. *)
20+
21+
val mangle_lid : ?fixpoint:string -> affix -> Longident.t -> Longident.t
22+
(** [mangle_lid ~fixpoint affix lid] does the same as {!mangle}, but for the
23+
last component of [lid]. *)

src/ppxlib.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ module Keyword = Keyword
5959
module Loc = Loc
6060
module Location = Location
6161
module Longident = Longident
62+
module Mangle = Mangle
6263
module Merlin_helpers = Merlin_helpers
6364
module Reserved_namespaces = Name.Reserved_namespaces
6465
module Spellcheck = Spellcheck

test/mangle/dune

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
(rule
2+
(alias runtest)
3+
(enabled_if
4+
(>= %{ocaml_version} "4.08.0"))
5+
(deps
6+
(:test test.ml)
7+
(package ppxlib))
8+
(action
9+
(chdir
10+
%{project_root}
11+
(progn
12+
(run expect-test %{test})
13+
(diff? %{test} %{test}.corrected)))))

test/mangle/test.ml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
open Ppxlib;;
2+
3+
Mangle.mangle (`Prefix "pre") "foo";;
4+
[%%expect{|
5+
- : string = "pre_foo"
6+
|}]
7+
8+
Mangle.mangle (`Suffix "suf") "foo";;
9+
[%%expect{|
10+
- : string = "foo_suf"
11+
|}]
12+
13+
Mangle.mangle (`PrefixSuffix ("pre", "suf")) "foo";;
14+
[%%expect{|
15+
- : string = "pre_foo_suf"
16+
|}]
17+
18+
Mangle.mangle (`Prefix "pre") "t";;
19+
[%%expect{|
20+
- : string = "pre"
21+
|}]
22+
23+
Mangle.mangle (`Suffix "suf") "t";;
24+
[%%expect{|
25+
- : string = "suf"
26+
|}]
27+
28+
Mangle.mangle (`PrefixSuffix ("pre", "suf")) "t";;
29+
[%%expect{|
30+
- : string = "pre_suf"
31+
|}]
32+
33+
Mangle.mangle ~fixpoint:"foo" (`Prefix "pre") "foo";;
34+
[%%expect{|
35+
- : string = "pre"
36+
|}]
37+
38+
Mangle.mangle ~fixpoint:"foo" (`Suffix "suf") "foo";;
39+
[%%expect{|
40+
- : string = "suf"
41+
|}]
42+
43+
Mangle.mangle ~fixpoint:"foo" (`PrefixSuffix ("pre", "suf")) "foo";;
44+
[%%expect{|
45+
- : string = "pre_suf"
46+
|}]

0 commit comments

Comments
 (0)