X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Feval.cs;h=ced26cd301a4f763dcb9b43aa64f0839590c3040;hb=b0eab80ae5355b96faedd20d8ffeecfc7c0de7e4;hp=39524fb85be486d639566049d3fd52fd43b09b6d;hpb=5a3d0c9d65159c066d16855d7e3a9000f435a234;p=mono.git diff --git a/mcs/mcs/eval.cs b/mcs/mcs/eval.cs index 39524fb85be..ced26cd301a 100644 --- a/mcs/mcs/eval.cs +++ b/mcs/mcs/eval.cs @@ -11,7 +11,7 @@ // using System; using System.Threading; -using System.Collections; +using System.Collections.Generic; using System.Reflection; using System.Reflection.Emit; using System.IO; @@ -54,16 +54,18 @@ namespace Mono.CSharp { static string current_debug_name; static int count; static Thread invoke_thread; - - static ArrayList using_alias_list = new ArrayList (); - internal static ArrayList using_list = new ArrayList (); - static Hashtable fields = new Hashtable (); + + static List using_alias_list = new List (); + internal static List using_list = new List (); + static Dictionary fields = new Dictionary (); static Type interactive_base_class = typeof (InteractiveBase); static Driver driver; static bool inited; - static CompilerContext ctx = new CompilerContext (new Report (new ConsoleReportPrinter ())); + static CompilerContext ctx; + + public static TextWriter MessageOutput = Console.Out; /// /// Optional initialization for the Evaluator. @@ -83,7 +85,11 @@ namespace Mono.CSharp { InitAndGetStartupFiles (args); } - + internal static ReportPrinter SetPrinter (ReportPrinter report_printer) + { + return ctx.Report.SetPrinter (report_printer); + } + /// /// Optional initialization for the Evaluator. /// @@ -111,22 +117,22 @@ namespace Mono.CSharp { if (driver == null) throw new Exception ("Failed to create compiler driver with the given arguments"); - RootContext.ToplevelTypes = new ModuleContainer (ctx, true); + RootContext.ToplevelTypes = new ModuleCompiled (ctx, true); driver.ProcessDefaultConfig (); - ArrayList startup_files = new ArrayList (); + var startup_files = new List (); foreach (CompilationUnit file in Location.SourceFiles) startup_files.Add (file.Path); CompilerCallableEntryPoint.Reset (); - RootContext.ToplevelTypes = new ModuleContainer (ctx, true); + RootContext.ToplevelTypes = new ModuleCompiled (ctx, true); driver.LoadReferences (); RootContext.EvalMode = true; inited = true; - return (string []) startup_files.ToArray (typeof (string)); + return startup_files.ToArray (); } } @@ -138,6 +144,18 @@ namespace Mono.CSharp { static void Reset () { CompilerCallableEntryPoint.PartialReset (); + + // Workaround for API limitation where full message printer cannot be passed + ReportPrinter printer; + if (MessageOutput == Console.Out || MessageOutput == Console.Error){ + var console_reporter = new ConsoleReportPrinter (MessageOutput); + console_reporter.Fatal = driver.fatal_errors; + printer = console_reporter; + } else + printer = new StreamReportPrinter (MessageOutput); + + ctx = new CompilerContext (new Report (printer)); + RootContext.ToplevelTypes = new ModuleCompiled (ctx, true); // // PartialReset should not reset the core types, this is very redundant. @@ -295,7 +313,7 @@ namespace Mono.CSharp { // Either null (on error) or the compiled method. return compiled; } - + // // Todo: Should we handle errors, or expect the calling code to setup // the recording themselves? @@ -341,7 +359,7 @@ namespace Mono.CSharp { // The code execution does not need to keep the compiler lock // object retval = typeof (NoValueSet); - + try { invoke_thread = System.Threading.Thread.CurrentThread; invoking = true; @@ -418,7 +436,7 @@ namespace Mono.CSharp { } catch (CompletionResult cr){ prefix = cr.BaseText; return cr.Result; - } + } } finally { parser.undo.ExecuteUndo (); } @@ -600,6 +618,7 @@ namespace Mono.CSharp { partial_input = false; Reset (); queued_fields.Clear (); + Tokenizer.LocatedToken.Initialize (); Stream s = new MemoryStream (Encoding.Default.GetBytes (input)); SeekableStreamReader seekable = new SeekableStreamReader (s, Encoding.Default); @@ -640,14 +659,10 @@ namespace Mono.CSharp { if (mode == ParseMode.GetCompletions) parser.Lexer.CompleteOnEOF = true; - bool disable_error_reporting; + ReportPrinter old_printer = null; if ((mode == ParseMode.Silent || mode == ParseMode.GetCompletions) && CSharpParser.yacc_verbose_flag == 0) - disable_error_reporting = true; - else - disable_error_reporting = false; - - if (disable_error_reporting) - ctx.Report.DisableReporting (); + old_printer = SetPrinter (new StreamReportPrinter (TextWriter.Null)); + try { parser.parse (); } finally { @@ -659,8 +674,8 @@ namespace Mono.CSharp { parser = null; } - if (disable_error_reporting) - ctx.Report.EnableReporting (); + if (old_printer != null) + SetPrinter (old_printer); } return parser; } @@ -670,7 +685,7 @@ namespace Mono.CSharp { // or reflection gets confused (it basically gets confused, and variables override each // other). // - static ArrayList queued_fields = new ArrayList (); + static List queued_fields = new List (); //static ArrayList types = new ArrayList (); @@ -711,8 +726,10 @@ namespace Mono.CSharp { } RootContext.EmitCode (); - if (Report.Errors != 0) + if (Report.Errors != 0){ + undo.ExecuteUndo (); return null; + } RootContext.CloseTypes (); @@ -733,11 +750,11 @@ namespace Mono.CSharp { foreach (Field field in queued_fields){ FieldInfo fi = tt.GetField (field.Name); - FieldInfo old = (FieldInfo) fields [field.Name]; + FieldInfo old; // If a previous value was set, nullify it, so that we do // not leak memory - if (old != null){ + if (fields.TryGetValue (field.Name, out old)){ if (TypeManager.IsStruct (old.FieldType)){ // // TODO: Clear fields for structs @@ -775,7 +792,9 @@ namespace Mono.CSharp { static internal FieldInfo LookupField (string name) { - FieldInfo fi = (FieldInfo) fields [name]; + FieldInfo fi; + if (!fields.TryGetValue (name, out fi)) + return null; return fi; } @@ -819,9 +838,9 @@ namespace Mono.CSharp { } } - static internal ICollection GetUsingList () + static internal ICollection GetUsingList () { - ArrayList res = new ArrayList (using_list.Count); + var res = new List (using_list.Count); foreach (object ue in using_list) res.Add (ue.ToString ()); return res; @@ -830,7 +849,7 @@ namespace Mono.CSharp { static internal string [] GetVarNames () { lock (evaluator_lock){ - return (string []) new ArrayList (fields.Keys).ToArray (typeof (string)); + return new List (fields.Keys).ToArray (); } } @@ -839,8 +858,8 @@ namespace Mono.CSharp { lock (evaluator_lock){ StringBuilder sb = new StringBuilder (); - foreach (DictionaryEntry de in fields){ - FieldInfo fi = LookupField ((string) de.Key); + foreach (var de in fields){ + FieldInfo fi = LookupField (de.Key); object value = null; bool error = false; @@ -885,7 +904,12 @@ namespace Mono.CSharp { GlobalRootNamespace.Instance.ComputeNamespaces (ctx); } } - + + /// + /// If true, turns type expressions into valid expressions + /// and calls the describe method on it + /// + public static bool DescribeTypeExpressions; } @@ -1138,15 +1162,38 @@ namespace Mono.CSharp { { } - public override Expression DoResolve (ResolveContext ec) + protected override Expression DoResolve (ResolveContext ec) { CloneContext cc = new CloneContext (); Expression clone = source.Clone (cc); + var old_printer = Evaluator.SetPrinter (new StreamReportPrinter (TextWriter.Null)); clone = clone.Resolve (ec); - if (clone == null) - return null; + if (clone == null){ + // + // A useful feature for the REPL: if we can resolve the expression + // as a type, Describe the type; + // + if (Evaluator.DescribeTypeExpressions){ + clone = source.Clone (cc); + clone = clone.Resolve (ec, ResolveFlags.Type); + if (clone == null){ + Evaluator.SetPrinter (old_printer); + clone = source.Clone (cc); + clone = clone.Resolve (ec); + return null; + } + Arguments args = new Arguments (1); + args.Add (new Argument (new TypeOf (source, Location))); + source = new Invocation (new SimpleName ("Describe", Location), args).Resolve (ec); + } else { + Evaluator.SetPrinter (old_printer); + return null; + } + } + Evaluator.SetPrinter (old_printer); + // This means its really a statement. if (clone.Type == TypeManager.void_type){ source = source.Resolve (ec); @@ -1177,11 +1224,11 @@ namespace Mono.CSharp { } public class Undo { - ArrayList undo_types; + List> undo_types; public Undo () { - undo_types = new ArrayList (); + undo_types = new List> (); } public void AddTypeContainer (TypeContainer current_container, TypeContainer tc) @@ -1190,10 +1237,11 @@ namespace Mono.CSharp { Console.Error.WriteLine ("Internal error: inserting container into itself"); return; } - + if (undo_types == null) - undo_types = new ArrayList (); - undo_types.Add (new Pair (current_container, tc)); + undo_types = new List> (); + + undo_types.Add (new KeyValuePair (current_container, tc)); } public void ExecuteUndo () @@ -1201,10 +1249,10 @@ namespace Mono.CSharp { if (undo_types == null) return; - foreach (Pair p in undo_types){ - TypeContainer current_container = (TypeContainer) p.First; + foreach (var p in undo_types){ + TypeContainer current_container = p.Key; - current_container.RemoveTypeContainer ((TypeContainer) p.Second); + current_container.RemoveTypeContainer (p.Value); } undo_types = null; }