Copyright © 2006-2009 Huiqing Li, Simon Thompson
Version: 0.7
Authors: Huiqing Li, Simon Thompson [web site: http://www.cs.kent.ac.uk/projects/forse].
| add_a_tag/6 | Add a tag to all the messages received by a server process. |
| duplicated_code_in_buffer/4 | A duplicated code detector that only works with the current Erlang buffer. |
| duplicated_code_in_dirs/4 | A duplicated code detector that works with multiple Erlang modules. |
| expression_search/4 | Search for clones of an expression/expression sequence selected in the current file. |
| fold_against_macro/5 | Fold expressions/patterns against a macro definition. |
| fold_expr/1 | Fold expressions against a function definition. |
| fun_extraction/5 | Introduce a new function to represent an expression or expression sequence. |
| fun_to_process/6 | Turn a function into a server process. |
| generalise/6 | Generalise a function definition. |
| move_fun/7 | Move a function definition from its current module to another. |
| new_macro/6 | Introduce a macro to represent a syntactically well-formed expression/pattern or a sequence of expressions/patterns. |
| register_pid/6 | Register a process. |
| rename_fun/6 | Rename a function with a new name supplied by the user. |
| rename_mod/4 | Rename a module with a new name supplied by the user. |
| rename_mod_batch/4 | Rename a collection of modules in batch mode. |
| rename_process/6 | Rename a registered process with a new name supplied by the user. |
| rename_var/6 | Rename a variable with a new name supplied by the user. |
| tuple_funpar/6 | Turn some consecutive parameters of a function into a tuple parameter. |
| tuple_to_record/9 | From tuple to record representation. |
add_a_tag(Filename::filename(), Line::integer(), Col::integer(), Tag::string(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {ok, [filename()]}
Add a tag to all the messages received by a server process.
This refactoring should be initiated from the main receive function of a server process. The current implementation is still in an experimental stage, and has a number of limitations:
send ... receive pattern, to other processes
spawn
or spawn_link
Usage: to apply this refactoring, point the cursor to the function name, then select Add a Tag to Messages from the Refactor menu, Wrangler will then prompt to enter the tag.
duplicated_code_in_buffer(FileName::filename(), MinToks::integer(), MinClones::integer(), TabWidth::integer()) -> {ok, string()}
A duplicated code detector that only works with the current Erlang buffer.
This function reports duplicated code fragments found in the current Erlang buffer, it does not remove those code clones though. The user will be prompted for two parameters: the minimum number of tokens a cloned code fragment should have, and the minimum number of times a code fragment appears in the program.
The current version of the duplicated code detector reports clones that are syntactically identical after consistent renaming of variables, except for variations in literals, layout and comments.
Usage: simply select the Detect Duplicated Code in Current Buffer from the Refactor sub-menu, Wrangler will prompt to input the parameters.
duplicated_code_in_dirs(FileNameList::[filename() | dir()], MinToks::string(), MinClones::string(), TabWidth::integer()) -> {ok, string()}
A duplicated code detector that works with multiple Erlang modules.
This function reports duplicated code fragments found in the directories specified by SearchPaths, it does not remove those code clones though. The user will be prompted for two parameters: the minimum number of tokens that a cloned code fragment should have, and the minimum number of times a code fragment appears in the program.
The current version of the duplicated code detector reports clones that are syntactically identical after consistent renaming of variables, except for variations in literals, layout and comments.
Usage: first check the SearchPaths specificed in the customisation page to make sure that the directory (or directories) specified is the place where you want to search for duplicated code, then select Detect Duplicated Code in Dirs from the Refactor sub-menu, Wrangler will then prompt to input the parameters.
expression_search(FileName::filename(), Start::Pos, End::Pos, TabWidth::integer()) -> {ok, [{integer(), integer(), integer(), integer()}]} | {error, string()}
Search for clones of an expression/expression sequence selected in the current file.
This functionality allows searching for clones of a selected expression or expression sequence. The found clones are syntactically identical to the code fragment selected after consistent renaming of variables, except for variations in literals, layout and comments.
When the selected code contains multiple, but non-continuous sequence of, expressions, the first continuous sequence of expressions is taken as the user-selected expression. A continuous sequence of expressions is a sequence of expressions separated by ','.
Usage: highlight the expression/expression sequence of interest, then selected Expression Search from the Refactor sub-menu.fold_against_macro(FileName, Line, Col, SearchPaths, TabWidth) -> any()
Fold expressions/patterns against a macro definition.
This refactoring replaces instances of the right-hand side of a macro definition by the corresponding left-hand side with necessary parameter substitutions.
To apply this refactoring, first point the cursor to the macro definition against which candidate expressions/candidates will be folded; then select Fold Against Macro Definition from the Refactor menu; after that, Wrangler will search the current module for expressions/patterns which are instances of the right-hand side of the selected macro definition; and direct you through the refactoring process.
fold_expr(X1::{{FileName::filename(), Line::integer(), Col::integer(), SearchPaths::[dir()], TabWidth::integer()} | {FileName::filename(), ModName::modulename(), Arity::integer(), ClauseIndex::integer(), SearchPaths::[dir()], TabWidth::integer()}}) -> {ok, [{{{integer(), integer()}, {integer(), integer()}}, syntaxTree()}]} | {error, string()}
Fold expressions against a function definition.
This refactoring replaces instances of the right-hand side of a function clause definition by the corresponding left-hand side with necessary parameter substitutions. The function clause can be defined in either the current module or another module.
In the case that a candidate expression/expression sequence needs to export some variables which are used by the code following code, that expression/expression sequence will be replaced by a match expression, whose left-hand side it the exported variable(s), and right-hand side is the function application.
This refactoring does not support folding against function clauses with guard expressions, or function clauses with complex formal parameters, such as tuples, lists, or records.
Usage: first point the cursor to the function clause against which expressions will be folded if the function is defined in the current module, or leave the cursor anywhere if you would like to fold against a function clause defined in another module; then select Fold Expression Against Function from the Refactor menu; after that, Wrangler then asks to confirm that you want to fold against the function clause pointed to by the cursor, if you answer 'no', Wrangler will prompt to provide the module name, function name ,arity of the function and the index of the function clause (starting from 1). After all these initial interaction, Wrangler will search the current module for expressions which are instances of the right-hand side of the selected function clause.
If no candidate expression has been found, a message will be given, and the refactoring finishes; otherwise, Wrangler will go through the found candidate expressions one by one, and ask the user whether she/he wants to replace the expression with an application of selected function. If the user answers 'yes' to one instance, that instance will be replaced by function application, otherwise it will remain unchanged.
fun_extraction(FileName::filename(), Start::Pos, End::Pos, FunName::string(), TabWidth::integer()) -> {error, string()} | {ok, string()}
Introduce a new function to represent an expression or expression sequence.
This refactoring allows the user to introduce a new function to represent a selected expression or expression sequence, and replace the selected code with a call to the new function. Free variables within the selected code become the formal parameters of the function definition.
Usage: highlight the expression/expression sequence of interest, then selected the Function Extraction from the Refactor sub-menu, Wrangler will then prompt for the new function name.
fun_to_process(FileName::filename(), Line::integer(), Col::integer(), ProcessName::string(), SearchPaths::[dir()], TabWidth::integer()) -> {ok, [filename()]} | {error, string()}
Turn a function into a server process.
This refactoring turns a function into a server process, and all the function calls to this function into process communication. Turning a function into a server process provides potential for memorisation of calculated values, adding states to the process, etc.
The following example shows the application of this refactoring to the function f/2 on the
left-hand side, and the result is shown on the right-hand side.
f(add,X,Y) -> X +Y; f_rpc(RegName, Request) ->
f(sub,X,Y) -> X - Y. Fun = fun() ->
try
g(X, Y) -> register(RegName, self())
f(add, X,Y)*f(sub, X, Y). catch
true -> f();
error:_ -> already_running
end
end,
Spawn(Fun),
RegName ! {self(), Request},
receive {RegName, Response} -> Response end.
f() ->
receive
{From, {add, X, Y}} -> From ! {f, X + Y}, f();
{From, {sub, X, Y}} -> From ! {f, X - Y}, f()
end.
g(X, Y) ->
f_rpc(f, {add, X, Y}) * f_rpc(f, {sub, X, Y}).
The following side-conditions apply to this refactoring:
Pid returned by self().
Wrangler generates the new function name and the rpc function name automatically, but the user could always rename it afterwards.
Suppose the original function is f/n, then the new function name would be f/0 and the rpc
function name would be f_rpc/2; if any conflicts occur, '_i' will be attached to the end of the function
name where i is a smallest number that makes the name fresh.
To apply this refactoring, point the cursor to the function of interest, then select From Function to Process from the Refactor sub-menu, after that, Wrangler will prompt to enter the process registration name in the mini-buffer.
generalise(FileName::filename(), Start::Pos, End::Pos, ParName::string(), SearchPaths::[dir()], TabWidth::integer()) -> {ok, string()} | {error, string()}
Generalise a function definition.
Generalise a function definition by selecting a sub-expression of its right-hand side and making this the value of a new argument added to the definition of the function. The sub-expression becomes the actual parameter at the call sites.
Here is an example of generalisation, in which the function add_one defined
on the left-hand side is generalised on the expression 1 , and the result is
shown on the right-hand side.
-module (test). -module (test).
-export([f/1]). -export([f/1]).
add_one ([H|T]) -> add_one (N, [H|T]) ->
[H+1 | add_one(T)]; [H+N | add_one(N,T)];
add_one ([]) -> []. add_one (N, []) -> [].
f(X) -> add_one(X). f(X) -> add_one(1,X)
In the case that the selected expression has a side-effect, the refactorer will wrap this expression
in an function expression before passing it as the actual parameter to the call-sites. This is illustrated
in the following example, in which function repeat/1 is generalised on the expression
io:format("Hello\n").
-module (test). -module (test).
-export([f/0]). -export([f/0]).
repeat(0) -> ok; repeat(A, 0) -> ok;
repeat(N) -> repeat(A, N) ->
io:format("Hello\n"), A( ),
repeat(N-1). repeat(A,N-1).
f() -> repeat(5). f( ) ->
repeat (fun( )->io:format ("Hello\n") end, 5).
This refactoring only affects the module in which the refactoring is initialised. In the case that the generalised function is exported by the module, an auxiliary function will be created to wrap the generalised function up, so that the module's interface is not changed.
The following side-conditions apply to this refactoring:
foo/n , then foo/n+1 should not
be in scope before the generalisation;Usage: to apply this refactoring, highlight the expression first, then select Generalise Function Definition from the Refactor menu, after that the refactorer will prompt to enter the parameter name in the mini-buffer.
move_fun(FileName::filename(), Line::integer(), Col::integer(), TargetModName::string(), CreateNewFile::boolean(), SearchPaths::[dir()], TabWidth::integer()) -> {ok, [filename()]} | {error, string()}
Move a function definition from its current module to another.
This refactoring has a global effect, i.e., it affects all the modules in which the function is imported/used.
This refactoring assumes that an Erlang module name always matches its file name.
Suppose we move function foo/n from its current module M to module N , then the following side-conditions apply to this refactoring:
Usage: to apply this refactoring, point the cursor at the function definition, then select Move Definition to Another Module from the Refactor menu, Wrangler will then prompt to enter the target module name in the mini-buffer.
new_macro(FileName::filename(), Start::pos(), End::pos(), NewMacroName::string(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {ok, string()}
Introduce a macro to represent a syntactically well-formed expression/pattern or a sequence of expressions/patterns.
This refactoring allows the user to define a new macro to represent a expression/pattern or sequence of of expressions/patterns selected by the user, and replace the selected code with an application of the macro. Free variables within the selected code become the formal parameters of the macro definition.
register_pid(Filename::filename(), Start::pos(), End::pos(), RegName::string(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {ok, [filename()]}
Register a process.
This refactoring registers a process id, Pid say, with a name, regname say, and replaces
the uses of Pid ! Msg with regname ! Msg whenever it is possible.
The following side-conditions apply to this refactoring:
Usage: First select a match expression whose left-hand side is a process identifier, and right-hand side is a spawn expression, then select Register a Process command from the Refactor menu, after that, Wrangler will prompt for the process name.
rename_fun(FileName::filename(), Line::integer(), Col::integer(), NewName::string(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {ok, [filename()]}
Rename a function with a new name supplied by the user.
When renaming an exported function, this refactoring has a global effect, that is, it affects all those modules in which this function is imported/used.
The following side-conditions (or pre-conditions } apply to this refactoring:
Usage: to apply this refactoring, point the cursor to any occurrence of this function name, then select Rename Function Name from the Refactor menu, after that, Wrangler will prompt to enter the new function name in the mini-buffer.
rename_mod(FileName::filename(), NewName::string(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {ok, [filename()]}
Rename a module with a new name supplied by the user.
This refactoring affects all those modules in which the module name is used.
The following side-conditions apply to this refactoring:
Usage: to apply this refactoring, point the cursor anywhere in the module to be renamed, then select Rename Module Name from the Refactor menu, after that, the refactorer will prompt to enter the new module name in the mini-buffer.
rename_mod_batch(OldNamePattern::string(), NewNamePattern::string(), SearchPaths::[dir()], TabWidth::integer()) -> {ok, string()} | {error, string()}
Rename a collection of modules in batch mode.
This refactoring has a global effect.
The following side-conditions apply to this refactoring:
Usage: this refactoring is supposed to be run from the Erlang shell. For example,
to rename all those module names which match the regular expression "foo_*" to
"foo_*_1_0" in the directory c:/wrangler/test , just type the following command:
wrangler:rename_mod_batch("foo_*, "foo_*_1_0", ["c:/wrangler/test"]) .
rename_process(FileName::filename(), Line::integer(), Col::integer(), NewName::string(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {undecidables, string()} | {ok, [filename()]}
Rename a registered process with a new name supplied by the user.
To apply this refactoring, point the cursor to the process name, then select Rename a Process from the Refactor menu, after that, Wrangler will prompt to enter the new process name in the mini-buffer.
This refactoring has a global effect, i.e. it needs to check the whole program for places where the original process name is used.
The following side-conditions apply to this refactoring:
rename_var(FileName::filename(), Line::integer(), Col::integer(), NewName::string(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {ok, string()}
Rename a variable with a new name supplied by the user.
This refactoring has a local effect, i.e., it only affects the function clause in which the refactoring is initialised.
The following side-conditions (or pre-conditions) apply to this refactoring:
Usage: to apply this refactoring, point the cursor to any occurrence of this variable, then select Rename Variable Name from the Refactor sub-menu, after that, Wrangler will prompt to enter the new variable name in the mini-buffer.
tuple_funpar(FileName::filename(), Line::integer(), Col::integer(), Number::string(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {ok, [filename()]}
Turn some consecutive parameters of a function into a tuple parameter.
When the function under consideration is exported by the module where it is defined, this refactoring has a global effect.
Suppose the new function after refactoring is f/n, then the following side-conditions apply:
f/n should not cause confliction with any of the functions which are in scope in the
current module;f/n
should not be already in scope (either defined or imported) in that module. Usage: to apply this refactoring, point the cursor to the parameter which is going to be the first element of the tuple, then select Tuple Function Arguments from the Refactor sub-menu, after that, Wrangler will prompt to enter the number of parameters to include into the tuple in the minibuffer.
tuple_to_record(File::filename(), FLine::integer(), FCol::integer(), LLine::integer(), LCol::integer(), RecName::string(), FieldString::[string()], SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {ok, [filename()]}
From tuple to record representation. NOTE: this refactoring is still in an experimental stage.
This refactoring has a global effect, i.e., it affects all those modules in which this function is imported/used.
The following side-conditions apply to this refactoring:
To apply this refactoring, highlight the tuple, which should be a function parameter, then select From Tuple To Record from the Refactor sub-menu, Wrangler will then prompt to enter the record name and the record field names.
Generated by EDoc, Mar 19 2009, 13:06:01.