Я пишу экстрактор метаданных для C# проектов. Он работает путем создания SyntaxTrees
из исходных файлов с помощью CSharpSyntaxTree.ParseText()
, компиляции их с помощью CSharpCompilation.Create()
и последующего анализа символов в SemanticModel
.
Я сталкиваюсь с проблемой, когда различные ссылки на сборки не отображаются. t обрабатывается правильно.
Я генерирую ссылки на сборки, анализируя project.assets.json
и извлекая ссылки на пакеты времени компиляции (мой тестовый проект не содержит ссылок на проекты). Секция целей project.assets.json
выглядит следующим образом:
"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": {}
}
}
}
}
В результате получается список ссылок:
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
Я игнорирую два странно отформатированных netstandard1.0, заменяя их они со ссылкой, созданной MetadataReference.CreateFromFile( Assembly.Load( "netstandard" ).Location ) )
, и разрешают оставшиеся пути для локальных репозиториев nuget, создавая ссылки из библиотек.
Это в основном работает нормально ... но некоторые вещи не решаются. Вот сообщения c о диагностике, которые я получаю после компиляции с CSharpCompilation.Create()
:
CS0103 - Имя «Сборка» не существует в текущем контексте
CS0103 - Имя «Путь» не существует в текущем контексте
CS1069 - Не удалось найти имя типа «ApplicationException» в пространстве имен «Система». Этот тип был перенаправлен в сборку «System.Runtime, версия = 4.1.0.0, культура = нейтральная, PublicKeyToken = b03f5f7f11d50a3a». Попробуйте добавить ссылку на эту сборку. SymbolExtractor :: AnalyzeProject
CS0103 - имя 'Environment' не существует в текущем контексте
Интересно, что все эти ошибки относятся к одному методу в классе stati c в проект я пытаюсь скомпилировать. Я не уверен, что это уместно, но вот код, о котором идет речь:
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;
}
Что мне не хватает в разрешении зависимостей сборки? Нужно ли также включать ссылки на сборки, требуемые также во время выполнения?