|
@@ -48,7 +48,7 @@ findType([_H|T]) ->
|
|
|
|
|
|
record_fields(_RecordName, []) -> [];
|
|
record_fields(_RecordName, []) -> [];
|
|
record_fields(RecordName, [{attribute, _, record, {RecordName, Fields}} | _Forms]) ->
|
|
record_fields(RecordName, [{attribute, _, record, {RecordName, Fields}} | _Forms]) ->
|
|
- [record_field(Field, RecordName) || Field <- Fields];
|
|
|
|
|
|
+ [record_field(Field, RecordName) || Field <- Fields];
|
|
record_fields(RecordName, [_ | Forms]) -> record_fields(RecordName, Forms).
|
|
record_fields(RecordName, [_ | Forms]) -> record_fields(RecordName, Forms).
|
|
|
|
|
|
last_export_line(Exports) ->
|
|
last_export_line(Exports) ->
|
|
@@ -58,88 +58,97 @@ last_export_line(Exports) ->
|
|
end.
|
|
end.
|
|
|
|
|
|
generate({FunName, _Arity} = Fun, Record, Fields, Forms) ->
|
|
generate({FunName, _Arity} = Fun, Record, Fields, Forms) ->
|
|
- Exports = lists:filter(fun({attribute, _, export, _}) -> true; (_) -> false end, Forms),
|
|
|
|
- case exported(Fun, Exports) of
|
|
|
|
- true -> Forms;
|
|
|
|
- false ->
|
|
|
|
- Line = last_export_line(Exports),
|
|
|
|
- Gen = list_to_atom("generate_" ++ atom_to_list(FunName)),
|
|
|
|
- lists:flatten([?MODULE:Gen(export(Form, Fun, Line), Record, Fields) || Form <- Forms])
|
|
|
|
- end.
|
|
|
|
|
|
+ Exports = lists:filter(
|
|
|
|
+ fun({attribute, _, export, _}) -> true;
|
|
|
|
+ (_) -> false
|
|
|
|
+ end, Forms),
|
|
|
|
+ case exported(Fun, Exports) of
|
|
|
|
+ true -> Forms;
|
|
|
|
+ false ->
|
|
|
|
+ Line = last_export_line(Exports),
|
|
|
|
+ Gen = list_to_atom("generate_" ++ atom_to_list(FunName)),
|
|
|
|
+ lists:flatten([?MODULE:Gen(export(Form, Fun, Line), Record, Fields) || Form <- Forms])
|
|
|
|
+ end.
|
|
|
|
|
|
-exported(Fun, Exports) -> lists:member(Fun, lists:flatten([E || {attribute, _, export, E} <- Exports])).
|
|
|
|
|
|
+exported(Fun, Exports) ->
|
|
|
|
+ lists:member(Fun, lists:flatten([E || {attribute, _, export, E} <- Exports])).
|
|
|
|
|
|
-field_var(Field) -> list_to_atom("V_" ++ atom_to_list(Field)).
|
|
|
|
|
|
+field_var(Field) -> erlang:list_to_atom("V_" ++ erlang:atom_to_list(Field)).
|
|
|
|
|
|
from_json_prelude(Line) ->
|
|
from_json_prelude(Line) ->
|
|
- {clause, Line,
|
|
|
|
- [{nil, Line}, {var, Line, 'Acc'}],
|
|
|
|
- [],
|
|
|
|
- [{var, Line, 'Acc'}]}.
|
|
|
|
|
|
+ {clause, Line,
|
|
|
|
+ [{nil, Line}, {var, Line, 'Acc'}],
|
|
|
|
+ [],
|
|
|
|
+ [{var, Line, 'Acc'}]}.
|
|
|
|
|
|
from_json_coda(Line) ->
|
|
from_json_coda(Line) ->
|
|
- {clause, Line,
|
|
|
|
- [{cons, Line, {var, Line, '_'}, {var, Line, 'Json'}}, {var, Line, 'Acc'}],
|
|
|
|
- [],
|
|
|
|
- [{call, Line, {atom, Line, from_json}, [
|
|
|
|
|
|
+ {clause, Line,
|
|
|
|
+ [{cons, Line, {var, Line, '_'}, {var, Line, 'Json'}}, {var, Line, 'Acc'}],
|
|
|
|
+ [],
|
|
|
|
+ [{call, Line, {atom, Line, from_json}, [
|
|
%{var, Line, 'Json'}, % here is fix for recursive binarized preprocessing to raw X:from_json
|
|
%{var, Line, 'Json'}, % here is fix for recursive binarized preprocessing to raw X:from_json
|
|
{call, Line, {remote, Line, {atom, Line, ?MODULE}, {atom, Line, binarize}}, [{var, Line, 'Json'}]},
|
|
{call, Line, {remote, Line, {atom, Line, ?MODULE}, {atom, Line, binarize}}, [{var, Line, 'Json'}]},
|
|
- {var, Line, 'Acc'}]}]}.
|
|
|
|
|
|
+ {var, Line, 'Acc'}
|
|
|
|
+ ]}]}.
|
|
|
|
|
|
from_json_clauses(_, _, []) -> [];
|
|
from_json_clauses(_, _, []) -> [];
|
|
from_json_clauses(Line, Record, [Field | Fields]) ->
|
|
from_json_clauses(Line, Record, [Field | Fields]) ->
|
|
- [{clause, Line,
|
|
|
|
- [{cons, Line,
|
|
|
|
- {tuple, Line,
|
|
|
|
- [{bin, Line,
|
|
|
|
- [{bin_element, Line, {string, Line, atom_to_list(Field)}, default, default}]},
|
|
|
|
- {var, Line, field_var(Field)}]},
|
|
|
|
- {var, Line, 'Json'}},
|
|
|
|
- {var, Line, 'Acc'}],
|
|
|
|
- [],
|
|
|
|
- [{call, Line,
|
|
|
|
- {atom, Line, from_json},
|
|
|
|
- [{var, Line, 'Json'},
|
|
|
|
- {record, Line,
|
|
|
|
- {var, Line, 'Acc'},
|
|
|
|
- Record,
|
|
|
|
- [{record_field, Line,
|
|
|
|
- {atom, Line, Field},
|
|
|
|
- {call, Line,
|
|
|
|
- {remote, Line, {atom, Line, ?MODULE }, {atom, Line, from_json}},
|
|
|
|
- [{var, Line, field_var(Field)},
|
|
|
|
- {atom, Line, case erlang:get({Record, Field}) of undefined -> Record; FieldType -> FieldType end}]}
|
|
|
|
- }]}]}]}
|
|
|
|
- | from_json_clauses(Line, Record, Fields)].
|
|
|
|
|
|
+ [{clause, Line,
|
|
|
|
+ [{cons, Line,
|
|
|
|
+ {tuple, Line,
|
|
|
|
+ [{bin, Line,
|
|
|
|
+ [{bin_element, Line, {string, Line, erlang:atom_to_list(Field)}, default, default}]},
|
|
|
|
+ {var, Line, field_var(Field)}]},
|
|
|
|
+ {var, Line, 'Json'}},
|
|
|
|
+ {var, Line, 'Acc'}],
|
|
|
|
+ [],
|
|
|
|
+ [{call, Line,
|
|
|
|
+ {atom, Line, from_json},
|
|
|
|
+ [{var, Line, 'Json'},
|
|
|
|
+ {record, Line,
|
|
|
|
+ {var, Line, 'Acc'},
|
|
|
|
+ Record,
|
|
|
|
+ [{record_field, Line,
|
|
|
|
+ {atom, Line, Field},
|
|
|
|
+ {call, Line,
|
|
|
|
+ {remote, Line, {atom, Line, ?MODULE }, {atom, Line, from_json}},
|
|
|
|
+ [{var, Line, field_var(Field)},
|
|
|
|
+ {atom, Line,
|
|
|
|
+ case erlang:get({Record, Field}) of
|
|
|
|
+ undefined -> Record;
|
|
|
|
+ FieldType -> FieldType
|
|
|
|
+ end}]}
|
|
|
|
+ }]}]}]}
|
|
|
|
+ | from_json_clauses(Line, Record, Fields)].
|
|
|
|
|
|
generate_from_json({eof, Line}, Record, Fields) ->
|
|
generate_from_json({eof, Line}, Record, Fields) ->
|
|
- [{function, Line, from_json, 2,
|
|
|
|
- [from_json_prelude(Line)] ++ from_json_clauses(Line, Record, Fields) ++ [from_json_coda(Line)]},
|
|
|
|
- {eof, Line + 1}];
|
|
|
|
|
|
+ [{function, Line, from_json, 2,
|
|
|
|
+ [from_json_prelude(Line)] ++ from_json_clauses(Line, Record, Fields) ++ [from_json_coda(Line)]},
|
|
|
|
+ {eof, Line + 1}];
|
|
generate_from_json(Form, _, _) -> Form.
|
|
generate_from_json(Form, _, _) -> Form.
|
|
|
|
|
|
export({attribute, LastExportLine, export, Exports}, Fun, LastExportLine) ->
|
|
export({attribute, LastExportLine, export, Exports}, Fun, LastExportLine) ->
|
|
- {attribute, LastExportLine, export, [Fun | Exports]};
|
|
|
|
|
|
+ {attribute, LastExportLine, export, [Fun | Exports]};
|
|
export(Form, _, _) -> Form.
|
|
export(Form, _, _) -> Form.
|
|
|
|
|
|
to_json_cons(Line, []) -> {nil, Line};
|
|
to_json_cons(Line, []) -> {nil, Line};
|
|
to_json_cons(Line, [Field | Fields]) ->
|
|
to_json_cons(Line, [Field | Fields]) ->
|
|
- {cons, Line,
|
|
|
|
- {tuple, Line,
|
|
|
|
- [{atom, Line, Field},
|
|
|
|
- {call, Line,
|
|
|
|
- {remote, Line, {atom, Line, ?MODULE}, {atom, Line, to_json}},
|
|
|
|
- [{var, Line, field_var(Field)}]}]},
|
|
|
|
- to_json_cons(Line, Fields)}.
|
|
|
|
|
|
+ {cons, Line,
|
|
|
|
+ {tuple, Line,
|
|
|
|
+ [{atom, Line, Field},
|
|
|
|
+ {call, Line,
|
|
|
|
+ {remote, Line, {atom, Line, ?MODULE}, {atom, Line, to_json}},
|
|
|
|
+ [{var, Line, field_var(Field)}]}]},
|
|
|
|
+ to_json_cons(Line, Fields)}.
|
|
|
|
|
|
generate_to_json({eof, Line}, Record, Fields) ->
|
|
generate_to_json({eof, Line}, Record, Fields) ->
|
|
- [{function, Line, to_json, 1,
|
|
|
|
- [{clause, Line,
|
|
|
|
- [{record, Line, Record,
|
|
|
|
- [{record_field, Line, {atom, Line, F}, {var, Line, field_var(F)}} || F <- Fields]}],
|
|
|
|
- [],
|
|
|
|
- [to_json_cons(Line, Fields)]}]},
|
|
|
|
- {eof, Line + 1}];
|
|
|
|
|
|
+ [{function, Line, to_json, 1,
|
|
|
|
+ [{clause, Line,
|
|
|
|
+ [{record, Line, Record,
|
|
|
|
+ [{record_field, Line, {atom, Line, F}, {var, Line, field_var(F)}} || F <- Fields]}],
|
|
|
|
+ [],
|
|
|
|
+ [to_json_cons(Line, Fields)]}]},
|
|
|
|
+ {eof, Line + 1}];
|
|
|
|
|
|
generate_to_json(Form, _, _) -> Form.
|
|
generate_to_json(Form, _, _) -> Form.
|
|
|
|
|
|
@@ -169,13 +178,14 @@ to_json(X) when erlang:is_tuple(X) ->
|
|
Module:to_json(X);
|
|
Module:to_json(X);
|
|
to_json(Data) ->
|
|
to_json(Data) ->
|
|
case is_string(Data) of
|
|
case is_string(Data) of
|
|
- true -> rest:to_binary(Data);
|
|
|
|
|
|
+ true -> to_binary(Data);
|
|
false -> json_match(Data)
|
|
false -> json_match(Data)
|
|
end.
|
|
end.
|
|
|
|
|
|
json_match([{_, _} | _] = Props) ->
|
|
json_match([{_, _} | _] = Props) ->
|
|
- [{rest:to_binary(Key), to_json(Value)} || {Key, Value} <- Props];
|
|
|
|
-json_match([_ | _] = NonEmptyList) -> [to_json(X) || X <- NonEmptyList];
|
|
|
|
|
|
+ [{to_binary(Key), to_json(Value)} || {Key, Value} <- Props];
|
|
|
|
+json_match([_ | _] = NonEmptyList) ->
|
|
|
|
+ [to_json(X) || X <- NonEmptyList];
|
|
json_match(Any) -> Any.
|
|
json_match(Any) -> Any.
|
|
|
|
|
|
is_char(C) -> erlang:is_integer(C) andalso C >= 0 andalso C =< 255.
|
|
is_char(C) -> erlang:is_integer(C) andalso C >= 0 andalso C =< 255.
|
|
@@ -186,7 +196,7 @@ is_string(_) -> false.
|
|
to_binary(A) when erlang:is_atom(A) -> erlang:atom_to_binary(A, latin1);
|
|
to_binary(A) when erlang:is_atom(A) -> erlang:atom_to_binary(A, latin1);
|
|
to_binary(B) when erlang:is_binary(B) -> B;
|
|
to_binary(B) when erlang:is_binary(B) -> B;
|
|
to_binary(I) when erlang:is_integer(I) -> to_binary(erlang:integer_to_list(I));
|
|
to_binary(I) when erlang:is_integer(I) -> to_binary(erlang:integer_to_list(I));
|
|
-to_binary(F) when erlang:is_float(F) -> float_to_binary(F, [{decimals, 9}, compact]);
|
|
|
|
|
|
+to_binary(F) when erlang:is_float(F) -> erlang:float_to_binary(F, [{decimals, 9}, compact]);
|
|
to_binary(L) when erlang:is_list(L) -> erlang:iolist_to_binary(L).
|
|
to_binary(L) when erlang:is_list(L) -> erlang:iolist_to_binary(L).
|
|
|
|
|
|
parse(String) ->
|
|
parse(String) ->
|