ACI should also track payable
This commit is contained in:
parent
d0485304b6
commit
bb0c3b54df
@ -113,7 +113,7 @@ encode_contract(Contract = {contract, _, {con, _, Name}, _}) ->
|
|||||||
|| F <- sort_decls(contract_funcs(Contract)),
|
|| F <- sort_decls(contract_funcs(Contract)),
|
||||||
is_entrypoint(F) ],
|
is_entrypoint(F) ],
|
||||||
|
|
||||||
#{contract => C3#{functions => Fdefs}};
|
#{contract => C3#{functions => Fdefs, payable => is_payable(Contract)}};
|
||||||
encode_contract(Namespace = {namespace, _, {con, _, Name}, _}) ->
|
encode_contract(Namespace = {namespace, _, {con, _, Name}, _}) ->
|
||||||
Tdefs = [ encode_typedef(T) || T <- sort_decls(contract_types(Namespace)) ],
|
Tdefs = [ encode_typedef(T) || T <- sort_decls(contract_types(Namespace)) ],
|
||||||
#{namespace => #{name => encode_name(Name),
|
#{namespace => #{name => encode_name(Name),
|
||||||
@ -125,12 +125,14 @@ encode_function(FDef = {letfun, _, {id, _, Name}, Args, Type, _}) ->
|
|||||||
#{name => encode_name(Name),
|
#{name => encode_name(Name),
|
||||||
arguments => encode_args(Args),
|
arguments => encode_args(Args),
|
||||||
returns => encode_type(Type),
|
returns => encode_type(Type),
|
||||||
stateful => is_stateful(FDef)};
|
stateful => is_stateful(FDef),
|
||||||
|
payable => is_payable(FDef)};
|
||||||
encode_function(FDecl = {fun_decl, _, {id, _, Name}, {fun_t, _, _, Args, Type}}) ->
|
encode_function(FDecl = {fun_decl, _, {id, _, Name}, {fun_t, _, _, Args, Type}}) ->
|
||||||
#{name => encode_name(Name),
|
#{name => encode_name(Name),
|
||||||
arguments => encode_anon_args(Args),
|
arguments => encode_anon_args(Args),
|
||||||
returns => encode_type(Type),
|
returns => encode_type(Type),
|
||||||
stateful => is_stateful(FDecl)}.
|
stateful => is_stateful(FDecl),
|
||||||
|
payable => is_payable(FDecl)}.
|
||||||
|
|
||||||
encode_anon_args(Types) ->
|
encode_anon_args(Types) ->
|
||||||
Anons = [ list_to_binary("_" ++ integer_to_list(X)) || X <- lists:seq(1, length(Types))],
|
Anons = [ list_to_binary("_" ++ integer_to_list(X)) || X <- lists:seq(1, length(Types))],
|
||||||
@ -234,12 +236,13 @@ do_render_aci_json(Json) ->
|
|||||||
{ok, list_to_binary(string:join(DecodedContracts, "\n"))}.
|
{ok, list_to_binary(string:join(DecodedContracts, "\n"))}.
|
||||||
|
|
||||||
decode_contract(#{contract := #{name := Name,
|
decode_contract(#{contract := #{name := Name,
|
||||||
|
payable := Payable,
|
||||||
type_defs := Ts0,
|
type_defs := Ts0,
|
||||||
functions := Fs} = C}) ->
|
functions := Fs} = C}) ->
|
||||||
MkTDef = fun(N, T) -> #{name => N, vars => [], typedef => T} end,
|
MkTDef = fun(N, T) -> #{name => N, vars => [], typedef => T} end,
|
||||||
Ts = [ MkTDef(<<"state">>, maps:get(state, C)) || maps:is_key(state, C) ] ++
|
Ts = [ MkTDef(<<"state">>, maps:get(state, C)) || maps:is_key(state, C) ] ++
|
||||||
[ MkTDef(<<"event">>, maps:get(event, C)) || maps:is_key(event, C) ] ++ Ts0,
|
[ MkTDef(<<"event">>, maps:get(event, C)) || maps:is_key(event, C) ] ++ Ts0,
|
||||||
["contract ", io_lib:format("~s", [Name])," =\n",
|
[payable(Payable), "contract ", io_lib:format("~s", [Name])," =\n",
|
||||||
decode_tdefs(Ts), decode_funcs(Fs)];
|
decode_tdefs(Ts), decode_funcs(Fs)];
|
||||||
decode_contract(#{namespace := #{name := Name, type_defs := Ts}}) when Ts /= [] ->
|
decode_contract(#{namespace := #{name := Name, type_defs := Ts}}) when Ts /= [] ->
|
||||||
["namespace ", io_lib:format("~s", [Name])," =\n",
|
["namespace ", io_lib:format("~s", [Name])," =\n",
|
||||||
@ -249,8 +252,8 @@ decode_contract(_) -> [].
|
|||||||
decode_funcs(Fs) -> [ decode_func(F) || F <- Fs ].
|
decode_funcs(Fs) -> [ decode_func(F) || F <- Fs ].
|
||||||
|
|
||||||
%% decode_func(#{name := init}) -> [];
|
%% decode_func(#{name := init}) -> [];
|
||||||
decode_func(#{name := Name, arguments := As, returns := T}) ->
|
decode_func(#{name := Name, payable := Payable, arguments := As, returns := T}) ->
|
||||||
[" entrypoint", " ", io_lib:format("~s", [Name]), " : ",
|
[" ", payable(Payable), "entrypoint ", io_lib:format("~s", [Name]), " : ",
|
||||||
decode_args(As), " => ", decode_type(T), $\n].
|
decode_args(As), " => ", decode_type(T), $\n].
|
||||||
|
|
||||||
decode_args(As) ->
|
decode_args(As) ->
|
||||||
@ -321,13 +324,16 @@ decode_deftype(#{record := _Efs}) -> "record";
|
|||||||
decode_deftype(#{variant := _}) -> "datatype";
|
decode_deftype(#{variant := _}) -> "datatype";
|
||||||
decode_deftype(_T) -> "type".
|
decode_deftype(_T) -> "type".
|
||||||
|
|
||||||
decode_tvars([]) -> []; %No tvars, no parentheses
|
decode_tvars([]) -> []; %No tvars, no parentheses
|
||||||
decode_tvars(Vs) ->
|
decode_tvars(Vs) ->
|
||||||
Dvs = [ decode_tvar(V) || V <- Vs ],
|
Dvs = [ decode_tvar(V) || V <- Vs ],
|
||||||
[$(,lists:join(", ", Dvs),$)].
|
[$(,lists:join(", ", Dvs),$)].
|
||||||
|
|
||||||
decode_tvar(#{name := N}) -> io_lib:format("~s", [N]).
|
decode_tvar(#{name := N}) -> io_lib:format("~s", [N]).
|
||||||
|
|
||||||
|
payable(true) -> "payable ";
|
||||||
|
payable(false) -> "".
|
||||||
|
|
||||||
%% #contract{Ann, Con, [Declarations]}.
|
%% #contract{Ann, Con, [Declarations]}.
|
||||||
|
|
||||||
contract_funcs({C, _, _, Decls}) when C == contract; C == namespace ->
|
contract_funcs({C, _, _, Decls}) when C == contract; C == namespace ->
|
||||||
@ -352,6 +358,7 @@ sort_decls(Ds) ->
|
|||||||
|
|
||||||
is_entrypoint(Node) -> aeso_syntax:get_ann(entrypoint, Node, false).
|
is_entrypoint(Node) -> aeso_syntax:get_ann(entrypoint, Node, false).
|
||||||
is_stateful(Node) -> aeso_syntax:get_ann(stateful, Node, false).
|
is_stateful(Node) -> aeso_syntax:get_ann(stateful, Node, false).
|
||||||
|
is_payable(Node) -> aeso_syntax:get_ann(payable, Node, false).
|
||||||
|
|
||||||
typedef_name({type_def, _, {id, _, Name}, _, _}) -> Name.
|
typedef_name({type_def, _, {id, _, Name}, _, _}) -> Name.
|
||||||
|
|
||||||
|
@ -14,20 +14,22 @@ test_contract(N) ->
|
|||||||
?assertEqual({ok, DecACI}, aeso_aci:render_aci_json(JSON)).
|
?assertEqual({ok, DecACI}, aeso_aci:render_aci_json(JSON)).
|
||||||
|
|
||||||
test_cases(1) ->
|
test_cases(1) ->
|
||||||
Contract = <<"contract C =\n"
|
Contract = <<"payable contract C =\n"
|
||||||
" entrypoint a(i : int) = i+1\n">>,
|
" payable stateful entrypoint a(i : int) = i+1\n">>,
|
||||||
MapACI = #{contract =>
|
MapACI = #{contract =>
|
||||||
#{name => <<"C">>,
|
#{name => <<"C">>,
|
||||||
type_defs => [],
|
type_defs => [],
|
||||||
|
payable => true,
|
||||||
functions =>
|
functions =>
|
||||||
[#{name => <<"a">>,
|
[#{name => <<"a">>,
|
||||||
arguments =>
|
arguments =>
|
||||||
[#{name => <<"i">>,
|
[#{name => <<"i">>,
|
||||||
type => <<"int">>}],
|
type => <<"int">>}],
|
||||||
returns => <<"int">>,
|
returns => <<"int">>,
|
||||||
stateful => false}]}},
|
stateful => true,
|
||||||
DecACI = <<"contract C =\n"
|
payable => true}]}},
|
||||||
" entrypoint a : (int) => int\n">>,
|
DecACI = <<"payable contract C =\n"
|
||||||
|
" payable entrypoint a : (int) => int\n">>,
|
||||||
{Contract,MapACI,DecACI};
|
{Contract,MapACI,DecACI};
|
||||||
|
|
||||||
test_cases(2) ->
|
test_cases(2) ->
|
||||||
@ -35,7 +37,7 @@ test_cases(2) ->
|
|||||||
" type allan = int\n"
|
" type allan = int\n"
|
||||||
" entrypoint a(i : allan) = i+1\n">>,
|
" entrypoint a(i : allan) = i+1\n">>,
|
||||||
MapACI = #{contract =>
|
MapACI = #{contract =>
|
||||||
#{name => <<"C">>,
|
#{name => <<"C">>, payable => false,
|
||||||
type_defs =>
|
type_defs =>
|
||||||
[#{name => <<"allan">>,
|
[#{name => <<"allan">>,
|
||||||
typedef => <<"int">>,
|
typedef => <<"int">>,
|
||||||
@ -46,7 +48,8 @@ test_cases(2) ->
|
|||||||
type => <<"C.allan">>}],
|
type => <<"C.allan">>}],
|
||||||
name => <<"a">>,
|
name => <<"a">>,
|
||||||
returns => <<"int">>,
|
returns => <<"int">>,
|
||||||
stateful => false}]}},
|
stateful => false,
|
||||||
|
payable => false}]}},
|
||||||
DecACI = <<"contract C =\n"
|
DecACI = <<"contract C =\n"
|
||||||
" type allan = int\n"
|
" type allan = int\n"
|
||||||
" entrypoint a : (C.allan) => int\n">>,
|
" entrypoint a : (C.allan) => int\n">>,
|
||||||
@ -64,8 +67,8 @@ test_cases(3) ->
|
|||||||
type =>
|
type =>
|
||||||
#{<<"C.bert">> => [<<"string">>]}}],
|
#{<<"C.bert">> => [<<"string">>]}}],
|
||||||
name => <<"a">>,returns => <<"int">>,
|
name => <<"a">>,returns => <<"int">>,
|
||||||
stateful => false}],
|
stateful => false, payable => false}],
|
||||||
name => <<"C">>,
|
name => <<"C">>, payable => false,
|
||||||
event => #{variant => [#{<<"SingleEventDefined">> => []}]},
|
event => #{variant => [#{<<"SingleEventDefined">> => []}]},
|
||||||
state => <<"unit">>,
|
state => <<"unit">>,
|
||||||
type_defs =>
|
type_defs =>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user