public Compilation CreateCompilation(CompilationOptionsReader compilationOptionsReader, string fileName) { var pdbCompilationOptions = compilationOptionsReader.GetMetadataCompilationOptions(); if (pdbCompilationOptions.Length == 0) { throw new InvalidDataException("Did not find compilation options in pdb"); } var metadataReferenceInfos = compilationOptionsReader.GetMetadataReferences(); var encoding = compilationOptionsReader.GetEncoding(); var sourceFileInfos = compilationOptionsReader.GetSourceFileInfos(encoding); _logger.LogInformation("Locating metadata references"); var metadataReferences = _referenceResolver.ResolveReferences(metadataReferenceInfos); logResolvedMetadataReferences(); var sourceLinks = ResolveSourceLinks(compilationOptionsReader); var sources = ResolveSources(sourceFileInfos, sourceLinks, encoding); logResolvedSources(); if (pdbCompilationOptions.TryGetUniqueOption("language", out var language)) { var compilation = language switch { LanguageNames.CSharp => CreateCSharpCompilation(fileName, compilationOptionsReader, sources, metadataReferences), LanguageNames.VisualBasic => CreateVisualBasicCompilation(fileName, compilationOptionsReader, sources, metadataReferences), _ => throw new InvalidDataException($"{language} is not a known language") }; return(compilation); } throw new InvalidDataException("Did not find language in compilation options"); void logResolvedMetadataReferences() { using var _ = _logger.BeginScope("Metadata References"); for (var i = 0; i < metadataReferenceInfos.Length; i++) { _logger.LogInformation($@"""{metadataReferences[i].Display}"" - {metadataReferenceInfos[i].Mvid}"); } } void logResolvedSources() { using var _ = _logger.BeginScope("Source Names"); foreach (var resolvedSource in sources) { var sourceFileInfo = resolvedSource.SourceFileInfo; var hash = BitConverter.ToString(sourceFileInfo.Hash).Replace("-", ""); var embeddedCompressedHash = sourceFileInfo.EmbeddedCompressedHash is { } compressedHash ? ("[uncompressed]" + BitConverter.ToString(compressedHash).Replace("-", "")) : null; _logger.LogInformation($@"""{resolvedSource.DisplayPath}"" - {sourceFileInfo.HashAlgorithm} - {hash} - {embeddedCompressedHash}"); } } }
public (Compilation?compilation, bool isError) CreateCompilation(CompilationOptionsReader compilationOptionsReader, string fileName) { // We try to handle assemblies missing compilation options gracefully by skipping them. // However, if an assembly has some bad combination of data, for example if it contains // compilation options but not metadata references, then we throw an exception. if (!compilationOptionsReader.TryGetMetadataCompilationOptions(out var pdbCompilationOptions) || pdbCompilationOptions.Length == 0) { _logger.LogInformation($"{fileName} did not contain compilation options in its PDB"); return(compilation : null, isError : false); } var metadataReferenceInfos = compilationOptionsReader.GetMetadataReferences(); var encoding = compilationOptionsReader.GetEncoding(); var sourceFileInfos = compilationOptionsReader.GetSourceFileInfos(encoding); _logger.LogInformation("Locating metadata references"); if (!_referenceResolver.TryResolveReferences(metadataReferenceInfos, out var metadataReferences)) { _logger.LogError($"Failed to rebuild {fileName} due to missing metadata references"); return(compilation : null, isError : true); } logResolvedMetadataReferences(); var sourceLinks = ResolveSourceLinks(compilationOptionsReader); var sources = ResolveSources(sourceFileInfos, sourceLinks, encoding); logResolvedSources(); if (pdbCompilationOptions.TryGetUniqueOption("language", out var language)) { var diagnosticBag = DiagnosticBag.GetInstance(); var compilation = language switch { LanguageNames.CSharp => CreateCSharpCompilation(fileName, compilationOptionsReader, sources, metadataReferences), LanguageNames.VisualBasic => CreateVisualBasicCompilation(fileName, compilationOptionsReader, sources, metadataReferences, diagnosticBag), _ => throw new InvalidDataException($"{language} is not a known language") }; var diagnostics = diagnosticBag.ToReadOnlyAndFree(); var hadError = false; foreach (var diagnostic in diagnostics) { if (diagnostic.Severity == DiagnosticSeverity.Error) { _logger.LogError(diagnostic.ToString()); hadError = true; } else { _logger.LogWarning(diagnostic.ToString()); } } compilation = hadError ? null : compilation; return(compilation, isError : compilation is null); } throw new InvalidDataException("Did not find language in compilation options"); void logResolvedMetadataReferences() { using var _ = _logger.BeginScope("Metadata References"); for (var i = 0; i < metadataReferenceInfos.Length; i++) { _logger.LogInformation($@"""{metadataReferences[i].Display}"" - {metadataReferenceInfos[i].Mvid}"); } } void logResolvedSources() { using var _ = _logger.BeginScope("Source Names"); foreach (var resolvedSource in sources) { var sourceFileInfo = resolvedSource.SourceFileInfo; var hash = BitConverter.ToString(sourceFileInfo.Hash).Replace("-", ""); var embeddedCompressedHash = sourceFileInfo.EmbeddedCompressedHash is { } compressedHash ? ("[uncompressed]" + BitConverter.ToString(compressedHash).Replace("-", "")) : null; _logger.LogInformation($@"""{resolvedSource.DisplayPath}"" - {sourceFileInfo.HashAlgorithm} - {hash} - {embeddedCompressedHash}"); } } }