Refactoring Erlang Programs
Refactoring Erlang Programs
Huiqing Li
Simon Thompson
28/02/08 1
Outline
Refactoring
Erlang/OTP
Available Erlang Frontends/Tools
Implementing Renaming a Variable name
The Erlang Refactorer Interface
Demo
Future work
28/02/08 2
Refactoring
Changing the structure of existing code
without changing its meaning.
A refactoring tool automating the refactoring
process should
preserve the program’s behaviour.
preserve the program’s layout as much as
possible.
28/02/08 3
The Erlang Language and
Erlang/OTP
Erlang: a strict, dynamically typed functional
programming language with support for
concurrency, communication, distribution, and
faulttolerance.
Erlang/OTP
The Erlang language.
Application and libraries.
A set of design principles for Erlang programs.
28/02/08 4
Erlang Vs. Haskell 98
Non explicit type signature.
All named functions are toplevel functions.
No partial application.
Simpler module interface.
Layout insensitive.
Simpler comment rules.
Message passing.
Marco directives.
Design Principles.
28/02/08 5
Available Erlang Frontends/Tools
Stdlib
Lexer
discards layout and comment information.
Tokens = [{atom(), Line} |
| {atom(), Line, term()}]
28/02/08 6
Available Erlang Frontends/Tools
Stdlib
Parser
Converts tokens into the abstract form of either
forms (i.e., toplevel constructs), expressions,
or terms.
e.g.
parse_form(Tokens) >
{ok, AbsForm} | {error, ErrorInfo}
28/02/08 7
Available Erlang Frontends/Tools
Stdlib
Parser
No binding information in the “parse tree”.
No layout and comment information.
Traversing the parse tree needs lots of
boilerplate code.
28/02/08 8
Available Erlang Frontends/Tools
Erlang Syntax tools (by Richard Carlsson).
A package contains modules for handling
abstract Erlang syntax trees, in a way that is
compatible with the “parse trees“.
Utilities for reading source files and pretty
printing syntax trees.
Module merger and renamer called Igor, as
well as an automatic codecleaner.
28/02/08 9
Available Erlang Frontends/Tools
Modules in Erlang Syntax tools.
erl_syntax
Defines an abstract data type for representing
Erlang source code as syntax trees, in a way
that is backwards compatible with the “parse
tree”.
Deals with the composition and decomposition
of syntactic entities (as opposed to semantic
ones).
28/02/08 10
Available Erlang Frontends/Tools
Modules in Erlang Syntax tools.
erl_syntax
Some data types:
record(com, {pre = [], post = []}).
record(attr, {pos = 0, ann = [], com = none}).
record(wrapper, {type, attr = #attr{}, tree}).
28/02/08 11
Available Erlang Frontends/Tools
Modules in Erlang Syntax tools.
erl_syntax_lib
contains utility functions, such as free and
declared variable analysis and some generic
abstract syntax tree traversal functions, for
working with the abstract data type defined in
the module erl_syntax.
28/02/08 12
Available Erlang Frontends/Tools
Modules in Erlang Syntax tools.
erl_comment_scan
Functions for reading comment lines from
Erlang source code.
erl_recomment
Functions for inserting comments, described by
position, indentation and text, as attachments
on an abstract syntax tree, at the correct
places.
28/02/08 13
Available Erlang Frontends/Tools
Modules in Erlang Syntax tools.
erl_prettypr
Pretty printing of abstract Erlang syntax trees.
erl_doger
Tokenises and parses most Erlang source code
without expanding preprocessor directives and
macro applications.
28/02/08 14
Available Erlang Frontends/Tools
Modules in Erlang Syntax tools.
erl_tidy
Tidies and prettyprints Erlang source code, removing
unused functions, updating obsolete constructs and
function calls, etc.
erl_igor
Merges the source code of one or more Erlang modules
into a single module, which can then replace the original
set of modules; renames a set of modules, without joining
them into a single module.
28/02/08 15
Available Erlang Frontends/Tools
Dialyzer: a tool that identifies some software
defects such as type errors, unreachable
code, redundant tests, etc. using compiler
and static analysis techniques.
TypEr: a type annotator of Erlang Code using
constraintbased type inference technique.
28/02/08 16
Build the Refactoring Tool on Top
of Erlang Syntax Tools
First Attempt:
Added location information (in terms of line
and column number) to the abstract syntax
tree.
Added binding information (in terms of
defining and use locations) to the variables
in the abstract syntax tree.
28/02/08 17
Renaming a Variable
rename(Node, {Pos, NewName}) >
stop_tdTP(fun do_rename/2, Node, {Pos, NewName}).
do_rename (Node,{Pos, NewName}) >
case erl_syntax:type(Node) of
variable > case erl_syntax:get_pos(Node) of
{_, Pos} >
{erl_syntax:set_name(Node, NewName), true};
_ > {Node, false}
end;
_ > {Node, false}
end.
28/02/08 18
Renaming a Variable (cont.)
stop_tdTP (Fun, Tree, Others) >
case Fun (Tree, Others) of
{Tree1, true} > Tree1;
{Tree1, false} >
case erl_syntax:subtrees(Tree1) of
[] > Tree1;
Gs > Gs1 = [[stop_tdTP (Fun, T, Others) || T < G] || G < Gs],
Tree2 = erl_syntax:make_tree
(erl_syntax:type(Tree1), Gs1),
erl_syntax:copy_attrs(Tree1, Tree2)
end
end.
28/02/08 19
The Erlang Refactorer
Program source
Scanner/Parser
Parse Tree
Syntax tools
Abstract syntax tree (AST) with comments
Program analysis and transformation
by the refactorer
Transformed AST
Pretty printer
Program source
28/02/08 20
Interface
The “official” development environment for
Erlang is Emacs.
There is a Erlang mode for Emacs.
Distel: an Emacsbased user interface toolkit for
Erlang.
28/02/08 21
Distel
A set of Emacsbased programs for interacting
with running Erlang nodes.
Allows to write Emacs Lisp processes and have
them communicate with normal Erlang
processes in real nodes.
Makes it easy to write conventional Emacs user
interfaces to Erlang programs.
28/02/08 22
The Erlang Refactorer
DEMO
28/02/08 23
Future Work
More refactorings.
Renaming function name.
Introduce a new definition.
From nontail recursive to tailrecursive
function.
Separating functional part from nonfunctional
part.
Verification of refactorings.
28/02/08 24