GenerateAssignmentOperator.refscript

This page describes the GenerateAssignmentOperator RefactorScript shipped with VisualGDB.

Overview

This script iterates over all the fields of a class and generates assignment operators (const reference and rvalue).
You can use it by selecting a class in Code Explorer -> Outline, or via Smart Tags in the code editor.

You can easily customize the script by saving it under %LOCALAPPDATA% via the "Save As" button and changing the parts listed below:
1. The 'inline' argument determines whether to an inline constructor vs. a separate declaration and implementation.
2. The ShouldMoveType() function determines whether to wrap that field with "std::move"

Script


[Main, Description("Generate '=' operator"), SuggestFor(Record)]
generator GenerateAssignmentOperator(Record class,
                                     bool inline = true,
                                     bool isMove = false)
{
    if (inline)
        DoGenerateAssignmentOperator(class, false, false, isMove);
    else
    {
        DoGenerateAssignmentOperator(class, true, false, isMove);
>    
        DoGenerateAssignmentOperator(class, false, true, isMove);
    }
}

generator DoGenerateAssignmentOperator(Record class,
                                       bool declarationOnly,
                                       bool qualifyName,
                                       bool isMove)
{
    set argName = "another";

    if (qualifyName)
>>$class.QualifiedName &$class.QualifiedName::operator=(
    else
>>$class.ShortName &operator=(

    if (isMove)
>>$class.ShortName &&$argName
    else
>>const $class.ShortName &$argName

    if (declarationOnly)
    {
>);
        return;
    }

>)
>{
    foreach(decl in class.NonStaticFields)
    {
        set init = MakeFieldReference(decl, argName, isMove);
>    $decl.ShortName = $init;
    }

>
>    return *this;
>}
}

function ShouldMoveType(TypeRef type)
{
    if (type.Resolved.IsPointerOrReference)
        return false;

    return true;
}

function MakeFieldReference(Field decl, string argName, bool isMove)
{
    set ref = argName + "." + decl.ShortName;
    if (isMove && ShouldMoveType(decl.Type))
        set ref = "std::move(" + ref + ")";
    return ref;
}

generator MakeInitializerList(Array decls, string argName, bool isMove)
{
    foreach(decl in decls)
    {
        if (decl.IsFirst)
>>        :
        else
>>        ,

    set init = MakeFieldReference(decl, argName, isMove);
> $decl.ShortName($init)
    }
}

Sample Input

class SimpleClass
{
public:
    int IntField;
    void *PointerField;
};

Sample Output

SimpleClass &operator=(SimpleClass &&another)
{
    IntField = std::move(another.IntField);
    PointerField = another.PointerField;

    return *this;
}
A detailed reference on RefactorScript syntax and data model is available here.
See this page for a full list of RefactorScripts shipped with VisualGDB.