Skip to content

Commit

Permalink
Few small fixes (#68)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredpar authored Oct 30, 2023
1 parent f8199fb commit 0830874
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 115 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ bld/
[Oo]bj/
[Ll]og/
[Ll]ogs/
.complog/

# Visual Studio 2015/2017 cache/options directory
.vs/
Expand Down
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/src/Basic.CompilerLog/bin/Debug/net7.0/Basic.CompilerLog.dll",
"args": ["rsp", "c:\\users\\jaredpar\\temp\\console\\console.csproj"],
"program": "${workspaceFolder}/artifacts/bin/Basic.CompilerLog/debug/Basic.CompilerLog.dll",
"args": ["replay", "C:\\Users\\jaredpar\\code\\roslyn\\artifacts\\log\\Debug\\Build.binlog", "-export", "-o", "c:/users/jaredpar/temp/export"],
"cwd": "${workspaceFolder}/src/Basic.CompilerLog",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ This global tool can be installed via
From there the following commands are available:

- `create`: create a compilerlog file from an existing binary log
- `diagnostics`: print diagnostics from the specified compilations
- `create`: create a complog file from an existing binary log
- `replay`: replay the builds from the complog
- `export`: export complete compilations to disk
- `ref`: export references for a compilation to disk
- `rsp`: generate rsp files for compilation events
- `print`: print the summary of a compilerlog on the command line
- `print`: print the summary of a complog on the command line

## Info

Expand Down
2 changes: 1 addition & 1 deletion src/Basic.CompilerLog.UnitTests/ProgramTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public void ExportHelloWorld(string template)
public void EmitConsole(string arg)
{
using var emitDir = new TempDir();
RunCompLog($"emit {arg} -o {emitDir.DirectoryPath} {Fixture.ConsoleComplogPath.Value}");
RunCompLog($"replay {arg} -emit -o {emitDir.DirectoryPath} {Fixture.ConsoleComplogPath.Value}");

AssertOutput(@"console\emit\console.dll");
AssertOutput(@"console\emit\console.pdb");
Expand Down
2 changes: 1 addition & 1 deletion src/Basic.CompilerLog.Util/Basic.CompilerLog.Util.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="7.0.13" />
<PackageReference Include="MSBuild.StructuredLogger" Version="2.1.844" />
<PackageReference Include="MSBuild.StructuredLogger" Version="2.1.858" />
<PackageReference Include="System.IO.Compression" Version="4.3.0" Condition="'$(TargetFramework)' == 'net472'" />
</ItemGroup>

Expand Down
16 changes: 11 additions & 5 deletions src/Basic.CompilerLog.Util/CompilerLogBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ internal bool Add(CompilerCall compilerCall)

AddCompilationOptions(infoPack, commandLineArguments, compilerCall);

var entry = ZipArchive.CreateEntry(GetCompilerEntryName(_compilationCount), CompressionLevel.Optimal);
var entry = ZipArchive.CreateEntry(GetCompilerEntryName(_compilationCount), CompressionLevel.Fastest);
using (var entryStream = entry.Open())
{
MessagePackSerializer.Serialize(entryStream, infoPack, SerializerOptions);
Expand Down Expand Up @@ -198,14 +198,14 @@ public void Close()

void WriteMetadata()
{
var entry = ZipArchive.CreateEntry(MetadataFileName, CompressionLevel.Optimal);
var entry = ZipArchive.CreateEntry(MetadataFileName, CompressionLevel.Fastest);
using var writer = Polyfill.NewStreamWriter(entry.Open(), ContentEncoding, leaveOpen: false);
Metadata.Create(_compilationCount).Write(writer);
}

void WriteAssemblyInfo()
{
var entry = ZipArchive.CreateEntry(AssemblyInfoFileName, CompressionLevel.Optimal);
var entry = ZipArchive.CreateEntry(AssemblyInfoFileName, CompressionLevel.Fastest);
using var writer = Polyfill.NewStreamWriter(entry.Open(), ContentEncoding, leaveOpen: false);
foreach (var kvp in _mvidToRefInfoMap.OrderBy(x => x.Value.FileName).ThenBy(x => x.Key))
{
Expand Down Expand Up @@ -268,6 +268,12 @@ bool AddGeneratedFilesCore()
{
// This only works when using portable and embedded pdb formats. A full PDB can't store
// generated files
if (!args.EmitPdb)
{
Diagnostics.Add($"Can't read generated files as no PDB is emitted");
return false;
}

if (args.EmitOptions.DebugInformationFormat is not (DebugInformationFormat.Embedded or DebugInformationFormat.PortablePdb))
{
Diagnostics.Add($"Can't read generated files from native PDB");
Expand Down Expand Up @@ -440,7 +446,7 @@ private string AddContent(Stream stream)

if (_contentHashMap.Add(hashText))
{
var entry = ZipArchive.CreateEntry(GetContentEntryName(hashText), CompressionLevel.Optimal);
var entry = ZipArchive.CreateEntry(GetContentEntryName(hashText), CompressionLevel.Fastest);
using var entryStream = entry.Open();
stream.Position = 0;
stream.CopyTo(entryStream);
Expand Down Expand Up @@ -617,7 +623,7 @@ private Guid AddAssembly(string filePath)
return mvid;
}

var entry = ZipArchive.CreateEntry(GetAssemblyEntryName(mvid), CompressionLevel.Optimal);
var entry = ZipArchive.CreateEntry(GetAssemblyEntryName(mvid), CompressionLevel.Fastest);
using var entryStream = entry.Open();
file.Position = 0;
file.CopyTo(entryStream);
Expand Down
11 changes: 9 additions & 2 deletions src/Basic.CompilerLog.Util/EmitData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,14 @@ public EmitData(
}
}

public readonly struct EmitDiskResult
public interface IEmitResult
{
public bool Success { get; }
public ImmutableArray<Diagnostic> Diagnostics { get; }
}


public readonly struct EmitDiskResult : IEmitResult
{
public bool Success { get; }
public string Directory { get; }
Expand Down Expand Up @@ -70,7 +77,7 @@ public EmitDiskResult(
}
}

public readonly struct EmitMemoryResult
public readonly struct EmitMemoryResult : IEmitResult
{
public bool Success { get; }
public MemoryStream AssemblyStream { get; }
Expand Down
2 changes: 1 addition & 1 deletion src/Basic.CompilerLog.Util/Serialize/MessagePackTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public class CSharpCompilationOptionsPack
public class VisualBasicCompilationOptionsPack
{
[Key(1)]
public ImmutableArray<GlobalImport> GlobalImports { get; set; }
public string[] GlobalImports { get; set; }
[Key(2)]
public string? RootNamespace { get; set; }
[Key(3)]
Expand Down
5 changes: 3 additions & 2 deletions src/Basic.CompilerLog.Util/Serialize/MessagePackUtil.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

using System.Collections.Immutable;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
Expand Down Expand Up @@ -217,7 +218,7 @@ internal static VisualBasicCompilationOptions CreateVisualBasicCompilationOption
moduleName: optionsPack.ModuleName,
mainTypeName: optionsPack.MainTypeName,
scriptClassName: WellKnownMemberNames.DefaultScriptClassName,
globalImports: basicPack.GlobalImports,
globalImports: basicPack.GlobalImports.Select(x => GlobalImport.Parse(x)).ToImmutableArray(),
rootNamespace: basicPack.RootNamespace,
optionStrict: basicPack.OptionStrict,
optionInfer: basicPack.OptionInfer,
Expand Down Expand Up @@ -246,7 +247,7 @@ internal static (CompilationOptionsPack, VisualBasicCompilationOptionsPack, Pars
var tuple = CreateVisualBasicParseOptionsPack(options.ParseOptions);
var pack = new VisualBasicCompilationOptionsPack()
{
GlobalImports = options.GlobalImports,
GlobalImports = options.GlobalImports.Select(x => x.Name).ToArray(),
RootNamespace = options.RootNamespace,
OptionStrict = options.OptionStrict,
OptionInfer = options.OptionInfer,
Expand Down
126 changes: 57 additions & 69 deletions src/Basic.CompilerLog/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@
return command.ToLower() switch
{
"create" => RunCreate(rest),
"diagnostics" => RunDiagnostics(rest),
"replay" => RunReplay(rest, cts.Token),
"export" => RunExport(rest),
"ref" => RunReferences(rest),
"rsp" => RunResponseFile(rest),
"emit" => RunEmit(rest, cts.Token),
"analyzers" => RunAnalyzers(rest),
"print" => RunPrint(rest),
"help" => RunHelp(rest),

// Older option names
"diagnostics" => RunReplay(rest, cts.Token),
"emit" => RunReplay(rest, cts.Token),
_ => RunHelp(null)
};
}
Expand Down Expand Up @@ -368,12 +371,20 @@ void PrintUsage()
}
}

int RunEmit(IEnumerable<string> args, CancellationToken cancellationToken)
int RunReplay(IEnumerable<string> args, CancellationToken cancellationToken)
{
var baseOutputPath = "";
var severity = DiagnosticSeverity.Warning;
var export = false;
var emit = false;
var analyzers = false;
var options = new FilterOptionSet(includeNoneHost: true)
{
{ "o|out=", "path to output binaries to", o => baseOutputPath = o },
{ "severity", "minimum severity to display (default Warning)", (DiagnosticSeverity s) => severity = s },
{ "export", "export failed compilation", e => export = e is not null },
{ "emit", "emit compilation", e => emit = e is not null },
{ "analyzers", "use actual analyzers / generators (default uses generated files)", a => analyzers = a is not null },
{ "o|out=", "path to export to ", b => baseOutputPath = b },
};

try
Expand All @@ -385,88 +396,65 @@ int RunEmit(IEnumerable<string> args, CancellationToken cancellationToken)
return ExitFailure;
}

using var compilerLogStream = GetOrCreateCompilerLogStream(extra);
using var reader = GetCompilerLogReader(compilerLogStream, leaveOpen: true);
var compilerCalls = reader.ReadAllCompilerCalls(options.FilterCompilerCalls);
var allSucceeded = true;
if (!string.IsNullOrEmpty(baseOutputPath) && !(export || emit))
{
WriteLine("Error: Specified a path to export to but did not specify -export");
return ExitFailure;
}

baseOutputPath = GetBaseOutputPath(baseOutputPath);
WriteLine($"Generating binary files to {baseOutputPath}");
Directory.CreateDirectory(baseOutputPath);
if (!string.IsNullOrEmpty(baseOutputPath))
{
WriteLine($"Outputting to {baseOutputPath}");
}

var analyzerHostOptions = analyzers ? BasicAnalyzerHostOptions.Default : BasicAnalyzerHostOptions.None;
using var compilerLogStream = GetOrCreateCompilerLogStream(extra);
using var reader = GetCompilerLogReader(compilerLogStream, leaveOpen: true, analyzerHostOptions);
var compilerCalls = reader.ReadAllCompilerCalls(options.FilterCompilerCalls);
var exportUtil = new ExportUtil(reader, includeAnalyzers: analyzerHostOptions.Kind != BasicAnalyzerKind.None);
var sdkDirs = DotnetUtil.GetSdkDirectories();

for (int i = 0; i < compilerCalls.Count; i++)
{
cancellationToken.ThrowIfCancellationRequested();

var compilerCall = compilerCalls[i];
var emitDirPath = GetOutputPath(baseOutputPath, compilerCalls, i, "emit");
Directory.CreateDirectory(emitDirPath);

Write($"{compilerCall.GetDiagnosticName()} ... ");
Write($"{compilerCall.GetDiagnosticName()} ...");

var compilationData = reader.ReadCompilationData(compilerCall);
var result = compilationData.EmitToDisk(emitDirPath, cancellationToken);
if (result.Success)
var compilation = compilationData.GetCompilationAfterGenerators();

IEmitResult emitResult;
if (emit)
{
WriteLine("done");
var path = GetOutputPath(baseOutputPath, compilerCalls, i, "emit");
Directory.CreateDirectory(path);
emitResult = compilationData.EmitToDisk(path, cancellationToken);
}
else
{
allSucceeded = false;
WriteLine("FAILED");
foreach (var diagnostic in result.Diagnostics)
{
WriteLine(diagnostic.GetMessage());
}
emitResult = compilationData.EmitToMemory(cancellationToken);
}
}

return allSucceeded ? ExitSuccess : ExitFailure;
}
catch (OptionException e)
{
WriteLine(e.Message);
PrintUsage();
return ExitFailure;
}

void PrintUsage()
{
WriteLine("complog rsp [OPTIONS] msbuild.complog");
options.WriteOptionDescriptions(Out);
}
}

int RunDiagnostics(IEnumerable<string> args)
{
var severity = DiagnosticSeverity.Warning;
var options = new FilterOptionSet(includeNoneHost: true)
{
{ "severity", "minimum severity to display (default Warning)", (DiagnosticSeverity s) => severity = s },
};

try
{
var extra = options.Parse(args);
if (options.Help)
{
PrintUsage();
return ExitFailure;
}

using var compilerLogStream = GetOrCreateCompilerLogStream(extra);
using var reader = GetCompilerLogReader(compilerLogStream, leaveOpen: true);
var compilationDatas = reader.ReadAllCompilationData(options.FilterCompilerCalls);

foreach (var compilationData in compilationDatas)
{
var compilerCall = compilationData.CompilerCall;
WriteLine(compilerCall.GetDiagnosticName());
var compilation = compilationData.GetCompilationAfterGenerators();
foreach (var diagnostic in compilation.GetDiagnostics())
WriteLine(emitResult.Success ? "Success" : "Error");
foreach (var diagnostic in emitResult.Diagnostics)
{
if (diagnostic.Severity >= severity)
{
Write(" ");
WriteLine(diagnostic.GetMessage());
}
}

if (!emitResult.Success && export)
{
var exportPath = GetOutputPath(baseOutputPath, compilerCalls, i, "export");
Directory.CreateDirectory(exportPath);
WriteLine($"Exporting to {exportPath}");
exportUtil.Export(compilationData.CompilerCall, exportPath, sdkDirs);
}
}

return ExitSuccess;
Expand All @@ -480,7 +468,7 @@ int RunDiagnostics(IEnumerable<string> args)

void PrintUsage()
{
WriteLine("complog diagnostics [OPTIONS] msbuild.complog");
WriteLine("complog replay [OPTIONS] msbuild.complog");
options.WriteOptionDescriptions(Out);
}
}
Expand Down Expand Up @@ -542,9 +530,9 @@ List<CompilerCall> GetCompilerCalls(List<string> extra, Func<CompilerCall, bool>
}
}

CompilerLogReader GetCompilerLogReader(Stream compilerLogStream, bool leaveOpen)
CompilerLogReader GetCompilerLogReader(Stream compilerLogStream, bool leaveOpen, BasicAnalyzerHostOptions? options = null)
{
var reader = CompilerLogReader.Create(compilerLogStream, leaveOpen);
var reader = CompilerLogReader.Create(compilerLogStream, leaveOpen, options);
if (reader.MetadataVersion > CompilerLogReader.LatestMetadataVersion)
{
WriteLine($"Compiler log version newer than toolset: {reader.MetadataVersion}");
Expand Down
Loading

0 comments on commit 0830874

Please sign in to comment.