diff options
author | Henrik Nord <[email protected]> | 2011-11-18 17:33:22 +0100 |
---|---|---|
committer | Henrik Nord <[email protected]> | 2011-11-18 17:33:42 +0100 |
commit | b130455e73b0bcacee2bfd3dfe6bafa9dd497886 (patch) | |
tree | 2f97ac74f573b2f0c5a4f846e4505dec871e05f5 /lib/dialyzer/src/dialyzer_utils.erl | |
parent | 01bf07008b38839f4e1dff3293f921c2e35a44c4 (diff) | |
parent | 8167578ca6b23f3043ae2e21ded4b13b8db74e20 (diff) | |
download | otp-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.erl | 49 |
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}. %% ============================================================================ %% |