X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Feval.cs;h=d4e83a506a0fcfbf1d1b00d8522173ca92f15462;hb=20ab5bfe7ae2cf84cd9e6fdad9758ded9f687ca2;hp=5d9a291b1c51f1c3bc99b1dbfa36b37530c8202f;hpb=b86af4848657c5fa6041d0eefa47ac004dc54442;p=mono.git diff --git a/mcs/mcs/eval.cs b/mcs/mcs/eval.cs index 5d9a291b1c5..d4e83a506a0 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; + } } // @@ -370,26 +416,30 @@ namespace Mono.CSharp if (parser == null){ return null; } - - Class parser_result = parser.InteractiveResult; -#if NET_4_0 + Class host = parser.InteractiveResult; + + var base_class_imported = importer.ImportType (base_class); + var baseclass_list = new List (1) { + new TypeExpression (base_class_imported, host.Location) + }; + host.SetBaseTypes (baseclass_list); + 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 (); + host.CreateContainer (); + // Need to setup base type + host.DefineContainer (); - var method = parser_result.Members[0] as Method; + var method = host.Members[0] as Method; BlockContext bc = new BlockContext (method, method.Block, ctx.BuiltinTypes.Void); try { - method.Block.Resolve (null, bc, method); + method.Block.Resolve (bc, method); } catch (CompletionResult cr) { prefix = cr.BaseText; return cr.Result; @@ -440,6 +490,11 @@ namespace Mono.CSharp return result; } + /// + /// Experimental! + /// + public ValueModificationHandler ModificationListener { get; set; } + enum InputKind { EOF, StatementOrExpression, @@ -459,7 +514,7 @@ namespace Mono.CSharp // InputKind ToplevelOrStatement (SeekableStreamReader seekable) { - Tokenizer tokenizer = new Tokenizer (seekable, source_file, new ParserSession ()); + Tokenizer tokenizer = new Tokenizer (seekable, source_file, new ParserSession (), ctx.Report); // Prefer contextual block keywords over identifiers tokenizer.parsing_block++; @@ -472,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: @@ -511,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; @@ -644,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); } @@ -729,6 +781,7 @@ namespace Mono.CSharp } module.EmitContainer (); + if (Report.Errors != 0){ if (undo != null) undo.ExecuteUndo (); @@ -813,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); } @@ -830,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; @@ -1038,9 +1101,7 @@ namespace Mono.CSharp static public string help { get { return "Static methods:\n" + -#if !NET_2_1 " Describe (object); - Describes the object's type\n" + -#endif " LoadPackage (package); - Loads the given Package (like -pkg:FILE)\n" + " LoadAssembly (assembly); - Loads the given assembly (like -r:ASSEMBLY)\n" + " ShowVars (); - Shows defined local variables.\n" + @@ -1073,7 +1134,7 @@ namespace Mono.CSharp QuitRequested = true; } -#if !NET_2_1 +#if !MOBILE /// /// Describes an object or a type. /// @@ -1227,10 +1288,13 @@ namespace Mono.CSharp if (undo_actions == null) undo_actions = new List (); - var existing = current_container.Containers.FirstOrDefault (l => l.Basename == tc.Basename); - if (existing != null) { - current_container.RemoveContainer (existing); - undo_actions.Add (() => current_container.AddTypeContainer (existing)); + if (current_container.Containers != null) + { + 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)); + } } undo_actions.Add (() => current_container.RemoveContainer (tc)); @@ -1248,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); + } + } }