aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/src
diff options
context:
space:
mode:
authorStavros Aronis <[email protected]>2010-05-30 23:42:34 +0300
committerHenrik Nord <[email protected]>2011-10-07 17:08:03 +0200
commit493262e2f024d3a0773b8a062c24de84b5cf21d5 (patch)
tree2b35e1b3e1f11be37609108dd62ae94baa513696 /lib/stdlib/src
parent0edb6a4d2d76960846fd04ecce3aa00b3348691b (diff)
downloadotp-493262e2f024d3a0773b8a062c24de84b5cf21d5.tar.gz
otp-493262e2f024d3a0773b8a062c24de84b5cf21d5.tar.bz2
otp-493262e2f024d3a0773b8a062c24de84b5cf21d5.zip
Automatically generate 'behaviour_info' function from '-callback' attributes
'behaviour_info(callbacks)' is a special function that is defined in a module which describes a behaviour and returns a list of its callbacks. This function is now automatically generated using the '-callback' specs. An error is returned by lint if user defines both '-callback' attributes and the behaviour_info/1 function. If no type info is needed for a callback use a generic spec for it.
Diffstat (limited to 'lib/stdlib/src')
-rw-r--r--lib/stdlib/src/erl_lint.erl23
1 files changed, 22 insertions, 1 deletions
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 0d8773ff0d..78b996d94b 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -319,6 +319,9 @@ format_error({undefined_behaviour_callbacks,Behaviour}) ->
format_error({ill_defined_behaviour_callbacks,Behaviour}) ->
io_lib:format("behaviour ~w callback functions erroneously defined",
[Behaviour]);
+format_error({behaviour_info, {_M,F,A}}) ->
+ io_lib:format("cannot define callback attibute for ~w/~w when "
+ "behaviour_info is defined",[F,A]);
%% --- types and specs ---
format_error({singleton_typevar, Name}) ->
io_lib:format("type variable ~w is only used once (is unbound)", [Name]);
@@ -845,7 +848,8 @@ post_traversal_check(Forms, St0) ->
StB = check_unused_types(Forms, StA),
StC = check_untyped_records(Forms, StB),
StD = check_on_load(StC),
- check_unused_records(Forms, StD).
+ StE = check_unused_records(Forms, StD),
+ check_callback_information(StE).
%% check_behaviour(State0) -> State
%% Check that the behaviour attribute is valid.
@@ -1144,6 +1148,23 @@ check_unused_records(Forms, St0) ->
St0
end.
+check_callback_information(#lint{callbacks = Callbacks,
+ defined = Defined} = State) ->
+ case gb_sets:is_member({behaviour_info,1}, Defined) of
+ false -> State;
+ true ->
+ case dict:size(Callbacks) of
+ 0 -> State;
+ _ ->
+ CallbacksList = dict:to_list(Callbacks),
+ FoldL =
+ fun({Fa,Line},St) ->
+ add_error(Line, {behaviour_info, Fa}, St)
+ end,
+ lists:foldl(FoldL, State, CallbacksList)
+ end
+ end.
+
%% For storing the import list we use the orddict module.
%% We know an empty set is [].