dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19k stars 4.03k forks source link

Question : Is there anyway to convert a Type to SyntaxTree in .NET Core ? #17239

Closed HamedFathi closed 7 years ago

HamedFathi commented 7 years ago

suppose, I have Person Type (only type not source code). Can I get SyntaxTree of this type ?

for example SyntaxTree syntaxTree = CSharpSyntaxTree.ParseType(typeof(Person));

alrz commented 7 years ago

Compilation.GetTypeByMetadataName

I'm not on my machine to check, but I think there is also an extension to get a type syntax from type symbol.

HamedFathi commented 7 years ago

@alrz , Can you provide a snippet code for me ? I am not familiar with GetTypeByMetadataName. I need a working sample If you can.

svick commented 7 years ago

What should the returned SyntaxTree contain? Do you expect Roslyn to fully decompile the type? Because AFAIK, Roslyn does not contain a decompiler.

HamedFathi commented 7 years ago

Decompiler is so bigger than my need, of course you right this is task of a decompiler. Is there any way for convert a type to roslyn syntax tree?

Pilchie commented 7 years ago

@HamedFathi what are you trying to do? In general, there is no guarantee that you can ever get a SyntaxTree for a type - it may come from a metadata reference for example.

HamedFathi commented 7 years ago

@Pilchie suppose I have Poco assembly contains 'Student','Person',... I want to convert Person class or Student class to SyntaxTree convert object(Type) to SyntaxTree

typeof(Person) => SyntaxTree or Person => SyntaxTree

when we have a source code we can get SyntaxTree easily but How can I get SyntaxTree from a Type or Instance ?

CyrusNajmabadi commented 7 years ago

Are you asking for something that would decompile the type and generate the approximate source code that would have generated it?

I say "approximate" because there's no relation to a System.Type and a CSharpSyntaxTree. A System.Type could have come from many sources. C#, VB, F#, C++/CLI. Heck, it could have come from straight IL. Unless you provide more information, this seems like not a very clear request on your part.

HamedFathi commented 7 years ago

@CyrusNajmabadi @Pilchie , Why do you say no relation between a System.Type and a CSharpSyntaxTree ? suppose I use a template engine with a Type

typeof(Person)

with reflection I can create class template

public PropertyType Name {get;set;} // public Guid Id {get;set;} public PropertyType Name {get;set;} // public int No {get;set;} public PropertyType Name {get;set;} // public string Name {get;set;}

...

after create the source structure (with reflection on Type and a template engine) I can convert source string to SyntaxTree

now, Why can not we convert Type to SyntaxTree ?

CyrusNajmabadi commented 7 years ago

Why do you say no relation between a System.Type and a CSharpSyntaxTree

For the reasons i gave in my post :) The System.Type may not have come from a CSharpSyntaxTree. It may contain contents that might not even be expressible in C#.

after create the source structure (with reflection on Type and a template engine) I can convert source string to SyntaxTree

As i said, you can "generate the approximate source code". Technically Roslyn has some support for this. It's how we provide, for example, the go-to-definition support for Metadata-Types. However, it's very basic. For example, we don't produce syntax for member bodies.

CyrusNajmabadi commented 7 years ago

Here's a simple example: In IL you might have a member marked as "FamANDAssem". i.e. it's both "protected AND internal" not the standard C# "protected (OR) internal". How would you represent this code in a CSharpSyntaxTree?

HamedFathi commented 7 years ago

@CyrusNajmabadi , You right.

Technically Roslyn has some support for this

for example, the go-to-definition support for Metadata-Types.

The way might be enough for me Can you show me (a blog post, an article, a snippet code) How can I use roslyn for getting this approximate source code ?

thanks for your clarification

CyrusNajmabadi commented 7 years ago

SyntaxGenerator is the primary API for doing this sort of thing.

You can create a Roslyn CSharpCompilation instance that has the dlls you care about referenced inside of it. You can find the Roslyn symbol associated with the System.Type you care about by calling Compilation.GetTypeByMetadataName

You can then use this INamedTypeSymbol and the child symbols in it along with SyntaxGenerator to get this approximate source code generation.