This library provides the predicate replace/5, which is the basic entry point
for all the refactoring scenarios.
Note for implementors/hackers:
- Be careful with some variables, they use destructive assignment --
format("~a", [Atom]) does not behaves as
write_term(Atom, Options), since a
space is not added to separate operators from the next term, for instance
after rewriting :- dynamic a/1, you would get :- dynamica/1.
write('') is used to reset the effect of the
- replace(+Level, +Patt, -Into, :Expander, :Options) is det
- Given a Level of operation, in all terms of the source code that subsumes
Patt, replace each Patt with Into, provided that Expander succeeds.
Expander can be used to finalize the shape of Into as well as to veto the
expansion (if fails). The Options argument is used to control the behavior
and scope of the replacement.
The predicate is efficient enough to be used also as a walker to capture all
matches of Term, and failing to avoid the replacement. For example:
(refactor_message(information, format("~w", [X])), fail),
will display all the occurrences of use_module/1 declarations in the file
F. Would be useful for some complex refactoring scenarios.
The levels of operations stablishes where to look for matching terms, and
could take one of the following values:
Look for terms that match a given goal. This is implemented using the source
Look for sub-terms in a given read term recursivelly.
Look for a matching term
Look for matching clause heads
In a clause head, look for matching terms recursivelly
Look for a matching clause body
In a clause body, look for matching terms recursivelly
If level is sent, some special cases of Term are used to control its
Adds an extra sentence at the top of the file.
Adds an extra sentence at the bottom of the file.
Replace list of sentences
Print X but without the ending dot
The term Into could contain certain hacks to control its behavior, as
- X @@ Y
Print the term X with the surroundings of Y (comments, etc.). This is
useful to preserve comments in Y, if Y is going to dissapear in the
- X $@ Y
Print the term X following the format of Y.
Use write_term for X (this will ignore automatic formatting following the
- '$G'(Into, Goal)
Hook to execute Goal over the transformation generated by Into.
Just Ignore, but process X to get possible expected side effects (for
instance, '$G'/2 hacks).
- '$BODY'(X, Offset)
Print X as if it where the body of a clause, that is, by introducing a new
line per each conjunction and indentation starting at Offset position,
plus extra characters if required.
Like '$BODY'(X, 0)
- '$BODYB'(X, Offset)
Like '$BODY', but adding braces if required
Like '$BODYB'(X, 0)
- '$CLAUSE'(X, Offset)
Print X as if it where a clause, starting indentation at Offset position.
Like '$CLAUSE'(X, 0)
Print each element of L
- '$APP'(L1, L2)
Print the result of
append(L1, L2, L), but preserving the formats of L1 and L2
Note that if you use append/3 directly, the format of L1 will be lost
Print each element of L in a way similar to portray_clause
Print each element of L placing a comma between them
Print each element of L followed by a comma
Print each element of L followed by a comma and a new line If Level is
sent, the tool will add this automatically if the replacement is a list,
and in the case of an empty list, the sentence will be removed.
Print each element of L followed by a dot and a new line without clause
- '$TEXT'(T, N)
Write T with higest priority and no quoted, byasing N characters to the
like '$TEXT'(T, 0)
- '$TEXTQ'(T, N)
Like '$TEXT'(T, N) but quoted
like '$TEXTQ'(T, 0)
- '$POS'(Name, Term)
Preserves the current write position in Name, for further usage in hacks
that have Offset as argument
In an Offset expression, is replaced by the current write position.
is equivalent to:
'$POS'(my_outpos, '$TEXT'(T, my_outpos))
- '$SEEK'(T, O)
Seek 0 in the current output before to print T.
- '$TAB'(T, O)
Print as many spaces as needed to make O the current write position
Defined options are:
States that the replacement should be applied recursively, until no more
modifications are caused by the replacement.
Value=decreasing is the default, and means that the recursion stops if the
transformed term contains more terms that could potentially match to avoid
loops. If the level is a non recursive one (see level_rec/2), such value
is equivalent to none.
Value=file means that the recursion is performed over the hole file.
Value=term means that the recursion is performed over the transformed term.
Value=true means that the recursion is applied up to reach the fixpoint
without decreasing control. If Level is a non recursive one, the recursion
is performed over the hole file, otherwise the recursion is only applied
over the transformed term.
Value=none don't apply the fixpoint algorithm.
- decrease_metric(:Metric) is a predicate of arity 3 of the form
predicate(+Term, +Pattern, -Size) to define the metric used to perform the
decreasing control (by default pattern_size/3).