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);
+ }
+ }
}