Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Roslyn generate source code from an object instance?

Using the Roslyn API with Visual Studio 2015, can I convert an object instance to source code? Can I create an extension method like ".ToSourceCode()" as shown below?

class Foo { }
class Program
{
    static string classSourceCode = "class Foo { }";
    static void Main()
    {
        var instance = new Foo();
        var instanceSourceCode = instance.GetType().ToSourceCode();
        System.Diagnostics.Debug.Assert(instanceSourceCode == classSourceCode);
    }
}
like image 710
Robin Avatar asked Apr 10 '15 17:04

Robin


People also ask

What are source code generators?

A Source Generator is a . NET Standard 2.0 assembly that is loaded by the compiler along with any analyzers. It's usable in environments where . NET Standard components can be loaded and run.

What is source code C#?

C# Tutorial and source code C# (pronounced C sharp) is a programming language designed for building a wide range of enterprise applications that run on the . NET Framework. The goal of C# is to provide a simple, safe, modern, object-oriented, highperformance , robust and durable language for . NET development.

How do I install Roslyn?

To install Roslyn compilers without installing Visual Studio, you need to download and install Microsoft Build Tools. Roslyn can also be downloaded from Github, then you can compile and get binary files csc.exe and vbc.exe, which can be accessed from the command line.


1 Answers

No. However, ILSpy can.

Based on the comments on the question and what I understand about Roslyn, decompilation is not supported. However, thanks to @Bradley's ILSpy tip, there is a solution:

  1. Download the ILSpy binaries from http://ilspy.net/
  2. Reference the following assemblies: ICSharpCode.Decompiler.dll, ILSpy.exe, Mono.Cecil.dll, ILSpy.BamlDecompiler.Plugin.dll
  3. Implement the ".ToSourceCode()" extension method as shown below:
using System;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy;
using Mono.Cecil;
class Foo { }
class Program
{
    static string classSourceCode = "using System; internal class Foo { } ";
    static void Main()
    {
        var instance = new Foo();
        var instanceSourceCode = instance.GetType().ToSourceCode();
        System.Diagnostics.Debug.Assert(instanceSourceCode == classSourceCode);
    }
}

static class TypeExtensions
{
    public static string ToSourceCode(this Type source)
    {
        var assembly = AssemblyDefinition.ReadAssembly(Assembly.GetExecutingAssembly().Location);
        var type = assembly.MainModule.Types.FirstOrDefault(t => t.FullName == source.FullName);
        if (type == null) return string.Empty;
        var plainTextOutput = new PlainTextOutput();
        var decompiler = new CSharpLanguage();
        decompiler.DecompileType(type, plainTextOutput, new DecompilationOptions());
        return Regex.Replace(Regex.Replace(plainTextOutput.ToString(), @"\n|\r", " "), @"\s+", " ");
    }
}
like image 79
Robin Avatar answered Sep 23 '22 05:09

Robin