27.20.1 Writing a Refactoring Script
Below there is a thoroughly commented example script to illustrate the XML syntax used by the scripting engine.
XML header and DTD specification on the first lines.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE refactor-script PUBLIC "-//DVT//refactor-script" "refactor-script.dtd" >
Start of refactoring script content. The script name is displayed in visual controls.
<refactor-script version="1" name="My refactoring script">
You can specify
exceptions, i.e. paths that will not be affected by the refactoring. Paths are absolute or relative to the project root. You can specify both files and folders. For a folder, all files in it and in all its subfolders will be skipped.
<exception kind="path" path="skipme"/>
It is advised to exclude sensitive project configuration files, for example:
<exception kind="path" path=".project"/>
Actual refactoring directives are called
items. There are several kinds of items, differentiated by the
action they perform.
When writing a script, one must be careful not to have item collisions: situations when the same piece of text is modified by more than one item. Here are examples that illustrate all the actions currently available in DVT.
replace-in-text: perform plain textual search & replace for all the text files in the project like source files, scripts etc. Note that the search string is case sensitive.
<item action="replace-in-text"
search="ovm"
replacement="uvm" />
replace-in-file-name and
replace-in-dir-name: perform plain textual search & replace in the names of all files/folders within the project.
<item action="replace-in-file-name"
search="ovm" replacement="uvm" />
<item action="replace-in-dir-name"
search="ovm"
replacement="uvm" />
rename all occurrences of the specified element (declaration and usages).
The
element-full-name uniquely identifies a SystemVerilog language element, and should be specified as follows:
<item action="rename"
element-full-name="`my_macro"
newname="`my_macro_new_name"/>
for types, modules, methods, etc., the name of the element, preceded by the names of its enclosing elements, including the package (if it's the case)
<item action="rename"
element-full-name="my_pkg::my_class"
newname="my_class_new_name"/>
Note that the
newname is just the name of the element. Here are some more examples:
<item action="rename"
element-full-name="my_library.my_module.my_task"
newname="my_task_new_name"/>
<item action="rename"
element-full-name="outer_class.inner_class.my_function"
newname="my_function_new_name"
comment="XXX: API change. Function renamed from my_function to my_function_new_name."/>
In the last example,
outer_class is not inside any package (it's in the global scope).
Also, you can optionally specify a comment that will be inserted on the line above the occurence. If the comment contains a
Task Tag (like
TODO,
FIXME,
XXX or a custom defined one), after refactoring is completed you can use the
Tasks View to inspect action items or notes automatically added by the refactoring.
add-comment: to each occurrence of the specified element. The comment will be inserted on the line above the occurrence.
<item action="add-comment"
element-full-name="my_type.foo"
comment="FIXME: function removed from my_type API"/>
You can also specify whether you want to add comments only to the element
declaration or only to its
usages:
<item action="add-comment"
apply-to="declaration"
comment=" @deprecated API"
element-full-name="my_class.deprecated_function" />
For
add-comment items you can specify a set of elements that shall be affected by the refactoring (instead of specifying a single element via
element-full-name) using a declaration comment pattern matcher and optionally a path matcher:
<item action="add-comment"
comment=" FIXME: usage of deprecated ${element-signature}"
apply-to="usages"
element-comment-matches="*@deprecated*"
element-path-matches="*/my_vip/*"/>
You can also use the
element-comment-matches-not to invert the logic of the matcher.
Both
element-comment-matches and
element-path-matches perform simple pattern matching, that is * for any character sequence and ? for any character.
You can use
${element-signature} in the comment, as shown in the example above: it shall be replaced with the element signature, as seen for example in tooltips.
Finally, the script closing tag.
To see a larger example, you can simply start the
OVM to UVM Migration wizard and inspect the script behind it (there is an
Inspect button on the right side of the first wizard page).
Tip:
Right-click in the XML editor >
Validate to early detect syntax problems (requires the DTD specification line in the xml header).
Tip: Use
Ctrl+Space to invoke
autocomplete in the XML editor for tag and attribute names (requires the DTD specification line in the xml header).