0

We are using Roslyn Compiler for generating a Dependency Graph for a given application code. The application code can span across multiple solutions and can have references between the solutions (ex. Service code in one solution, common business logic in another solution etc.)

For the purpose of generating the Dependency Graph, we would require fully-qualified name and exact path of all the custom types refereed (ones which we have created as our application code).

Roslyn happens to give this information using the SemanticModel's Symbol Information.

Scenario which works:

SemanticModel's Symbol Information gives the Location (path) and ContainingSymbol information for any Type if the type is declared in the same Solution (under some project) in which it is getting used.

Scenario which does not work:

If the refereed Type is not part of the current solution but is part of some other solution which is getting refereed in the existing solution, then the SemanticModel does not give any Symbol Information which can give the Path and Fully Qualified Name.

Note:

  1. We have already tried using the variants of GetSpeculativeSymbolInfo and GetSpeculativeTypeInfo. But it does not give any information. It just mentions that its a part of MetaData (as if we are using a Type from .NET Class Lib).
  2. Following link "Get fully-qualified metadata name in Roslyn" gives a direction; but the approach does not work in the context of cross solution references.
  3. Have refereed following link: "Roslyn: get the symbol for a type defined in a third-party library". But this is not working as well (or may be we are missing on some thing simple). We were trying to explore the option of using Compilation.GetTypeByMetadataName().

Looking forward to some pointers from the Experts.

EDIT: Further details

//Sample Code for Testing

public class TestClass
{
    Student student = new Student();
    Person person = new Person();
}

public class Student
{
    public string Name { get; set; }
}

Notes:

  1. TestClass is part of project Project_1 which is in Solution_1.
  2. TestClass has two members: Class Student is part of project Project_2 which is in Solution_1 and Project_1 has a Project Reference to Project_2.
    Class Person is part of project Project_XYZ which is in Solution_XYZ and Project1 from Solution_1 has a dll Reference to Project_XYZ from Solution Solution_XYZ.

The .dll of Project_XYZ is getting created at location "..\Projects\SourceCode\AllBinaries" and "Project_1" from Solution_1 refers the .dll of Project_XYZ from this location "..\Projects\SourceCode\AllBinaries"

Code for getting Symbol Information of the Type:

private void GetSymbolDetails(TypeSyntax typeSyntax)
{
    ISymbol symbol = semanticModel.GetSymbolInfo(typeSyntax).Symbol; 
   //HERE semanticModel = document.GetSemanticModelAsync().Result;
}

Scenario which works:
When the above code is called with input parameter as "IdentifierNameSyntax IdentifierName Student", the "symbol" gives all the required symbol details of "Student" (including fully-qualified name and exact path).

Scenario which does not work:
When the above code is called with input parameter as "IdentifierNameSyntax IdentifierName Person", the "symbol" value is null.

Hope I was able to give a better overview of my problem. Looking forward to further updates.

Community
  • 1
  • 1
  • What problems are you having? As long as you can resolve the metadata reference, symbols should work perfectly. – SLaks Sep 12 '16 at 15:55
  • Thanks for replying SLaks. Scenario which does not work: If the refereed Type is not part of the current solution but is part of some other solution which is getting refereed in the existing solution, then the SemanticModel does not give any Symbol Information which can give the Path and Fully Qualified Name. So we want a way in which we can get the fully-qualified name and file path of a Type which is declared in another solution and referred in the current code at hand. Please let me know if you require any other input. – Abhijit Parkhi Sep 13 '16 at 04:20
  • What exactly does `GetSymbolInfo()` return? Show us your code. **Every** symbol has a fully-qualified name. Symbols from metadata will not have a path. – SLaks Sep 13 '16 at 15:07
  • @AbhijitParkhi: you'll probably need to describe how you're getting your Compilations. Also, grab a compilation and call GetDiagnostics() to see if it's building correctly. My gut is telling me that something either in your environment or your code is causing references between compilations to get lost, so the compiler doesn't have symbols to work with. – Jason Malinowski Sep 17 '16 at 00:31
  • I had a similar problem, I solved it by generating a new solution file that contains all the projects, and use that. We also had to change references to dll files to references to the projects that generate those files in all projects. I don't have that code around right now though, sorry. – Kris Vandermotten Sep 17 '16 at 09:43
  • @KrisVandermotten, thanks for your valuable input. Initially we had thought of taking the same approach that you have suggested. But then we realized that the approach will have a major performance issue on following considerations: – Abhijit Parkhi Sep 20 '16 at 03:50
  • @KrisVandermotten: Normally for a Solution of about 1GB code(100 plus projects) the average time the code "MSBuildWorkspace.OpenSolutionAsync(solutionPath).Result" takes to load the solution is 52sec. For a real life scenario, clubbing projects from different solutions into one solution and then pening the Solution is going to take much higher time. It will be very helpful if you can share your experience on the performance consideration with the approach in context of the scenario i have mentioned above. Looking forward to hear from you. Thanks again for sparing your valuable time. – Abhijit Parkhi Sep 20 '16 at 04:08
  • Well, like I said I had a *similar* problem, not the same. In my case, my problem needed solving correctly. Doing that efficiently was, as always, a nice to have, but not required. Solving the problem correctly was the only requirement. And that necessitated the approach we took. Whether it does for you too, I leave that up to you to decide. – Kris Vandermotten Sep 20 '16 at 09:29
  • @JasonMalinowski, I have added more details to my problem statement. Please let me know if you need any more information. Looking forward to your responses. – Abhijit Parkhi Sep 21 '16 at 05:52
  • @SLaks, I have added more details to my problem statement. Please let me know if you need any more information. Looking forward to your responses – Abhijit Parkhi Sep 21 '16 at 05:53
  • It sounds like you're missing a metadata reference. – SLaks Sep 21 '16 at 15:08
  • @SLaks, sorry for coming late on this thread. I dint get you. Can you please elaborate on "missing a metadata reference" ? As i have mentioned it earlier, I am loading one solution using MSBuildWorkspac.OpenSolutionAsync() and then I am iterating through each Project of the solution and through project I am iterating through each Document object. In one of the Documents (Compilation Unit), I have a reference to a type which is defined in a completely different solution and refereed using a .dll reference . We want to resolve this Type along with its file path where it is defined. – Abhijit Parkhi Oct 13 '16 at 13:21
  • Roslyn probably couldn't resolve the reference to that DLL. Look at the diagnostics for the compilation, or look at the properties of the reference. – SLaks Oct 13 '16 at 14:06

0 Answers0