Monday, August 30, 2010

Using Visual Studio Macros for Code Generation

Visual Studio Macros are great for automating repetitive tasks and can be real time savers. One thing I esp. like to use them for is code generation.

For example, this macro generates the code for C# class properties (I actually prefer this to using automatic properties as I don't have to change the code later):

Sub CreateProperties()

    Dim textSelection As EnvDTE.TextSelection
    textSelection = CType(DTE.ActiveDocument.Selection(), EnvDTE.TextSelection)

    Dim outputText As String
    Dim regExpression As New Regex("\s*(static)*\s*(\S+)\s*([a-zA-Z0-9_]+)", RegexOptions.Compiled)
    For Each line As String In textSelection.Text.Split(New Char() {vbNewLine})
    Dim m As Match = regExpression.Match(line)
        If m.Success Then
            Dim staticModifier As String = m.Groups(1).Value
            Dim propertyDataType As String = m.Groups(2).Value
            Dim propertyName As String = m.Groups(3).Value.Substring(0, 1).ToLower() & m.Groups(3).Value.Remove(0, 1)
            outputText &= String.Format("private {4}{0} _{1};{3}public {4}{0} {2}{3}{{{3}get{3}{{{3}return _{1};{3}}}{3}}}{3}{3}", _
            propertyDataType, _
            propertyName, _
            propertyName.Substring(0, 1).ToUpper() & propertyName.Remove(0, 1), _
            Environment.NewLine, _
            IIf(staticModifier = "", "", staticModifier & " "))
        Else
            If Not Regex.IsMatch(line, "^\s*$") Then
                MsgBox("Input mismatch")
                Exit Sub
            End If
        End If
    Next

    textSelection.Insert(outputText, 0)
    textSelection.SmartFormat()

End Sub

To use this macro, you type the data type of the property and its name (you can also use the static modifier), like this:

int count
string name
string description
static int globalCount

Then, you select the code and run the macro (most conveniently, using a keyboard shortcut), to get this code:

private int _count;
public int Count
{
    get
    {
        return _count;
    }
}

private string _name;
public string Name
{
    get
    {
        return _name;
    }
}

private string _description;
public string Description
{
    get
    {
        return _description;
    }
}

private static int _globalCount;
public static int GlobalCount
{
    get
    {
        return _globalCount;
    }
}

This is only a very simple use of VS Macros to demonstrate how they can be used for code generation. They are very powerful and can do much more complex things. If you do a lot of coding, it's certainly worth the time to learn more about this very powerful, yet underused, feature of Visual Studio.

Happy coding!