diff --git a/src/Basic.CompilerLog.UnitTests/CompilationDataTests.cs b/src/Basic.CompilerLog.UnitTests/CompilationDataTests.cs index eb67c15..6608b2e 100644 --- a/src/Basic.CompilerLog.UnitTests/CompilationDataTests.cs +++ b/src/Basic.CompilerLog.UnitTests/CompilationDataTests.cs @@ -2,6 +2,7 @@ using Basic.CompilerLog.Util; using Basic.CompilerLog.Util.Impl; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Emit; using Microsoft.Testing.Platform.Extensions.Messages; using Xunit; @@ -82,6 +83,28 @@ public void EmitToMemoryCombinations() }); } + /// + /// Covers while the fix in + /// is not yet available in our Roslyn package. + /// + [Fact] + public void EmitToMemoryMetadataOnlyWithPdbPath() + { + RunInContext(Fixture.ClassLib.Value.CompilerLogPath, static (testOutputHelper, filePath, cancellationToken) => + { + using var reader = CompilerLogReader.Create(filePath); + var data = reader.ReadCompilationData(0); + var emitOptions = data.EmitOptions + .WithEmitMetadataOnly(true) + .WithDebugInformationFormat(DebugInformationFormat.Embedded) + .WithPdbFilePath("test.pdb"); + + var exception = Assert.Throws( + () => data.EmitToMemory(EmitFlags.MetadataOnly, emitOptions, cancellationToken)); + Assert.Equal("metadataPEStream", exception.ParamName); + }); + } + [Fact] public void EmitToMemoryRefOnly() { diff --git a/src/Basic.CompilerLog.Util/CompilerLogReader.cs b/src/Basic.CompilerLog.Util/CompilerLogReader.cs index 1c543e9..48280c1 100644 --- a/src/Basic.CompilerLog.Util/CompilerLogReader.cs +++ b/src/Basic.CompilerLog.Util/CompilerLogReader.cs @@ -374,6 +374,7 @@ public IReadOnlyCollection ReadArguments(CompilerCall compilerCall) CompilationDataPack dataPack) { var emitOptions = MessagePackUtil.CreateEmitOptions(GetContentPack(pack.EmitOptionsHash)); + emitOptions = ApplyMetadataOnlyEmitWorkaround(emitOptions); ParseOptions parseOptions; CompilationOptions compilationOptions; if (pack.IsCSharp) @@ -396,6 +397,25 @@ public IReadOnlyCollection ReadArguments(CompilerCall compilerCall) compilationOptions = MaterializeCryptoKeyFile(dataPack, compilationOptions); return (emitOptions, parseOptions, compilationOptions); + EmitOptions ApplyMetadataOnlyEmitWorkaround(EmitOptions emitOptions) + { + // Metadata-only output cannot have an associated PDB. Current Roslyn can retain the PDB path, + // emit a CodeView entry, or reject embedded debug information. Work around dotnet/roslyn#85028 + // until a Roslyn package containing the fix is available. + if (!emitOptions.EmitMetadataOnly) + { + return emitOptions; + } + + emitOptions = emitOptions.WithPdbFilePath(null!); + if (emitOptions.DebugInformationFormat == DebugInformationFormat.Embedded) + { + emitOptions = emitOptions.WithDebugInformationFormat(DebugInformationFormat.PortablePdb); + } + + return emitOptions; + } + // This method will materialize the crypto key file to the location specified by the path mapping util. This // is the rare case where reading compilation information will cause a file to be written to disk. It's the // rare case where the compiler reads directly from disk at binding vs. pre-reading at Compilation creation