Select generated operations without introducing hidden dependencies

This commit is contained in:
sneeker committed 2019-04-07 10:12:51 +00:00
1 parent d2a38bd4bc
commit faefa72427
4 files changed
+64 -7

No files matched your search

+1
View File
@@ -20,6 +20,7 @@ test: all
./runtime.byte ./runtime.byte
$(OCAMLC) -ppx ./rewrite fieldglass.cma record.ml -o record.byte $(OCAMLC) -ppx ./rewrite fieldglass.cma record.ml -o record.byte
./record.byte ./record.byte
OCAMLC=$(OCAMLC) sh error.sh
clean: clean:
rm -f *.cmi *.cmo *.cma *.byte rewrite rm -f *.cmi *.cmo *.cma *.byte rewrite
+27
View File
@@ -0,0 +1,27 @@
#!/bin/sh
set -eu
directory=$(mktemp -d)
trap 'rm -rf "$directory"' EXIT HUP INT TERM
reject() {
printf '%s\n' "$1" > "$directory/rejected.ml"
if "${OCAMLC:-ocamlc}" -ppx ./rewrite -c "$directory/rejected.ml" 2> "$directory/error"; then
echo "Unexpected compilation success: $1" >&2
exit 1
fi
if ! grep -q "$2" "$directory/error"; then
cat "$directory/error" >&2
exit 1
fi
}
reject 'type t = { colour : string } [@@fieldglass generate ~no_get]
let _ = colour' 'Unbound value colour'
reject 'type t = { colour : string } [@@fieldglass generate ~no_set]
let _ = set_colour' 'Unbound value set_colour'
reject 'type t = { colour : string } [@@fieldglass generate ~no_update]
let _ = update_colour' 'Unbound value update_colour'
reject 'type t = { colour : string } [@@fieldglass generate ~no_lens]
let _ = _colour' 'Unbound value _colour'
reject 'type t = { colour : string } [@@fieldglass generate ~just_lens]
let _ = colour' 'Unbound value colour'
+17
View File
@@ -116,3 +116,20 @@ let () =
assert (Fieldglass.set Ordered._count 2 Ordered.{ count = 1 } = Ordered.{ count = 2 }); assert (Fieldglass.set Ordered._count 2 Ordered.{ count = 1 } = Ordered.{ count = 2 });
assert (Positional.update_count Positional.{ count = 1 } succ = Positional.{ count = 2 }); assert (Positional.update_count Positional.{ count = 1 } succ = Positional.{ count = 2 });
assert (Last.update_count succ Last.{ count = 1 } = Last.{ count = 2 }) assert (Last.update_count succ Last.{ count = 1 } = Last.{ count = 2 })
module Pairs = struct
type t = { colour : string } [@@fieldglass generate ~just_lens]
end
module Silent = struct
type t = { colour : string } [@@fieldglass generate ~just_lens ~no_lens]
end
module Functions = struct
type t = { colour : string } [@@fieldglass generate ~no_lens ~no_get:false]
end
let () =
assert (Fieldglass.view Pairs._colour Pairs.{ colour = "grey" } = "grey");
assert (Silent.{ colour = "grey" }.colour = "grey");
assert (Functions.colour Functions.{ colour = "grey" } = "grey")
+19 -7
View File
@@ -17,10 +17,15 @@ type options = {
update_prefix : string; update_prefix : string;
self_first : bool; self_first : bool;
function_label : string option; function_label : string option;
getters : bool;
setters : bool;
updaters : bool;
lenses : bool;
} }
let defaults = { field_prefix = Plain; get_prefix = None; let defaults = { field_prefix = Plain; get_prefix = None;
set_prefix = "set"; update_prefix = "update"; set_prefix = "set"; update_prefix = "update";
self_first = false; function_label = Some "f" } self_first = false; function_label = Some "f";
getters = true; setters = true; updaters = true; lenses = true }
let word expression = let word expression =
match expression.pexp_desc with match expression.pexp_desc with
@@ -49,6 +54,13 @@ let configure options (label, expression) =
| Labelled "func_named_arg" -> { options with function_label = Some (word expression) } | Labelled "func_named_arg" -> { options with function_label = Some (word expression) }
| Labelled "func_no_named_arg" -> | Labelled "func_no_named_arg" ->
{ options with function_label = if flag "func_no_named_arg" expression then None else Some "f" } { options with function_label = if flag "func_no_named_arg" expression then None else Some "f" }
| Labelled "no_get" -> { options with getters = not (flag "no_get" expression) }
| Labelled "no_set" -> { options with setters = not (flag "no_set" expression) }
| Labelled "no_update" -> { options with updaters = not (flag "no_update" expression) }
| Labelled "no_lens" -> { options with lenses = not (flag "no_lens" expression) }
| Labelled "just_lens" ->
let functions = not (flag "just_lens" expression) in
{ options with getters = functions; setters = functions; updaters = functions }
| _ -> Location.raise_errorf ~loc:expression.pexp_loc | _ -> Location.raise_errorf ~loc:expression.pexp_loc
"fieldglass: unrecognised configuration option" "fieldglass: unrecognised configuration option"
@@ -110,12 +122,12 @@ let generate options declaration =
let updater = arguments options.self_first label "__fg_function" let updater = arguments options.self_first label "__fg_function"
(replace (Exp.apply ~loc (value ~loc "__fg_function") (replace (Exp.apply ~loc (value ~loc "__fg_function")
[Nolabel, Exp.field ~loc source (ident ~loc name)])) in [Nolabel, Exp.field ~loc source (ident ~loc name)])) in
List.map (fun (name, body) -> List.concat (List.map (fun (enabled, name, body) ->
Str.value ~loc Nonrecursive [Vb.mk ~loc (variable ~loc name) body]) if enabled then [Str.value ~loc Nonrecursive [Vb.mk ~loc (variable ~loc name) body]] else [])
[(match options.get_prefix with None -> short_name | Some prefix -> prefix ^ "_" ^ short_name), getter; [options.getters, (match options.get_prefix with None -> short_name | Some prefix -> prefix ^ "_" ^ short_name), getter;
options.set_prefix ^ "_" ^ short_name, setter options.self_first; options.setters, options.set_prefix ^ "_" ^ short_name, setter options.self_first;
options.update_prefix ^ "_" ^ short_name, updater; options.updaters, options.update_prefix ^ "_" ^ short_name, updater;
"_" ^ short_name, Exp.tuple ~loc [getter; setter false]]) fields (field_names fields)) options.lenses, "_" ^ short_name, Exp.tuple ~loc [getter; setter false]])) fields (field_names fields))
let structure mapper items = let structure mapper items =
List.concat (List.map (fun item -> List.concat (List.map (fun item ->