Skip to content
Merged
Show file tree
Hide file tree
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
59 changes: 41 additions & 18 deletions MCPForUnity/Editor/Tools/ExecuteCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,34 +275,57 @@ private static Assembly CodeDomCompile(string source, string[] assemblyPaths, ou
// CodeDom needs the netstandard-aware filtered paths
var filtered = FilterAssemblyPathsForCodeDom(assemblyPaths);

using (var provider = new CSharpCodeProvider())
// CSharpCodeProvider turns every ReferencedAssemblies entry into a literal /r:"..." flag
// on the csc command line. Projects with ~100+ asmdefs blow past Windows' 32 KB
// CreateProcess argument limit and fail with "The filename or extension is too long."
// Route references through a response file (@responsefile is supported by both mcs and
// Roslyn csc) so we pass exactly one short argument regardless of reference count.
string responseFilePath = Path.Combine(Path.GetTempPath(), $"mcp-codedom-{Guid.NewGuid():N}.rsp");

try
{
var parameters = new CompilerParameters
using (var writer = new StreamWriter(responseFilePath, append: false, Encoding.UTF8))
{
GenerateInMemory = true,
GenerateExecutable = false,
TreatWarningsAsErrors = false,
};
foreach (var path in filtered)
{
writer.Write("/r:\"");
Comment on lines +287 to +291
writer.Write(path);
writer.WriteLine("\"");
}
}

foreach (var path in filtered)
parameters.ReferencedAssemblies.Add(path);
using (var provider = new CSharpCodeProvider())
{
var parameters = new CompilerParameters
{
GenerateInMemory = true,
GenerateExecutable = false,
TreatWarningsAsErrors = false,
CompilerOptions = "@\"" + responseFilePath + "\"",
};

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

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

return results.CompiledAssembly;
return results.CompiledAssembly;
}
}
finally
{
try { if (File.Exists(responseFilePath)) File.Delete(responseFilePath); }
catch { /* best effort */ }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,41 @@ public void NullParams_ReturnsError()
Assert.IsFalse(result.Value<bool>("success"), result.ToString());
}

// ──────────────────── CodeDom backend ────────────────────

// Regression for CoplayDev/unity-mcp#1144: large projects (~100+ asmdefs) blew past the
// Windows 32 KB CreateProcess limit because every reference became an inline /r: flag.
// The fix routes references through a @responsefile, so this just verifies that the
// codedom path still compiles and runs end-to-end.
[Test]
public void Execute_CodedomBackend_CompilesAndRuns()
{
var result = ToJObject(ExecuteCode.HandleCommand(new JObject
{
["action"] = "execute",
["code"] = "return 1 + 1;",
["compiler"] = "codedom"
}));

Assert.IsTrue(result.Value<bool>("success"), result.ToString());
Assert.AreEqual(2, result["data"]["result"].Value<int>());
Assert.AreEqual("codedom", result["data"]["compiler"].Value<string>());
}

[Test]
public void Execute_CodedomBackend_ResolvesUnityTypes()
{
var result = ToJObject(ExecuteCode.HandleCommand(new JObject
{
["action"] = "execute",
["code"] = "return UnityEngine.Application.unityVersion;",
["compiler"] = "codedom"
}));

Assert.IsTrue(result.Value<bool>("success"), result.ToString());
Assert.IsNotNull(result["data"]["result"]);
}

// ──────────────────── Helpers ────────────────────

private static JObject Execute(string code)
Expand Down
Loading