2007-10-27 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / class / corlib / System / Exception.cs
index a35521f8f703ecc8e15f5f1e05cd11d145394169..97a6d5bd3fd9d77d644c89aa93a72282ffb289ae 100644 (file)
@@ -6,10 +6,7 @@
 //   Patrik Torstensson
 //
 // (C) Ximian, Inc.  http://www.ximian.com
-//
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+using System.Collections;
+using System.Diagnostics;
+using System.Reflection;
+using System.Text;
 using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
 using System.Runtime.Serialization;
-using System.Reflection;
-using System.Diagnostics;
+using System.Security.Permissions;
 
 namespace System
 {
        [Serializable]
+#if NET_2_0
+       [ComVisible(true)]
+       [ComDefaultInterface (typeof (_Exception))]
+       [ClassInterface (ClassInterfaceType.None)]
+#else
        [ClassInterface (ClassInterfaceType.AutoDual)]
+#endif
        public class Exception : ISerializable 
+#if NET_2_0
+       , _Exception
+#endif
        {
+               #region Sync with object-internals.h
                IntPtr [] trace_ips;
                Exception inner_exception;
-               string message;
+               internal string message;
                string help_link;
                string class_name;
-               string stack_trace = null;
-               string remote_stack_trace = "";
-               int remote_stack_index = 0;
-               int hresult = unchecked ((int)0x80004005);
+               string stack_trace;
+               string remote_stack_trace;
+               int remote_stack_index;
+               internal int hresult = unchecked ((int)0x80004005);
                string source;
+               private IDictionary _data;
+               #endregion
 
                public Exception ()
                {
-                       inner_exception = null;
-                       message = null;
-                       class_name = GetType().FullName;
                }
 
                public Exception (string msg)
                {
-                       inner_exception = null;
                        message = msg;
-                       class_name = GetType().FullName;
                }
 
                protected Exception (SerializationInfo info, StreamingContext sc)
@@ -87,7 +95,6 @@ namespace System
                {
                        inner_exception = e;
                        message = msg;
-                       class_name = GetType().FullName;
                }
 
                public Exception InnerException {
@@ -124,6 +131,9 @@ namespace System
                }
 
                public virtual string Source {
+#if ONLY_1_1
+                       [ReflectionPermission (SecurityAction.Assert, TypeInformation = true)]
+#endif
                        get {
                                if (source == null) {
                                        StackTrace st = new StackTrace (this, true);
@@ -132,7 +142,7 @@ namespace System
                                                if (st != null) {
                                                        MethodBase method = sf.GetMethod ();
                                                        if (method != null) {
-                                                               source = method.DeclaringType.Assembly.GetName ().Name;
+                                                               source = method.DeclaringType.Assembly.UnprotectedGetName ().Name;
                                                        }
                                                }
                                        }
@@ -149,11 +159,55 @@ namespace System
 
                public virtual string StackTrace {
                        get {
+                               if (stack_trace == null) {
+                                       if (trace_ips == null)
+                                               /* Not thrown yet */
+                                               return null;
+
+                                       StackTrace st = new StackTrace (this, 0, true, true);
+
+                                       StringBuilder sb = new StringBuilder ();
+
+                                       string newline = String.Format ("{0}  {1} ", Environment.NewLine, Locale.GetText ("at"));
+                                       string unknown = Locale.GetText ("<unknown method>");
+
+                                       for (int i = 0; i < st.FrameCount; i++) {
+                                               StackFrame frame = st.GetFrame (i);
+                                               if (i == 0)
+                                                       sb.AppendFormat ("  {0} ", Locale.GetText ("at"));
+                                               else
+                                                       sb.Append (newline);
+
+                                               if (frame.GetMethod () == null) {
+                                                       string internal_name = frame.GetInternalMethodName ();
+                                                       if (internal_name != null)
+                                                               sb.Append (internal_name);
+                                                       else
+                                                               sb.AppendFormat ("<0x{0:x5}> {1}", frame.GetNativeOffset (), unknown);
+                                               } else {
+                                                       sb.Append (GetFullNameForStackTrace (frame.GetMethod ()));
+
+                                                       if (frame.GetILOffset () == -1)
+                                                               sb.AppendFormat (" <0x{0:x5}> ", frame.GetNativeOffset ());
+                                                       else
+                                                               sb.AppendFormat (" [0x{0:x5}] ", frame.GetILOffset ());
+
+                                                       string fileName = frame.GetFileName ();
+                                                       if (fileName != null)
+                                                               sb.AppendFormat ("in {0}:{1} ", fileName, frame.GetFileLineNumber ());
+                                                       }
+                                       }
+                                       stack_trace = sb.ToString ();
+                               }
+
                                return stack_trace;
                        }
                }
 
                public MethodBase TargetSite {
+#if ONLY_1_1
+                       [ReflectionPermission (SecurityAction.Demand, TypeInformation = true)]
+#endif
                        get {
                                StackTrace st = new StackTrace (this, true);
                                if (st.FrameCount > 0)
@@ -163,6 +217,18 @@ namespace System
                        }
                }
 
+#if NET_2_0
+               public virtual IDictionary Data {
+                       get {
+                               if (_data == null) {
+                                       // default to empty dictionary
+                                       _data = (IDictionary) new Hashtable ();
+                               }
+                               return _data;
+                       }
+               }
+#endif
+
                public virtual Exception GetBaseException ()
                {
                        Exception inner = inner_exception;
@@ -178,13 +244,23 @@ namespace System
                        return this;
                }
 
+#if ONLY_1_1
+               [ReflectionPermission (SecurityAction.Assert, TypeInformation = true)]
+#endif
+               [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
                public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
                {
+                       if (info == null)
+                               throw new ArgumentNullException ("info");
+
+                       if (class_name == null)
+                               class_name = GetType ().FullName;
+
                        info.AddValue ("ClassName", class_name);
                        info.AddValue ("Message", message);
                        info.AddValue ("InnerException", inner_exception);
                        info.AddValue ("HelpURL", help_link);
-                       info.AddValue ("StackTraceString", stack_trace);
+                       info.AddValue ("StackTraceString", StackTrace);
                        info.AddValue ("RemoteStackTraceString", remote_stack_trace);
                        info.AddValue ("RemoteStackIndex", remote_stack_index);
                        info.AddValue ("HResult", hresult);
@@ -192,6 +268,9 @@ namespace System
                        info.AddValue ("ExceptionMethod", null);
                }
 
+#if ONLY_1_1
+               [ReflectionPermission (SecurityAction.Assert, TypeInformation = true)]
+#endif
                public override string ToString ()
                {
                        System.Text.StringBuilder result = new System.Text.StringBuilder (this.GetType ().FullName);
@@ -207,8 +286,8 @@ namespace System
                                result.Append (Environment.NewLine);
                        }
 
-                       if (stack_trace != null)
-                               result.Append (Environment.NewLine).Append (stack_trace);
+                       if (StackTrace != null)
+                               result.Append (Environment.NewLine).Append (StackTrace);
                        return result.ToString();
                }
 
@@ -226,5 +305,49 @@ namespace System
 
                        return this;
                }
+
+               internal string GetFullNameForStackTrace (MethodBase mi)
+               {
+                       string parms = String.Empty;
+                       ParameterInfo[] p = mi.GetParameters ();
+                       for (int i = 0; i < p.Length; ++i) {
+                               if (i > 0)
+                                       parms = parms + ", ";
+                               string paramName = (p [i].Name == null) ? String.Empty : (" " + p [i].Name);
+                               Type pt = p[i].ParameterType;
+                               if (pt.IsClass && pt.Namespace != String.Empty)
+                                       parms = parms + pt.Namespace + "." + pt.Name + paramName;
+                               else
+                                       parms = parms + pt.Name + paramName;
+                       }
+
+                       string generic = String.Empty;
+#if NET_2_0 || BOOTSTRAP_NET_2_0
+                       if (mi.IsGenericMethod) {
+                               Type[] gen_params = mi.GetGenericArguments ();
+                               generic = "[";
+                               for (int j = 0; j < gen_params.Length; j++) {
+                                       if (j > 0)
+                                               generic += ",";
+                                       generic += gen_params [j].Name;
+                               }
+                               generic += "]";
+                       }
+#endif
+                       return mi.DeclaringType.ToString () + "." + mi.Name + generic + " (" + parms + ")";
+               }
+
+#if NET_2_0
+               //
+               // The documentation states that this is available in 1.x,
+               // but it was not available (MemberRefing this would fail)
+               // and it states the signature is `override sealed', but the
+               // correct value is `newslot' 
+               //
+               public new Type GetType ()
+               {
+                       return base.GetType ();
+               }
+#endif
        }
 }