Mono.CSharp.Evaluator.CompileBlock C# (CSharp) Method

CompileBlock() private method

private CompileBlock ( Class host, Undo undo, Report Report ) : CompiledMethod
host Class
undo Undo
Report Report
return CompiledMethod
        CompiledMethod CompileBlock(Class host, Undo undo, Report Report)
        {
            string current_debug_name = "eval-" + count + ".dll";
            ++count;
            #if STATIC
            throw new NotSupportedException ();
            #else
            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.Run;
            #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 (host, baseclass_list);

                host.CreateType ();
                host.DefineType ();
                host.Define ();

                expression_method = (Method) host.Methods[0];
            } else {
                expression_method = null;
            }

            module.CreateType ();
            module.Define ();

            if (Report.Errors != 0){
                if (undo != null)
                    undo.ExecuteUndo ();

                return null;
            }

            if (host != null){
                host.EmitType ();
            }

            module.Emit ();
            if (Report.Errors != 0){
                if (undo != null)
                    undo.ExecuteUndo ();
                return null;
            }

            module.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 (host.TypeBuilder.Name);
            var mi = tt.GetMethod (expression_method.Name);

            if (host.Fields != null) {
                //
                // We need to then go from FieldBuilder to FieldInfo
                // or reflection gets confused (it basically gets confused, and variables override each
                // other).
                //
                foreach (Field field in host.Fields) {
                    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
        }