Merge remote-tracking branch 'kanaka/master' into kotlin
[jackhill/mal.git] / cs / interop.cs
CommitLineData
01c97316
JM
1using System;
2using System.CodeDom.Compiler;
3using System.Collections.Generic;
4using System.Linq;
5using System.Text;
6using Microsoft.CSharp;
7
8public static class EvalProvider
9{
10 public static Func<T, TResult> CreateEvalMethod<T, TResult>(string code, string[] usingStatements = null, string[] assemblies = null)
11 {
12 Type returnType = typeof(TResult);
13 Type inputType = typeof(T);
14
15 var includeUsings = new HashSet<string>(new[] { "System" });
16 includeUsings.Add(returnType.Namespace);
17 includeUsings.Add(inputType.Namespace);
18 if (usingStatements != null)
19 foreach (var usingStatement in usingStatements)
20 includeUsings.Add(usingStatement);
21
22 using (CSharpCodeProvider compiler = new CSharpCodeProvider())
23 {
24 var name = "F" + Guid.NewGuid().ToString().Replace("-", string.Empty);
25 var includeAssemblies = new HashSet<string>(new[] { "system.dll" });
26 if (assemblies != null)
27 foreach (var assembly in assemblies)
28 includeAssemblies.Add(assembly);
29
30 var parameters = new CompilerParameters(includeAssemblies.ToArray())
31 {
32 GenerateInMemory = true
33 };
34
35 string source = string.Format(@"
36{0}
37namespace {1}
38{{
39 public static class EvalClass
40 {{
41 public static {2} Eval({3} arg)
42 {{
43 {4}
44 }}
45 }}
46}}", GetUsing(includeUsings), name, returnType.Name, inputType.Name, code);
47
48 var compilerResult = compiler.CompileAssemblyFromSource(parameters, source);
49 var compiledAssembly = compilerResult.CompiledAssembly;
50 var type = compiledAssembly.GetType(string.Format("{0}.EvalClass", name));
51 var method = type.GetMethod("Eval");
52 return (Func<T, TResult>)Delegate.CreateDelegate(typeof(Func<T, TResult>), method);
53 }
54 }
55
56 private static string GetUsing(HashSet<string> usingStatements)
57 {
58 StringBuilder result = new StringBuilder();
59 foreach (string usingStatement in usingStatements)
60 {
61 result.AppendLine(string.Format("using {0};", usingStatement));
62 }
63 return result.ToString();
64 }
65}
66