<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Keiho Sakapon</title>
    <description>The latest articles on DEV Community by Keiho Sakapon (@saka_pon).</description>
    <link>https://dev.to/saka_pon</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F44737%2F24db749d-cc50-4202-a9d7-643edc9241b1.jpeg</url>
      <title>DEV Community: Keiho Sakapon</title>
      <link>https://dev.to/saka_pon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/saka_pon"/>
    <language>en</language>
    <item>
      <title>Build your own debugger using Roslyn's syntax analysis</title>
      <dc:creator>Keiho Sakapon</dc:creator>
      <pubDate>Mon, 14 Jan 2019 11:15:36 +0000</pubDate>
      <link>https://dev.to/saka_pon/build-your-own-debugger-using-roslyns-syntax-analysis-1p44</link>
      <guid>https://dev.to/saka_pon/build-your-own-debugger-using-roslyns-syntax-analysis-1p44</guid>
      <description>&lt;p&gt;// This is the 23rd article of &lt;a href="https://qiita.com/advent-calendar/2018/c-sharp" rel="noopener noreferrer"&gt;C# Advent Calendar 2018 in Japan&lt;/a&gt;.&lt;br&gt;
// The original article is &lt;a href="https://sakapon.wordpress.com/2018/12/23/syntax-tree-debugger/" rel="noopener noreferrer"&gt;Roslyn の構文解析を使ってデバッガーを自作する&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I tried to make something like a debugger.&lt;/p&gt;
&lt;h3&gt;
  
  
  Motivation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I normally use Visual Studio, but it is troublesome to step through code manually at debugging

&lt;ul&gt;
&lt;li&gt;When the number of steps is large in a loop or the like&lt;/li&gt;
&lt;li&gt;When I want to check the state of branching or variables lightly&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Specify only the time interval of the step and let the debugger run automatically

&lt;ul&gt;
&lt;li&gt;A list of variables is displayed&lt;/li&gt;
&lt;li&gt;Time interval can be adjusted in real time&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Using the syntax analysis of .NET Compiler Platform (Roslyn), it seems to be realizable if we insert debugging code between each step&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Result
&lt;/h3&gt;

&lt;p&gt;So, as a result of trying to make prototype "Tick-tack Debugger" with WPF, it looked like this.&lt;br&gt;
As an example, we are figuring out a square root by the Newton's method.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6uegq2wnmo4rdre179ux.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6uegq2wnmo4rdre179ux.gif"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Commentary
&lt;/h3&gt;

&lt;p&gt;The following is an outline technical explanation.&lt;br&gt;
Before creating a WPF application, first try a console application on the .NET Framework.&lt;br&gt;
To use C# syntax analysis, install &lt;a href="https://www.nuget.org/packages/Microsoft.CodeAnalysis.CSharp" rel="noopener noreferrer"&gt;Microsoft.CodeAnalysis.CSharp&lt;/a&gt; via NuGet.&lt;/p&gt;

&lt;p&gt;It is a policy to insert debugging code into the source code to be debugged, compile it dynamically and execute it.&lt;br&gt;
The source code of the console application is shown below (the whole solution is in &lt;a href="https://github.com/sakapon/Samples-2018/tree/master/SyntaxTreeSample" rel="noopener noreferrer"&gt;SyntaxTreeSample&lt;/a&gt;).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In the SyntaxHelper class, C# source code to be debugged is converted to a syntax tree and scanned, and a line of code for debugging is inserted before each statement.&lt;/p&gt;

&lt;p&gt;By using the &lt;code&gt;CSharpSyntaxTree.ParseText&lt;/code&gt; method, you can convert the source code to a SyntaxTree object.&lt;br&gt;
Also, the superclass representing all nodes, such as methods, statements and expressions, is the SyntaxNode class,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parent property&lt;/li&gt;
&lt;li&gt;Ancestors method&lt;/li&gt;
&lt;li&gt;ChildNodes method&lt;/li&gt;
&lt;li&gt;DescendantNodes method&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;if you know these members, you can scan nodes.&lt;/p&gt;

&lt;p&gt;In addition to this, DebuggerLib is created as a class library that defines methods called from code for debugging.&lt;br&gt;
Let this library go through to notify the position of each statement and, the variables and their values that exist immediately before it.&lt;/p&gt;

&lt;p&gt;In the Program class, after saving the generated debugging source code to a file, compile it using CodeDomProvider in the System.CodeDom.Compiler namespace, and call its entry point (the Main method).&lt;br&gt;
It also registers the event handler when the debug code is executed, and pauses the program for the specified time using the &lt;code&gt;Thread.Sleep&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Now, if the original source code to be debugged is Program.cs below, the following Program.g.cs is generated as the debugging source code.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;When we run the console application we created, it will look like the following figure (the time interval is 0.3 seconds).&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr402fs87e6yr0b5qub8q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr402fs87e6yr0b5qub8q.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Based on the above, we created a debugging tool as a WPF application.&lt;br&gt;
The part of the C# source code on the left is a TextBox and can be edited.&lt;br&gt;
When debugging is executed, highlighting is done by setting each statement to the selected state.&lt;br&gt;
The part where the variable list is displayed on the right is a DataGrid.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjph4sizifcqov6cspz8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjph4sizifcqov6cspz8.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(An example of figuring out the pi)&lt;/p&gt;

&lt;p&gt;This time I tried to make a prototype by the above method, but I think that there is a smarter way to insert debug code and compile.&lt;/p&gt;

&lt;h3&gt;
  
  
  Remarks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;We can not deal with all possible statements. Also, we only scan the Main method.&lt;/li&gt;
&lt;li&gt;The assemblies generated at compile time (EXE) are saved in the &lt;code&gt;%TEMP%&lt;/code&gt; folder (user's &lt;code&gt;AppData\Local\Temp&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;In the TextBox, setting IsInactiveSelectionHighlightEnabled to True may not work. In addition, highlights in the selected state may slip. It might be better to use Run etc in RichTextBox.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Samples Created
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/sakapon/Samples-2018/tree/master/SyntaxTreeSample" rel="noopener noreferrer"&gt;SyntaxTreeSample (GitHub)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Version
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;.NET Framework 4.7&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.nuget.org/packages/Microsoft.CodeAnalysis.CSharp" rel="noopener noreferrer"&gt;Microsoft.CodeAnalysis.CSharp&lt;/a&gt; 2.10.0&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.nuget.org/packages/ReactiveProperty/" rel="noopener noreferrer"&gt;ReactiveProperty&lt;/a&gt; 5.3.2&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/" rel="noopener noreferrer"&gt;.NET Compiler Platform SDK (Roslyn API)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>csharp</category>
      <category>roslyn</category>
      <category>wpf</category>
      <category>debugging</category>
    </item>
  </channel>
</rss>
