fix(bpapi): Use argument types from the spec
This commit is contained in:
parent
7b65684c45
commit
04bac16741
|
@ -20,6 +20,9 @@
|
||||||
|
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
|
|
||||||
|
%% Using an undocumented API here :(
|
||||||
|
-include_lib("dialyzer/src/dialyzer.hrl").
|
||||||
|
|
||||||
-type api_dump() :: #{{emqx_bpapi:api(), emqx_bpapi:api_version()} =>
|
-type api_dump() :: #{{emqx_bpapi:api(), emqx_bpapi:api_version()} =>
|
||||||
#{ calls := [emqx_bpapi:rpc()]
|
#{ calls := [emqx_bpapi:rpc()]
|
||||||
, casts := [emqx_bpapi:rpc()]
|
, casts := [emqx_bpapi:rpc()]
|
||||||
|
@ -128,21 +131,24 @@ typecheck_apis( #{release := CallerRelease, api := CallerAPIs, signatures := Cal
|
||||||
setnok(),
|
setnok(),
|
||||||
[?ERROR("Incompatible RPC call: "
|
[?ERROR("Incompatible RPC call: "
|
||||||
"type of the parameter ~p of RPC call ~s on release ~p "
|
"type of the parameter ~p of RPC call ~s on release ~p "
|
||||||
"is not a subtype of the target function ~s on release ~p",
|
"is not a subtype of the target function ~s on release ~p.~n"
|
||||||
|
"Caller type: ~s~nCallee type: ~s~n",
|
||||||
[Var, format_call(From), CallerRelease,
|
[Var, format_call(From), CallerRelease,
|
||||||
format_call(To), CalleeRelease])
|
format_call(To), CalleeRelease,
|
||||||
|| Var <- TypeErrors]
|
erl_types:t_to_string(CallerType),
|
||||||
|
erl_types:t_to_string(CalleeType)])
|
||||||
|
|| {Var, CallerType, CalleeType} <- TypeErrors]
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
AllCalls).
|
AllCalls).
|
||||||
|
|
||||||
-spec typecheck_rpc(param_types(), param_types()) -> [emqx_bpapi:var_name()].
|
-spec typecheck_rpc(param_types(), param_types()) -> [{emqx_bpapi:var_name(), _Type, _Type}].
|
||||||
typecheck_rpc(Caller, Callee) ->
|
typecheck_rpc(Caller, Callee) ->
|
||||||
maps:fold(fun(Var, CalleeType, Acc) ->
|
maps:fold(fun(Var, CalleeType, Acc) ->
|
||||||
#{Var := CallerType} = Caller,
|
#{Var := CallerType} = Caller,
|
||||||
case erl_types:t_is_subtype(CallerType, CalleeType) of
|
case erl_types:t_is_subtype(CallerType, CalleeType) of
|
||||||
true -> Acc;
|
true -> Acc;
|
||||||
false -> [Var|Acc]
|
false -> [{Var, CallerType, CalleeType}|Acc]
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
[],
|
[],
|
||||||
|
@ -182,7 +188,7 @@ dump(Opts) ->
|
||||||
warn_nonbpapi_rpcs(NonBPAPICalls),
|
warn_nonbpapi_rpcs(NonBPAPICalls),
|
||||||
APIDump = collect_bpapis(BPAPICalls),
|
APIDump = collect_bpapis(BPAPICalls),
|
||||||
DialyzerDump = collect_signatures(PLT, APIDump),
|
DialyzerDump = collect_signatures(PLT, APIDump),
|
||||||
Release = emqx_app:get_release(),
|
[Release|_] = string:split(emqx_app:get_release(), "-"),
|
||||||
dump_api(#{api => APIDump, signatures => DialyzerDump, release => Release}),
|
dump_api(#{api => APIDump, signatures => DialyzerDump, release => Release}),
|
||||||
xref:stop(?XREF),
|
xref:stop(?XREF),
|
||||||
erase(bpapi_ok).
|
erase(bpapi_ok).
|
||||||
|
@ -263,9 +269,11 @@ collect_signatures(PLT, APIs) ->
|
||||||
enrich({From0, To0}, {Acc0, PLT}) ->
|
enrich({From0, To0}, {Acc0, PLT}) ->
|
||||||
From = call_to_mfa(From0),
|
From = call_to_mfa(From0),
|
||||||
To = call_to_mfa(To0),
|
To = call_to_mfa(To0),
|
||||||
case {dialyzer_plt:lookup(PLT, From), dialyzer_plt:lookup(PLT, To)} of
|
case {dialyzer_plt:lookup_contract(PLT, From), dialyzer_plt:lookup(PLT, To)} of
|
||||||
{{value, TFrom}, {value, TTo}} ->
|
{{value, #contract{args = FromArgs}}, {value, TTo}} ->
|
||||||
Acc = Acc0#{ From => TFrom
|
%% TODO: Check return type
|
||||||
|
FromRet = erl_types:t_any(),
|
||||||
|
Acc = Acc0#{ From => {FromRet, FromArgs}
|
||||||
, To => TTo
|
, To => TTo
|
||||||
},
|
},
|
||||||
{Acc, PLT};
|
{Acc, PLT};
|
||||||
|
|
Loading…
Reference in New Issue