Exemplo n.º 1
0
        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}");
                }
            }
        }
Exemplo n.º 2
0
        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}");
                }
            }
        }