CompiledMethod CompileBlock (Class host, Undo undo, Report Report) { #if STATIC throw new NotSupportedException (); #else string current_debug_name = "eval-" + count + ".dll"; ++count; AssemblyDefinitionDynamic assembly; AssemblyBuilderAccess access; if (Environment.GetEnvironmentVariable ("SAVE") != null) { access = AssemblyBuilderAccess.RunAndSave; assembly = new AssemblyDefinitionDynamic (module, current_debug_name, current_debug_name); assembly.Importer = importer; } else { #if NET_4_0 access = AssemblyBuilderAccess.RunAndCollect; #else access = AssemblyBuilderAccess.Run; #endif assembly = new AssemblyDefinitionDynamic (module, current_debug_name); } assembly.Create (AppDomain.CurrentDomain, access); Method expression_method; if (host != null) { var base_class_imported = importer.ImportType (base_class); var baseclass_list = new List<FullNamedExpression> (1) { new TypeExpression (base_class_imported, host.Location) }; host.AddBasesForPart (baseclass_list); host.CreateContainer (); host.DefineContainer (); host.Define (); expression_method = (Method) host.Members[0]; } else { expression_method = null; } module.CreateContainer (); source_file.EnableUsingClausesRedefinition (); module.Define (); if (Report.Errors != 0){ if (undo != null) undo.ExecuteUndo (); return null; } if (host != null){ host.EmitContainer (); } module.EmitContainer (); if (Report.Errors != 0){ if (undo != null) undo.ExecuteUndo (); return null; } module.CloseContainer (); if (host != null) host.CloseContainer (); if (access == AssemblyBuilderAccess.RunAndSave) assembly.Save (); if (host == null) return null; // // Unlike Mono, .NET requires that the MethodInfo is fetched, it cant // work from MethodBuilders. Retarded, I know. // var tt = assembly.Builder.GetType (host.TypeBuilder.Name); var mi = tt.GetMethod (expression_method.MemberName.Name); // // We need to then go from FieldBuilder to FieldInfo // or reflection gets confused (it basically gets confused, and variables override each // other). // foreach (var member in host.Members) { var field = member as Field; if (field == null) continue; var fi = tt.GetField (field.Name); Tuple<FieldSpec, FieldInfo> old; // If a previous value was set, nullify it, so that we do // not leak memory if (fields.TryGetValue (field.Name, out old)) { if (old.Item1.MemberType.IsStruct) { // // TODO: Clear fields for structs // } else { try { old.Item2.SetValue (null, null); } catch { } } } fields[field.Name] = Tuple.Create (field.Spec, fi); } return (CompiledMethod) System.Delegate.CreateDelegate (typeof (CompiledMethod), mi); #endif }
CompiledMethod CompileBlock (Class host, Undo undo, Report Report) { #if STATIC throw new NotSupportedException (); #else string current_debug_name = "eval-" + count + ".dll"; ++count; AssemblyDefinitionDynamic assembly; AssemblyBuilderAccess access; if (Environment.GetEnvironmentVariable ("SAVE") != null) { access = AssemblyBuilderAccess.RunAndSave; assembly = new AssemblyDefinitionDynamic (module, current_debug_name, current_debug_name); assembly.Importer = importer; } else { #if NET_4_0 access = AssemblyBuilderAccess.RunAndCollect; #else access = AssemblyBuilderAccess.Run; #endif assembly = new AssemblyDefinitionDynamic (module, current_debug_name); } assembly.Create (AppDomain.CurrentDomain, access); Method expression_method; if (host != null) { var base_class_imported = importer.ImportType (base_class); var baseclass_list = new List<FullNamedExpression> (1) { new TypeExpression (base_class_imported, host.Location) }; host.SetBaseTypes (baseclass_list); expression_method = (Method) host.Members[0]; if ((expression_method.ModFlags & Modifiers.ASYNC) != 0) { // // Host method is async. When WaitOnTask is set we wrap it with wait // // void AsyncWait (ref object $retval) { // $retval = Host(); // ((Task)$retval).Wait(); // When WaitOnTask is set // } // var p = new ParametersCompiled ( new Parameter (new TypeExpression (module.Compiler.BuiltinTypes.Object, Location.Null), "$retval", Parameter.Modifier.REF, null, Location.Null) ); var method = new Method(host, new TypeExpression(module.Compiler.BuiltinTypes.Void, Location.Null), Modifiers.PUBLIC | Modifiers.STATIC, new MemberName("AsyncWait"), p, null); method.Block = new ToplevelBlock(method.Compiler, p, Location.Null); method.Block.AddStatement(new StatementExpression (new SimpleAssign( new SimpleName(p [0].Name, Location.Null), new Invocation(new SimpleName(expression_method.MemberName.Name, Location.Null), new Arguments(0)), Location.Null), Location.Null)); if (WaitOnTask) { var task = new Cast (expression_method.TypeExpression, new SimpleName (p [0].Name, Location.Null), Location.Null); method.Block.AddStatement (new StatementExpression (new Invocation ( new MemberAccess (task, "Wait", Location.Null), new Arguments (0)), Location.Null)); } host.AddMember(method); expression_method = method; } host.CreateContainer(); host.DefineContainer(); host.Define(); } else { expression_method = null; } module.CreateContainer (); // Disable module and source file re-definition checks module.EnableRedefinition (); source_file.EnableRedefinition (); module.Define (); if (Report.Errors != 0){ if (undo != null) undo.ExecuteUndo (); return null; } if (host != null){ host.PrepareEmit (); host.EmitContainer (); } module.EmitContainer (); if (Report.Errors != 0){ if (undo != null) undo.ExecuteUndo (); return null; } module.CloseContainer (); if (host != null) host.CloseContainer (); if (access == AssemblyBuilderAccess.RunAndSave) assembly.Save (); if (host == null) return null; // // Unlike Mono, .NET requires that the MethodInfo is fetched, it cant // work from MethodBuilders. Retarded, I know. // var tt = assembly.Builder.GetType (host.TypeBuilder.Name); var mi = tt.GetMethod (expression_method.MemberName.Name); // // We need to then go from FieldBuilder to FieldInfo // or reflection gets confused (it basically gets confused, and variables override each // other). // foreach (var member in host.Members) { var field = member as Field; if (field == null) continue; var fi = tt.GetField (field.Name); Tuple<FieldSpec, FieldInfo> old; // If a previous value was set, nullify it, so that we do // not leak memory if (fields.TryGetValue (field.Name, out old)) { if (old.Item1.MemberType.IsStruct) { // // TODO: Clear fields for structs // } else { try { old.Item2.SetValue (null, null); } catch { } } } fields[field.Name] = Tuple.Create (field.Spec, fi); } return (CompiledMethod) System.Delegate.CreateDelegate (typeof (CompiledMethod), mi); #endif }
public string [] GetCompletions (string input, out string prefix) { prefix = ""; if (input == null || input.Length == 0) return null; lock (evaluator_lock){ if (!inited) Init (); bool partial_input; CSharpParser parser = ParseString (ParseMode.GetCompletions, input, out partial_input); if (parser == null){ return null; } Class parser_result = parser.InteractiveResult; #if NET_4_0 var access = AssemblyBuilderAccess.RunAndCollect; #else var access = AssemblyBuilderAccess.Run; #endif var a = new AssemblyDefinitionDynamic (module, "completions"); a.Create (AppDomain.CurrentDomain, access); module.SetDeclaringAssembly (a); // Need to setup MemberCache parser_result.CreateContainer (); var method = parser_result.Members[0] as Method; BlockContext bc = new BlockContext (method, method.Block, ctx.BuiltinTypes.Void); try { method.Block.Resolve (null, bc, method); } catch (CompletionResult cr) { prefix = cr.BaseText; return cr.Result; } } return null; }
public static string [] GetCompletions (string input, out string prefix) { prefix = ""; if (input == null || input.Length == 0) return null; lock (evaluator_lock){ if (!inited) Init (); bool partial_input; CSharpParser parser = ParseString (ParseMode.GetCompletions, input, out partial_input); if (parser == null){ if (CSharpParser.yacc_verbose_flag != 0) Console.WriteLine ("DEBUG: No completions available"); return null; } Class parser_result = parser.InteractiveResult; try { var a = new AssemblyDefinitionDynamic (RootContext.ToplevelTypes, "temp"); a.Create (AppDomain.CurrentDomain, AssemblyBuilderAccess.Run); RootContext.ToplevelTypes.SetDeclaringAssembly (a); RootContext.ToplevelTypes.CreateType (); RootContext.ToplevelTypes.Define (); parser_result.CreateType (); parser_result.Define (); if (ctx.Report.Errors != 0) return null; MethodOrOperator method = null; foreach (MemberCore member in parser_result.Methods){ if (member.Name != "Host") continue; method = (MethodOrOperator) member; break; } if (method == null) throw new InternalErrorException ("did not find the the Host method"); BlockContext bc = new BlockContext (method, method.Block, method.ReturnType); try { method.Block.Resolve (null, bc, method); } catch (CompletionResult cr){ prefix = cr.BaseText; return cr.Result; } } finally { parser.undo.ExecuteUndo (); } } return null; }
static CompiledMethod CompileBlock (Class host, Undo undo, Report Report) { AssemblyDefinitionDynamic assembly; AssemblyBuilderAccess access; if (Environment.GetEnvironmentVariable ("SAVE") != null) { access = AssemblyBuilderAccess.RunAndSave; assembly = new AssemblyDefinitionDynamic (RootContext.ToplevelTypes, current_debug_name, current_debug_name); assembly.Importer = loader.Importer; } else { #if NET_4_0 access = AssemblyBuilderAccess.RunAndCollect; #else access = AssemblyBuilderAccess.Run; #endif assembly = new AssemblyDefinitionDynamic (RootContext.ToplevelTypes, current_debug_name); } assembly.Create (AppDomain.CurrentDomain, access); if (host != null) { host.CreateType (); host.Define (); } RootContext.ToplevelTypes.CreateType (); RootContext.ToplevelTypes.Define (); if (Report.Errors != 0){ undo.ExecuteUndo (); return null; } TypeBuilder tb = null; MethodBuilder mb = null; if (host != null){ tb = host.TypeBuilder; mb = null; foreach (MemberCore member in host.Methods){ if (member.Name != "Host") continue; MethodOrOperator method = (MethodOrOperator) member; mb = method.MethodBuilder; break; } if (mb == null) throw new Exception ("Internal error: did not find the method builder for the generated method"); host.EmitType (); } RootContext.ToplevelTypes.Emit (); if (Report.Errors != 0){ undo.ExecuteUndo (); return null; } RootContext.ToplevelTypes.CloseType (); if (host != null) host.CloseType (); if (access == AssemblyBuilderAccess.RunAndSave) assembly.Save (); if (host == null) return null; // // Unlike Mono, .NET requires that the MethodInfo is fetched, it cant // work from MethodBuilders. Retarded, I know. // var tt = assembly.Builder.GetType (tb.Name); MethodInfo mi = tt.GetMethod (mb.Name); // Pull the FieldInfos from the type, and keep track of them foreach (Field field in queued_fields){ FieldInfo fi = tt.GetField (field.Name); Tuple<FieldSpec, FieldInfo> old; // If a previous value was set, nullify it, so that we do // not leak memory if (fields.TryGetValue (field.Name, out old)) { if (old.Item1.MemberType.IsStruct) { // // TODO: Clear fields for structs // } else { try { old.Item2.SetValue (null, null); } catch { } } fields [field.Name] = Tuple.Create (field.Spec, fi); } else { fields.Add (field.Name, Tuple.Create (field.Spec, fi)); } } queued_fields.Clear (); return (CompiledMethod) System.Delegate.CreateDelegate (typeof (CompiledMethod), mi); }
//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; }
// // 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 (settings.FirstSourceFile == 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; } if (settings.Platform == Platform.AnyCPU32Preferred && (settings.Target == Target.Library || settings.Target == Target.Module)) { Report.Error (4023, "Platform option `anycpu32bitpreferred' is valid only for executables"); 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) { tr.StopTotal (); tr.ShowStats (); return true; } var output_file = settings.OutputFile; string output_file_name; if (output_file == null) { var source_file = settings.FirstSourceFile; if (source_file == null) { Report.Error (1562, "If no source files are specified you must specify the output file with -out:"); return false; } output_file_name = source_file.Name; 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 (string.IsNullOrEmpty (Path.GetFileNameWithoutExtension (output_file_name)) || output_file_name.IndexOfAny (Path.GetInvalidFileNameChars ()) >= 0) { Report.Error (2021, "Output file name is not valid"); return false; } } #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.CreateContainer (); importer.AddCompiledAssembly (assembly); tr.Stop (TimeReporter.TimerType.CreateTypeTotal); references_loader.LoadReferences (module); tr.Start (TimeReporter.TimerType.PredefinedTypesInit); if (!ctx.BuiltinTypes.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.BuiltinTypes); assembly.Importer = importer; var loader = new DynamicLoader (importer, ctx); loader.LoadReferences (module); if (!ctx.BuiltinTypes.CheckDefinitions (module)) return false; if (!assembly.Create (AppDomain.CurrentDomain, AssemblyBuilderAccess.Save)) return false; module.CreateContainer (); loader.LoadModules (assembly, module.GlobalRootNamespace); #endif module.InitializePredefinedTypes (); tr.Start (TimeReporter.TimerType.ModuleDefinitionTotal); module.Define (); tr.Stop (TimeReporter.TimerType.ModuleDefinitionTotal); if (Report.Errors > 0) return false; if (settings.DocumentationFile != null) { var doc = new DocumentationBuilder (module); doc.OutputDocComment (output_file, settings.DocumentationFile); } 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.CloseContainer (); tr.Stop (TimeReporter.TimerType.CloseTypes); tr.Start (TimeReporter.TimerType.Resouces); if (!settings.WriteMetadataOnly) 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; }
// // Main compilation method // public bool Compile () { var module = new ModuleContainer (ctx); RootContext.ToplevelTypes = module; if (timestamps) { stopwatch = Stopwatch.StartNew (); first_time = DateTime.Now; } Parse (module); ShowTime ("Parsing source files"); if (Report.Errors > 0) return false; if (RootContext.TokenizeOnly || RootContext.ParseOnly) return true; if (RootContext.ToplevelTypes.NamespaceEntry != null) throw new InternalErrorException ("who set it?"); // // Quick hack // var output_file = RootContext.OutputFile; string output_file_name; if (output_file == null) { if (first_source == null) { Report.Error (1562, "If no source files are specified you must specify the output file with -out:"); return false; } int pos = first_source.LastIndexOf ('.'); if (pos > 0) output_file = first_source.Substring (0, pos) + RootContext.TargetExt; else output_file = first_source + RootContext.TargetExt; output_file_name = output_file; } else { output_file_name = Path.GetFileName (output_file); } // // Load assemblies required // if (timestamps) stopwatch = Stopwatch.StartNew (); #if STATIC var assembly = new AssemblyDefinitionStatic (module, output_file_name, output_file); module.SetDeclaringAssembly (assembly); var importer = new StaticImporter (); assembly.Importer = importer; var loader = new StaticLoader (importer, ctx); loader.LoadReferences (module); ShowTime ("Imporing referenced assemblies"); if (!ctx.BuildinTypes.CheckDefinitions (module)) return false; ShowTime ("Initializing predefined types"); if (!assembly.Create (loader)) return false; // System.Object was not loaded, use compiled assembly as corlib if (loader.Corlib == null) loader.Corlib = assembly.Builder; loader.LoadModules (assembly, module.GlobalRootNamespace); #else var assembly = new AssemblyDefinitionDynamic (module, output_file_name, output_file); module.SetDeclaringAssembly (assembly); var importer = new ReflectionImporter (ctx.BuildinTypes); assembly.Importer = importer; var loader = new DynamicLoader (importer, ctx); loader.LoadReferences (module); ShowTime ("Imporing referenced assemblies"); if (!ctx.BuildinTypes.CheckDefinitions (module)) return false; ShowTime ("Initializing predefined types"); if (!assembly.Create (AppDomain.CurrentDomain, AssemblyBuilderAccess.Save)) return false; loader.LoadModules (assembly, module.GlobalRootNamespace); #endif module.Define (); ShowTime ("Types definition"); if (Report.Errors > 0) return false; if (Report.Errors == 0 && RootContext.Documentation != null && !RootContext.Documentation.OutputDocComment ( output_file, Report)) return false; // // Verify using aliases now // NamespaceEntry.VerifyAllUsing (); if (Report.Errors > 0){ return false; } assembly.Resolve (); if (Report.Errors > 0) return false; // // The code generator // if (timestamps) stopwatch = Stopwatch.StartNew (); assembly.Emit (); ShowTime ("Resolving and emitting members blocks"); if (Report.Errors > 0){ return false; } module.CloseType (); ShowTime ("Closing types"); if (timestamps) stopwatch = Stopwatch.StartNew (); assembly.EmbedResources (); ShowTime ("Embedding resources"); if (Report.Errors > 0) return false; if (timestamps) stopwatch = Stopwatch.StartNew (); assembly.Save (); #if STATIC loader.Dispose (); #endif ShowTime ("Saving output assembly"); ShowTotalTime ("Total"); Timer.ShowTimers (); return (Report.Errors == 0); }
public string[] GetCompletions(string input, out string prefix) { prefix = ""; if (input == null || input.Length == 0) return null; try { invoke_thread = System.Threading.Thread.CurrentThread; invoking = true; lock (evaluator_lock) { if (!inited) Init(); bool partial_input; CSharpParser parser = ParseString(ParseMode.GetCompletions, input, out partial_input); if (parser == null) { if (CSharpParser.yacc_verbose_flag != 0) Console.WriteLine("DEBUG: No completions available"); return null; } Class parser_result = parser.InteractiveResult; #if NET_4_0 var access = AssemblyBuilderAccess.Run; #else var access = AssemblyBuilderAccess.Run; #endif var a = new AssemblyDefinitionDynamic(module, "completions"); a.Create(AppDomain.CurrentDomain, access); module.SetDeclaringAssembly(a); // Need to setup MemberCache parser_result.CreateType(); var method = parser_result.Methods[0] as Method; BlockContext bc = new BlockContext(method, method.Block, TypeManager.void_type); try { method.Block.Resolve(null, bc, method); } catch (CompletionResult cr) { prefix = cr.BaseText; return cr.Result; } } } catch (ThreadAbortException e) { Console.WriteLine("Interrupted!\n{0}", e); } finally { invoking = false; } return null; }
public string [] GetCompletions (string input, out string prefix) { prefix = ""; if (input == null || input.Length == 0) return null; lock (evaluator_lock){ if (!inited) Init (); bool partial_input; CSharpParser parser = ParseString (ParseMode.GetCompletions, input, out partial_input); if (parser == null){ return null; } Class host = parser.InteractiveResult; var base_class_imported = importer.ImportType (base_class); var baseclass_list = new List<FullNamedExpression> (1) { new TypeExpression (base_class_imported, host.Location) }; host.SetBaseTypes (baseclass_list); var access = AssemblyBuilderAccess.RunAndCollect; var a = new AssemblyDefinitionDynamic (module, "completions"); a.Create (AppDomain.CurrentDomain, access); module.SetDeclaringAssembly (a); // Need to setup MemberCache host.CreateContainer (); // Need to setup base type host.DefineContainer (); var method = host.Members[0] as Method; BlockContext bc = new BlockContext (method, method.Block, ctx.BuiltinTypes.Void); try { method.Block.Resolve (bc, method); } catch (CompletionResult cr) { prefix = cr.BaseText; return cr.Result; } } return null; }
public bool Compile(out AssemblyBuilder assembly, AppDomain domain, bool generateInMemory) { // Get the current settings CompilerSettings settings = context.Settings; // Set the result for quick exit assembly = null; // Check if any source files were supplied if (settings.FirstSourceFile == null && (((MCSTarget)settings.Target == MCSTarget.Exe || (MCSTarget)settings.Target == MCSTarget.WinExe || (MCSTarget)settings.Target == MCSTarget.Module) || settings.Resources == null)) { Report.Error(2008, "No source files specified"); return(false); } // Check for any invalid settings if (settings.Platform == Platform.AnyCPU32Preferred && ((MCSTarget)settings.Target == MCSTarget.Library || (MCSTarget)settings.Target == MCSTarget.Module)) { Report.Error(4023, "The preferred platform '{0}' is only valid on executable outputs", Platform.AnyCPU32Preferred.ToString()); return(false); } // Create the time reporter TimeReporter time = new TimeReporter(settings.Timestamps); context.TimeReporter = time; time.StartTotal(); // Create the module ModuleContainer module = new ModuleContainer(context); RootContext.ToplevelTypes = module; // Start timing the parse stage time.Start(TimeReporter.TimerType.ParseTotal); { // Begin parse Parse(module); } time.Stop(TimeReporter.TimerType.ParseTotal); // Check for any errors if (Report.Errors > 0) { return(false); } // Check for partial compilation if (settings.TokenizeOnly == true || settings.ParseOnly == true) { time.StopTotal(); time.ShowStats(); return(true); } // Get the output file string output = settings.OutputFile; string outputName = Path.GetFileName(output); // Create an assembly defenition AssemblyDefinitionDynamic defenition = new AssemblyDefinitionDynamic(module, outputName, output); module.SetDeclaringAssembly(defenition); ReflectionImporter importer = new ReflectionImporter(module, context.BuiltinTypes); defenition.Importer = importer; DynamicLoader loader = new DynamicLoader(importer, context); loader.LoadReferences(module); // Validate built in types if (context.BuiltinTypes.CheckDefinitions(module) == false) { return(false); } // Create the assmbly in domain if (defenition.Create(domain, AssemblyBuilderAccess.RunAndSave) == false) { return(false); } module.CreateContainer(); loader.LoadModules(defenition, module.GlobalRootNamespace); module.InitializePredefinedTypes(); // Check for any resource strings if (settings.GetResourceStrings != null) { module.LoadGetResourceStrings(settings.GetResourceStrings); } // Time the module defenition time.Start(TimeReporter.TimerType.ModuleDefinitionTotal); { try { // Begin defining module.Define(); } catch { // Failed to define module return(false); } } time.Stop(TimeReporter.TimerType.ModuleDefinitionTotal); // Check for any errors if (Report.Errors > 0) { return(false); } // Check for documentation if (settings.DocumentationFile != null) { // Build the xml docs file DocumentationBuilder docs = new DocumentationBuilder(module); docs.OutputDocComment(output, settings.DocumentationFile); } defenition.Resolve(); // Check for documentation errors if (Report.Errors > 0) { return(false); } // Finally emit the defenition into something useful time.Start(TimeReporter.TimerType.EmitTotal); { // Emit assembly defenition.Emit(); } time.Stop(TimeReporter.TimerType.EmitTotal); // Check for any emit errors if (Report.Errors > 0) { return(false); } // Module cleanup time.Start(TimeReporter.TimerType.CloseTypes); { module.CloseContainer(); } time.Stop(TimeReporter.TimerType.CloseTypes); // Check for embedded resources time.Start(TimeReporter.TimerType.Resouces); { if (settings.WriteMetadataOnly == false) { defenition.EmbedResources(); } } time.Stop(TimeReporter.TimerType.Resouces); // Embedd errors if (Report.Errors > 0) { return(false); } // Check for generate in memory if (generateInMemory == false) { defenition.Save(); } // Store the result assembly = defenition.Builder; time.StopTotal(); time.ShowStats(); // Check for errors return(Report.Errors == 0); }
// Mimicked from https://github.com/kkdevs/Patchwork/blob/master/Patchwork/MonoScript.cs#L124 public static Assembly Compile(Dictionary <string, byte[]> sources, TextWriter logger = null) { ReportPrinter reporter = logger == null ? new ConsoleReportPrinter() : new StreamReportPrinter(logger); Location.Reset(); var dllName = $"compiled_{DateTime.Now.Ticks}"; compiledAssemblies.Add(dllName); var ctx = CreateContext(reporter); ctx.Settings.SourceFiles.Clear(); var i = 0; SeekableStreamReader GetFile(SourceFile file) { return(new SeekableStreamReader(new MemoryStream(sources[file.OriginalFullPathName]), Encoding.UTF8)); } foreach (var source in sources) { ctx.Settings.SourceFiles.Add(new SourceFile(Path.GetFileName(source.Key), source.Key, i, GetFile)); i++; } var container = new ModuleContainer(ctx); RootContext.ToplevelTypes = container; Location.Initialize(ctx.Settings.SourceFiles); var session = new ParserSession { UseJayGlobalArrays = true, LocatedTokens = new LocatedToken[15000] }; container.EnableRedefinition(); foreach (var sourceFile in ctx.Settings.SourceFiles) { var stream = sourceFile.GetInputStream(sourceFile); var source = new CompilationSourceFile(container, sourceFile); source.EnableRedefinition(); container.AddTypeContainer(source); var parser = new CSharpParser(stream, source, session); parser.parse(); } var ass = new AssemblyDefinitionDynamic(container, dllName, $"{dllName}.dll"); container.SetDeclaringAssembly(ass); var importer = new ReflectionImporter(container, ctx.BuiltinTypes) { IgnoreCompilerGeneratedField = false, IgnorePrivateMembers = false }; ass.Importer = importer; var loader = new DynamicLoader(importer, ctx); ImportAppdomainAssemblies(a => importer.ImportAssembly(a, container.GlobalRootNamespace)); loader.LoadReferences(container); ass.Create(AppDomain.CurrentDomain, AssemblyBuilderAccess.RunAndSave); container.CreateContainer(); loader.LoadModules(ass, container.GlobalRootNamespace); container.InitializePredefinedTypes(); container.Define(); if (ctx.Report.Errors > 0) { logger?.WriteLine("Found errors! Aborting compilation..."); return(null); } try { ass.Resolve(); ass.Emit(); container.CloseContainer(); ass.EmbedResources(); } catch (Exception e) { logger?.WriteLine($"Failed to compile because {e}"); return(null); } return(ass.Builder); }