From ae2f6d76bef28daba9a18144b2e8ce0b6f918262 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Sat, 16 Aug 2025 21:14:05 +0200 Subject: [PATCH 1/6] Support source-generated files --- src/SourceBrowser/src/BinLogToSln/Program.cs | 52 +++++++++++++++----- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/SourceBrowser/src/BinLogToSln/Program.cs b/src/SourceBrowser/src/BinLogToSln/Program.cs index 5def968..f5c827b 100644 --- a/src/SourceBrowser/src/BinLogToSln/Program.cs +++ b/src/SourceBrowser/src/BinLogToSln/Program.cs @@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; -using System.Numerics; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; using System.Runtime.CompilerServices; @@ -146,6 +145,7 @@ private static bool ShouldExcludeInvocation(CompilerInvocation invocation) return false; } + static void Main(string[] args) { string binlog = null; @@ -205,7 +205,7 @@ static void Main(string[] args) WriteSolutionHeader(sln); IEnumerable invocations = BinLogCompilerInvocationsReader.ExtractInvocations(binlog); - + // Group invocations by assembly name and select the best one for each var invocationGroups = invocations .Where(invocation => !ShouldExcludeInvocation(invocation)) @@ -255,6 +255,7 @@ static void Main(string[] args) project.WriteLine(" false"); project.WriteLine(" false"); project.WriteLine(" true"); + project.WriteLine(" <_SkipAnalyzers>true"); // we only need source generators project.WriteLine($" {invocation.AssemblyName}"); int idx = 1; if (invocation.Parsed.CompilationOptions is CSharpCompilationOptions cSharpOptions) @@ -290,18 +291,33 @@ static void Main(string[] args) project.WriteLine(" "); foreach (CommandLineReference reference in invocation.Parsed.MetadataReferences) { - string path = reference.Reference; - if (!File.Exists(path)) + includeReference("ReferencePath", reference.Reference); + } + project.WriteLine(" "); + + // Add source generators. + if (!invocation.Parsed.AnalyzerReferences.IsDefaultOrEmpty) + { + project.WriteLine(" "); + foreach (CommandLineAnalyzerReference analyzer in invocation.Parsed.AnalyzerReferences) { - Console.WriteLine($"Could not find reference '{path}'"); - continue; + includeReference("Analyzer", analyzer.FilePath); } - string projToRepoPath = Path.GetRelativePath(invocation.ProjectDirectory, repoRoot); - string projToOutputPath = Path.Join(projToRepoPath, ".."); - string refPath = DedupeReference(output, path); - project.WriteLine($" "); + project.WriteLine(" "); } - project.WriteLine(" "); + + // Add additional files (might be used by source generators). + if (!invocation.Parsed.AdditionalFiles.IsDefaultOrEmpty) + { + project.WriteLine(" "); + foreach (CommandLineSourceFile additionalFile in invocation.Parsed.AdditionalFiles) + { + includeFile(additionalFile.Path, out string projectRelativePath, out _); + project.WriteLine($" "); + } + project.WriteLine(" "); + } + project.WriteLine(""); if (!string.IsNullOrEmpty(invocation.OutputAssemblyPath)) { @@ -339,6 +355,20 @@ void includeFile(string originalPath, out string projectRelativePath, out string File.Copy(filePath, outputFile); } } + + void includeReference(string kind, string path) + { + if (!File.Exists(path)) + { + Console.WriteLine($"Could not find analyzer '{path}'"); + return; + } + + string projToRepoPath = Path.GetRelativePath(invocation.ProjectDirectory, repoRoot); + string projToOutputPath = Path.Join(projToRepoPath, ".."); + string refPath = DedupeReference(output, path); + project.WriteLine($" <{kind} Include=\"{Path.Join(projToOutputPath, refPath)}\"/>"); + } } Console.WriteLine("Finished"); From 73cea20a510e8986e5fc02c3229e84f86cbfdede Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Sat, 16 Aug 2025 21:47:26 +0200 Subject: [PATCH 2/6] Fix message --- src/SourceBrowser/src/BinLogToSln/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SourceBrowser/src/BinLogToSln/Program.cs b/src/SourceBrowser/src/BinLogToSln/Program.cs index f5c827b..f172273 100644 --- a/src/SourceBrowser/src/BinLogToSln/Program.cs +++ b/src/SourceBrowser/src/BinLogToSln/Program.cs @@ -360,7 +360,7 @@ void includeReference(string kind, string path) { if (!File.Exists(path)) { - Console.WriteLine($"Could not find analyzer '{path}'"); + Console.WriteLine($"Could not find {kind} '{path}'"); return; } From a849cd2b7809b9172fa1b2a01ed78d51ed087c95 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Tue, 19 Aug 2025 15:00:01 +0200 Subject: [PATCH 3/6] Include source-generated files in stage 1 --- src/SourceBrowser/src/BinLogToSln/Program.cs | 184 ++++++++++++++++--- 1 file changed, 154 insertions(+), 30 deletions(-) diff --git a/src/SourceBrowser/src/BinLogToSln/Program.cs b/src/SourceBrowser/src/BinLogToSln/Program.cs index f172273..6f64631 100644 --- a/src/SourceBrowser/src/BinLogToSln/Program.cs +++ b/src/SourceBrowser/src/BinLogToSln/Program.cs @@ -1,17 +1,20 @@ +using LibGit2Sharp; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Emit; +using Microsoft.CodeAnalysis.Text; +using Microsoft.SourceBrowser.BinLogParser; +using Mono.Options; +using NuGet.Frameworks; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.IO.Compression; using System.Linq; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; using System.Runtime.CompilerServices; -using LibGit2Sharp; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.SourceBrowser.BinLogParser; -using Mono.Options; -using NuGet.Frameworks; [assembly: InternalsVisibleTo("BinLogToSln.Tests")] @@ -240,11 +243,10 @@ static void Main(string[] args) using var projFile = new FileStream(projectFilePath, FileMode.Create); using var project = new StreamWriter(projFile); - string typeGuid = invocation.Language switch + (string typeGuid, Guid languageGuid, string languageExtension) = invocation.Language switch { - LanguageNames.CSharp => CSharpProjectTypeGuid, - LanguageNames.VisualBasic => VBProjectTypeGuid, - _ => CSharpProjectTypeGuid, + LanguageNames.VisualBasic => (VBProjectTypeGuid, VBLanguageGuid, ".vb"), + _ => (CSharpProjectTypeGuid, CSharpLanguageGuid, ".cs"), }; sln.WriteLine($"Project(\"{typeGuid}\") = \"{projectName}\", \"{Path.Join("src", repoRelativeProjectPath)}\", \"{GetProjectGuid()}\""); sln.WriteLine("EndProject"); @@ -295,28 +297,23 @@ static void Main(string[] args) } project.WriteLine(" "); - // Add source generators. - if (!invocation.Parsed.AnalyzerReferences.IsDefaultOrEmpty) - { - project.WriteLine(" "); - foreach (CommandLineAnalyzerReference analyzer in invocation.Parsed.AnalyzerReferences) - { - includeReference("Analyzer", analyzer.FilePath); - } - project.WriteLine(" "); - } - - // Add additional files (might be used by source generators). - if (!invocation.Parsed.AdditionalFiles.IsDefaultOrEmpty) + // Add generated files. + project.WriteLine(" "); + foreach (var generatedFile in getGeneratedFiles()) { - project.WriteLine(" "); - foreach (CommandLineSourceFile additionalFile in invocation.Parsed.AdditionalFiles) + string filePath = generatedFile.FilePath; + if (!File.Exists(filePath)) { - includeFile(additionalFile.Path, out string projectRelativePath, out _); - project.WriteLine($" "); + Directory.CreateDirectory(Path.GetDirectoryName(filePath)); + var stream = generatedFile.Stream; + stream.Position = 0; + using var fileStream = File.OpenWrite(filePath); + stream.CopyTo(fileStream); } - project.WriteLine(" "); + includeFile(filePath, out string projectRelativePath, out string link); + project.WriteLine($" "); } + project.WriteLine(" "); project.WriteLine(""); if (!string.IsNullOrEmpty(invocation.OutputAssemblyPath)) @@ -369,6 +366,128 @@ void includeReference(string kind, string path) string refPath = DedupeReference(output, path); project.WriteLine($" <{kind} Include=\"{Path.Join(projToOutputPath, refPath)}\"/>"); } + +#nullable enable + // From https://github.com/jaredpar/complog/blob/a629fb3c05e40ebe673410144e8911bd5f86bdf2/src/Basic.CompilerLog.Util/RoslynUtil.cs#L440. + IEnumerable<(string FilePath, MemoryStream Stream)> getGeneratedFiles() + { + try + { + if (!invocation.Parsed.EmitPdb) + { + throw new InvalidOperationException($"{nameof(CommandLineArguments.EmitPdb)} is {false}."); + } + + if (invocation.Parsed.EmitOptions.DebugInformationFormat is not (DebugInformationFormat.Embedded or DebugInformationFormat.PortablePdb) and var format) + { + throw new InvalidOperationException($"Unsupported {nameof(DebugInformationFormat)}={format}."); + } + + using var reader = File.OpenRead(invocation.OutputAssemblyPath); + using var peReader = new PEReader(reader); + if (!peReader.TryOpenAssociatedPortablePdb(invocation.OutputAssemblyPath, pdbFileStreamProvider, out var pdbReaderProvider, out var pdbPath)) + { + throw new InvalidOperationException($"Could not open PDB for '{invocation.OutputAssemblyPath}'."); + } + + var pdbReader = pdbReaderProvider!.GetMetadataReader(); + var generatedFiles = new List<(string FilePath, MemoryStream Stream)>(); + foreach (var documentHandle in pdbReader.Documents.Skip(invocation.Parsed.SourceFiles.Length)) + { + if (getContentStream(languageGuid, languageExtension, pdbReader, documentHandle) is { } tuple) + { + generatedFiles.Add(tuple); + } + } + return generatedFiles; + } + catch (Exception ex) + { + // We don't want to fail official builds during stage 1, so just log a warning. + Console.WriteLine($"##vso[task.logissue type=warning;]Error processing generated files for '{invocation.ProjectFilePath}': {ex}"); + return []; + } + + static Stream? pdbFileStreamProvider(string filePath) + { + if (!File.Exists(filePath)) + { + return null; + } + + return File.OpenRead(filePath); + } + + static (string FilePath, MemoryStream Stream)? getContentStream( + Guid languageGuid, + string languageExtension, + MetadataReader pdbReader, + DocumentHandle documentHandle) + { + var document = pdbReader.GetDocument(documentHandle); + if (pdbReader.GetGuid(document.Language) != languageGuid) + { + return null; + } + + var filePath = pdbReader.GetString(document.Name); + + if (Path.GetExtension(filePath) != languageExtension) + { + return null; + } + + foreach (var cdiHandle in pdbReader.GetCustomDebugInformation(documentHandle)) + { + var cdi = pdbReader.GetCustomDebugInformation(cdiHandle); + if (pdbReader.GetGuid(cdi.Kind) != EmbeddedSourceGuid) + { + continue; + } + + var hashAlgorithmGuid = pdbReader.GetGuid(document.HashAlgorithm); + var hashAlgorithm = + hashAlgorithmGuid == HashAlgorithmSha1 ? SourceHashAlgorithm.Sha1 + : hashAlgorithmGuid == HashAlgorithmSha256 ? SourceHashAlgorithm.Sha256 + : SourceHashAlgorithm.None; + if (hashAlgorithm == SourceHashAlgorithm.None) + { + continue; + } + + var bytes = pdbReader.GetBlobBytes(cdi.Value); + if (bytes is null) + { + continue; + } + + int uncompressedSize = BitConverter.ToInt32(bytes, 0); + var stream = new MemoryStream(bytes, sizeof(int), bytes.Length - sizeof(int)); + + if (uncompressedSize != 0) + { + var decompressed = new MemoryStream(uncompressedSize); + using (var deflateStream = new DeflateStream(stream, CompressionMode.Decompress)) + { + deflateStream.CopyTo(decompressed); + } + + if (decompressed.Length != uncompressedSize) + { + throw new InvalidOperationException("Stream did not decompress to expected size"); + } + + stream = decompressed; + } + + stream.Position = 0; + return (filePath, stream); + } + + return null; + } + } +#nullable disable } Console.WriteLine("Finished"); @@ -416,7 +535,12 @@ private static string GetProjectGuid() return Guid.NewGuid().ToString("B"); } - private static string CSharpProjectTypeGuid = "{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"; - private static string VBProjectTypeGuid = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"; + private static readonly string CSharpProjectTypeGuid = "{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"; + private static readonly string VBProjectTypeGuid = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"; + private static readonly Guid CSharpLanguageGuid = new("{3f5162f8-07c6-11d3-9053-00c04fa302a1}"); + private static readonly Guid VBLanguageGuid = new("{3a12d0b8-c26c-11d0-b442-00a0244a1dd2}"); + private static readonly Guid EmbeddedSourceGuid = new("0E8A571B-6926-466E-B4AD-8AB04611F5FE"); + private static readonly Guid HashAlgorithmSha1 = unchecked(new Guid((int)0xff1816ec, (short)0xaa5e, 0x4d10, 0x87, 0xf7, 0x6f, 0x49, 0x63, 0x83, 0x34, 0x60)); + private static readonly Guid HashAlgorithmSha256 = unchecked(new Guid((int)0x8829d00f, 0x11b8, 0x4213, 0x87, 0x8b, 0x77, 0x0e, 0x85, 0x97, 0xac, 0x16)); } } From 5f5495078fc65157c028bb98575df17d72096690 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Tue, 26 Aug 2025 09:51:59 +0200 Subject: [PATCH 4/6] Use complog util --- .../src/BinLogToSln/BinLogToSln.csproj | 11 +- src/SourceBrowser/src/BinLogToSln/Program.cs | 127 +----------------- .../src/Directory.Packages.props | 1 + 3 files changed, 14 insertions(+), 125 deletions(-) diff --git a/src/SourceBrowser/src/BinLogToSln/BinLogToSln.csproj b/src/SourceBrowser/src/BinLogToSln/BinLogToSln.csproj index 37b0df1..c7adf93 100644 --- a/src/SourceBrowser/src/BinLogToSln/BinLogToSln.csproj +++ b/src/SourceBrowser/src/BinLogToSln/BinLogToSln.csproj @@ -9,11 +9,12 @@ 1.0.1 - - - - - + + + + + + diff --git a/src/SourceBrowser/src/BinLogToSln/Program.cs b/src/SourceBrowser/src/BinLogToSln/Program.cs index 6f64631..d3841e8 100644 --- a/src/SourceBrowser/src/BinLogToSln/Program.cs +++ b/src/SourceBrowser/src/BinLogToSln/Program.cs @@ -1,8 +1,6 @@ using LibGit2Sharp; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Emit; -using Microsoft.CodeAnalysis.Text; using Microsoft.SourceBrowser.BinLogParser; using Mono.Options; using NuGet.Frameworks; @@ -10,7 +8,6 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; -using System.IO.Compression; using System.Linq; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; @@ -243,10 +240,10 @@ static void Main(string[] args) using var projFile = new FileStream(projectFilePath, FileMode.Create); using var project = new StreamWriter(projFile); - (string typeGuid, Guid languageGuid, string languageExtension) = invocation.Language switch + (string typeGuid, bool isCSharp) = invocation.Language switch { - LanguageNames.VisualBasic => (VBProjectTypeGuid, VBLanguageGuid, ".vb"), - _ => (CSharpProjectTypeGuid, CSharpLanguageGuid, ".cs"), + LanguageNames.VisualBasic => (VBProjectTypeGuid, false), + _ => (CSharpProjectTypeGuid, true), }; sln.WriteLine($"Project(\"{typeGuid}\") = \"{projectName}\", \"{Path.Join("src", repoRelativeProjectPath)}\", \"{GetProjectGuid()}\""); sln.WriteLine("EndProject"); @@ -367,39 +364,14 @@ void includeReference(string kind, string path) project.WriteLine($" <{kind} Include=\"{Path.Join(projToOutputPath, refPath)}\"/>"); } -#nullable enable - // From https://github.com/jaredpar/complog/blob/a629fb3c05e40ebe673410144e8911bd5f86bdf2/src/Basic.CompilerLog.Util/RoslynUtil.cs#L440. IEnumerable<(string FilePath, MemoryStream Stream)> getGeneratedFiles() { try { - if (!invocation.Parsed.EmitPdb) - { - throw new InvalidOperationException($"{nameof(CommandLineArguments.EmitPdb)} is {false}."); - } - - if (invocation.Parsed.EmitOptions.DebugInformationFormat is not (DebugInformationFormat.Embedded or DebugInformationFormat.PortablePdb) and var format) - { - throw new InvalidOperationException($"Unsupported {nameof(DebugInformationFormat)}={format}."); - } - - using var reader = File.OpenRead(invocation.OutputAssemblyPath); - using var peReader = new PEReader(reader); - if (!peReader.TryOpenAssociatedPortablePdb(invocation.OutputAssemblyPath, pdbFileStreamProvider, out var pdbReaderProvider, out var pdbPath)) - { - throw new InvalidOperationException($"Could not open PDB for '{invocation.OutputAssemblyPath}'."); - } - - var pdbReader = pdbReaderProvider!.GetMetadataReader(); - var generatedFiles = new List<(string FilePath, MemoryStream Stream)>(); - foreach (var documentHandle in pdbReader.Documents.Skip(invocation.Parsed.SourceFiles.Length)) - { - if (getContentStream(languageGuid, languageExtension, pdbReader, documentHandle) is { } tuple) - { - generatedFiles.Add(tuple); - } - } - return generatedFiles; + return Basic.CompilerLog.Util.RoslynUtil.ReadGeneratedFilesFromPdb( + isCSharp: isCSharp, + diagnosticName: invocation.ProjectFilePath, + invocation.Parsed); } catch (Exception ex) { @@ -407,87 +379,7 @@ void includeReference(string kind, string path) Console.WriteLine($"##vso[task.logissue type=warning;]Error processing generated files for '{invocation.ProjectFilePath}': {ex}"); return []; } - - static Stream? pdbFileStreamProvider(string filePath) - { - if (!File.Exists(filePath)) - { - return null; - } - - return File.OpenRead(filePath); - } - - static (string FilePath, MemoryStream Stream)? getContentStream( - Guid languageGuid, - string languageExtension, - MetadataReader pdbReader, - DocumentHandle documentHandle) - { - var document = pdbReader.GetDocument(documentHandle); - if (pdbReader.GetGuid(document.Language) != languageGuid) - { - return null; - } - - var filePath = pdbReader.GetString(document.Name); - - if (Path.GetExtension(filePath) != languageExtension) - { - return null; - } - - foreach (var cdiHandle in pdbReader.GetCustomDebugInformation(documentHandle)) - { - var cdi = pdbReader.GetCustomDebugInformation(cdiHandle); - if (pdbReader.GetGuid(cdi.Kind) != EmbeddedSourceGuid) - { - continue; - } - - var hashAlgorithmGuid = pdbReader.GetGuid(document.HashAlgorithm); - var hashAlgorithm = - hashAlgorithmGuid == HashAlgorithmSha1 ? SourceHashAlgorithm.Sha1 - : hashAlgorithmGuid == HashAlgorithmSha256 ? SourceHashAlgorithm.Sha256 - : SourceHashAlgorithm.None; - if (hashAlgorithm == SourceHashAlgorithm.None) - { - continue; - } - - var bytes = pdbReader.GetBlobBytes(cdi.Value); - if (bytes is null) - { - continue; - } - - int uncompressedSize = BitConverter.ToInt32(bytes, 0); - var stream = new MemoryStream(bytes, sizeof(int), bytes.Length - sizeof(int)); - - if (uncompressedSize != 0) - { - var decompressed = new MemoryStream(uncompressedSize); - using (var deflateStream = new DeflateStream(stream, CompressionMode.Decompress)) - { - deflateStream.CopyTo(decompressed); - } - - if (decompressed.Length != uncompressedSize) - { - throw new InvalidOperationException("Stream did not decompress to expected size"); - } - - stream = decompressed; - } - - stream.Position = 0; - return (filePath, stream); - } - - return null; - } } -#nullable disable } Console.WriteLine("Finished"); @@ -537,10 +429,5 @@ private static string GetProjectGuid() private static readonly string CSharpProjectTypeGuid = "{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"; private static readonly string VBProjectTypeGuid = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"; - private static readonly Guid CSharpLanguageGuid = new("{3f5162f8-07c6-11d3-9053-00c04fa302a1}"); - private static readonly Guid VBLanguageGuid = new("{3a12d0b8-c26c-11d0-b442-00a0244a1dd2}"); - private static readonly Guid EmbeddedSourceGuid = new("0E8A571B-6926-466E-B4AD-8AB04611F5FE"); - private static readonly Guid HashAlgorithmSha1 = unchecked(new Guid((int)0xff1816ec, (short)0xaa5e, 0x4d10, 0x87, 0xf7, 0x6f, 0x49, 0x63, 0x83, 0x34, 0x60)); - private static readonly Guid HashAlgorithmSha256 = unchecked(new Guid((int)0x8829d00f, 0x11b8, 0x4213, 0x87, 0x8b, 0x77, 0x0e, 0x85, 0x97, 0xac, 0x16)); } } diff --git a/src/SourceBrowser/src/Directory.Packages.props b/src/SourceBrowser/src/Directory.Packages.props index 9c77671..ceb1502 100644 --- a/src/SourceBrowser/src/Directory.Packages.props +++ b/src/SourceBrowser/src/Directory.Packages.props @@ -41,6 +41,7 @@ + From 6c9f3349c08429f9ee9da44a479cabaff0d09b41 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Tue, 26 Aug 2025 17:35:41 +0200 Subject: [PATCH 5/6] Include `` by default --- src/SourceBrowser/src/BinLogToSln/Program.cs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/SourceBrowser/src/BinLogToSln/Program.cs b/src/SourceBrowser/src/BinLogToSln/Program.cs index d3841e8..9c835bb 100644 --- a/src/SourceBrowser/src/BinLogToSln/Program.cs +++ b/src/SourceBrowser/src/BinLogToSln/Program.cs @@ -269,7 +269,7 @@ static void Main(string[] args) } if (cSharpOptions.CryptoKeyFile != null) { - includeFile(cSharpOptions.CryptoKeyFile, out string projectRelativePath, out _); + string projectRelativePath = includeFile(cSharpOptions.CryptoKeyFile, includeCompile: false); project.WriteLine($" {projectRelativePath}"); } } @@ -283,8 +283,7 @@ static void Main(string[] args) project.WriteLine(" "); foreach (CommandLineSourceFile sourceFile in invocation.Parsed.SourceFiles) { - includeFile(sourceFile.Path, out string projectRelativePath, out string link); - project.WriteLine($" "); + includeFile(sourceFile.Path); } project.WriteLine(" "); project.WriteLine(" "); @@ -307,8 +306,7 @@ static void Main(string[] args) using var fileStream = File.OpenWrite(filePath); stream.CopyTo(fileStream); } - includeFile(filePath, out string projectRelativePath, out string link); - project.WriteLine($" "); + includeFile(filePath); } project.WriteLine(" "); @@ -321,12 +319,13 @@ static void Main(string[] args) File.Copy(invocation.OutputAssemblyPath, outputFilePath, true); } - void includeFile(string originalPath, out string projectRelativePath, out string link) + string includeFile(string originalPath, bool includeCompile = true) { string filePath = Path.GetFullPath(originalPath); string repoRelativePath = Path.GetRelativePath(repoRoot, filePath); string outputFile; - link = null; + string link = null; + string projectRelativePath; if (repoRelativePath.StartsWith("..\\", StringComparison.Ordinal) || repoRelativePath.StartsWith("../", StringComparison.Ordinal) || Path.IsPathRooted(repoRelativePath)) { string externalPath = Path.Join("_external", idx++.ToString(), Path.GetFileName(filePath)); @@ -348,6 +347,13 @@ void includeFile(string originalPath, out string projectRelativePath, out string { File.Copy(filePath, outputFile); } + + if (includeCompile) + { + project.WriteLine($" "); + } + + return projectRelativePath; } void includeReference(string kind, string path) From 4f4d097455eaa1b121239a4e23c861c8346c851b Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Tue, 26 Aug 2025 17:37:59 +0200 Subject: [PATCH 6/6] Remove outdated comment --- src/SourceBrowser/src/BinLogToSln/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SourceBrowser/src/BinLogToSln/Program.cs b/src/SourceBrowser/src/BinLogToSln/Program.cs index 9c835bb..84a0ffd 100644 --- a/src/SourceBrowser/src/BinLogToSln/Program.cs +++ b/src/SourceBrowser/src/BinLogToSln/Program.cs @@ -254,7 +254,7 @@ static void Main(string[] args) project.WriteLine(" false"); project.WriteLine(" false"); project.WriteLine(" true"); - project.WriteLine(" <_SkipAnalyzers>true"); // we only need source generators + project.WriteLine(" <_SkipAnalyzers>true"); project.WriteLine($" {invocation.AssemblyName}"); int idx = 1; if (invocation.Parsed.CompilationOptions is CSharpCompilationOptions cSharpOptions)