Null constant cannot be used for ref/out variables
[mono.git] / mcs / tools / csharp / repl.cs
index 93f484733adc2674f198f1e29cfa9620bdcbadb6..5137fcb4c4ad768a9b2ea9c3c8b468a0eb432df0 100644 (file)
@@ -25,9 +25,9 @@ using System.Reflection.Emit;
 using System.Threading;
 using System.Net;
 using System.Net.Sockets;
+using System.Collections.Generic;
 
 using Mono.CSharp;
-using Mono.Attach;
 
 namespace Mono {
 
@@ -35,26 +35,68 @@ namespace Mono {
                
                static int Main (string [] args)
                {
+#if !ON_DOTNET
                        if (args.Length > 0 && args [0] == "--attach") {
-                               new ClientCSharpShell (Int32.Parse (args [1])).Run ();
+                               new ClientCSharpShell (Int32.Parse (args [1])).Run (null);
                                return 0;
-                       } else if (args.Length > 0 && args [0].StartsWith ("--agent:")) {
+                       }
+
+                       if (args.Length > 0 && args [0].StartsWith ("--agent:")) {
                                new CSharpAgent (args [0]);
                                return 0;
-                       } else {
-                               try {
-                                       Evaluator.Init (args);
-                               } catch {
-                                       return 1;
-                               }
-                       
-                               return new CSharpShell ().Run ();
+                       }
+#endif
+                       return Startup(args);
+               }
+
+               static int Startup (string[] args)
+               {
+                       string[] startup_files;
+                       try {
+                               startup_files = Evaluator.InitAndGetStartupFiles (args);
+                               Evaluator.DescribeTypeExpressions = true;
+                               Evaluator.SetInteractiveBaseClass (typeof (InteractiveBaseShell));
+                       } catch {
+                               return 1;
+                       }
+
+                       return new CSharpShell ().Run (startup_files);
+               }
+       }
+
+       public class InteractiveBaseShell : InteractiveBase {
+               static bool tab_at_start_completes;
+               
+               static InteractiveBaseShell ()
+               {
+                       tab_at_start_completes = false;
+               }
+
+               internal static Mono.Terminal.LineEditor Editor;
+               
+               public static bool TabAtStartCompletes {
+                       get {
+                               return tab_at_start_completes;
+                       }
+
+                       set {
+                               tab_at_start_completes = value;
+                               if (Editor != null)
+                                       Editor.TabAtStartCompletes = value;
+                       }
+               }
+
+               public static new string help {
+                       get {
+                               return InteractiveBase.help +
+                                       "  TabAtStartCompletes - Whether tab will complete even on emtpy lines\n";
                        }
                }
        }
        
        public class CSharpShell {
-               static bool isatty = true;
+               static bool isatty = true, is_unix = false;
+               string [] startup_files;
                
                Mono.Terminal.LineEditor editor;
                bool dumb;
@@ -69,10 +111,25 @@ namespace Mono {
                
                void SetupConsole ()
                {
-                       string term = Environment.GetEnvironmentVariable ("TERM");
-                       dumb = term == "dumb" || term == null || isatty == false;
+                       if (is_unix){
+                               string term = Environment.GetEnvironmentVariable ("TERM");
+                               dumb = term == "dumb" || term == null || isatty == false;
+                       } else
+                               dumb = false;
                        
                        editor = new Mono.Terminal.LineEditor ("csharp", 300);
+                       InteractiveBaseShell.Editor = editor;
+
+                       editor.AutoCompleteEvent += delegate (string s, int pos){
+                               string prefix = null;
+
+                               string complete = s.Substring (0, pos);
+                               
+                               string [] completions = Evaluator.GetCompletions (complete, out prefix);
+                               
+                               return new Mono.Terminal.LineEditor.Completion (prefix, completions);
+                       };
+                       
 #if false
                        //
                        // This is a sample of how completions sould be implemented.
@@ -118,13 +175,24 @@ namespace Mono {
 
                void InitTerminal ()
                {
-                       isatty = UnixUtils.isatty (0) && UnixUtils.isatty (1);
+#if ON_DOTNET
+                       is_unix = false;
+                       isatty = true;
+#else
+                       int p = (int) Environment.OSVersion.Platform;
+                       is_unix = (p == 4) || (p == 128);
+
+                       if (is_unix)
+                               isatty = UnixUtils.isatty (0) && UnixUtils.isatty (1);
+                       else
+                               isatty = true;
+#endif
 
                        // Work around, since Console is not accounting for
                        // cursor position when writing to Stderr.  It also
                        // has the undesirable side effect of making
                        // errors plain, with no coloring.
-                       Report.Stderr = Console.Out;
+//                     Report.Stderr = Console.Out;
                        SetupConsole ();
 
                        if (isatty)
@@ -132,6 +200,25 @@ namespace Mono {
 
                }
 
+               void ExecuteSources (IEnumerable<string> sources, bool ignore_errors)
+               {
+                       foreach (string file in sources){
+                               try {
+                                       try {
+                                               using (System.IO.StreamReader r = System.IO.File.OpenText (file)){
+                                                       ReadEvalPrintLoopWith (p => r.ReadLine ());
+                                               }
+                                       } catch (FileNotFoundException){
+                                               Console.Error.WriteLine ("cs2001: Source file `{0}' not found", file);
+                                               return;
+                                       }
+                               } catch {
+                                       if (!ignore_errors)
+                                               throw;
+                               }
+                       }
+               }
+               
                protected virtual void LoadStartupFiles ()
                {
                        string dir = Path.Combine (
@@ -140,20 +227,22 @@ namespace Mono {
                        if (!Directory.Exists (dir))
                                return;
 
-                       foreach (string file in Directory.GetFiles (dir)){
+                       List<string> sources = new List<string> ();
+                       List<string> libraries = new List<string> ();
+                       
+                       foreach (string file in System.IO.Directory.GetFiles (dir)){
                                string l = file.ToLower ();
                                
-                               if (l.EndsWith (".cs")){
-                                       try {
-                                               using (StreamReader r = File.OpenText (file)){
-                                                       ReadEvalPrintLoopWith (p => r.ReadLine ());
-                                               }
-                                       } catch {
-                                       }
-                               } else if (l.EndsWith (".dll")){
-                                       Evaluator.LoadAssembly (file);
-                               }
+                               if (l.EndsWith (".cs"))
+                                       sources.Add (file);
+                               else if (l.EndsWith (".dll"))
+                                       libraries.Add (file);
                        }
+
+                       foreach (string file in libraries)
+                               Evaluator.LoadAssembly (file);
+
+                       ExecuteSources (sources, true);
                }
 
                void ReadEvalPrintLoopWith (ReadLiner readline)
@@ -175,12 +264,20 @@ namespace Mono {
 
                public int ReadEvalPrintLoop ()
                {
-                       InitTerminal ();
+                       if (startup_files != null && startup_files.Length == 0)
+                               InitTerminal ();
 
                        InitializeUsing ();
 
                        LoadStartupFiles ();
-                       ReadEvalPrintLoopWith (GetLine);
+
+                       //
+                       // Interactive or startup files provided?
+                       //
+                       if (startup_files.Length != 0)
+                               ExecuteSources (startup_files, false);
+                       else
+                               ReadEvalPrintLoopWith (GetLine);
 
                        return 0;
                }
@@ -323,13 +420,15 @@ namespace Mono {
                {
                }
 
-               public virtual int Run ()
+               public virtual int Run (string [] startup_files)
                {
+                       this.startup_files = startup_files;
                        return ReadEvalPrintLoop ();
                }
                
        }
 
+#if !ON_DOTNET
        //
        // A shell connected to a CSharpAgent running in a remote process.
        //  - maybe add 'class_name' and 'method_name' arguments to LoadAgent.
@@ -352,7 +451,7 @@ namespace Mono {
                                                          ((IPEndPoint)listener.Server.LocalEndPoint).Port,
                                                          ((IPEndPoint)interrupt_listener.Server.LocalEndPoint).Port);
        
-                       VirtualMachine vm = new VirtualMachine (pid);
+                       var vm = new Attach.VirtualMachine (pid);
                        vm.Attach (agent_assembly, agent_arg);
        
                        /* Wait for the client to connect */
@@ -393,7 +492,7 @@ namespace Mono {
                        }
                }
                
-               public override int Run ()
+               public override int Run (string [] startup_files)
                {
                        // The difference is that we do not call Evaluator.Init, that is done on the target
                        return ReadEvalPrintLoop ();
@@ -503,7 +602,7 @@ namespace Mono {
                        NetworkStream s = client.GetStream ();
                        interrupt_stream = interrupt_client.GetStream ();
                        new Thread (InterruptListener).Start ();
-                       
+
                        try {
                                Evaluator.Init (new string [0]);
                        } catch {
@@ -542,7 +641,7 @@ namespace Mono {
                                try {
                                        string error_string;
                                        StringWriter error_output = new StringWriter ();
-                                       Report.Stderr = error_output;
+//                                     Report.Stderr = error_output;
                                        
                                        string line = s.GetString ();
        
@@ -591,6 +690,21 @@ namespace Mono {
                        }
                }
        }
+
+       public class UnixUtils {
+               [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")]
+               extern static int _isatty (int fd);
+                       
+               public static bool isatty (int fd)
+               {
+                       try {
+                               return _isatty (fd) == 1;
+                       } catch {
+                               return false;
+                       }
+               }
+       }
+#endif
 }
        
 namespace Mono.Management
@@ -600,4 +714,3 @@ namespace Mono.Management
        }
 }
 
-