Skip to content

Commit

Permalink
feat: add script compile message parsing and improve compile logs
Browse files Browse the repository at this point in the history
  • Loading branch information
sinnwrig committed Oct 10, 2024
1 parent 1de27d3 commit 6070560
Showing 1 changed file with 154 additions and 22 deletions.
176 changes: 154 additions & 22 deletions Prowl.Editor/Project/ProjectCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// Licensed under the MIT License. See the LICENSE file in the project root for details.

using System.Diagnostics;
using System.Reflection;
using System.Xml.Linq;

using Prowl.Runtime;

namespace Prowl.Editor;

Expand Down Expand Up @@ -85,26 +85,8 @@ public static int CompileCSProject(FileInfo project, DotnetCompileOptions option

process.Start();

process.OutputDataReceived += (sender, dataArgs) =>
{
string? data = dataArgs.Data;

if (string.IsNullOrWhiteSpace(data))
return;

if (data.Contains("Warning", StringComparison.OrdinalIgnoreCase))
Runtime.Debug.LogWarning(data);
else if (data.Contains("Error", StringComparison.OrdinalIgnoreCase))
Runtime.Debug.LogError(data);
else
Runtime.Debug.Log(data);
};

process.ErrorDataReceived += (sender, dataArgs) =>
{
if (dataArgs.Data is not null)
Runtime.Debug.LogError(dataArgs.Data);
};
process.OutputDataReceived += LogCompilationMessage;
process.ErrorDataReceived += LogCompilationMessage;

process.BeginOutputReadLine();
process.BeginErrorReadLine();
Expand All @@ -117,4 +99,154 @@ public static int CompileCSProject(FileInfo project, DotnetCompileOptions option

return exitCode;
}


private static string ParseMessageCSFile(string message, out string? csFile)
{
int validIndex = -1;
csFile = null;

foreach (int possibleIndex in AllIndexesOf(message, ".cs("))
{
string potentialFile = message.Substring(0, Math.Min(message.Length - 1, possibleIndex + 3));

if (File.Exists(potentialFile))
{
csFile = potentialFile;
validIndex = possibleIndex + 3;
break;
}
}

if (validIndex == -1)
return message;

return message.Substring(validIndex);
}


private static string ParseMessageCSProj(string message, out string? csprojFile)
{
int validIndex = -1;
csprojFile = null;

foreach (int possibleIndex in AllIndexesOf(message, "["))
{
string potentialFile = message.Substring(possibleIndex + 1, message.Length - (possibleIndex + 2));

if (File.Exists(potentialFile))
{
csprojFile = potentialFile;
validIndex = possibleIndex + 1;
break;
}
}

if (validIndex == -1)
return message;

return message.Substring(0, validIndex - 2);
}


private static string ParseFileLocations(string message, out int? line, out int? column)
{
line = null;
column = null;

int valueIndex = message.IndexOf(':');

if (valueIndex == -1)
return message;

string[] sourceLocations = message
.Substring(1, valueIndex - 2)
.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);

if (sourceLocations.Length > 0)
if (int.TryParse(sourceLocations[0], out int l))
line = l;

if (sourceLocations.Length > 1)
if (int.TryParse(sourceLocations[1], out int c))
column = c;

return message.Substring(valueIndex + 2);
}


private static string ParseSeverityAndType(string message, out LogSeverity severity, out string? type)
{
severity = LogSeverity.Normal;
type = null;

int valueIndex = message.IndexOf(':');

if (valueIndex == -1)
return message;

// Extract the (severity,warningType) from the message
string[] severityAndType = message.Substring(0, valueIndex).Split(default(char[]), StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);

if (severityAndType.Length > 0)
{
if (string.Equals(severityAndType[0], "warning", StringComparison.OrdinalIgnoreCase))
severity = LogSeverity.Warning;
else if (string.Equals(severityAndType[0], "error", StringComparison.OrdinalIgnoreCase))
severity = LogSeverity.Error;
else
severity = LogSeverity.Normal;
}

if (severityAndType.Length > 1)
{
type = severityAndType[1];
}

return message.Substring(valueIndex + 2);
}


private static void LogCompilationMessage(object? sender, DataReceivedEventArgs args)
{
string? message = args.Data;

if (string.IsNullOrWhiteSpace(message))
return;

message = ParseMessageCSFile(message, out string? csFile);

// Ignore info messages (restore, error/warn count, time elapsed, etc...)
if (csFile == null)
return;

message = ParseMessageCSProj(message, out string? csprojFile);
message = ParseFileLocations(message, out int? line, out int? column);
message = ParseSeverityAndType(message, out LogSeverity severity, out string? type);

if (type != null)
message = $"error {type}: " + message;

if (csFile != null)
message = $"{Path.GetFileName(csFile)}: " + message;

DebugStackTrace trace = csFile == null ?
new DebugStackTrace() :
new DebugStackTrace(
new DebugStackFrame(csFile, line, column)
);

Runtime.Debug.Log(message, severity, trace);
}


private static IEnumerable<int> AllIndexesOf(string str, string searchstring)
{
int minIndex = str.IndexOf(searchstring);
while (minIndex != -1)
{
yield return minIndex;
minIndex = str.IndexOf(searchstring, minIndex + searchstring.Length);
}
}
}

0 comments on commit 6070560

Please sign in to comment.