garret-smith / aeon

Another Erlang to Object Notation translator
BSD 3-Clause "New" or "Revised" License
11 stars 7 forks source link

Cannot use aeon:record_to_jsx/2 on OTP19 #3

Open hazsul opened 7 years ago

hazsul commented 7 years ago

When trying to implement aeon in OTP19, I am not getting any record specification:

** exception error: {no_type,{test,{record,user}}}
     in function  aeon_common:field_types/2 (/home/hazims/src/garret_aeon/_build/default/lib/aeon/src/aeon_common.erl, line 27)
     in call from aeon_to_jsx:record_to_jsx/2 (/home/hazims/src/garret_aeon/_build/default/lib/aeon/src/aeon_to_jsx.erl, line 11)
     in call from test2:test/0 (/home/hazims/src/garret_aeon/_build/default/lib/aeon/src/test2.erl, line 23)

If I try to get the record types defined in the test module:

7> test:'#types'(). 
[{{type,privilege},
  {union,[{atom,login},
          {atom,create},
          {atom,delete},
          {atom,grant}]}}]

The code is: test1.erl

-module(test).

-compile({parse_transform, runtime_types}).
-compile({parse_transform, exprecs}).

-type privilege() :: login | create | delete | grant.

-record(user, {
          name :: binary(),
          age :: integer(),
          height :: float(),
          birthday :: {Year :: integer(),
                       Month :: integer(),
                       Day :: integer()},
          privileges :: [privilege()]
         }).

-export_type([privilege/0]).
-export_records([user]).

It seems that some of the available record information is not available in OTP19.

Might have something to do with changes in erl_syntax_lib since R16.

//Hazim

garret-smith commented 7 years ago

'#types'() will only list types exported with 'export_type'. In order to see exported records, call Module:'#exported_records-'(). You can also create a type for the record and then export the type, ie '-type user() :: #user{}'

wjqwsp commented 6 years ago

@hazsul Hi, now I run into a similar problem. Have you fixed the no_type error in OTP19?

hazsul commented 6 years ago

@wjqwsp I didnt, but another contributor forked this and seems to have fixed it, can you try from https://github.com/havelkadragan/aeon, it worked well enough for me.

wjqwsp commented 6 years ago

Hi @hazsul , I have tried https://github.com/havelkadragan/aeon. When the record field does not need initiation, it works well. But if some fields need initiation, the compilation fails. For example:

-record(account_user, {
    id :: integer(),
    name :: string(),
    password :: string() | aeon:excluded_field(),
    type :: string(),
    status :: string(),
    create_date = erlang:universaltime() :: {{integer(), integer(), integer()}, {integer(), integer(), integer()}}
}).

The field "create_date" need to call "erlang:universaltime()" and the compilation fails. This is the error logs:

_build/test/lib/common_lib/test/auto_json_SUITE.erl:none: error in parse transform 'auto_json': {function_clause,
                                       [{parse_trans,find_attribute,
                                         [file,
                                          {error,
                                           [{"/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/test/lib/common_lib/test/auto_json_SUITE.erl",
                                             [{9999,parse_trans,
                                               {function_clause,
                                                [{runtime_types,field_info,
                                                  [{create_date,
                                                    {{call,11,
                                                      {remote,11,
                                                       {atom,11,erlang},
                                                       {atom,11,
                                                        universaltime}},
                                                      []},
                                                     {type,11,tuple,
                                                      [{type,11,tuple,
                                                        [{type,11,integer,[]},
                                                         {type,11,integer,[]},
                                                         {type,11,integer,
                                                          []}]},
                                                       {type,11,tuple,
                                                        [{type,11,integer,[]},
                                                         {type,11,integer,[]},
                                                         {type,11,integer,
                                                          []}]}]}}}],
                                                  [{file,
                                                    "/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/default/lib/aeon/src/runtime_types.erl"},
                                                   {line,62}]},
                                                 {runtime_types,
                                                  '-transform_attribute_rec/1-lc$^0/1-0-',
                                                  1,
                                                  [{file,
                                                    "/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/default/lib/aeon/src/runtime_types.erl"},
                                                   {line,54}]},
                                                 {runtime_types,
                                                  '-transform_attribute_rec/1-lc$^0/1-0-',
                                                  1,
                                                  [{file,
                                                    "/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/default/lib/aeon/src/runtime_types.erl"},
                                                   {line,54}]},
                                                 {runtime_types,
                                                  transform_attribute_rec,1,
                                                  [{file,
                                                    "/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/default/lib/aeon/src/runtime_types.erl"},
                                                   {line,54}]},
                                                 {runtime_types,
                                                  '-do_transform/2-lc$^2/1-0-',
                                                  1,
                                                  [{file,
                                                    "/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/default/lib/aeon/src/runtime_types.erl"},
                                                   {line,31}]},
                                                 {runtime_types,do_transform,
                                                  2,
                                                  [{file,
                                                    "/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/default/lib/aeon/src/runtime_types.erl"},
                                                   {line,31}]},
                                                 {parse_trans,top,3,
                                                  [{file,
                                                    "/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/default/lib/parse_trans/src/parse_trans.erl"},
                                                   {line,336}]},
                                                 {auto_json,parse_transform,
                                                  2,
                                                  [{file,
                                                    "/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/test/lib/common_lib/src/auto_json.erl"},
                                                   {line,11}]}]}}]}]}],
                                         [{file,
                                           "/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/default/lib/parse_trans/src/parse_trans.erl"},
                                          {line,254}]},
                                        {parse_trans,get_attribute,3,
                                         [{file,
                                           "/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/default/lib/parse_trans/src/parse_trans.erl"},
                                          {line,247}]},
                                        {parse_trans,get_file,1,
                                         [{file,
                                           "/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/default/lib/parse_trans/src/parse_trans.erl"},
                                          {line,219}]},
                                        {parse_trans,initial_context,2,
                                         [{file,
                                           "/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/default/lib/parse_trans/src/parse_trans.erl"},
                                          {line,291}]},
                                        {parse_trans,top,3,
                                         [{file,
                                           "/home/wangjiasheng/Documents/cold-storage/cluster/erl_apps/common_lib/_build/default/lib/parse_trans/src/parse_trans.erl"},
                                          {line,334}]},
                                        {compile,
                                         '-foldl_transform/2-anonymous-2-',2,
                                         [{file,"compile.erl"},{line,972}]},
                                        {compile,foldl_transform,2,
                                         [{file,"compile.erl"},{line,974}]},
                                        {compile,
                                         '-internal_comp/4-anonymous-1-',2,
                                         [{file,"compile.erl"},{line,329}]}]}
hazsul commented 6 years ago

Hi @wjqwsp,

Can you try the below patch:

diff --git a/src/runtime_types.erl b/src/runtime_types.erl
index 0f68556..dc85ee7 100644
--- a/src/runtime_types.erl
+++ b/src/runtime_types.erl
@@ -76,8 +76,11 @@ field_info({FieldName, {none, {_, _, _} = Type}}) ->
 field_info({FieldName, {{record, _, _, _}, Type}}) ->
     {FieldName, typename(Type)};
 field_info({FieldName, {{_, _, _}, Type}}) ->
+    {FieldName, typename(Type)};
+field_info({FieldName, {{call, _, _, _}, Type}}) ->
     {FieldName, typename(Type)}.

+
 typename(Value) when is_atom(Value) ->
     {atom, Value};
 typename({var, _, Lit}) ->

Also its that I noticed you are using string() as a type, but I dont think aeon/jsx supports that as a type because all strings are supposed to be binary().

wjqwsp commented 6 years ago

Thank you, after adding the patch aeon works well. Aeon seems to convert the string() to binary():

converted_value(Val, {type, Intrinsic}, _Module) when
      Intrinsic =:= integer;
      Intrinsic =:= float;
      Intrinsic =:= boolean;
      Intrinsic =:= binary;
      Intrinsic =:= atom;
      Intrinsic =:= any;
      Intrinsic =:= term
      ->
    Val;
converted_value(Val, {type, string}, _Module) when is_list(Val) ->
    unicode:characters_to_binary(Val, utf8, utf8);
converted_value(undefined, {type, string}, _Module) ->
    undefined;

I also notice that unlike other common types, when the type is string(), the record field value cannot be undefined, so I make a little change to make this work.