Resolving Assembly References in Roslyn

落爺英雄遲暮 提交于 2020-03-05 00:31:30

问题


I'm writing a metadata extractor for C# projects. It works by creating SyntaxTrees from source files via CSharpSyntaxTree.ParseText(), compiling them via CSharpCompilation.Create() and then analyzing symbols in the SemanticModel.

I'm running into an issue where various assembly references aren't being handled correctly.

I generate assembly references by parsing project.assets.json and extracting the compile-time package references (my test project doesn't include any project references). The targets section of project.assets.json looks like this:

"targets": {
".NETStandard,Version=v2.1": {
  "Autofac/5.1.2": {
    "type": "package",
    "compile": {
      "lib/netstandard2.1/Autofac.dll": {}
    },
    "runtime": {
      "lib/netstandard2.1/Autofac.dll": {}
    }
  },
  "Microsoft.NETCore.Platforms/1.1.0": {
    "type": "package",
    "compile": {
      "lib/netstandard1.0/_._": {}
    },
    "runtime": {
      "lib/netstandard1.0/_._": {}
    }
  },
  "Microsoft.NETCore.Targets/1.1.0": {
    "type": "package",
    "compile": {
      "lib/netstandard1.0/_._": {}
    },
    "runtime": {
      "lib/netstandard1.0/_._": {}
    }
  },
  "Serilog/2.9.0": {
    "type": "package",
    "compile": {
      "lib/netstandard2.0/Serilog.dll": {}
    },
    "runtime": {
      "lib/netstandard2.0/Serilog.dll": {}
    }
  },
  "Serilog.Sinks.Console/3.1.1": {
    "type": "package",
    "dependencies": {
      "Serilog": "2.5.0",
      "System.Console": "4.3.0"
    },
    "compile": {
      "lib/netstandard1.3/Serilog.Sinks.Console.dll": {}
    },
    "runtime": {
      "lib/netstandard1.3/Serilog.Sinks.Console.dll": {}
    }
  },
  "Serilog.Sinks.File/4.1.0": {
    "type": "package",
    "dependencies": {
      "Serilog": "2.5.0",
      "System.IO.FileSystem": "4.0.1",
      "System.Text.Encoding.Extensions": "4.0.11",
      "System.Threading.Timer": "4.0.1"
    },
    "compile": {
      "lib/netstandard2.0/Serilog.Sinks.File.dll": {}
    },
    "runtime": {
      "lib/netstandard2.0/Serilog.Sinks.File.dll": {}
    }
  },
  "System.Console/4.3.0": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.1.0",
      "Microsoft.NETCore.Targets": "1.1.0",
      "System.IO": "4.3.0",
      "System.Runtime": "4.3.0",
      "System.Text.Encoding": "4.3.0"
    },
    "compile": {
      "ref/netstandard1.3/System.Console.dll": {}
    }
  },
  "System.IO/4.3.0": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.1.0",
      "Microsoft.NETCore.Targets": "1.1.0",
      "System.Runtime": "4.3.0",
      "System.Text.Encoding": "4.3.0",
      "System.Threading.Tasks": "4.3.0"
    },
    "compile": {
      "ref/netstandard1.5/System.IO.dll": {}
    }
  },
  "System.IO.FileSystem/4.0.1": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.0.1",
      "Microsoft.NETCore.Targets": "1.0.1",
      "System.IO": "4.1.0",
      "System.IO.FileSystem.Primitives": "4.0.1",
      "System.Runtime": "4.1.0",
      "System.Runtime.Handles": "4.0.1",
      "System.Text.Encoding": "4.0.11",
      "System.Threading.Tasks": "4.0.11"
    },
    "compile": {
      "ref/netstandard1.3/System.IO.FileSystem.dll": {}
    }
  },
  "System.IO.FileSystem.Primitives/4.0.1": {
    "type": "package",
    "dependencies": {
      "System.Runtime": "4.1.0"
    },
    "compile": {
      "ref/netstandard1.3/System.IO.FileSystem.Primitives.dll": {}
    },
    "runtime": {
      "lib/netstandard1.3/System.IO.FileSystem.Primitives.dll": {}
    }
  },
  "System.Runtime/4.3.0": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.1.0",
      "Microsoft.NETCore.Targets": "1.1.0"
    },
    "compile": {
      "ref/netstandard1.5/System.Runtime.dll": {}
    }
  },
  "System.Runtime.Handles/4.0.1": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.0.1",
      "Microsoft.NETCore.Targets": "1.0.1",
      "System.Runtime": "4.1.0"
    },
    "compile": {
      "ref/netstandard1.3/System.Runtime.Handles.dll": {}
    }
  },
  "System.Text.Encoding/4.3.0": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.1.0",
      "Microsoft.NETCore.Targets": "1.1.0",
      "System.Runtime": "4.3.0"
    },
    "compile": {
      "ref/netstandard1.3/System.Text.Encoding.dll": {}
    }
  },
  "System.Text.Encoding.Extensions/4.0.11": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.0.1",
      "Microsoft.NETCore.Targets": "1.0.1",
      "System.Runtime": "4.1.0",
      "System.Text.Encoding": "4.0.11"
    },
    "compile": {
      "ref/netstandard1.3/System.Text.Encoding.Extensions.dll": {}
    }
  },
  "System.Threading.Tasks/4.3.0": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.1.0",
      "Microsoft.NETCore.Targets": "1.1.0",
      "System.Runtime": "4.3.0"
    },
    "compile": {
      "ref/netstandard1.3/System.Threading.Tasks.dll": {}
    }
  },
  "System.Threading.Timer/4.0.1": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.0.1",
      "Microsoft.NETCore.Targets": "1.0.1",
      "System.Runtime": "4.1.0"
    },
    "compile": {
      "ref/netstandard1.2/System.Threading.Timer.dll": {}
    }
  }
}
}

The resulting list of references is this:

lib/netstandard2.1/Autofac.dll
lib/netstandard1.0/_._
lib/netstandard1.0/_._
lib/netstandard2.0/Serilog.dll
lib/netstandard1.3/Serilog.Sinks.Console.dll
lib/netstandard2.0/Serilog.Sinks.File.dll
ref/netstandard1.3/System.Console.dll
ref/netstandard1.5/System.IO.dll
ref/netstandard1.3/System.IO.FileSystem.dll
ref/netstandard1.3/System.IO.FileSystem.Primitives.dll
ref/netstandard1.5/System.Runtime.dll
ref/netstandard1.3/System.Runtime.Handles.dll
ref/netstandard1.3/System.Text.Encoding.dll
ref/netstandard1.3/System.Text.Encoding.Extensions.dll
ref/netstandard1.3/System.Threading.Tasks.dll
ref/netstandard1.2/System.Threading.Timer.dll

I ignore the two oddly-formatted netstandard1.0 ones, replacing them with a reference created by MetadataReference.CreateFromFile( Assembly.Load( "netstandard" ).Location ) ), and resolve the remaining paths against the local nuget repositories, creating references from the dlls.

This mostly works fine...but certain things don't resolve. Here are the diagnostic messages I'm getting after compiling with CSharpCompilation.Create():

CS0103 - The name 'Assembly' does not exist in the current context

CS0103 - The name 'Path' does not exist in the current context

CS1069 - The type name 'ApplicationException' could not be found in the namespace 'System'. This type has been forwarded to assembly 'System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' Consider adding a reference to that assembly. SymbolExtractor::AnalyzeProject

CS0103 - The name 'Environment' does not exist in the current context

Interestingly, all these errors relate to one method in a static class in the project I'm trying to compile. I'm not sure if it's relevant but here's the code in question:

public static string DefineLocalAppDataLogPath( string fileStub, string folder = null )
{
    fileStub = IsFileNameValid( fileStub ) ? fileStub : "log.txt";

    if( string.IsNullOrEmpty( folder ) )
    {
        var assLoc = Assembly.GetExecutingAssembly().GetType().Assembly.Location;
            folder = Path.GetFileNameWithoutExtension( assLoc );
    }

    DirectoryInfo logDir = null;

    if( ( logDir = CreateLogFileDirectory( folder ) ) == null )
    {
        if( ( logDir = CreateLogFileDirectory( "LogFiles" ) ) == null )
            throw new ApplicationException(
                $"Couldn't create log file directory {folder} or the backup/default directory 'LogFiles'" );
    }

    return logDir.FullName;
}

What am I missing about resolving assembly dependencies? Do I need to also include references to the assemblies required at runtime as well?

来源:https://stackoverflow.com/questions/60404294/resolving-assembly-references-in-roslyn

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!