CompilerResults CompileLine(string codeStr, CHash type, string assemblyName, string className)
{
CompilerParameters cp = new CompilerParameters();
if (type == CHash.Function)
cp.OutputAssembly = assemblyName;
else
cp.GenerateInMemory = true;
foreach (string r in referenceList)
{
#if DEBUG
if (!System.Diagnostics.Debugger.IsAttached)
Utils.Print(r);
#endif
cp.ReferencedAssemblies.Add(r);
}
string exprStr = codeStr;
returnsValue = false;
if (type == CHash.Expression)
{
if (codeStr[0] != '{' && !word_within(firstToken(codeStr), keywords))
{
returnsValue = true;
exprStr = "V[\"_\"] = " + codeStr;
}
}
CompilerResults cr = CompileTemplate(cp, exprStr, type, className);
if (cr.Errors.HasErrors)
{
if (returnsValue)
{
// we assumed that this expression did return a value; we were wrong.
// Try it again, without assignment to $_
returnsValue = false;
cp.OutputAssembly = null; // Reset value, which is needed for Mono to work
CompilerResults cr2 = CompileTemplate(cp, codeStr, CHash.Expression, "");
if (!cr2.Errors.HasErrors)
return cr2;
try
{
bool firstErrorIsTypeConversion = false;
foreach (CompilerError err in cr.Errors)
{
// Check for "Cannot implicitly convert type `void' to `object'"
if (string.Equals("CS0029", err.ErrorNumber, StringComparison.OrdinalIgnoreCase)
&& (!string.IsNullOrEmpty(err.ErrorText))
&& (err.ErrorText.IndexOf("void", 0, StringComparison.OrdinalIgnoreCase) >= 0))
{
firstErrorIsTypeConversion = true;
break;
}
}
bool secondErrorIsTooCommon = false;
foreach (CompilerError err in cr2.Errors)
{
// Check for "Only assignment, call, increment, decrement, and new object expressions can be used as a statement"
if (string.Equals("CS0201", err.ErrorNumber, StringComparison.OrdinalIgnoreCase))
{
secondErrorIsTooCommon = true;
break;
}
}
// Usually show the second error, unless it is not very
// informative and the first error is unlikely to have
// been caused by our editing of the expression string
if ((!secondErrorIsTooCommon) || (firstErrorIsTypeConversion))
{
cr = cr2;
}
}
catch
{
// Assume that most recent error is mostly appropriate
cr = cr2;
}
}
ShowErrors(cr, codeStr);
return null;
}
else
return cr;
}