diff options
Diffstat (limited to 'lib/tools/src')
-rw-r--r-- | lib/tools/src/cover.erl | 2 | ||||
-rw-r--r-- | lib/tools/src/make.erl | 76 | ||||
-rw-r--r-- | lib/tools/src/tools.app.src | 3 | ||||
-rw-r--r-- | lib/tools/src/xref_base.erl | 3 | ||||
-rw-r--r-- | lib/tools/src/xref_reader.erl | 55 |
5 files changed, 88 insertions, 51 deletions
diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl index 92c10cc306..e2db4f0148 100644 --- a/lib/tools/src/cover.erl +++ b/lib/tools/src/cover.erl @@ -2053,7 +2053,7 @@ munge_expr({bin_element,Line,Value,Size,TypeSpecifierList}, Vars) -> {MungedValue,Vars2} = munge_expr(Value, Vars), {MungedSize,Vars3} = munge_expr(Size, Vars2), {{bin_element,Line,MungedValue,MungedSize,TypeSpecifierList},Vars3}; -munge_expr(Form, Vars) -> % var|char|integer|float|string|atom|nil|eof|default +munge_expr(Form, Vars) -> {Form, Vars}. munge_exprs([Expr|Exprs], Vars, MungedExprs) when Vars#vars.is_guard=:=true, diff --git a/lib/tools/src/make.erl b/lib/tools/src/make.erl index 37e67cbe34..60695febb4 100644 --- a/lib/tools/src/make.erl +++ b/lib/tools/src/make.erl @@ -29,7 +29,7 @@ -include_lib("kernel/include/file.hrl"). --define(MakeOpts,[noexec,load,netload,noload]). +-define(MakeOpts,[noexec,load,netload,noload,emake]). all_or_nothing() -> case all() of @@ -43,29 +43,30 @@ all() -> all([]). all(Options) -> - {MakeOpts,CompileOpts} = sort_options(Options,[],[]), - case read_emakefile('Emakefile',CompileOpts) of - Files when is_list(Files) -> - do_make_files(Files,MakeOpts); - error -> - error - end. + run_emake(undefined, Options). files(Fs) -> files(Fs, []). files(Fs0, Options) -> Fs = [filename:rootname(F,".erl") || F <- Fs0], + run_emake(Fs, Options). + +run_emake(Mods, Options) -> {MakeOpts,CompileOpts} = sort_options(Options,[],[]), - case get_opts_from_emakefile(Fs,'Emakefile',CompileOpts) of + Emake = get_emake(Options), + case normalize_emake(Emake, Mods, CompileOpts) of Files when is_list(Files) -> - do_make_files(Files,MakeOpts); - error -> error + do_make_files(Files,MakeOpts); + error -> + error end. do_make_files(Fs, Opts) -> process(Fs, lists:member(noexec, Opts), load_opt(Opts)). +sort_options([{emake, _}=H|T],Make,Comp) -> + sort_options(T,[H|Make],Comp); sort_options([H|T],Make,Comp) -> case lists:member(H,?MakeOpts) of @@ -89,20 +90,35 @@ sort_options([],Make,Comp) -> %%% %%% These elements are converted to [{ModList,OptList},...] %%% ModList is a list of modulenames (strings) -read_emakefile(Emakefile,Opts) -> - case file:consult(Emakefile) of - {ok,Emake} -> + +normalize_emake(EmakeRaw, Mods, Opts) -> + case EmakeRaw of + {ok, Emake} when Mods =:= undefined -> transform(Emake,Opts,[],[]); - {error,enoent} -> + {ok, Emake} when is_list(Mods) -> + ModsOpts = transform(Emake,Opts,[],[]), + ModStrings = [coerce_2_list(M) || M <- Mods], + get_opts_from_emakefile(ModsOpts,ModStrings,Opts,[]); + {error,enoent} when Mods =:= undefined -> %% No Emakefile found - return all modules in current %% directory and the options given at command line - Mods = [filename:rootname(F) || F <- filelib:wildcard("*.erl")], + CwdMods = [filename:rootname(F) || F <- filelib:wildcard("*.erl")], + [{CwdMods, Opts}]; + {error,enoent} when is_list(Mods) -> [{Mods, Opts}]; - {error,Other} -> - io:format("make: Trouble reading 'Emakefile':~n~tp~n",[Other]), + {error, Error} -> + io:format("make: Trouble reading 'Emakefile':~n~tp~n",[Error]), error end. +get_emake(Opts) -> + case proplists:get_value(emake, Opts, false) of + false -> + file:consult('Emakefile'); + OptsEmake -> + {ok, OptsEmake} + end. + transform([{Mod,ModOpts}|Emake],Opts,Files,Already) -> case expand(Mod,Already) of [] -> @@ -143,31 +159,19 @@ expand(Mod,Already) -> end end. -%%% Reads the given Emakefile to see if there are any specific compile +%%% Reads the given Emake to see if there are any specific compile %%% options given for the modules. -get_opts_from_emakefile(Mods,Emakefile,Opts) -> - case file:consult(Emakefile) of - {ok,Emake} -> - Modsandopts = transform(Emake,Opts,[],[]), - ModStrings = [coerce_2_list(M) || M <- Mods], - get_opts_from_emakefile2(Modsandopts,ModStrings,Opts,[]); - {error,enoent} -> - [{Mods, Opts}]; - {error,Other} -> - io:format("make: Trouble reading 'Emakefile':~n~tp~n",[Other]), - error - end. -get_opts_from_emakefile2([{MakefileMods,O}|Rest],Mods,Opts,Result) -> +get_opts_from_emakefile([{MakefileMods,O}|Rest],Mods,Opts,Result) -> case members(Mods,MakefileMods,[],Mods) of {[],_} -> - get_opts_from_emakefile2(Rest,Mods,Opts,Result); + get_opts_from_emakefile(Rest,Mods,Opts,Result); {I,RestOfMods} -> - get_opts_from_emakefile2(Rest,RestOfMods,Opts,[{I,O}|Result]) + get_opts_from_emakefile(Rest,RestOfMods,Opts,[{I,O}|Result]) end; -get_opts_from_emakefile2([],[],_Opts,Result) -> +get_opts_from_emakefile([],[],_Opts,Result) -> Result; -get_opts_from_emakefile2([],RestOfMods,Opts,Result) -> +get_opts_from_emakefile([],RestOfMods,Opts,Result) -> [{RestOfMods,Opts}|Result]. members([H|T],MakefileMods,I,Rest) -> diff --git a/lib/tools/src/tools.app.src b/lib/tools/src/tools.app.src index 4c7dd24006..17b1d06686 100644 --- a/lib/tools/src/tools.app.src +++ b/lib/tools/src/tools.app.src @@ -41,7 +41,6 @@ ] }, {runtime_dependencies, ["stdlib-3.1","runtime_tools-1.8.14", - "kernel-3.0","inets-5.10","erts-7.0", - "compiler-5.0"]} + "kernel-3.0","erts-7.0","compiler-5.0"]} ] }. diff --git a/lib/tools/src/xref_base.erl b/lib/tools/src/xref_base.erl index f298a1ce81..8d2cc07e40 100644 --- a/lib/tools/src/xref_base.erl +++ b/lib/tools/src/xref_base.erl @@ -809,7 +809,8 @@ abst(File, Builtins, _Mode = functions) -> {exports,X0}, {attributes,A}]}} -> %% R9C- Forms0 = epp:interpret_file_attribute(Code), - {_,_,Forms,_} = sys_pre_expand:module(Forms0, []), + Forms1 = erl_expand_records:module(Forms0, []), + Forms = erl_internal:add_predefined_functions(Forms1), X = mfa_exports(X0, A, M), D = deprecated(A, X, M), xref_reader:module(M, Forms, Builtins, X, D); diff --git a/lib/tools/src/xref_reader.erl b/lib/tools/src/xref_reader.erl index 41b93caaeb..6c4a1c4d8e 100644 --- a/lib/tools/src/xref_reader.erl +++ b/lib/tools/src/xref_reader.erl @@ -42,17 +42,15 @@ %% experimental; -xref(FunEdge) is recognized. lattrs=[], % local calls, {{mfa(),mfa()},Line} xattrs=[], % external calls, -"- - battrs=[] % badly formed xref attributes, term(). + battrs=[] % badly formed xref attributes, term(). }). -include("xref.hrl"). -%% sys_pre_expand has modified the forms slightly compared to what -%% erl_id_trans recognizes. - %% The versions of the abstract code are as follows: -%% R7: abstract_v1 -%% R8: abstract_v2 +%% R7: abstract_v1 +%% R8: abstract_v2 +%% R9C: raw_abstract_v1 %% -> {ok, Module, {DefAt, CallAt, LC, XC, X, Attrs}, Unresolved}} | EXIT %% Attrs = {ALC, AXC, Bad} @@ -92,7 +90,12 @@ form({function, Anno, Name, Arity, Clauses}, S) -> Line = erl_anno:line(Anno), S2 = S1#xrefr{def_at = [{MFA,Line} | S#xrefr.def_at]}, S3 = clauses(Clauses, S2), - S3#xrefr{function = []}. + S3#xrefr{function = []}; +form(_, S) -> + %% OTP 20. Other uninteresting forms such as {eof, _} and {warning, _}. + %% Exposed because sys_pre_expand is no longer run. + S. + clauses(Cls, S) -> #xrefr{funvars = FunVars, matches = Matches} = S, @@ -109,6 +112,8 @@ clauses([{clause, _Line, _H, G, B} | Cs], FunVars, Matches, S) -> clauses([], _FunVars, _Matches, S) -> S. +attr(NotList, Ln, M, Fun, AL, AX, B, S) when not is_list(NotList) -> + attr([NotList], Ln, M, Fun, AL, AX, B, S); attr([E={From, To} | As], Ln, M, Fun, AL, AX, B, S) -> case mfa(From, M) of {_, _, MFA} when MFA =:= Fun; [] =:= Fun -> @@ -154,6 +159,15 @@ expr({'try',_Line,Es,Scs,Ccs,As}, S) -> S2 = clauses(Scs, S1), S3 = clauses(Ccs, S2), expr(As, S3); +expr({'fun', Line, {function,M,F,A}}, S) + when is_atom(M), is_atom(F), is_integer(A) -> + %% This is the old format for external funs, generated by a pre-R15 + %% compiler. Exposed in OTP 20 because sys_pre_expand is no longer + %% run. + Fun = {'fun', Line, {function, {atom,Line,M}, + {atom,Line,F}, + {integer,Line,A}}}, + expr(Fun, S); expr({'fun', Line, {function, {atom,_,Mod}, {atom,_,Name}, {integer,_,Arity}}}, S) -> @@ -168,14 +182,21 @@ expr({'fun', Line, {function, Mod, Name, _Arity}}, S) -> %% New format in R15. M:F/A (one or more variables). As = {var, Line, '_'}, external_call(erlang, apply, [Mod, Name, As], Line, true, S); +%% Only abstract_v1 and abstract_v2. expr({'fun', Line, {function, Name, Arity}, _Extra}, S) -> %% Added in R8. handle_call(local, S#xrefr.module, Name, Arity, Line, S); expr({'fun', _Line, {clauses, Cs}, _Extra}, S) -> clauses(Cs, S); -expr({named_fun, _Line, '_', Cs, _Extra}, S) -> +%% End abstract_v1 and abstract_v2. +expr({'fun', Line, {function, Name, Arity}}, S) -> + %% Added in OTP 20. + handle_call(local, S#xrefr.module, Name, Arity, Line, S); +expr({'fun', _Line, {clauses, Cs}}, S) -> + clauses(Cs, S); +expr({named_fun, _Line, '_', Cs}, S) -> clauses(Cs, S); -expr({named_fun, _Line, Name, Cs, _Extra}, S) -> +expr({named_fun, _Line, Name, Cs}, S) -> S1 = S#xrefr{funvars = [Name | S#xrefr.funvars]}, clauses(Cs, S1); expr({call, Line, {atom, _, Name}, As}, S) -> @@ -193,7 +214,12 @@ expr({match, _Line, {var,_,Var}, {'fun', _, {clauses, Cs}, _Extra}}, S) -> %% that are passed around by the "expansion" of list comprehension. S1 = S#xrefr{funvars = [Var | S#xrefr.funvars]}, clauses(Cs, S1); -expr({match, _Line, {var,_,Var}, {named_fun, _, _, _, _} = Fun}, S) -> +expr({match, _Line, {var,_,Var}, {'fun', _, {clauses, Cs}}}, S) -> + %% OTP 20. Exposed because sys_pre_expand is no longer run. + S1 = S#xrefr{funvars = [Var | S#xrefr.funvars]}, + clauses(Cs, S1); +expr({match, _Line, {var,_,Var}, {named_fun, _, _, _} = Fun}, S) -> + %% OTP 20. Exposed because sys_pre_expand is no longer run. S1 = S#xrefr{funvars = [Var | S#xrefr.funvars]}, expr(Fun, S1); expr({match, _Line, {var,_,Var}, E}, S) -> @@ -295,10 +321,17 @@ check_funarg(W, ArgsList, Line, S) -> expr(ArgsList, S1). funarg({'fun', _, _Clauses, _Extra}, _S) -> true; +funarg({'fun', _, {clauses, _}}, _S) -> + %% OTP 20. sys_pre_expand not run. + true; +funarg({'fun', _, {function, _, _}}, _S) -> + %% OTP 20. sys_pre_expand not run. + true; funarg({'fun', _, {function,_,_,_}}, _S) -> %% New abstract format for fun M:F/A in R15. true; -funarg({named_fun, _, _, _, _}, _S) -> +funarg({named_fun, _, _, _}, _S) -> + %% OTP 20. sys_pre_expand not run. true; funarg({var, _, Var}, S) -> member(Var, S#xrefr.funvars); funarg(_, _S) -> false. |