{"id":7533,"date":"2021-10-28T18:09:28","date_gmt":"2021-10-29T01:09:28","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=7533"},"modified":"2021-11-05T18:01:42","modified_gmt":"2021-11-06T01:01:42","slug":"using-refactorscript-to-generate-boilerplate-code","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/intellisense\/refactorscript\/","title":{"rendered":"Using RefactorScript to Generate Boilerplate Code"},"content":{"rendered":"<p>This tutorial shows how to use <a href=\"https:\/\/visualgdb.com\/documentation\/refactorscript\/\">RefactorScript<\/a> to automatically generate boilerplate code &#8211; repetitive code constructs, such as initialization of all class fields, or printing of their values to a stream.<\/p>\n<p>We will create a simple C++ program that reads rows from a CSV file, sorts them, and outputs the results to stdout. We will manually create a class representing a row and will use RefactorScript to generate the constructor, comparison operator, and the code for printing the field values.<\/p>\n<p>Before you begin, install VisualGDB 5.6 or later and make sure you are using the Custom edition or higher.<\/p>\n<ol>\n<li>Start Visual Studio and launch the VisualGDB Linux Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/01-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7534\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/01-newprj.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Enter the name and location for your project: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/02-demo.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7535\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/02-demo.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Press the &#8220;Create&#8221; button to launch VisualGDB-specific part of the wizard. In this tutorial we will create a new Linux application using the Advanced CMake project subsystem, however RefactorScript will work for any project type that is using Clang IntelliSense: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/03-cmake.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7536\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/03-cmake.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>On the second page of the wizard select the computer and the toolchain that should be used for building the code: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/04-target.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7537\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/04-target.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Finally, select how VisualGDB should manage the source files for this project. In this tutorial we will keep them on the Windows side and will upload the changes remotely on each build, however you can also configure VisualGDB to access them directly via SSH:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/05-sources.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7538\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/05-sources.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Press &#8220;Finish&#8221; to create the project. Once it is created, replace the contents of the main file with the following code:\n<pre class=\"\">#include &lt;iostream&gt;\r\n#include &lt;vector&gt;\r\n#include &lt;string&gt;\r\n#include &lt;fstream&gt;\r\n#include &lt;sstream&gt;\r\n\r\nusing namespace std;\r\n\r\nvector&lt;int&gt; ReadCSVLine(istream&amp; str)\r\n{\r\n    vector&lt;int&gt; result;\r\n    string line;\r\n    getline(str, line);\r\n\r\n    stringstream lineStream(line);\r\n    string tmp;\r\n\r\n    while (getline(lineStream, tmp, ';'))\r\n        result.push_back(atoi(tmp.c_str()));\r\n\r\n    return move(result);\r\n}\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n    ifstream stream(\"data.csv\");\r\n\r\n    while (!stream.eof())\r\n    {\r\n        auto line = ReadCSVLine(stream);\r\n        asm(\"nop\");\r\n    }\r\n\r\n    return 0;\r\n}<\/pre>\n<\/li>\n<li>Add the following <strong>data.csv<\/strong> file to your project directory on the Windows machine:\n<pre class=\"\">3;10;100\r\n3;20;200\r\n2;30;300\r\n1;40;400<\/pre>\n<p>Then, use VisualGDB Project Properties to create the following upload action:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/upload.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7560\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/upload.png\" alt=\"\" width=\"1229\" height=\"708\" \/><\/a>This will upload <strong>data.csv<\/strong> to the target directory before debugging the project.<\/li>\n<li>Set a breakpoint in the <strong>asm(&#8220;nop&#8221;)<\/strong> line and make sure the first line of the file was read successfully:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/06-bkpt.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7539\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/06-bkpt.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>Now we will define a class encapsulating a single data row. Add the following code to the main source file:\n<pre class=\"\">struct DataRow\r\n{\r\n    int Col1, Col2, Col3;\r\n};<\/pre>\n<p>Also, add a vector of the <strong>DataRow<\/strong> objects to the main function and update the main loop to add items to it:<\/p>\n<pre class=\"\">std::vector&lt;DataRow&gt; rows;\r\n\r\nwhile (!stream.eof())\r\n{\r\n    auto line = ReadCSVLine(stream);\r\n    if (line.size() &gt;= 3)\r\n        rows.push_back(DataRow(line[0], line[1], line[2]));\r\n}<\/pre>\n<\/li>\n<li>This code will not work because <strong>DataRow<\/strong> is missing a constructor accepting 3 arguments. We will now use RefactorScript to generate it automatically. Go inside the <strong>DataRow<\/strong> struct (make sure the cursor is aligned with the &#8220;int&#8221; word) and press &#8220;Ctrl+.&#8221;. Then, select &#8220;<strong>Run a RefactorScript&#8230; -&gt; Generate a constructor<\/strong>&#8220;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/07-generate.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7540\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/07-generate.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><strong>Note: RefactorScript smart tags are supported starting from Visual Studio 2015. You can run RefactorScript on earlier Visual Studio versions via a button in <a href=\"https:\/\/visualgdb.com\/documentation\/codeexplorer\/outline\/\">Code Explorer<\/a>.<\/strong><\/li>\n<li>VisualGDB will open the <a href=\"https:\/\/visualgdb.com\/documentation\/refactorscript\/#window\">RefactorScript window<\/a> showing the current context (<strong>struct DataRow<\/strong>) and the currently selected script:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/08-script.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7541\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/08-script.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a>In this example, the script will work out-of-the-box, generating a constructor. You could also tweak every aspect of the generated code (e.g. decide which parameters to pass by reference) by editing the script. See the <a href=\"https:\/\/visualgdb.com\/documentation\/refactorscript\/language\/\">RefactorScript reference<\/a> for a comprehensive description of the RefactorScript language. We will also show a simple custom RefactorScript at the end of this tutorial.<\/li>\n<li>Press &#8220;Insert into code&#8221; to automatically insert the generated constructor. The code will now work as expected, producing a vector of <strong>DataRow<\/strong> instances:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/09-rows.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7542\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/09-rows.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>Now we will try sorting the rows. Add the following line to the <strong>main()<\/strong> function after the loop:\n<pre class=\"\">std::sort(rows.begin(), rows.end());<\/pre>\n<p>Note that it will result in a build error because <strong>DataRow<\/strong> does not have a comparison operator:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/10-error.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7543\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/10-error.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>We will now generate one automatically using RefactorScript. Go back to the DataRow struct, press &#8220;Ctrl+.&#8221; and select the &#8220;Generate comparison operators&#8221; script:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/11-comparison.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7544\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/11-comparison.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>This script will also work out-of-the-box . Note that you can select which operators to generate using the &#8220;script arguments&#8221; section at the top right of the window:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/12-generate-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7561\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/12-generate-1.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>Press <strong>Ctrl-Enter<\/strong> to insert the generated operator in the code. The project will now compile and work as expected: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/13-generated.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7546\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/13-generated.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>Finally, we will show how to create a simple RefactorScript from scratch. Add the following code to the end of the <strong>main()<\/strong> function:\n<pre class=\"\">for (const auto &amp;row : rows)\r\n    cout &lt;&lt; row;<\/pre>\n<p>As before, it will not not compile due to the missing &#8220;&lt;&lt;&#8221; operator:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/nomatch-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7563\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/nomatch-1.png\" alt=\"\" width=\"1301\" height=\"765\" \/><\/a><\/li>\n<li>To fix the error, add an empty operator before the <strong>main()<\/strong> function:\n<pre class=\"\">template&lt;class _Traits&gt; inline basic_ostream&lt;char, _Traits&gt;&amp; \r\n    operator&lt;&lt;(basic_ostream&lt;char, _Traits&gt;&amp; stream, const DataRow &amp;row)\r\n{\r\n    return stream;\r\n}<\/pre>\n<p>The code will now build, but won&#8217;t output anything yet:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/15-dumper.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7548\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/15-dumper.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>Make sure &#8220;DataRow&#8221; is selected in the Code Explorer and click the &#8220;<strong>Run a RefactorScript<\/strong>&#8221; button:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/16-script-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7564\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/16-script-1.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>Select any of the existing scripts and click &#8220;Save as&#8221;. Then, pick a new name for your script. In this tutorial, we will call it &#8220;<strong>GenerateOutputOperator.refscript<\/strong>&#8220;: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/17-output.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7550\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/17-output.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>Replace the contents of the script with the following code:\n<pre class=\"\">[Main]\r\ngenerator GenerateOutputOperator(Record class)\r\n{\r\n&gt;template&lt;class _Traits&gt; inline basic_ostream&lt;char, _Traits&gt;&amp; \r\n&gt;    operator&lt;&lt;(basic_ostream&lt;char, _Traits&gt;&amp; stream, const DataRow &amp;row)\r\n&gt;{\r\n&gt;    return stream;\r\n&gt;}\r\n}<\/pre>\n<p>It consists of a single <a href=\"https:\/\/visualgdb.com\/documentation\/refactorscript\/language\/#functions\">generator<\/a> that accepts an instance of the <a href=\"https:\/\/visualgdb.com\/documentation\/refactorscript\/datamodel\/#Record\">Record<\/a> object and <a href=\"https:\/\/visualgdb.com\/documentation\/refactorscript\/language\/#output\">outputs<\/a> a fixed block of code. The &#8220;Result&#8221; section at the bottom of the window will confirm that it matches the manually created operator: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/18-step1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7551\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/18-step1.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>We will now modify the script to use the real class name instead of hardcoding &#8220;<strong>DataRow<\/strong>&#8220;. Replace &#8220;<strong>DataRow<\/strong>&#8221; with &#8220;<strong>$class.ShortName<\/strong>&#8221; note how the RefactorScript window suggests &#8220;<strong>ShortName<\/strong>&#8221; from the context:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/19-short.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7552\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/19-short.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>Once you have replaced it, the Result section will immediately reflect this: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/20-generated.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7553\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/20-generated.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>Add the following lines inside the main generator:\n<pre class=\"\">&gt;\tstream &lt;&lt; \"[\";\r\n\tforeach(field in class.Fields)\r\n\t{\r\n\t\t\/\/TODO: dump every field\r\n\t}\r\n&gt;\tstream &lt;&lt; \"]\" &lt;&lt; endl;\r\n&gt;\treturn stream;<\/pre>\n<p>Make sure the script still runs without errors:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/21-step2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7554\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/21-step2.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>All we need to do now is to output each field of the class is to add another &#8220;&gt;&#8221; line inside the foreach block:\n<pre class=\"\">&gt;\tstream &lt;&lt; \"$field.ShortName = \" &lt;&lt; row.$field.ShortName<\/pre>\n<p>The line will be automatically repeated for each field of the class:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/22-expanded.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7555\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/22-expanded.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>To improve readability, we can print &#8221; ,&#8221; after each field except the last one:\n<pre class=\"\">if (!field.IsLast)\r\n\t&gt; stream &lt;&lt; \", \"<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/23-commas.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7556\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/23-commas.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>One last thing we can do is move the &#8220;, &#8221; part on the same line as the field output. To do this, replace the &#8220;&gt;&#8221;\u00a0 in the 2 lines within the <strong>foreach()<\/strong> loop with &#8220;&gt;&gt;&#8221;. This will suppress the end-of-line character after them. Add another line at the end of the loop to actually output the semicolon and end of line:\n<pre class=\"\">&gt;;<\/pre>\n<p>Now the generated operator contains everything needed to display the field values:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/24-final.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7557\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/24-final.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>Press &#8220;Copy and close&#8221; and insert the generated operator in the code. The sorting and outputting of rows will now work as expected:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/25-sorted.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7558\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/25-sorted.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<li>You can tweak every aspect of the generated code by checking numerous <a href=\"https:\/\/visualgdb.com\/documentation\/refactorscript\/datamodel\/\">properties<\/a> of the RefactorScript objects. E.g., you may want to skip static fields, add NULL pointer checks, or output field types along with their values. Use the right side of the RefactorScript window to explore the properties of the objects passed to the script:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/26-info.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7559\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/10\/26-info.png\" alt=\"\" width=\"1343\" height=\"855\" \/><\/a><\/li>\n<\/ol>\n<p>You can find the code shown in this tutorial in our <a href=\"https:\/\/github.com\/sysprogs\/tutorials\/tree\/master\/visualgdb\/Linux\/BasicRefactorScriptDemo\">tutorial repository on GitHub<\/a>.<\/p>\n<p>A detailed list of RefactorScripts shipped with VisualGDB, along with sample inputs and outputs is available <a href=\"https:\/\/visualgdb.com\/reference\/refactorscripts\/\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use RefactorScript to automatically generate boilerplate code &#8211; repetitive code constructs, such as initialization of<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[134],"tags":[52,238],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7533"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=7533"}],"version-history":[{"count":4,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7533\/revisions"}],"predecessor-version":[{"id":7693,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7533\/revisions\/7693"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=7533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=7533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=7533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}