/// <summary> /// Compiles the input string and returns a delegate that represents the compiled code. /// </summary> /// <remarks> /// /// Compiles the input string as a C# expression or /// statement, unlike the Evaluate method, the /// resulting delegate can be invoked multiple times /// without incurring in the compilation overhead. /// /// If the return value of this function is null, /// this indicates that the parsing was complete. /// If the return value is a string it indicates /// that the input string was partial and that the /// invoking code should provide more code before /// the code can be successfully compiled. /// /// If you know that you will always get full expressions or /// statements and do not care about partial input, you can use /// the other Compile overload. /// /// On success, in addition to returning null, the /// compiled parameter will be set to the delegate /// that can be invoked to execute the code. /// /// </remarks> static public string Compile(string input, out CompiledMethod compiled) { if (input == null || input.Length == 0) { compiled = null; return(null); } lock (evaluator_lock) { if (!inited) { Init(); } else { ctx.Report.Printer.Reset(); } // RootContext.ToplevelTypes = new ModuleContainer (ctx); bool partial_input; CSharpParser parser = ParseString(ParseMode.Silent, input, out partial_input); if (parser == null) { compiled = null; if (partial_input) { return(input); } ParseString(ParseMode.ReportErrors, input, out partial_input); return(null); } object parser_result = parser.InteractiveResult; if (!(parser_result is Class)) { int errors = ctx.Report.Errors; NamespaceEntry.VerifyAllUsing(); if (errors == ctx.Report.Errors) { parser.CurrentNamespace.Extract(using_alias_list, using_list); } else { NamespaceEntry.Reset(); } } #if STATIC throw new NotSupportedException(); #else compiled = CompileBlock(parser_result as Class, parser.undo, ctx.Report); return(null); #endif } }
/// <summary> /// Compiles the input string and returns a delegate that represents the compiled code. /// </summary> /// <remarks> /// /// Compiles the input string as a C# expression or /// statement, unlike the Evaluate method, the /// resulting delegate can be invoked multiple times /// without incurring in the compilation overhead. /// /// If the return value of this function is null, /// this indicates that the parsing was complete. /// If the return value is a string it indicates /// that the input string was partial and that the /// invoking code should provide more code before /// the code can be successfully compiled. /// /// If you know that you will always get full expressions or /// statements and do not care about partial input, you can use /// the other Compile overload. /// /// On success, in addition to returning null, the /// compiled parameter will be set to the delegate /// that can be invoked to execute the code. /// /// </remarks> static public string Compile(string input, out CompiledMethod compiled) { if (input == null || input.Length == 0) { compiled = null; return(null); } lock (evaluator_lock){ if (!inited) { Init(); } bool partial_input; CSharpParser parser = ParseString(true, input, out partial_input); if (parser == null) { compiled = null; if (partial_input) { return(input); } ParseString(false, input, out partial_input); return(null); } object parser_result = parser.InteractiveResult; if (!(parser_result is Class)) { int errors = Report.Errors; NamespaceEntry.VerifyAllUsing(); if (errors == Report.Errors) { parser.CurrentNamespace.Extract(using_alias_list, using_list); } } compiled = CompileBlock(parser_result as Class, parser.undo); } return(null); }
//public static string GetPackageFlags (string packages, Report report) //{ // ProcessStartInfo pi = new ProcessStartInfo (); // pi.FileName = "pkg-config"; // pi.RedirectStandardOutput = true; // pi.UseShellExecute = false; // pi.Arguments = "--libs " + packages; // Process p = null; // try { // p = Process.Start (pi); // } catch (Exception e) { // if (report == null) // throw; // report.Error (-27, "Couldn't run pkg-config: " + e.Message); // return null; // } // if (p.StandardOutput == null) { // if (report == null) // throw new ApplicationException ("Specified package did not return any information"); // report.Warning (-27, 1, "Specified package did not return any information"); // p.Close (); // return null; // } // string pkgout = p.StandardOutput.ReadToEnd (); // p.WaitForExit (); // if (p.ExitCode != 0) { // if (report == null) // throw new ApplicationException (pkgout); // report.Error (-27, "Error running pkg-config. Check the above output."); // p.Close (); // return null; // } // p.Close (); // return pkgout; //} // // Main compilation method // public bool Compile() { var settings = ctx.Settings; // // If we are an exe, require a source file for the entry point or // if there is nothing to put in the assembly, and we are not a library // if (Location.FirstFile == null && ((settings.Target == Target.Exe || settings.Target == Target.WinExe || settings.Target == Target.Module) || settings.Resources == null)) { Report.Error(2008, "No files to compile were specified"); return(false); } TimeReporter tr = new TimeReporter(settings.Timestamps); ctx.TimeReporter = tr; tr.StartTotal(); var module = new ModuleContainer(ctx); RootContext.ToplevelTypes = module; tr.Start(TimeReporter.TimerType.ParseTotal); Parse(module); tr.Stop(TimeReporter.TimerType.ParseTotal); if (Report.Errors > 0) { return(false); } if (settings.TokenizeOnly || settings.ParseOnly) { return(true); } if (RootContext.ToplevelTypes.NamespaceEntry != null) { throw new InternalErrorException("who set it?"); } var output_file = settings.OutputFile; string output_file_name; if (output_file == null) { output_file_name = Location.FirstFile; if (output_file_name == null) { Report.Error(1562, "If no source files are specified you must specify the output file with -out:"); return(false); } int pos = output_file_name.LastIndexOf('.'); if (pos > 0) { output_file_name = output_file_name.Substring(0, pos); } output_file_name += settings.TargetExt; output_file = output_file_name; } else { output_file_name = Path.GetFileName(output_file); } #if STATIC var importer = new StaticImporter(module); var references_loader = new StaticLoader(importer, ctx); tr.Start(TimeReporter.TimerType.AssemblyBuilderSetup); var assembly = new AssemblyDefinitionStatic(module, references_loader, output_file_name, output_file); assembly.Create(references_loader.Domain); tr.Stop(TimeReporter.TimerType.AssemblyBuilderSetup); // Create compiler types first even before any referenced // assembly is loaded to allow forward referenced types from // loaded assembly into compiled builder to be resolved // correctly tr.Start(TimeReporter.TimerType.CreateTypeTotal); module.CreateType(); importer.AddCompiledAssembly(assembly); tr.Stop(TimeReporter.TimerType.CreateTypeTotal); references_loader.LoadReferences(module); tr.Start(TimeReporter.TimerType.PredefinedTypesInit); if (!ctx.BuildinTypes.CheckDefinitions(module)) { return(false); } tr.Stop(TimeReporter.TimerType.PredefinedTypesInit); references_loader.LoadModules(assembly, module.GlobalRootNamespace); #else var assembly = new AssemblyDefinitionDynamic(module, output_file_name, output_file); module.SetDeclaringAssembly(assembly); var importer = new ReflectionImporter(module, ctx.BuildinTypes); assembly.Importer = importer; var loader = new DynamicLoader(importer, ctx); loader.LoadReferences(module); if (!ctx.BuildinTypes.CheckDefinitions(module)) { return(false); } if (!assembly.Create(AppDomain.CurrentDomain, AssemblyBuilderAccess.Run)) { return(false); } module.CreateType(); loader.LoadModules(assembly, module.GlobalRootNamespace); #endif tr.Start(TimeReporter.TimerType.ModuleDefinitionTotal); module.Define(); tr.Stop(TimeReporter.TimerType.ModuleDefinitionTotal); if (Report.Errors > 0) { return(false); } //if (settings.Documentation != null && // !settings.Documentation.OutputDocComment ( // output_file, Report)) // return false; // // Verify using aliases now // tr.Start(TimeReporter.TimerType.UsingVerification); NamespaceEntry.VerifyAllUsing(); tr.Stop(TimeReporter.TimerType.UsingVerification); if (Report.Errors > 0) { return(false); } assembly.Resolve(); if (Report.Errors > 0) { return(false); } tr.Start(TimeReporter.TimerType.EmitTotal); assembly.Emit(); tr.Stop(TimeReporter.TimerType.EmitTotal); if (Report.Errors > 0) { return(false); } tr.Start(TimeReporter.TimerType.CloseTypes); module.CloseType(); tr.Stop(TimeReporter.TimerType.CloseTypes); tr.Start(TimeReporter.TimerType.Resouces); assembly.EmbedResources(); tr.Stop(TimeReporter.TimerType.Resouces); if (Report.Errors > 0) { return(false); } assembly.Save(); #if STATIC references_loader.Dispose(); #endif tr.StopTotal(); tr.ShowStats(); return(Report.Errors == 0); }