//--------------------------------------------------------------------------------------------------------------------------------------------------- // CSharpCompiler class // Designed to execute code with the required assemblies, both C# code as well as DW engine code // Takes the student code, compiles it into memory, and returns the results //--------------------------------------------------------------------------------------------------------------------------------------------------- // Engineered by: Amanda Chaffin //--------------------------------------------------------------------------------------------------------------------------------------------------- namespace DarkWynter.Engine.Compiler { #region Using Statements using System; using System.Collections.Generic; using System.Text; using System.CodeDom; using System.CodeDom.Compiler; using System.Runtime.CompilerServices; using System.Reflection; using Microsoft.CSharp; using System.Security; using System.Security.Permissions; using System.IO; #endregion /// <summary> /// Creates a CSharpCompiler for use in game /// </summary> public class CSharpCompiler { public static object Execute(string source, string className, string functionName, object[] parameters) { CompilerResults compilerResults = CompileCode(source); if (compilerResults.Errors.Count > 0) { throw new Exception("Not a valid assembly"); } return Execute(compilerResults.CompiledAssembly, className, functionName, parameters); } /// <summary> /// Executes the code with the assembly information /// </summary> /// <param name="a">assembly provided</param> /// <param name="parameters">any needed object parameters</param>6 /// <param name="callingObject">the object that calls the method</param> /// <returns>returns the null object</returns> public static object Execute(Assembly a, // string className, // string functionName, object[] parameters, ref object callingObject) { object obj = null; Type type = a.GetType(); foreach (Type tempType in a.GetTypes()) { type = tempType; try { foreach (MethodInfo info in type.GetMethods()) { Array tempArray = info.GetParameters(); if (info.GetParameters().Length == 0) { if (obj == null) { obj = Activator.CreateInstance(type); info.Invoke(obj, null); } } } } catch (Exception e) { Console.WriteLine(e.Message); } } return obj; } /// <summary> /// Calls the execute function /// </summary> /// <param name="a">assembly provided</param> /// <param name="className">Name of the class to be executed</param> /// <param name="parameters">any needed object parameters</param> /// <param name="callingObject">the object that calls the method</param> /// <returns>returns the null object</returns> public static object Execute(Assembly assembly, string className, string functionName, object[] parameters) { object o = null; return Execute(assembly, parameters, ref o); } /// <summary> /// Gets the student code from the CompilerControl /// Adds in the assemblies we use to allow student control of game code /// Calls execute /// </summary> /// <param name="source">Student code</param> /// <returns>The results from the compiler</returns> public static CompilerResults CompileCode(String source) { CodeDomProvider provider = new CSharpCodeProvider(); CompilerParameters compilerParameters = new CompilerParameters(); // Generate a class library. compilerParameters.GenerateExecutable = false; compilerParameters.GenerateInMemory = true; // Generate debug information. compilerParameters.IncludeDebugInformation = false; // Add an assembly reference. Assembly assembly = Assembly.GetExecutingAssembly(); foreach (AssemblyName assemblyName in Assembly.GetEntryAssembly().GetReferencedAssemblies()) { if (assemblyName.Name == "DWEngine" || assemblyName.Name == "DWStream") { compilerParameters.ReferencedAssemblies.Add(assemblyName.Name + ".dll"); } } // compilerParameters.ReferencedAssemblies.Add("DarkWynterGame" + ".dll"); // Set the level at which the compiler // should start displaying warnings. compilerParameters.WarningLevel = 3; // Set whether to treat all warnings as errors. compilerParameters.TreatWarningsAsErrors = false; // Set compiler argument to optimize output. compilerParameters.CompilerOptions = "/optimize"; // Invoke compilation. CompilerResults compilerResults = provider.CompileAssemblyFromSource( compilerParameters, new string[] { source }); return compilerResults; //} } } }