Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 38 additions & 12 deletions MCPForUnity/Editor/Tools/ExecuteCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -294,32 +294,58 @@ private static Assembly CodeDomCompile(string source, string[] assemblyPaths, ou
}
}

// Compile to a controlled DLL path instead of in-memory. mcs prints a stray BOM line on
// stdout that Mono's CodeDom can't parse, so it fabricates a bogus error (no error number,
// text is just the BOM) and refuses to surface the assembly — even though mcs exits 0 and
// wrote the DLL. We skip that bogus error and Assembly.Load the produced DLL ourselves.
string outputAssemblyPath = Path.Combine(Path.GetTempPath(), $"mcp-codedom-{Guid.NewGuid():N}.dll");
using (var provider = new CSharpCodeProvider())
{
var parameters = new CompilerParameters
{
GenerateInMemory = true,
GenerateInMemory = false,
OutputAssembly = outputAssemblyPath,
GenerateExecutable = false,
TreatWarningsAsErrors = false,
CompilerOptions = "@\"" + responseFilePath + "\"",
};

var results = provider.CompileAssemblyFromSource(parameters, source);

if (results.Errors.HasErrors)
try
{
var results = provider.CompileAssemblyFromSource(parameters, source);

bool hasRealErrors = false;
foreach (CompilerError error in results.Errors)
{
if (!error.IsWarning)
{
int userLine = Math.Max(1, error.Line - WrapperLineOffset);
errors.Add($"Line {userLine}: {error.ErrorText}");
}
if (error.IsWarning)
continue;

// The bogus BOM "error": no error number, text is just the BOM/whitespace.
string text = error.ErrorText?.Trim('', ' ', '\t', '\r', '\n');
if (string.IsNullOrEmpty(error.ErrorNumber) && string.IsNullOrEmpty(text))
continue;

hasRealErrors = true;
int userLine = Math.Max(1, error.Line - WrapperLineOffset);
errors.Add($"Line {userLine}: {error.ErrorText}");
}
return null;
}

return results.CompiledAssembly;
if (hasRealErrors)
return null;

if (!File.Exists(outputAssemblyPath))
{
errors.Add("CodeDom reported success but produced no assembly.");
return null;
}

return Assembly.Load(File.ReadAllBytes(outputAssemblyPath));
}
finally
{
try { if (File.Exists(outputAssemblyPath)) File.Delete(outputAssemblyPath); }
catch { /* best effort */ }
}
}
}
finally
Expand Down