📄 report.cs
字号:
//// report.cs: report errors and warnings.//// Author: Miguel de Icaza (miguel@ximian.com)//// (C) 2001 Ximian, Inc. (http://www.ximian.com)//using System;using System.IO;using System.Text;using System.Collections;using System.Collections.Specialized;using System.Diagnostics;using System.Reflection;using System.Reflection.Emit;namespace Mono.CSharp { /// <summary> /// This class is used to report errors and warnings t te user. /// </summary> public class Report { /// <summary> /// Errors encountered so far /// </summary> static public int Errors; /// <summary> /// Warnings encountered so far /// </summary> static public int Warnings; /// <summary> /// Whether errors should be throw an exception /// </summary> static public bool Fatal; /// <summary> /// Whether warnings should be considered errors /// </summary> static public bool WarningsAreErrors; /// <summary> /// Whether to dump a stack trace on errors. /// </summary> static public bool Stacktrace; static public TextWriter Stderr = Console.Error; // // If the 'expected' error code is reported then the // compilation succeeds. // // Used for the test suite to excercise the error codes // static int expected_error = 0; // // Keeps track of the warnings that we are ignoring // public static Hashtable warning_ignore_table; static Hashtable warning_regions_table; /// <summary> /// List of symbols related to reported error/warning. You have to fill it before error/warning is reported. /// </summary> static StringCollection extra_information = new StringCollection (); // // 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 }; static Report () { // Just to be sure that binary search is working Array.Sort (AllWarnings); } public static void Reset () { Errors = Warnings = 0; WarningsAreErrors = false; warning_ignore_table = null; warning_regions_table = null; } abstract class AbstractMessage { static void Check (int code) { if (code == expected_error) { Environment.Exit (0); } } public abstract bool IsWarning { get; } public abstract string MessageType { get; } public virtual void Print (int code, string location, string text) { if (code < 0) code = 8000-code; StringBuilder msg = new StringBuilder (); if (location.Length != 0) { msg.Append (location); msg.Append (' '); } msg.AppendFormat ("{0} CS{1:0000}: {2}", MessageType, code, text); Stderr.WriteLine (msg.ToString ()); foreach (string s in extra_information) Stderr.WriteLine (s + MessageType); extra_information.Clear (); if (Stacktrace) Console.WriteLine (FriendlyStackTrace (new StackTrace (true))); if (Fatal) { if (!IsWarning || WarningsAreErrors) throw new Exception (text); } Check (code); } public virtual void Print (int code, Location location, string text) { if (location.IsNull) { Print (code, "", text); return; } Print (code, location.ToString (), text); } } sealed class WarningMessage : AbstractMessage { Location loc = Location.Null; readonly int Level; public WarningMessage (): this (-1) {} public WarningMessage (int level) { Level = level; } public override bool IsWarning { get { return true; } } bool IsEnabled (int code) { if (RootContext.WarningLevel < Level) return false; if (warning_ignore_table != null) { if (warning_ignore_table.Contains (code)) { return false; } } if (warning_regions_table == null || loc.Equals (Location.Null)) return true; WarningRegions regions = (WarningRegions)warning_regions_table [loc.Name]; if (regions == null) return true; return regions.IsWarningEnabled (code, loc.Row); } public override void Print(int code, string location, string text) { if (!IsEnabled (code)) { extra_information.Clear (); return; } if (WarningsAreErrors) { new ErrorMessage ().Print (code, location, text); return; } Warnings++; base.Print (code, location, text); } public override void Print(int code, Location location, string text) { loc = location; base.Print (code, location, text); } public override string MessageType { get { return "warning"; } } } sealed class ErrorMessage : AbstractMessage { public override void Print(int code, string location, string text) { Errors++; base.Print (code, location, text); } public override bool IsWarning { get { return false; } } public override string MessageType { get { return "error"; } } } public static void FeatureIsNotStandardized (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); } public static string FriendlyStackTrace (Exception e) { return FriendlyStackTrace (new StackTrace (e, true)); } static string FriendlyStackTrace (StackTrace t) { StringBuilder sb = new StringBuilder (); bool foundUserCode = false; for (int i = 0; i < t.FrameCount; i++) { StackFrame f = t.GetFrame (i); MethodBase mb = f.GetMethod (); if (!foundUserCode && mb.ReflectedType == typeof (Report)) continue; foundUserCode = true; sb.Append ("\tin "); if (f.GetFileLineNumber () > 0) sb.AppendFormat ("(at {0}:{1}) ", f.GetFileName (), f.GetFileLineNumber ()); sb.AppendFormat ("{0}.{1} (", mb.ReflectedType.Name, mb.Name); bool first = true; foreach (ParameterInfo pi in mb.GetParameters ()) { if (!first) sb.Append (", "); first = false; sb.Append (TypeManager.CSharpName (pi.ParameterType)); } sb.Append (")\n"); } return sb.ToString (); } public static void StackTrace () { Console.WriteLine (FriendlyStackTrace (new StackTrace (true))); } public static bool IsValidWarning (int code) { 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); } /// <summary> /// In most error cases is very useful to have information about symbol that caused the error. /// Call this method before you call Report.Error when it makes sense. /// </summary> static public void SymbolRelatedToPreviousError (Location loc, string symbol) { SymbolRelatedToPreviousError (loc.ToString (), symbol); } static public void SymbolRelatedToPreviousError (MemberInfo mi) { TypeContainer temp_ds = TypeManager.LookupTypeContainer (mi.DeclaringType); if (temp_ds == null) { SymbolRelatedToPreviousError (mi.DeclaringType.Assembly.Location, TypeManager.GetFullNameSignature (mi)); } else { if (mi is MethodBase) { IMethodData md = TypeManager.GetMethod ((MethodBase)mi); SymbolRelatedToPreviousError (md.Location, md.GetSignatureForError ()); return; } MemberCore mc = temp_ds.GetDefinition (mi.Name); SymbolRelatedToPreviousError (mc); } } static public void SymbolRelatedToPreviousError (MemberCore mc) { SymbolRelatedToPreviousError (mc.Location, mc.GetSignatureForError ()); } static public void SymbolRelatedToPreviousError (Type type) { if (type is TypeBuilder) { DeclSpace temp_ds = TypeManager.LookupDeclSpace (type); SymbolRelatedToPreviousError (temp_ds.Location, TypeManager.CSharpName (type)); } else if (type.HasElementType) { SymbolRelatedToPreviousError (type.GetElementType ()); } else { SymbolRelatedToPreviousError (type.Assembly.Location, TypeManager.CSharpName (type)); } } static void SymbolRelatedToPreviousError (string loc, string symbol) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -