Copyright © 2006-2009 Huiqing Li, Simon Thompson
Version: 0.8.2
Authors: Huiqing Li, Simon Thompson [web site: http://www.cs.kent.ac.uk/projects/wrangler].
| add_a_tag/6 | Add a tag to all the messages received by a server process (Beta). |
| duplicated_code_in_buffer/4 | An identical code detector that searches for identical code within the current Erlang buffer. |
| duplicated_code_in_dirs/4 | An identical code detector that searches for identical code across multiple Erlang modules. |
| 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 (Beta). |
| generalise/6 | Generalise a function definition. |
| identical_expression_search/4 | Search for expressions/expression sequences that are identical to the expression/expression sequence selected after consistent renaming of variables and literal substitution. |
| move_fun/6 | 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. |
| normalise_record_expr/6 | Reorder the record fields in a record expression to be consistent with the record definition. |
| register_pid/6 | Register a process (Beta). |
| rename_fun/6 | Rename a function. |
| rename_mod/4 | Rename a module. |
| rename_process/6 | Rename a registered process (Beta). |
| rename_var/6 | Rename a variable. |
| similar_code_detection/6 | A similar code detector that searches for similar code across multiple Erlang modules. |
| similar_code_detection_in_buffer/6 | A similar code detector that searches for similar code in the current Erlang buffer. |
| similar_expression_search/6 | Search for expression/expression sequences in the current buffer that are similar to the expression/expression sequence selected by the user. |
| tuple_funpar/5 | Group a consecutive sequence of parameters of a function into a tuple. |
| unfold_fun_app/4 | Unfold a function application to an instance of the function's body. |
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 (Beta).
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::string(), MinClones::string(), TabWidth::integer()) -> {ok, string()}
An identical code detector that searches for identical code within 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 identical code detector reports clones that are syntactically identical after consistent renaming of variables, except for variations in literals, layout and comments.
Usage: simply select Detect Identical Code in Current Buffer from Refactor, Wrangler will prompt to input the parameters.
duplicated_code_in_dirs(FileNameList::[filename() | dir()], MinToks::string(), MinClones::string(), TabWidth::integer()) -> {ok, string()}
An identical code detector that searches for identical code across 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 specified 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 Identical Code in Dirs from Refactor, Wrangler will then prompt to input the parameters.
fold_against_macro(FileName::filename(), Line::integer(), Col::integer(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {ok, [{{{integer(), integer()}, {integer(), integer()}}, syntaxTree()}]}
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.
Usage: 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 Refactor, 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 (Beta).
This refactoring turns a function into a server process. 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(add, X, Y) -> f_rpc(f, {add, X, Y});
f(sub, X, Y) -> X - Y. f(sub, X, Y) -> f_rpc(f, {sub, X, Y}).
g(X, Y) -> f() ->
f(add, X, Y)*f(sub, X, Y). receive
{From, {add, X, Y}} -> From ! {f, X + Y}, f();
{From, {sub, X, Y}} -> From ! {f, X - Y}, f()
end.
f_rpc(RegName, Request) ->
Sender = self(),
Fun = fun () ->
try
register(RegName, self())
of
true -> Sender ! {started, self()}, f()
catch
error:_ ->
Sender ! {already_running, self()},
already_running
end
end,
Pid = spawn(Fun),
receive {_, Pid} -> ok end,
RegName ! {self(), Request},
receive {RegName, Response} -> Response end.
g(X, Y) ->
f(add, X, Y) *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.
Usage: To apply this refactoring, point the cursor to the function of interest, then select From Function to Process from Refactor, 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.
NOTE: in Erlang some literal expressions can not be replaced by variables. For example, the atomfields
in the experssion record_info(fields, Record) should not be replaced by a variable or other expressions.
This kind of checking is NOT supported by Wrangler yet.
identical_expression_search(FileName::filename(), Start::pos(), End::pos(), TabWidth::integer()) -> {ok, [{integer(), integer(), integer(), integer()}]} | {error, string()}
Search for expressions/expression sequences that are identical to the expression/expression sequence selected after consistent renaming of variables and literal substitution.
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 Indentical Expression Search from Refactor.move_fun(FileName::filename(), Line::integer(), Col::integer(), TargetFileModName::string(), 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 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.
Usage: Highlight the expression of interest, then selected the Introduce a Macro from Refactor, Wrangler will then prompt for the new macro name.
normalise_record_expr(FileName::filename(), Line::integer(), Col::integer(), ShowDefault::bool(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {ok, [filename()]}
Reorder the record fields in a record expression to be consistent with the record definition.
Usage: point cursor to the record expression interested, then select Normalise Record Expression from Refactor.
register_pid(Filename::filename(), Start::pos(), End::pos(), RegName::string(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {ok, [filename()]}
Register a process (Beta).
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.
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()} | {question, string()} | {warning, string()} | {ok, [filename()]}
Rename a module.
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_process(FileName::filename(), Line::integer(), Col::integer(), NewName::string(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {undecidables, string()} | {ok, [filename()]}
Rename a registered process (Beta).
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:
Usage: 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.
rename_var(FileName::filename(), Line::integer(), Col::integer(), NewName::string(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {ok, string()}
Rename a variable.
This refactoring has a local effect, i.e., it only affects the function clause in which the refactoring is initialized.
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 Refactor , after that, Wrangler will prompt to enter the new variable name in the mini-buffer.
similar_code_detection(DirFileList::[filename() | dir()], MinLen::string(), MinFreq::string(), MinScore::string(), SearchPaths::[dir()], TabWidth::integer()) -> {ok, string()}
A similar code detector that searches for similar code across multiple Erlang modules.
This function reports similar expression sequences found in the directories specified, but does not remove those clones though. The algorithm is based on the notion of anti-unification, or the least common generalisation. The user needs to provide three parameters to be used by the clone detector, and they are: the minimum length of an expression sequence, the minimum number of duplication times, and a similarity score which should be between 0.1 and 1.0.
Usage: select Detect Similar Code in Dirs from Refactor, Wrangler will then prompt to input the parameters needed.
similar_code_detection_in_buffer(FileName::filename(), MinLen::string(), MinFreq::string(), MinScore::string(), SearchPaths::[dir()], TabWidth::integer()) -> {ok, string()}
A similar code detector that searches for similar code in the current Erlang buffer.
This function reports similar expression sequences found in the current Erlang buffer, but does not remove those clones though. The user needs to provide three parameters to be used by the clone detector, and they are: the minimum length of an expression sequence, the minimum number of duplication times, and a similarity score which should be between 0.1 and 1.0.
Usage: select Detect Similar Code in Buffer from Refactor, Wrangler will then prompt to input the parameters needed.
similar_expression_search(FileName::filename(), Start::pos(), End::pos(), SimiScore::string(), SearchPaths::[dir()], TabWidth::integer()) -> {ok, [{integer(), integer(), integer(), integer()}]} | {error, string()}
Search for expression/expression sequences in the current buffer that are similar to the expression/expression sequence selected by the user.
This functionality allows searching for expression sequence that are similar to the expression sequence selected. In this context, two expressions, A and B say, are similar if there exists an anti-unifier, say C, of A and B, and C satisfies the similarity score specified by the user (the calculation calculated of similarity score is going to be further explored).
Usage: highlight the expression sequence of interest, then selected Similar Expression Search from Refactor.tuple_funpar(FileName::filename(), StartLoc::pos(), EndLoc::pos(), SearchPaths::[dir()], TabWidth::integer()) -> {error, string()} | {ok, [filename()]}
Group a consecutive sequence of parameters of a function into a tuple.
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, highlight the arguments to be grouped into a tuple from the function definition, then select Tuple Function Arguments from Refactor.
unfold_fun_app(FileName::filename(), Pos::pos(), SearchPaths::[dir()], TabWidth::integer) -> {error, string()} | {ok, [string()]}
Unfold a function application to an instance of the function's body.
This refactoring replaces a function application with an instance of the function body. With the current implementation, Wrangler unfolds a function application only if the function is defined in the same module, and Wrangler could work out which function clause to use (in case the function definition contains multiple function clauses).
Usage: Point the cursor to the function name in the function application to unfold, then select Unfold Function Application from Refactor.
Generated by EDoc, Oct 30 2009, 16:18:31.