// report.cs: report errors and warnings.
//
// Author: Miguel de Icaza (miguel@ximian.com)
-// Marek Safar (marek.safar@seznam.cz)
+// Marek Safar (marek.safar@gmail.com)
//
// Copyright 2001 Ximian, Inc. (http://www.ximian.com)
+// Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
//
using System;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Reflection;
-using System.Reflection.Emit;
namespace Mono.CSharp {
List<int> warnings_as_error;
List<int> warnings_only;
- public static int DebugFlags = 0;
+ public const int RuntimeErrorId = 10000;
//
// Keeps track of the warnings that we are ignoring
//
- public Dictionary<int, bool> warning_ignore_table;
+ HashSet<int> warning_ignore_table;
- Dictionary<string, WarningRegions> warning_regions_table;
+ Dictionary<int, WarningRegions> warning_regions_table;
int warning_level;
28, 67, 78,
105, 108, 109, 114, 162, 164, 168, 169, 183, 184, 197,
219, 251, 252, 253, 278, 282,
- 402, 414, 419, 420, 429, 436, 440, 458, 464, 465, 467, 469, 472,
- 612, 618, 626, 628, 642, 649, 652, 658, 659, 660, 661, 665, 672, 675, 693,
- 809,
- 1030, 1058, 1066,
+ 402, 414, 419, 420, 429, 436, 437, 440, 458, 464, 465, 467, 469, 472, 473,
+ 612, 618, 626, 628, 642, 649, 652, 657, 658, 659, 660, 661, 665, 672, 675, 693,
+ 728,
+ 809, 824,
+ 1030, 1058, 1060, 1066,
1522, 1570, 1571, 1572, 1573, 1574, 1580, 1581, 1584, 1587, 1589, 1590, 1591, 1592,
- 1616, 1633, 1634, 1635, 1685, 1690, 1691, 1692,
- 1700, 1717, 1718, 1720,
- 1901,
+ 1607, 1616, 1633, 1634, 1635, 1685, 1690, 1691, 1692, 1695, 1696, 1699,
+ 1700, 1701, 1702, 1709, 1711, 1717, 1718, 1720, 1735,
+ 1901, 1956, 1981, 1998,
2002, 2023, 2029,
3000, 3001, 3002, 3003, 3005, 3006, 3007, 3008, 3009,
3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 3019,
3021, 3022, 3023, 3024, 3026, 3027
};
- static Report ()
- {
- // Just to be sure that binary search is working
- Array.Sort (AllWarnings);
- }
+ static HashSet<int> AllWarningsHashSet;
public Report (ReportPrinter printer)
{
--reporting_disabled;
}
- public void FeatureIsNotAvailable (Location loc, string feature)
+ public void FeatureIsNotAvailable (CompilerContext compiler, Location loc, string feature)
{
string version;
- switch (RootContext.Version) {
+ switch (compiler.Settings.Version) {
case LanguageVersion.ISO_1:
version = "1.0";
break;
case LanguageVersion.V_3:
version = "3.0";
break;
+ case LanguageVersion.V_4:
+ version = "4.0";
+ break;
+ case LanguageVersion.V_5:
+ version = "5.0";
+ break;
default:
- throw new InternalErrorException ("Invalid feature version", RootContext.Version);
+ throw new InternalErrorException ("Invalid feature version", compiler.Settings.Version);
}
Error (1644, loc,
feature);
}
- static bool IsValidWarning (int code)
- {
- return Array.BinarySearch (AllWarnings, code) >= 0;
- }
-
bool IsWarningEnabled (int code, int level, Location loc)
{
if (WarningLevel < level)
return false;
- if (warning_ignore_table != null) {
- if (warning_ignore_table.ContainsKey (code)) {
- return false;
- }
- }
+ if (IsWarningDisabledGlobally (code))
+ return false;
if (warning_regions_table == null || loc.IsNull)
return true;
WarningRegions regions;
- if (!warning_regions_table.TryGetValue (loc.Name, out regions))
+ if (!warning_regions_table.TryGetValue (loc.File, out regions))
return true;
return regions.IsWarningEnabled (code, loc.Row);
}
+ public bool IsWarningDisabledGlobally (int code)
+ {
+ return warning_ignore_table != null && warning_ignore_table.Contains (code);
+ }
+
bool IsWarningAsError (int code)
{
bool is_error = WarningsAreErrors;
/// </summary>
public void SymbolRelatedToPreviousError (Location loc, string symbol)
{
- SymbolRelatedToPreviousError (loc.ToString (), symbol);
+ SymbolRelatedToPreviousError (loc.ToString ());
}
- public void SymbolRelatedToPreviousError (MemberInfo mi)
+ public void SymbolRelatedToPreviousError (MemberSpec ms)
{
if (reporting_disabled > 0 || !printer.HasRelatedSymbolSupport)
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 (dt.Assembly.Location, TypeManager.GetFullNameSignature (mi));
+ var mc = ms.MemberDefinition as MemberCore;
+ while (ms is ElementTypeSpec) {
+ ms = ((ElementTypeSpec) ms).Element;
+ mc = ms.MemberDefinition as MemberCore;
+ }
+
+ if (mc != null) {
+ SymbolRelatedToPreviousError (mc);
} else {
- MethodBase mb = mi as MethodBase;
- if (mb != null) {
- mb = TypeManager.DropGenericMethodArguments (mb);
- IMethodData md = TypeManager.GetMethod (mb);
- if (md != null)
- SymbolRelatedToPreviousError (md.Location, md.GetSignatureForError ());
-
- return;
- }
+ if (ms.DeclaringType != null)
+ ms = ms.DeclaringType;
- // FIXME: Completely wrong, it has to use FindMembers
- MemberCore mc = temp_ds.GetDefinition (mi.Name);
- if (mc != null)
- SymbolRelatedToPreviousError (mc);
+ var imported_type = ms.MemberDefinition as ImportedTypeDefinition;
+ if (imported_type != null) {
+ var iad = imported_type.DeclaringAssembly as ImportedAssemblyDefinition;
+ SymbolRelatedToPreviousError (iad.Location);
+ }
}
}
SymbolRelatedToPreviousError (mc.Location, mc.GetSignatureForError ());
}
- public void SymbolRelatedToPreviousError (Type type)
- {
- if (reporting_disabled > 0 || !printer.HasRelatedSymbolSupport)
- 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));
- } else if (TypeManager.HasElementType (type)) {
- SymbolRelatedToPreviousError (TypeManager.GetElementType (type));
- } else {
- SymbolRelatedToPreviousError (type.Assembly.Location, TypeManager.CSharpName (type));
- }
- }
-
- void SymbolRelatedToPreviousError (string loc, string symbol)
+ public void SymbolRelatedToPreviousError (string loc)
{
string msg = String.Format ("{0} (Location of the symbol related to previous ", loc);
if (extra_information.Contains (msg))
try {
id = int.Parse (warningId);
} catch {
- id = -1;
+ CheckWarningCode (warningId, Location.Null);
+ return;
}
- if (!CheckWarningCode (id, warningId, Location.Null))
+ if (!CheckWarningCode (id, Location.Null))
return;
if (warnings_as_error == null)
try {
id = int.Parse (warningId);
} catch {
- id = -1;
+ CheckWarningCode (warningId, Location.Null);
+ return;
}
- if (!CheckWarningCode (id, warningId, Location.Null))
+ if (!CheckWarningCode (id, Location.Null))
return;
if (warnings_only == null)
warnings_only.Add (id);
}
- public bool CheckWarningCode (int code, Location loc)
+ public bool CheckWarningCode (string code, Location loc)
{
- return CheckWarningCode (code, code.ToString (), loc);
+ Warning (1691, 1, loc, "`{0}' is not a valid warning number", code);
+ return false;
}
- public bool CheckWarningCode (int code, string scode, Location loc)
+ public bool CheckWarningCode (int code, Location loc)
{
- if (IsValidWarning (code))
+ if (AllWarningsHashSet == null)
+ AllWarningsHashSet = new HashSet<int> (AllWarnings);
+
+ if (AllWarningsHashSet.Contains (code))
return true;
- Warning (1691, 1, loc, "`{0}' is not a valid warning number", scode);
- return false;
+ return CheckWarningCode (code.ToString (), loc);
}
public void ExtraInformation (Location loc, string msg)
WarningRegions regions;
if (warning_regions_table == null) {
regions = null;
- warning_regions_table = new Dictionary<string, WarningRegions> ();
+ warning_regions_table = new Dictionary<int, WarningRegions> ();
} else {
- warning_regions_table.TryGetValue (location.Name, out regions);
+ warning_regions_table.TryGetValue (location.File, out regions);
}
if (regions == null) {
regions = new WarningRegions ();
- warning_regions_table.Add (location.Name, regions);
+ warning_regions_table.Add (location.File, regions);
}
return regions;
return;
AbstractMessage msg;
- if (IsWarningAsError (code))
+ if (IsWarningAsError (code)) {
+ message = "Warning as Error: " + message;
msg = new ErrorMessage (code, loc, message, extra_information);
- else
+ } else {
msg = new WarningMessage (code, loc, message, extra_information);
+ }
extra_information.Clear ();
printer.Print (msg);
Error (code, loc, String.Format (format, arg1, arg2));
}
- public void Error (int code, Location loc, string format, params object[] args)
+ public void Error (int code, Location loc, string format, params string[] args)
{
Error (code, loc, String.Format (format, args));
}
get { return printer.ErrorsCount; }
}
+ public bool IsDisabled {
+ get {
+ return reporting_disabled > 0;
+ }
+ }
+
public ReportPrinter Printer {
get { return printer; }
}
public void SetIgnoreWarning (int code)
{
if (warning_ignore_table == null)
- warning_ignore_table = new Dictionary<int, bool> ();
+ warning_ignore_table = new HashSet<int> ();
- warning_ignore_table [code] = true;
+ warning_ignore_table.Add (code);
}
public ReportPrinter SetPrinter (ReportPrinter printer)
this.printer = printer;
return old;
}
-
+
public int WarningLevel {
get {
return warning_level;
[Conditional ("MCS_DEBUG")]
static public void Debug (int category, string message, params object[] args)
{
- if ((category & DebugFlags) == 0)
- return;
+// if ((category & DebugFlags) == 0)
+// return;
StringBuilder sb = new StringBuilder (message);
//
public abstract class ReportPrinter
{
- /// <summary>
- /// Whether to dump a stack trace on errors.
- /// </summary>
- public bool Stacktrace;
-
- int warnings, errors;
+ #region Properties
- public int WarningsCount {
- get { return warnings; }
- }
-
- public int ErrorsCount {
- get { return errors; }
- }
+ public int FatalCounter { get; set; }
- protected virtual string FormatText (string txt)
- {
- return txt;
- }
+ public int ErrorsCount { get; protected set; }
+
+ public bool ShowFullPaths { get; set; }
+ //
+ // Whether to dump a stack trace on errors.
+ //
+ public bool Stacktrace { get; set; }
+
+ public int WarningsCount { get; private set; }
+
//
// When (symbols related to previous ...) can be used
//
get { return true; }
}
+ #endregion
+
+
+ protected virtual string FormatText (string txt)
+ {
+ return txt;
+ }
+
public virtual void Print (AbstractMessage msg)
{
- if (msg.IsWarning)
- ++warnings;
- else
- ++errors;
+ if (msg.IsWarning) {
+ ++WarningsCount;
+ } else {
+ ++ErrorsCount;
+
+ if (ErrorsCount == FatalCounter)
+ throw new Exception (msg.Text);
+ }
}
protected void Print (AbstractMessage msg, TextWriter output)
{
StringBuilder txt = new StringBuilder ();
if (!msg.Location.IsNull) {
- txt.Append (msg.Location.ToString ());
+ if (ShowFullPaths)
+ txt.Append (msg.Location.ToStringFullName ());
+ else
+ txt.Append (msg.Location.ToString ());
+
txt.Append (" ");
}
output.WriteLine (s + msg.MessageType + ")");
}
}
+
+ public void Reset ()
+ {
+ // HACK: Temporary hack for broken repl flow
+ ErrorsCount = WarningsCount = 0;
+ }
+ }
+
+ sealed class NullReportPrinter : ReportPrinter
+ {
}
//
//
// This line is useful when debugging recorded messages
//
- // Console.WriteLine ("RECORDING: {0} {1} {2}", code, location, message);
+ // Console.WriteLine ("RECORDING: {0}", msg.ToString ());
if (session_messages == null)
session_messages = new List<AbstractMessage> ();
// Store common messages if any
//
for (int i = 0; i < common_messages.Count; ++i) {
- AbstractMessage cmsg = (AbstractMessage) common_messages[i];
+ AbstractMessage cmsg = common_messages[i];
bool common_msg_found = false;
foreach (AbstractMessage msg in session_messages) {
if (cmsg.Equals (msg)) {
// Merge session and previous messages
//
for (int i = 0; i < session_messages.Count; ++i) {
- AbstractMessage msg = (AbstractMessage) session_messages[i];
+ AbstractMessage msg = session_messages[i];
bool msg_found = false;
for (int ii = 0; ii < merged_messages.Count; ++ii) {
if (msg.Equals (merged_messages[ii])) {
if (messages_to_print == null)
return false;
- foreach (AbstractMessage msg in messages_to_print)
+ bool error_msg = false;
+ foreach (AbstractMessage msg in messages_to_print) {
dest.Print (msg);
+ error_msg |= !msg.IsWarning;
+ }
- return true;
+ return error_msg;
}
}
- class StreamReportPrinter : ReportPrinter
+ public class StreamReportPrinter : ReportPrinter
{
readonly TextWriter writer;
}
}
- class ConsoleReportPrinter : StreamReportPrinter
+ public class ConsoleReportPrinter : StreamReportPrinter
{
static readonly string prefix, postfix;
break;
case "xterm-color":
+ case "xterm-256color":
xterm_colors = true;
break;
}
{
}
- public bool Fatal { get; set; }
-
static int NameToCode (string s)
{
switch (s) {
for (int i = 0; i < t.FrameCount; i++) {
StackFrame f = t.GetFrame (i);
- MethodBase mb = f.GetMethod ();
+ var mb = f.GetMethod ();
if (!foundUserCode && mb.ReflectedType == typeof (Report))
continue;
sb.AppendFormat ("{0}.{1} (", mb.ReflectedType.Name, mb.Name);
bool first = true;
- foreach (ParameterInfo pi in mb.GetParameters ()) {
+ foreach (var pi in mb.GetParameters ()) {
if (!first)
sb.Append (", ");
first = false;
-
- sb.Append (TypeManager.CSharpName (pi.ParameterType));
+
+ sb.Append (pi.ParameterType.FullName);
}
sb.Append (")\n");
}
if (Stacktrace)
Console.WriteLine (FriendlyStackTrace (new StackTrace (true)));
-
- if (Fatal)
- throw new Exception (msg.Text);
}
public static string FriendlyStackTrace (Exception e)
}
}
- public enum TimerType {
- FindMembers = 0,
- TcFindMembers = 1,
- MemberLookup = 2,
- CachedLookup = 3,
- CacheInit = 4,
- MiscTimer = 5,
- CountTimers = 6
- }
-
- public enum CounterType {
- FindMembers = 0,
- MemberCache = 1,
- MiscCounter = 2,
- CountCounters = 3
- }
-
- public class Timer
+ class TimeReporter
{
- static DateTime[] timer_start;
- static TimeSpan[] timers;
- static long[] timer_counters;
- static long[] counters;
-
- static Timer ()
+ public enum TimerType
{
- timer_start = new DateTime [(int) TimerType.CountTimers];
- timers = new TimeSpan [(int) TimerType.CountTimers];
- timer_counters = new long [(int) TimerType.CountTimers];
- counters = new long [(int) CounterType.CountCounters];
-
- for (int i = 0; i < (int) TimerType.CountTimers; i++) {
- timer_start [i] = DateTime.Now;
- timers [i] = TimeSpan.Zero;
- }
+ ParseTotal,
+ AssemblyBuilderSetup,
+ CreateTypeTotal,
+ ReferencesLoading,
+ ReferencesImporting,
+ PredefinedTypesInit,
+ ModuleDefinitionTotal,
+ UsingResolve,
+ EmitTotal,
+ CloseTypes,
+ Resouces,
+ OutputSave,
+ DebugSave,
}
- [Conditional("TIMER")]
- static public void IncrementCounter (CounterType which)
+ readonly Stopwatch[] timers;
+ Stopwatch total;
+
+ public TimeReporter (bool enabled)
{
- ++counters [(int) which];
+ if (!enabled)
+ return;
+
+ timers = new Stopwatch[System.Enum.GetValues(typeof (TimerType)).Length];
}
- [Conditional("TIMER")]
- static public void StartTimer (TimerType which)
+ public void Start (TimerType type)
{
- timer_start [(int) which] = DateTime.Now;
+ if (timers != null) {
+ var sw = new Stopwatch ();
+ timers[(int) type] = sw;
+ sw.Start ();
+ }
}
- [Conditional("TIMER")]
- static public void StopTimer (TimerType which)
+ public void StartTotal ()
{
- timers [(int) which] += DateTime.Now - timer_start [(int) which];
- ++timer_counters [(int) which];
+ total = new Stopwatch ();
+ total.Start ();
}
- [Conditional("TIMER")]
- static public void ShowTimers ()
+ public void Stop (TimerType type)
{
- ShowTimer (TimerType.FindMembers, "- FindMembers timer");
- ShowTimer (TimerType.TcFindMembers, "- TypeContainer.FindMembers timer");
- ShowTimer (TimerType.MemberLookup, "- MemberLookup timer");
- ShowTimer (TimerType.CachedLookup, "- CachedLookup timer");
- ShowTimer (TimerType.CacheInit, "- Cache init");
- ShowTimer (TimerType.MiscTimer, "- Misc timer");
-
- ShowCounter (CounterType.FindMembers, "- Find members");
- ShowCounter (CounterType.MemberCache, "- Member cache");
- ShowCounter (CounterType.MiscCounter, "- Misc counter");
+ if (timers != null) {
+ timers[(int) type].Stop ();
+ }
}
- static public void ShowCounter (CounterType which, string msg)
+ public void StopTotal ()
{
- Console.WriteLine ("{0} {1}", counters [(int) which], msg);
+ total.Stop ();
}
- static public void ShowTimer (TimerType which, string msg)
+ public void ShowStats ()
{
- Console.WriteLine (
- "[{0:00}:{1:000}] {2} (used {3} times)",
- (int) timers [(int) which].TotalSeconds,
- timers [(int) which].Milliseconds, msg,
- timer_counters [(int) which]);
+ if (timers == null)
+ return;
+
+ Dictionary<TimerType, string> timer_names = new Dictionary<TimerType,string> () {
+ { TimerType.ParseTotal, "Parsing source files" },
+ { TimerType.AssemblyBuilderSetup, "Assembly builder setup" },
+ { TimerType.CreateTypeTotal, "Compiled types created" },
+ { TimerType.ReferencesLoading, "Referenced assemblies loading" },
+ { TimerType.ReferencesImporting, "Referenced assemblies importing" },
+ { TimerType.PredefinedTypesInit, "Predefined types initialization" },
+ { TimerType.ModuleDefinitionTotal, "Module definition" },
+ { TimerType.UsingResolve, "Top-level usings resolve" },
+ { TimerType.EmitTotal, "Resolving and emitting members blocks" },
+ { TimerType.CloseTypes, "Module types closed" },
+ { TimerType.Resouces, "Embedding resources" },
+ { TimerType.OutputSave, "Writing output file" },
+ { TimerType.DebugSave, "Writing debug symbols file" },
+ };
+
+ int counter = 0;
+ double percentage = (double) total.ElapsedMilliseconds / 100;
+ long subtotal = total.ElapsedMilliseconds;
+ foreach (var timer in timers) {
+ string msg = timer_names[(TimerType) counter++];
+ var ms = timer == null ? 0 : timer.ElapsedMilliseconds;
+ Console.WriteLine ("{0,4:0.0}% {1,5}ms {2}", ms / percentage, ms, msg);
+ subtotal -= ms;
+ }
+
+ Console.WriteLine ("{0,4:0.0}% {1,5}ms Other tasks", subtotal / percentage, subtotal);
+ Console.WriteLine ();
+ Console.WriteLine ("Total elapsed time: {0}", total.Elapsed);
}
}
public InternalErrorException (string message, params object[] args)
: base (String.Format (message, args))
- { }
+ {
+ }
+
+ public InternalErrorException (Exception exception, string message, params object[] args)
+ : base (String.Format (message, args), exception)
+ {
+ }
public InternalErrorException (Exception e, Location loc)
: base (loc.ToString (), e)
public void WarningEnable (Location location, int code, Report Report)
{
- if (Report.CheckWarningCode (code, location))
- regions.Add (new Enable (location.Row, code));
+ if (!Report.CheckWarningCode (code, location))
+ return;
+
+ if (Report.IsWarningDisabledGlobally (code))
+ Report.Warning (1635, 1, location, "Cannot restore warning `CS{0:0000}' because it was disabled globally", code);
+
+ regions.Add (new Enable (location.Row, code));
}
public bool IsWarningEnabled (int code, int src_line)