aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer/src/dialyzer_utils.erl
diff options
context:
space:
mode:
authorHenrik Nord <[email protected]>2011-11-18 17:33:22 +0100
committerHenrik Nord <[email protected]>2011-11-18 17:33:42 +0100
commitb130455e73b0bcacee2bfd3dfe6bafa9dd497886 (patch)
tree2f97ac74f573b2f0c5a4f846e4505dec871e05f5 /lib/dialyzer/src/dialyzer_utils.erl
parent01bf07008b38839f4e1dff3293f921c2e35a44c4 (diff)
parent8167578ca6b23f3043ae2e21ded4b13b8db74e20 (diff)
downloadotp-b130455e73b0bcacee2bfd3dfe6bafa9dd497886.tar.gz
otp-b130455e73b0bcacee2bfd3dfe6bafa9dd497886.tar.bz2
otp-b130455e73b0bcacee2bfd3dfe6bafa9dd497886.zip
Merge branch 'sa/dialyzer-behaviours'
* sa/dialyzer-behaviours: Wrap up behaviours patch for Dialyzer Detection of callback-spec discrepancies Allow none() as return value in callbacks Behaviour callback discrepancy detection for Dialyzer Add lookup function for callbacks Store callbacks in codeserver and PLT Collect callback definitions during compilation Update inets results OTP-9731
Diffstat (limited to 'lib/dialyzer/src/dialyzer_utils.erl')
-rw-r--r--lib/dialyzer/src/dialyzer_utils.erl49
1 files changed, 34 insertions, 15 deletions
diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl
index 12f8dec67e..2a248fb028 100644
--- a/lib/dialyzer/src/dialyzer_utils.erl
+++ b/lib/dialyzer/src/dialyzer_utils.erl
@@ -311,11 +311,15 @@ merge_records(NewRecords, OldRecords) ->
%%
%% ============================================================================
+-type spec_dict() :: dict().
+-type callback_dict() :: dict().
+
-spec get_spec_info(atom(), abstract_code(), dict()) ->
- {'ok', dict()} | {'error', string()}.
+ {'ok', spec_dict(), callback_dict()} | {'error', string()}.
get_spec_info(ModName, AbstractCode, RecordsDict) ->
- get_spec_info(AbstractCode, dict:new(), RecordsDict, ModName, "nofile").
+ get_spec_info(AbstractCode, dict:new(), dict:new(),
+ RecordsDict, ModName, "nofile").
%% TypeSpec is a list of conditional contracts for a function.
%% Each contract is of the form {[Argument], Range, [Constraint]} where
@@ -323,21 +327,34 @@ get_spec_info(ModName, AbstractCode, RecordsDict) ->
%% - Constraint is of the form {subtype, T1, T2} where T1 and T2
%% are erl_types:erl_type()
-get_spec_info([{attribute, Ln, spec, {Id, TypeSpec}}|Left],
- SpecDict, RecordsDict, ModName, File) when is_list(TypeSpec) ->
+get_spec_info([{attribute, Ln, Contract, {Id, TypeSpec}}|Left],
+ SpecDict, CallbackDict, RecordsDict, ModName, File)
+ when ((Contract =:= 'spec') or (Contract =:= 'callback')),
+ is_list(TypeSpec) ->
MFA = case Id of
{_, _, _} = T -> T;
{F, A} -> {ModName, F, A}
end,
- try dict:find(MFA, SpecDict) of
+ ActiveDict =
+ case Contract of
+ spec -> SpecDict;
+ callback -> CallbackDict
+ end,
+ try dict:find(MFA, ActiveDict) of
error ->
- NewSpecDict =
+ NewActiveDict =
dialyzer_contracts:store_tmp_contract(MFA, {File, Ln}, TypeSpec,
- SpecDict, RecordsDict),
- get_spec_info(Left, NewSpecDict, RecordsDict, ModName, File);
+ ActiveDict, RecordsDict),
+ {NewSpecDict, NewCallbackDict} =
+ case Contract of
+ spec -> {NewActiveDict, CallbackDict};
+ callback -> {SpecDict, NewActiveDict}
+ end,
+ get_spec_info(Left, NewSpecDict, NewCallbackDict,
+ RecordsDict, ModName,File);
{ok, {{OtherFile, L},_C}} ->
{Mod, Fun, Arity} = MFA,
- Msg = flat_format(" Contract for function ~w:~w/~w "
+ Msg = flat_format(" Contract/callback for function ~w:~w/~w "
"already defined in ~s:~w\n",
[Mod, Fun, Arity, OtherFile, L]),
throw({error, Msg})
@@ -347,12 +364,14 @@ get_spec_info([{attribute, Ln, spec, {Id, TypeSpec}}|Left],
[Ln, Error])}
end;
get_spec_info([{attribute, _, file, {IncludeFile, _}}|Left],
- SpecDict, RecordsDict, ModName, _File) ->
- get_spec_info(Left, SpecDict, RecordsDict, ModName, IncludeFile);
-get_spec_info([_Other|Left], SpecDict, RecordsDict, ModName, File) ->
- get_spec_info(Left, SpecDict, RecordsDict, ModName, File);
-get_spec_info([], SpecDict, _RecordsDict, _ModName, _File) ->
- {ok, SpecDict}.
+ SpecDict, CallbackDict, RecordsDict, ModName, _File) ->
+ get_spec_info(Left, SpecDict, CallbackDict,
+ RecordsDict, ModName, IncludeFile);
+get_spec_info([_Other|Left], SpecDict, CallbackDict,
+ RecordsDict, ModName, File) ->
+ get_spec_info(Left, SpecDict, CallbackDict, RecordsDict, ModName, File);
+get_spec_info([], SpecDict, CallbackDict, _RecordsDict, _ModName, _File) ->
+ {ok, SpecDict, CallbackDict}.
%% ============================================================================
%%