X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Freport.cs;h=478f0bea9e352382cbb4b1f6ac53f2975a9e990b;hb=6e009b793028df01f6d17e65d197f6a5f5e0e25d;hp=2065e52b226ede487476c2e6f558fdac917d08fd;hpb=4a2ab0336e97f3591eebbb881a1471d3051946c9;p=mono.git diff --git a/mcs/mcs/report.cs b/mcs/mcs/report.cs index 2065e52b226..478f0bea9e3 100644 --- a/mcs/mcs/report.cs +++ b/mcs/mcs/report.cs @@ -2,6 +2,7 @@ // report.cs: report errors and warnings. // // Author: Miguel de Icaza (miguel@ximian.com) +// Marek Safar (marek.safar@seznam.cz) // // (C) 2001 Ximian, Inc. (http://www.ximian.com) // @@ -41,6 +42,7 @@ namespace Mono.CSharp { /// static public bool WarningsAreErrors; + /// /// Whether to dump a stack trace on errors. /// @@ -63,28 +65,45 @@ namespace Mono.CSharp { static Hashtable warning_regions_table; + // + // This is used to save/restore the error state. When the + // error stack contains elements, warnings and errors are not + // reported to the user. This is used by the Lambda expression + // support to compile the code with various parameter values. + // A stack because of `Report.Errors == errors;' + // + static Stack error_stack; + static Stack warning_stack; + static bool reporting_disabled; + + static int warning_level; + /// /// List of symbols related to reported error/warning. You have to fill it before error/warning is reported. /// - static StringCollection extra_information = new StringCollection (); + static ArrayList extra_information = new ArrayList (); // // IF YOU ADD A NEW WARNING YOU HAVE TO ADD ITS ID HERE // public static readonly int[] AllWarnings = new int[] { - 28, 67, 78, - 105, 108, 109, 114, 162, 164, 168, 169, 183, 184, 197, - 219, 251, 252, 253, 282, - 419, 420, 429, 436, 440, 465, - 612, 618, 626, 628, 642, 649, 652, 658, 659, 660, 661, 665, 672, - 1030, 1058, - 1522, 1570, 1571, 1572, 1573, 1574, 1580, 1581, 1584, 1587, 1589, 1590, 1591, 1592, - 1616, 1633, 1634, 1635, 1691, 1692, - 1717, 1718, - 1901, - 2002, 2023, - 3005, 3012, 3019, 3021, 3022, 3023, 3026, 3027 - }; + 28, 67, 78, + 105, 108, 109, 114, 162, 164, 168, 169, 183, 184, 197, + 219, 251, 252, 253, 278, 282, + 419, 420, 429, 436, 440, 465, 467, 469, 472, + 612, 618, 626, 628, 642, 649, 652, 658, 659, 660, 661, 665, 672, 675, + 809, + 1030, + 1522, 1570, 1571, 1572, 1573, 1574, 1580, 1581, 1584, 1587, 1589, 1590, 1591, 1592, + 1616, 1633, 1634, 1635, 1685, 1690, 1691, 1692, + 1717, 1718, 1720, + 1901, + 2002, 2023, 2029, + 3005, 3012, 3018, 3019, 3021, 3022, 3023, 3026, 3027, +#if GMCS_SOURCE + 402, 414, 458, 693, 1058, 1700, 3024 +#endif + }; static Report () { @@ -98,9 +117,175 @@ namespace Mono.CSharp { WarningsAreErrors = false; warning_ignore_table = null; warning_regions_table = null; + reporting_disabled = false; + error_stack = warning_stack = null; + } + + public static void DisableReporting () + { + if (error_stack == null) + error_stack = new Stack (); + error_stack.Push (Errors); + + if (Warnings > 0) { + if (warning_stack == null) + warning_stack = new Stack (); + warning_stack.Push (Warnings); + } + + reporting_disabled = true; + } + + public static void EnableReporting () + { + if (warning_stack != null) + Warnings = (int) warning_stack.Pop (); + + Errors = (int) error_stack.Pop (); + if (error_stack.Count == 0) { + reporting_disabled = false; + } } - abstract class AbstractMessage { + public static IMessageRecorder msg_recorder; + + public static IMessageRecorder SetMessageRecorder (IMessageRecorder recorder) + { + IMessageRecorder previous = msg_recorder; + msg_recorder = recorder; + return previous; + } + + public interface IMessageRecorder + { + void EndSession (); + void AddMessage (AbstractMessage msg); + bool PrintMessages (); + } + + // + // Default message recorder, it uses two types of message groups. + // Common messages: messages reported in all sessions. + // Merged messages: union of all messages in all sessions. + // + public struct MessageRecorder : IMessageRecorder + { + ArrayList session_messages; + // + // A collection of exactly same messages reported in all sessions + // + ArrayList common_messages; + + // + // A collection of unique messages reported in all sessions + // + ArrayList merged_messages; + + public void EndSession () + { + if (session_messages == null) + return; + + // + // Handles the first session + // + if (common_messages == null) { + common_messages = new ArrayList (session_messages); + merged_messages = session_messages; + session_messages = null; + return; + } + + // + // Store common messages if any + // + for (int i = 0; i < common_messages.Count; ++i) { + AbstractMessage cmsg = (AbstractMessage) common_messages [i]; + bool common_msg_found = false; + foreach (AbstractMessage msg in session_messages) { + if (cmsg.Equals (msg)) { + common_msg_found = true; + break; + } + } + + if (!common_msg_found) + common_messages.RemoveAt (i); + } + + // + // Merge session and previous messages + // + for (int i = 0; i < session_messages.Count; ++i) { + AbstractMessage msg = (AbstractMessage) session_messages [i]; + bool msg_found = false; + for (int ii = 0; ii < merged_messages.Count; ++ii) { + if (msg.Equals (merged_messages [ii])) { + msg_found = true; + break; + } + } + + if (!msg_found) + merged_messages.Add (msg); + } + } + + public void AddMessage (AbstractMessage msg) + { + if (session_messages == null) + session_messages = new ArrayList (); + + session_messages.Add (msg); + } + + // + // Prints collected messages, common messages have a priority + // + public bool PrintMessages () + { + ArrayList messages_to_print = merged_messages; + if (common_messages != null && common_messages.Count > 0) { + messages_to_print = common_messages; + } + + if (messages_to_print == null) + return false; + + foreach (AbstractMessage msg in messages_to_print) + msg.Print (); + + return true; + } + } + + public abstract class AbstractMessage + { + readonly string[] extra_info; + protected readonly int code; + protected readonly Location location; + readonly string message; + + protected AbstractMessage (int code, Location loc, string msg, ArrayList extraInfo) + { + this.code = code; + if (code < 0) + this.code = 8000 - code; + + this.location = loc; + this.message = msg; + if (extraInfo.Count != 0) { + this.extra_info = (string[])extraInfo.ToArray (typeof (string)); + } + } + + protected AbstractMessage (AbstractMessage aMsg) + { + this.code = aMsg.code; + this.location = aMsg.location; + this.message = aMsg.message; + this.extra_info = aMsg.extra_info; + } static void Check (int code) { @@ -109,57 +294,80 @@ namespace Mono.CSharp { } } + public override bool Equals (object obj) + { + AbstractMessage msg = obj as AbstractMessage; + if (msg == null) + return false; + + return code == msg.code && location.Equals (msg.location) && message == msg.message; + } + + public override int GetHashCode () + { + return code.GetHashCode (); + } + public abstract bool IsWarning { get; } public abstract string MessageType { get; } - public virtual void Print (int code, string location, string text) + public virtual void Print () { - if (code < 0) - code = 8000-code; + if (msg_recorder != null) { + // + // This line is useful when debugging messages recorder + // + // Console.WriteLine ("RECORDING: {0} {1} {2}", code, location, message); + msg_recorder.AddMessage (this); + return; + } + + if (reporting_disabled) + return; StringBuilder msg = new StringBuilder (); - if (location.Length != 0) { - msg.Append (location); - msg.Append (' '); + if (!location.IsNull) { + msg.Append (location.ToString ()); + msg.Append (" "); } - msg.AppendFormat ("{0} CS{1:0000}: {2}", MessageType, code, text); - Stderr.WriteLine (msg.ToString ()); + msg.AppendFormat ("{0} CS{1:0000}: {2}", MessageType, code, message); - foreach (string s in extra_information) - Stderr.WriteLine (s + MessageType); + // + // + if (Stderr == Console.Error) + Stderr.WriteLine (ColorFormat (msg.ToString ())); + else + Stderr.WriteLine (msg.ToString ()); - extra_information.Clear (); + if (extra_info != null) { + foreach (string s in extra_info) + Stderr.WriteLine (s + MessageType + ")"); + } if (Stacktrace) Console.WriteLine (FriendlyStackTrace (new StackTrace (true))); if (Fatal) { if (!IsWarning || WarningsAreErrors) - throw new Exception (text); + throw new Exception (message); } Check (code); } - public virtual void Print (int code, Location location, string text) + public virtual string ColorFormat (string s) { - if (location.IsNull) { - Print (code, "", text); - return; - } - Print (code, location.ToString (), text); + return s; } } - sealed class WarningMessage : AbstractMessage { - Location loc = Location.Null; + sealed class WarningMessage : AbstractMessage + { readonly int Level; - public WarningMessage (): - this (-1) {} - - public WarningMessage (int level) + public WarningMessage (int code, int level, Location loc, string message, ArrayList extra_info) + : base (code, loc, message, extra_info) { Level = level; } @@ -168,9 +376,9 @@ namespace Mono.CSharp { get { return true; } } - bool IsEnabled (int code) + bool IsEnabled () { - if (RootContext.WarningLevel < Level) + if (WarningLevel < Level) return false; if (warning_ignore_table != null) { @@ -179,36 +387,28 @@ namespace Mono.CSharp { } } - if (warning_regions_table == null || loc.Equals (Location.Null)) + if (warning_regions_table == null || location.IsNull) return true; - WarningRegions regions = (WarningRegions)warning_regions_table [loc.Name]; + WarningRegions regions = (WarningRegions)warning_regions_table [location.Name]; if (regions == null) return true; - return regions.IsWarningEnabled (code, loc.Row); + return regions.IsWarningEnabled (code, location.Row); } - public override void Print(int code, string location, string text) + public override void Print () { - if (!IsEnabled (code)) { - extra_information.Clear (); + if (!IsEnabled ()) return; - } if (WarningsAreErrors) { - new ErrorMessage ().Print (code, location, text); + new ErrorMessage (this).Print (); return; } Warnings++; - base.Print (code, location, text); - } - - public override void Print(int code, Location location, string text) - { - loc = location; - base.Print (code, location, text); + base.Print (); } public override string MessageType { @@ -218,12 +418,134 @@ namespace Mono.CSharp { } } - sealed class ErrorMessage : AbstractMessage { + static int NameToCode (string s) + { + switch (s){ + case "black": + return 0; + case "red": + return 1; + case "green": + return 2; + case "yellow": + return 3; + case "blue": + return 4; + case "magenta": + return 5; + case "cyan": + return 6; + case "grey": + case "white": + return 7; + } + return 7; + } + + // + // maps a color name to its xterm color code + // + static string GetForeground (string s) + { + string highcode; + + if (s.StartsWith ("bright")){ + highcode = "1;"; + s = s.Substring (6); + } else + highcode = ""; - public override void Print(int code, string location, string text) + return "\x001b[" + highcode + (30 + NameToCode (s)).ToString () + "m"; + } + + static string GetBackground (string s) + { + return "\x001b[" + (40 + NameToCode (s)).ToString () + "m"; + } + + sealed class ErrorMessage : AbstractMessage + { + static string prefix, postfix; + + [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")] + extern static int _isatty (int fd); + + static bool isatty (int fd) + { + try { + return _isatty (fd) == 1; + } catch { + return false; + } + } + + static ErrorMessage () + { + string term = Environment.GetEnvironmentVariable ("TERM"); + bool xterm_colors = false; + + switch (term){ + case "xterm": + case "rxvt": + case "rxvt-unicode": + if (Environment.GetEnvironmentVariable ("COLORTERM") != null){ + xterm_colors = true; + } + break; + + case "xterm-color": + xterm_colors = true; + break; + } + if (!xterm_colors) + return; + + if (!(isatty (1) && isatty (2))) + return; + + string config = Environment.GetEnvironmentVariable ("MCS_COLORS"); + if (config == null){ + config = "errors=red"; + //config = "brightwhite,red"; + } + + if (config == "disable") + return; + + if (!config.StartsWith ("errors=")) + return; + + config = config.Substring (7); + + int p = config.IndexOf (","); + if (p == -1) + prefix = GetForeground (config); + else + prefix = GetBackground (config.Substring (p+1)) + GetForeground (config.Substring (0, p)); + postfix = "\x001b[0m"; + } + + public ErrorMessage (int code, Location loc, string message, ArrayList extraInfo) + : base (code, loc, message, extraInfo) + { + } + + public ErrorMessage (AbstractMessage aMsg) + : base (aMsg) + { + } + + public override string ColorFormat (string s) + { + if (prefix != null) + return prefix + s + postfix; + return s; + } + + public override void Print() { Errors++; - base.Print (code, location, text); + base.Print (); } public override bool IsWarning { @@ -235,12 +557,29 @@ namespace Mono.CSharp { return "error"; } } - } - public static void FeatureIsNotStandardized (Location loc, string feature) + public static void FeatureIsNotAvailable (Location loc, string feature) { - Report.Error (1644, loc, "Feature `{0}' cannot be used because it is not part of the standardized ISO C# language specification", feature); + string version; + switch (RootContext.Version) { + case LanguageVersion.ISO_1: + version = "1.0"; + break; + case LanguageVersion.ISO_2: + version = "2.0"; + break; + case LanguageVersion.Default_MCS: + Report.Error (1644, loc, "Feature `{0}' is not available in Mono mcs compiler. Consider using Mono gmcs compiler instead", + feature); + return; + default: + throw new InternalErrorException ("Invalid feature version", RootContext.Version); + } + + Report.Error (1644, loc, + "Feature `{0}' cannot be used because it is not part of the C# {1} language specification", + feature, version); } public static string FriendlyStackTrace (Exception e) @@ -293,12 +632,7 @@ namespace Mono.CSharp { { return Array.BinarySearch (AllWarnings, code) >= 0; } - - static public void LocationOfPreviousError (Location loc) - { - Stderr.WriteLine (String.Format ("{0} (Location of symbol related to previous error)", loc)); - } - + static public void RuntimeMissingSupport (Location loc, string feature) { Report.Error (-88, loc, "Your .NET Runtime does not support `{0}'. Please use the latest Mono runtime instead.", feature); @@ -315,12 +649,23 @@ namespace Mono.CSharp { static public void SymbolRelatedToPreviousError (MemberInfo mi) { - TypeContainer temp_ds = TypeManager.LookupTypeContainer (mi.DeclaringType); + if (reporting_disabled) + return; + + Type dt = TypeManager.DropGenericTypeArguments (mi.DeclaringType); + if (TypeManager.IsDelegateType (dt)) { + SymbolRelatedToPreviousError (dt); + return; + } + + DeclSpace temp_ds = TypeManager.LookupDeclSpace (dt); if (temp_ds == null) { - SymbolRelatedToPreviousError (mi.DeclaringType.Assembly.Location, TypeManager.GetFullNameSignature (mi)); + SymbolRelatedToPreviousError (dt.Assembly.Location, TypeManager.GetFullNameSignature (mi)); } else { - if (mi is MethodBase) { - IMethodData md = TypeManager.GetMethod ((MethodBase)mi); + MethodBase mb = mi as MethodBase; + if (mb != null) { + mb = TypeManager.DropGenericMethodArguments (mb); + IMethodData md = TypeManager.GetMethod (mb); SymbolRelatedToPreviousError (md.Location, md.GetSignatureForError ()); return; } @@ -337,6 +682,19 @@ namespace Mono.CSharp { static public void SymbolRelatedToPreviousError (Type type) { + if (reporting_disabled) + return; + + type = TypeManager.DropGenericTypeArguments (type); + + if (TypeManager.IsGenericParameter (type)) { + TypeParameter tp = TypeManager.LookupTypeParameter (type); + if (tp != null) { + SymbolRelatedToPreviousError (tp.Location, ""); + return; + } + } + if (type is TypeBuilder) { DeclSpace temp_ds = TypeManager.LookupDeclSpace (type); SymbolRelatedToPreviousError (temp_ds.Location, TypeManager.CSharpName (type)); @@ -349,7 +707,7 @@ namespace Mono.CSharp { static void SymbolRelatedToPreviousError (string loc, string symbol) { - extra_information.Add (String.Format ("{0}: `{1}', name of symbol related to previous ", loc, symbol)); + extra_information.Add (String.Format ("{0} (Location of the symbol related to previous ", loc)); } public static void ExtraInformation (Location loc, string msg) @@ -370,34 +728,70 @@ namespace Mono.CSharp { return regions; } + static public void Warning (int code, int level, Location loc, string message) + { + WarningMessage w = new WarningMessage (code, level, loc, message, extra_information); + extra_information.Clear (); + w.Print (); + } + + static public void Warning (int code, int level, Location loc, string format, string arg) + { + WarningMessage w = new WarningMessage (code, level, loc, String.Format (format, arg), extra_information); + extra_information.Clear (); + w.Print (); + } + + static public void Warning (int code, int level, Location loc, string format, string arg1, string arg2) + { + WarningMessage w = new WarningMessage (code, level, loc, String.Format (format, arg1, arg2), extra_information); + extra_information.Clear (); + w.Print (); + } + static public void Warning (int code, int level, Location loc, string format, params object[] args) { - WarningMessage w = new WarningMessage (level); - w.Print (code, loc, String.Format (format, args)); + WarningMessage w = new WarningMessage (code, level, loc, String.Format (format, args), extra_information); + extra_information.Clear (); + w.Print (); } - static public void Warning (int code, Location loc, string format, params object[] args) + static public void Warning (int code, int level, string message) { - WarningMessage w = new WarningMessage (); - w.Print (code, loc, String.Format (format, args)); + Warning (code, level, Location.Null, message); } - static public void Warning (int code, string format, params object[] args) + static public void Warning (int code, int level, string format, string arg) { - Warning (code, Location.Null, String.Format (format, args)); + Warning (code, level, Location.Null, format, arg); } - /// - /// Did you test your WarningLevel, that you use this method - /// - static public void Warning (int code, string text) + static public void Warning (int code, int level, string format, string arg1, string arg2) { - Warning (code, Location.Null, text); + Warning (code, level, Location.Null, format, arg1, arg2); } - static public void Error (int code, string format, params object[] args) + static public void Warning (int code, int level, string format, params string[] args) { - Error (code, Location.Null, String.Format (format, args)); + Warning (code, level, Location.Null, String.Format (format, args)); + } + + static public void Error (int code, Location loc, string error) + { + new ErrorMessage (code, loc, error, extra_information).Print (); + extra_information.Clear (); + } + + static public void Error (int code, Location loc, string format, string arg) + { + new ErrorMessage (code, loc, String.Format (format, arg), extra_information).Print (); + extra_information.Clear (); + } + + static public void Error (int code, Location loc, string format, string arg1, string arg2) + { + new ErrorMessage (code, loc, String.Format (format, arg1, arg2), extra_information).Print (); + extra_information.Clear (); } static public void Error (int code, Location loc, string format, params object[] args) @@ -405,9 +799,24 @@ namespace Mono.CSharp { Error (code, loc, String.Format (format, args)); } - static public void Error (int code, Location loc, string error) + static public void Error (int code, string error) { - new ErrorMessage ().Print (code, loc, error); + Error (code, Location.Null, error); + } + + static public void Error (int code, string format, string arg) + { + Error (code, Location.Null, format, arg); + } + + static public void Error (int code, string format, string arg1, string arg2) + { + Error (code, Location.Null, format, arg1, arg2); + } + + static public void Error (int code, string format, params string[] args) + { + Error (code, Location.Null, String.Format (format, args)); } static public void SetIgnoreWarning (int code) @@ -426,6 +835,15 @@ namespace Mono.CSharp { return expected_error; } } + + public static int WarningLevel { + get { + return warning_level; + } + set { + warning_level = value; + } + } public static int DebugFlags = 0; @@ -572,6 +990,11 @@ namespace Mono.CSharp { } public class InternalErrorException : Exception { + public InternalErrorException (MemberCore mc, Exception e) + : base (mc.Location + " " + mc.GetSignatureForError (), e) + { + } + public InternalErrorException () : base ("Internal error") { @@ -581,6 +1004,15 @@ namespace Mono.CSharp { : base (message) { } + + public InternalErrorException (string message, params object[] args) + : base (String.Format (message, args)) + { } + + public InternalErrorException (Exception e, Location loc) + : base (loc.ToString (), e) + { + } } /// @@ -689,12 +1121,12 @@ namespace Mono.CSharp { return result; } - bool CheckWarningCode (int code, Location loc) + static bool CheckWarningCode (int code, Location loc) { if (Report.IsValidWarning (code)) return true; - Report.Warning (1691, 1, loc, "`{0}' is not a valid warning number", code); + Report.Warning (1691, 1, loc, "`{0}' is not a valid warning number", code.ToString ()); return false; } }