X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Feval.cs;h=62c02b1fd5602de8f4a01d5096f183472d3d2b9a;hb=890f40d7ad1d68ea5ff86ffdd3f6829dbd86b3ab;hp=5bda997062587af84c2d227d0cf5e371c5dea3ef;hpb=416d4e10f905b8fe3d57f20b957e8cff86a7f1ec;p=mono.git diff --git a/mcs/mcs/eval.cs b/mcs/mcs/eval.cs index 5bda9970625..62c02b1fd56 100644 --- a/mcs/mcs/eval.cs +++ b/mcs/mcs/eval.cs @@ -24,6 +24,11 @@ using System.Linq; namespace Mono.CSharp { + /// + /// Experimental! + /// + public delegate void ValueModificationHandler (string variableName, int row, int column, object value); + /// /// Evaluator: provides an API to evaluate C# statements and /// expressions dynamically. @@ -71,6 +76,8 @@ namespace Mono.CSharp readonly ModuleContainer module; readonly ReflectionImporter importer; readonly CompilationSourceFile source_file; + + int? listener_id; public Evaluator (CompilerContext ctx) { @@ -185,8 +192,13 @@ namespace Mono.CSharp if (!inited || !invoking) return; - if (invoke_thread != null) + if (invoke_thread != null) { +#if MONO_FEATURE_THREAD_ABORT invoke_thread.Abort (); +#else + invoke_thread.Interrupt (); +#endif + } } /// @@ -291,6 +303,30 @@ namespace Mono.CSharp return compiled; } + static MethodInfo listener_proxy_value; + internal void EmitValueChangedCallback (EmitContext ec, string name, TypeSpec type, Location loc) + { + if (listener_id == null) + listener_id = ListenerProxy.Register (ModificationListener); + + if (listener_proxy_value == null) + listener_proxy_value = typeof (ListenerProxy).GetMethod ("ValueChanged"); + +#if STATIC + throw new NotSupportedException (); +#else + // object value, int row, int col, string name, int listenerId + if (type.IsStructOrEnum) + ec.Emit (OpCodes.Box, type); + + ec.EmitInt (loc.Row); + ec.EmitInt (loc.Column); + ec.Emit (OpCodes.Ldstr, name); + ec.EmitInt (listener_id.Value); + ec.Emit (OpCodes.Call, listener_proxy_value); +#endif + } + /// /// Evaluates and expression or statement and returns any result values. /// @@ -336,11 +372,21 @@ namespace Mono.CSharp invoke_thread = System.Threading.Thread.CurrentThread; invoking = true; compiled (ref retval); +#if MONO_FEATURE_THREAD_ABORT } catch (ThreadAbortException e){ Thread.ResetAbort (); Console.WriteLine ("Interrupted!\n{0}", e); +#else + } catch (ThreadInterruptedException e) { + Console.WriteLine ("Interrupted!\n{0}", e); +#endif } finally { invoking = false; + + if (listener_id != null) { + ListenerProxy.Unregister (listener_id.Value); + listener_id = null; + } } // @@ -379,11 +425,7 @@ namespace Mono.CSharp }; host.SetBaseTypes (baseclass_list); -#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); @@ -448,6 +490,11 @@ namespace Mono.CSharp return result; } + /// + /// Experimental! + /// + public ValueModificationHandler ModificationListener { get; set; } + enum InputKind { EOF, StatementOrExpression, @@ -480,6 +527,7 @@ namespace Mono.CSharp // These are toplevels case Token.EXTERN: case Token.OPEN_BRACKET: + case Token.OPEN_BRACKET_EXPR: case Token.ABSTRACT: case Token.CLASS: case Token.ENUM: @@ -519,7 +567,7 @@ namespace Mono.CSharp if (t == Token.EOF) return InputKind.EOF; - if (t == Token.IDENTIFIER) + if (t == Token.IDENTIFIER || t == Token.STATIC) return InputKind.CompilationUnit; return InputKind.StatementOrExpression; @@ -652,11 +700,7 @@ namespace Mono.CSharp 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); } @@ -737,6 +781,7 @@ namespace Mono.CSharp } module.EmitContainer (); + if (Report.Errors != 0){ if (undo != null) undo.ExecuteUndo (); @@ -821,13 +866,19 @@ namespace Mono.CSharp public string GetUsing () { + if (source_file == null || source_file.Usings == null) + return string.Empty; + StringBuilder sb = new StringBuilder (); // TODO: //foreach (object x in ns.using_alias_list) // sb.AppendFormat ("using {0};\n", x); foreach (var ue in source_file.Usings) { - sb.AppendFormat ("using {0};", ue.ToString ()); + if (ue.Alias != null || ue.ResolvedExpression == null) + continue; + + sb.AppendFormat("using {0};", ue.ToString ()); sb.Append (Environment.NewLine); } @@ -838,7 +889,11 @@ namespace Mono.CSharp { var res = new List (); - foreach (var ue in source_file.Usings) { + if (source_file == null || source_file.Usings == null) + return res; + + foreach (var ue in source_file.Usings) + { if (ue.Alias != null || ue.ResolvedExpression == null) continue; @@ -1235,7 +1290,7 @@ namespace Mono.CSharp if (current_container.Containers != null) { - var existing = current_container.Containers.FirstOrDefault (l => l.Basename == tc.Basename); + var existing = current_container.Containers.FirstOrDefault (l => l.MemberName.Basename == tc.MemberName.Basename); if (existing != null) { current_container.RemoveContainer (existing); undo_actions.Add (() => current_container.AddTypeContainer (existing)); @@ -1257,5 +1312,38 @@ namespace Mono.CSharp undo_actions = null; } } - + + static class ListenerProxy + { + static readonly Dictionary listeners = new Dictionary (); + + static int counter; + + public static int Register (ValueModificationHandler listener) + { + lock (listeners) { + var id = counter++; + listeners.Add (id, listener); + return id; + } + } + + public static void Unregister (int listenerId) + { + lock (listeners) { + listeners.Remove (listenerId); + } + } + + public static void ValueChanged (object value, int row, int col, string name, int listenerId) + { + ValueModificationHandler action; + lock (listeners) { + if (!listeners.TryGetValue (listenerId, out action)) + return; + } + + action (name, row, col, value); + } + } }