예제 #1
0
        public async Task Execute(string code, NScriptOptions scriptOptions)
        {
            if (code.Contains("static void Main(") || code.Contains("static async Task Main("))
            {
                // Program
            }
            else
            {
                // Statement
                if (code.Contains("await "))
                {
                    //async
                    code = $@"public static async Task MainAsync()
  {{
    {code}
  }}";
                }
                else
                {
                    // sync
                    code = $@"public static void Main(string[] args)
  {{
    {code}
  }}";
                }
            }

            if (!code.Contains("static void Main(") && code.Contains("static async Task Main("))
            {
                if (code.Contains("static async Task Main()"))
                {
                    code = $@"{code}
public static void Main() => MainAsync().Wait();
";
                }
                else
                {
                    code = $@"{code}
public static void Main() => MainAsync(null).Wait();
";
                }
            }

            if (!code.Contains("class Program"))
            {
                code = $@"public class Program
{{
  {code}
}}";
            }

            scriptOptions.UsingList.Add("NatashaPad");

            code = $"{scriptOptions.UsingList.Select(ns => $"using {ns};").StringJoin(Environment.NewLine)}{Environment.NewLine}{code}";

            using var domain = DomainManagement.Random;
            var assBuilder = new AssemblyCSharpBuilder();

            assBuilder.Add(code, scriptOptions.UsingList);

            // add reference
            if (scriptOptions.ReferenceResolvers.Count > 0)
            {
                var references = await scriptOptions.ReferenceResolvers
                                 .Select(r => r.Resolve())
                                 .WhenAll()
                                 .ContinueWith(r => r.Result.SelectMany(_ => _).ToArray());

                // add reference
                foreach (var reference in references)
                {
                    // TODO: handle none filePath reference
                    if (!string.IsNullOrEmpty(reference?.FilePath))
                    {
                        domain.LoadPluginFromStream(reference.FilePath);
                    }
                }
            }
            assBuilder.Compiler.Domain             = domain;
            assBuilder.Compiler.AssemblyOutputKind = AssemblyBuildKind.File;

            var assembly = assBuilder.GetAssembly();

            using (var capture = await ConsoleOutput.CaptureAsync())
            {
                var entryPoint = assembly.EntryPoint
                                 ?? assembly.GetType("Program")?.GetMethod("Main",
                                                                           BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                if (null != entryPoint)
                {
                    entryPoint.Invoke(null, entryPoint.GetParameters().Select(p => p.ParameterType.GetDefaultValue()).ToArray());
                }
                else
                {
                    throw new ArgumentException("can not find entry point");
                }
                if (!string.IsNullOrEmpty(capture.StandardOutput))
                {
                    DumpOutHelper.OutputAction?.Invoke(capture.StandardOutput);
                }
            }
        }
예제 #2
0
 public CompilerTemplate()
 {
     AssemblyBuilder = new AssemblyCSharpBuilder();
 }
예제 #3
0
 public static T UseCompiler(AssemblyCSharpBuilder builder, Action <AssemblyCSharpBuilder> option = default)
 {
     return(UseDomain(builder.Compiler.Domain, option));
 }
예제 #4
0
 public CompilerTemplate()
 {
     AssemblyBuilder = new();
 }