5

I'm trying to open RoslynLight.sln with OpenSolutionAsync then iterate through all the projects. For my purposes I need a semantic model and resolved references. Through a combination of this issue and this question, I've arrived at this partial solution:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.MSBuild;
using System.IO;

namespace OpenRoslyn
{
  class Program
  {
    static void Main(string[] args)
    {

      var msbw = MSBuildWorkspace.Create();
      var sln = msbw.OpenSolutionAsync(@"C:\Users\carr27\Documents\GitHub\roslyn\src\RoslynLight.sln").Result;
      //var proj = sln.Projects.First(x => x.Name == "CodeAnalysis.Desktop");
      var messages = new List<string>();
      foreach (var p in sln.Projects)
      {
        Console.WriteLine(p.FilePath);
        messages.Add(p.FilePath);
        var facadesDir = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\";
        var proj = p.AddMetadataReference(MetadataReference.CreateFromAssembly(typeof(object).Assembly));
        proj = proj.AddMetadataReference(MetadataReference.CreateFromFile(facadesDir + "System.Runtime.dll"));
        proj = proj.AddMetadataReference(MetadataReference.CreateFromFile(facadesDir + "System.Runtime.Extensions.dll"));
        proj = proj.AddMetadataReference(MetadataReference.CreateFromFile(facadesDir + "System.IO.dll"));
        proj = proj.AddMetadataReference(MetadataReference.CreateFromFile(facadesDir + "System.Threading.Tasks.dll"));
        proj = proj.AddMetadataReference(MetadataReference.CreateFromFile(facadesDir + "System.Text.Encoding.dll"));
        proj = proj.AddMetadataReference(MetadataReference.CreateFromFile(facadesDir + "System.Reflection.dll"));
        try
        {
          var cu = proj.GetCompilationAsync().Result;
          // here I would do useful work, but for know I just get diagnostics
          foreach (var e in cu.GetDiagnostics().Where(x => x.Severity == DiagnosticSeverity.Error))
          {
            Console.WriteLine("{0}: {1}", e.Location, e.GetMessage());
            messages.Add(String.Format("{0}: {1}", e.Location, e.GetMessage()));
          }
        }
        catch (AggregateException e)
        {
          foreach(var ie in e.InnerExceptions)
          {
            Console.WriteLine(ie.Message);
            messages.Add(ie.Message);
          }

        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            messages.Add(e.Message);
        }
      }
      File.WriteAllLines("log.txt", messages);
      Console.WriteLine("done.");
      Console.ReadKey();
    }
  }
}

The log for this program is too big for me to post, but the work around only works for certain projects. For example, rosyln\src\compilers\Core\Desktop\CodeAnalysis.Desktop.csproj has no errors, but roslyn\src\Compilers\CSharp\Portable\CSharpCodeAnalysis.csproj has:

None: Multiple assemblies with equivalent identity have been imported: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Threading.Tasks.dll' and 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\System.Threading.Tasks.dll'. Remove one of the duplicate references.
None: Multiple assemblies with equivalent identity have been imported: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Text.Encoding.dll' and 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\System.Text.Encoding.dll'. Remove one of the duplicate references.
None: Multiple assemblies with equivalent identity have been imported: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Runtime.Extensions.dll' and 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\System.Runtime.Extensions.dll'. Remove one of the duplicate references.
None: Multiple assemblies with equivalent identity have been imported: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Runtime.dll' and 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\System.Runtime.dll'. Remove one of the duplicate references.
None: Multiple assemblies with equivalent identity have been imported: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Reflection.dll' and 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\System.Reflection.dll'. Remove one of the duplicate references.
None: Multiple assemblies with equivalent identity have been imported: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.IO.dll' and 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\System.IO.dll'. Remove one of the duplicate references.
SourceFile(C:\Users\carr27\Documents\GitHub\roslyn\src\Compilers\CSharp\Portable\BoundTree\UnboundLambda.cs[9068..9109)): The type 'ConcurrentDictionary<TKey, TValue>' exists in both 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' and 'System.Collections.Concurrent, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
SourceFile(C:\Users\carr27\Documents\GitHub\roslyn\src\Compilers\CSharp\Portable\BoundTree\UnboundLambda.cs[9203..9250)): The type 'ConcurrentDictionary<TKey, TValue>' exists in both 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' and 'System.Collections.Concurrent, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

... and many others. It seems to me any way I could make this work for an arbitrary project/solution would be very hacky. Am I missing something?

Community
  • 1
  • 1
Scott Carr
  • 113
  • 1
  • 4

2 Answers2

4

I'm looking at fixing this in the MSBuild targets, but in the meantime, the following workaround should address the issue. Instead of using:

MSBuildWorkspace.Create();

use:

MSBuildWorkspace.Create(new Dictionary<string, string> { { "CheckForSystemRuntimeDependency", "true" } });
svick
  • 236,525
  • 50
  • 385
  • 514
Kevin Pilch
  • 11,485
  • 1
  • 39
  • 41
3

You only need to add the façade references if the project is targeting the "full" .NET framework. So if you look at the existing references first, if there are any references that come from Reference Assemblies\Microsoft.NETPortable\v4.5\Profile\... then you shouldn't need to add them.

Jason Malinowski
  • 18,148
  • 1
  • 38
  • 55
  • Thank you! Checking for missing references almost worked, but there is still (at least) one project with missing references (I think). When I open BasicCodeAnalysis.Desktop.vbproj I get a whole bunch of type errors: [gist](https://gist.github.com/scottcarr/cedcf98060159cdac418#file-gistfile1-txt) Any ideas? – Scott Carr Apr 02 '15 at 20:48
  • It seems l get a lot more errors for VB than C#. If I try to only open all the C# projects in RoslynLight.sln, I get a managable number of errors: https://gist.github.com/scottcarr/fdc07fad670be7006852#file-gistfile1-txt. The code is here:https://github.com/scottcarr/roslyn_repros – Scott Carr Apr 02 '15 at 21:28
  • Your VB errors would look like there's something that glitched with VB-to-C# project references. It looks like the VB side can't find stuff in our "shared" code that's written in C#. – Jason Malinowski Apr 03 '15 at 05:29
  • And as far as Roslyn.sln, vs. RoslynLight.sln, I think you might have to use the Light one since there have been breaking changes that you don't have a new VS drop for. – Jason Malinowski Apr 03 '15 at 05:29