RefactorScript Language Description

This page provides an overview of the RefactorScript language used by VisualGDB to define custom code generation patterns.

Contents

Overview
Output
Expression Substitution
Statements
set
foreach
if
Variables
Functions and Generators
Data Types
string
array
Main Generator Parameters
Attributes

Overview

The RefactorScript syntax is based on a simplified C# syntax. It is optimized for extremely fast execution, so you can typically preview the results of running your script directly as you type it.

Each RefactorScript must contain at least one generator – a function that generates output. The simplest syntax for a generator is shown below:

[Main]
generator DemoGenerator(Function func)
{
}

Note that the [Main] attribute marks the entry point of the RefactorScript and is only needed if the script contains multiple generators.

Output

Any line inside a generator that starts with “>” will be directly translated to an output line. E.g. the following generator will just produce the “//Hello, World” text:

generator DemoGenerator(Function func)
{
>//Hello, World
}

Lines starting with “>>” will be treated as incomplete (i.e. no newline will be inserted after them). E.g.:

generator DemoGenerator(Function func)
{
>>//Hello,
> World!
>//Hello, Script!
}

The generator above will produce the following output:

//Hello, World!
//Hello, Script!

Expression Substitution

The lines starting with “>” and “>>” can use the “$” syntax to refer to expressions based on the generator parameters. E.g. the following script will output the name of the function passed to it:

generator DemoGenerator(Function func)
{
>//Hello, $func.ShortName
}

The expressions can include multiple levels of fields, but cannot include function calls, e.g.:

Format Result
>Hello, $func.Arguments.First.ShortName
//Hello, argc
>Hello, $func.Arguments.First.ShortName.AddPrefix("m_")
Error
set tmp = func.Arguments.First.ShortName.AddPrefix("m_");
>//Hello, $tmp
//Hello, m_argc

The first input to the main generator always contains an object representing the C/C++ entity that was selected when running the script. It contains exhaustive information about fields, methods, variables, types, typedefs, etc. You can find a detailed reference of the RefactorScript data model here, or simply use the view on the right side of the RefactorScript window to explore it in real time:

Statements

RefactorScript statements are based on the C# statements. The following statements are supported:

  • set
  • foreach
  • if
  • else
  • break
  • continue
  • return

Unless otherwise noted, the syntax of the statements is the same as for the C/C++/C# languages. Individual statements are described below:

set

The set statement creates or updates a local variable. E.g.:

set tmp = 123;
>//tmp = $tmp;

foreach

The foreach statement iterates over all of the elements of an array. Note that each element will automatically have the IsFirst and IsLast fields set depending on their position in the array, e.g. to list all arguments of a function separated by “, ” use the following syntax:

foreach(arg in func.Arguments)
{
    >>$arg.ShortName
    if (!arg.IsLast)
        >>, 
}

E.g. for the typical main() function the script above will produce “argc, argv”.

if

The if() statement uses the same syntax as C/C++/C#. Note that each “>” and “>>” line counts as a individual statement. I.e. the two variants shown below are equivalent (and will produce the same output as the foreach() example above):

foreach(arg in func.Arguments)
{
    if (!arg.IsFirst)
	>>, 
    >>$arg.ShortName
}
foreach(arg in func.Arguments)
{
    if (!arg.IsFirst)
    {
	>>, 
    }
    >>$arg.ShortName
}

Variables

You can set local variables using the “set” operator as shown below”, e.g.:

foreach(arg in func.Arguments)
{
    set fieldName = arg.ShortName.UppercaseFirst().AddPrefix("m_");
    if (!arg.IsFirst)
	>>, 
    >>$fieldName
}

For a typical main() function the script above will output “m_Argc, m_Argv”.

Note that the “varName = <…>” expression without a “set” statement will result in an error.

Functions and Generators

You can define the auxiliary generators or functions called by the main generators via the generator and function keywords respectively. E.g. the code below is equivalent to the previous example:

function MakeFieldName(Variable arg)
{
	return arg.ShortName.UppercaseFirst().AddPrefix("m_");
}
 
generator OutputFieldList(Array vars)
{
	foreach(arg in vars)
	{
		set fieldName = MakeFieldName(arg);
		if (!arg.IsFirst)
			>>, 
		>>$fieldName
	}
}
 
[Main]
generator GenerateNullChecks(Function func)
{
	OutputFieldList(func.Arguments);
}

Note that each function argument must be declared with a type. See the next section for the list of supported types.

Data Types

RefactorScript supports 3 built-in data types (string, int, Array) and an alias (bool = int) that can be used to put constraints on function/generator arguments. Additionally to them, every object describing a C/C++ entity has an explicit type assigned to it. See the RefactorScript Data Model Documentation for the list of supported types. You can also view the object types (including all parent types) via the right side of the RefactorScript window:Note that most C/C++ entities inherit from the Entity type.

string

The string type represents a built-in string. It contains the following built-in functions:

Function Meaning
StripPrefix(string prefix) If the string starts with a given prefix (e.g. “m_”), returns the string without it. Otherwise, returns the original string.
AddPrefix(string prefix) Prepends a given prefix (e.g. “m_”) to the string.
UppercaseFirst() Converts the first character of a string to upper case.
UppercaseAll() Converts all characters of a string to upper case.
LowercaseFirst() Converts the first character of a string to lower case.
LowercaseAll() Converts all characters of a string to upper case.
Trim(string chars = ” \t\r\n”) Removes the specified characters from the beginning and end of the string
TrimStart(string chars = ” \t\r\n”) Removes the specified characters from the beginning of the string
TrimEnd(string chars = ” \t\r\n”) Removes the specified characters from the end of the string
Contains(string str) Returns 1 if the string contains the specified substring
StartsWidth(string str) Returns 1 if the string starts with the specified substring
EndsWith(string str) Returns 1 if the string ends with the specified substring
MatchesRegex(string regex) Returns 1 if the string matches the given regular expression

Array

The Array type represents an array (e.g. list of class fields). You can iterate arrays via the foreach() statement, or use the fields below:

IsEmpty Specifies whether an array is empty
Length Contains the number of elements in an array
First Points to the first element of the array
Last Points to the last element of the array

Main Generator Parameters

The main generator of a RefactorScript can contain more than 1 parameter. VisualGDB will automatically translate them into the controls in the right side of the RefactorScript window, so that you can tweak your script behavior without having to edit it each time:

Attributes

If your script contains a single generator only, VisualGDB will automatically launch it when running the script. If the script contains multiple generators, use the [Main] attribute to mark the main generator.

Additionally, if you provide the Description and SuggestFor attributes as shown below, VisualGDB will show the script as a smart suggestion in the code editor:

[Main, Description("Generate NULL checks"), SuggestFor(Function)]

You can use the following entity types in the SuggestFor attribute to control the contexts where the suggestion will appear:

  • Typedef
  • Enum
  • Record
  • Value
  • Variable
    • Field
    • FunctionArgument
  • Function