Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2389-EpsLexicase/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory.CSharp-5.5.0/Parser/mcs/report.cs

Last change on this file was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 25.7 KB
Line 
1//
2// report.cs: report errors and warnings.
3//
4// Author: Miguel de Icaza (miguel@ximian.com)
5//         Marek Safar (marek.safar@gmail.com)         
6//
7// Copyright 2001 Ximian, Inc. (http://www.ximian.com)
8// Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
9//
10
11using System;
12using System.IO;
13using System.Text;
14using System.Collections.Generic;
15using System.Diagnostics;
16
17namespace Mono.CSharp {
18
19  //
20  // Errors and warnings manager
21  //
22  public class Report
23  {
24    public const int RuntimeErrorId = 10000;
25
26    Dictionary<int, WarningRegions> warning_regions_table;
27
28    ReportPrinter printer;
29
30    int reporting_disabled;
31
32    readonly CompilerSettings settings;
33   
34    /// <summary>
35    /// List of symbols related to reported error/warning. You have to fill it before error/warning is reported.
36    /// </summary>
37    List<string> extra_information = new List<string> ();
38
39    //
40    // IF YOU ADD A NEW WARNING YOU HAVE TO ADD ITS ID HERE
41    //
42    public static readonly int[] AllWarnings = new int[] {
43      28, 67, 78,
44      105, 108, 109, 114, 162, 164, 168, 169, 183, 184, 197,
45      219, 251, 252, 253, 278, 282,
46      402, 414, 419, 420, 429, 436, 437, 440, 458, 464, 465, 467, 469, 472, 473,
47      612, 618, 626, 628, 642, 649, 652, 657, 658, 659, 660, 661, 665, 672, 675, 693,
48      728,
49      809, 824,
50      1030, 1058, 1060, 1066,
51      1522, 1570, 1571, 1572, 1573, 1574, 1580, 1581, 1584, 1587, 1589, 1590, 1591, 1592,
52      1607, 1616, 1633, 1634, 1635, 1685, 1690, 1691, 1692, 1695, 1696, 1697, 1699,
53      1700, 1701, 1702, 1709, 1711, 1717, 1718, 1720, 1735,
54      1901, 1956, 1981, 1998,
55      2002, 2023, 2029,
56      3000, 3001, 3002, 3003, 3005, 3006, 3007, 3008, 3009,
57      3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 3019,
58      3021, 3022, 3023, 3024, 3026, 3027,
59      4014, 4024, 4025, 4026,
60      7035, 7080, 7081, 7082, 7095,
61      8009,
62    };
63
64    static HashSet<int> AllWarningsHashSet;
65
66    public Report (CompilerContext context, ReportPrinter printer)
67    {
68      if (context == null)
69        throw new ArgumentNullException ("settings");
70      if (printer == null)
71        throw new ArgumentNullException ("printer");
72
73      this.settings = context.Settings;
74      this.printer = printer;
75    }
76
77    public void DisableReporting ()
78    {
79      ++reporting_disabled;
80    }
81
82    public void EnableReporting ()
83    {
84      --reporting_disabled;
85    }
86
87    public void FeatureIsNotAvailable (CompilerContext compiler, Location loc, string feature)
88    {
89      string version;
90      switch (compiler.Settings.Version) {
91      case LanguageVersion.ISO_1:
92        version = "1.0";
93        break;
94      case LanguageVersion.ISO_2:
95        version = "2.0";
96        break;
97      case LanguageVersion.V_3:
98        version = "3.0";
99        break;
100      case LanguageVersion.V_4:
101        version = "4.0";
102        break;
103      case LanguageVersion.V_5:
104        version = "5.0";
105        break;
106      case LanguageVersion.V_6:
107        version = "6.0";
108        break;
109      default:
110        throw new InternalErrorException ("Invalid feature version", compiler.Settings.Version);
111      }
112
113      Error (1644, loc,
114        "Feature `{0}' cannot be used because it is not part of the C# {1} language specification",
115              feature, version);
116    }
117
118    public void FeatureIsNotSupported (Location loc, string feature)
119    {
120      Error (1644, loc,
121        "Feature `{0}' is not supported in Mono mcs1 compiler. Consider using the `gmcs' compiler instead",
122        feature);
123    }
124           
125    public void RuntimeMissingSupport (Location loc, string feature)
126    {
127      Error (-88, loc, "Your .NET Runtime does not support `{0}'. Please use the latest Mono runtime instead.", feature);
128    }
129
130    /// <summary>
131    /// In most error cases is very useful to have information about symbol that caused the error.
132    /// Call this method before you call Report.Error when it makes sense.
133    /// </summary>
134    public void SymbolRelatedToPreviousError (Location loc, string symbol)
135    {
136      SymbolRelatedToPreviousError (loc.ToString ());
137    }
138
139    public void SymbolRelatedToPreviousError (MemberSpec ms)
140    {
141      if (reporting_disabled > 0 || !printer.HasRelatedSymbolSupport)
142        return;
143
144      var mc = ms.MemberDefinition as MemberCore;
145      while (ms is ElementTypeSpec) {
146        ms = ((ElementTypeSpec) ms).Element;
147        mc = ms.MemberDefinition as MemberCore;
148      }
149
150      if (mc != null) {
151        SymbolRelatedToPreviousError (mc);
152      } else {
153        if (ms.DeclaringType != null)
154          ms = ms.DeclaringType;
155
156        var imported_type = ms.MemberDefinition as ImportedTypeDefinition;
157        if (imported_type != null) {
158          var iad = imported_type.DeclaringAssembly as ImportedAssemblyDefinition;
159          SymbolRelatedToPreviousError (iad.Location);
160        }
161      }
162    }
163
164    public void SymbolRelatedToPreviousError (MemberCore mc)
165    {
166      SymbolRelatedToPreviousError (mc.Location, mc.GetSignatureForError ());
167    }
168
169    public void SymbolRelatedToPreviousError (string loc)
170    {
171      string msg = String.Format ("{0} (Location of the symbol related to previous ", loc);
172      if (extra_information.Contains (msg))
173        return;
174
175      extra_information.Add (msg);
176    }
177
178    public bool CheckWarningCode (int code, Location loc)
179    {
180      if (AllWarningsHashSet == null)
181        AllWarningsHashSet = new HashSet<int> (AllWarnings);
182
183      if (AllWarningsHashSet.Contains (code))
184        return true;
185
186      Warning (1691, 1, loc, "`{0}' is not a valid warning number", code);
187      return false;
188    }
189
190    public void ExtraInformation (Location loc, string msg)
191    {
192      extra_information.Add (String.Format ("{0} {1}", loc, msg));
193    }
194
195    public WarningRegions RegisterWarningRegion (Location location)
196    {
197      WarningRegions regions;
198      if (warning_regions_table == null) {
199        regions = null;
200        warning_regions_table = new Dictionary<int, WarningRegions> ();
201      } else {
202        warning_regions_table.TryGetValue (location.File, out regions);
203      }
204
205      if (regions == null) {
206        regions = new WarningRegions ();
207        warning_regions_table.Add (location.File, regions);
208      }
209
210      return regions;
211    }
212
213    public void Warning (int code, int level, Location loc, string message)
214    {
215      if (reporting_disabled > 0)
216        return;
217
218      if (!settings.IsWarningEnabled (code, level))
219        return;
220
221      if (warning_regions_table != null && !loc.IsNull) {
222        WarningRegions regions;
223        if (warning_regions_table.TryGetValue (loc.File, out regions) && !regions.IsWarningEnabled (code, loc.Row))
224          return;
225      }
226
227      AbstractMessage msg;
228      if (settings.IsWarningAsError (code)) {
229        message = "Warning as Error: " + message;
230        msg = new ErrorMessage (code, loc, message, extra_information);
231      } else {
232        msg = new WarningMessage (code, loc, message, extra_information);
233      }
234
235      extra_information.Clear ();
236      printer.Print (msg, settings.ShowFullPaths);
237    }
238
239    public void Warning (int code, int level, Location loc, string format, string arg)
240    {
241      Warning (code, level, loc, String.Format (format, arg));
242    }
243
244    public void Warning (int code, int level, Location loc, string format, string arg1, string arg2)
245    {
246      Warning (code, level, loc, String.Format (format, arg1, arg2));
247    }
248
249    public void Warning (int code, int level, Location loc, string format, params object[] args)
250    {
251      Warning (code, level, loc, String.Format (format, args));
252    }
253
254    public void Warning (int code, int level, string message)
255    {
256      Warning (code, level, Location.Null, message);
257    }
258
259    public void Warning (int code, int level, string format, string arg)
260    {
261      Warning (code, level, Location.Null, format, arg);
262    }
263
264    public void Warning (int code, int level, string format, string arg1, string arg2)
265    {
266      Warning (code, level, Location.Null, format, arg1, arg2);
267    }
268
269    public void Warning (int code, int level, string format, params string[] args)
270    {
271      Warning (code, level, Location.Null, String.Format (format, args));
272    }
273
274    //
275    // Warnings encountered so far
276    //
277    public int Warnings {
278      get { return printer.WarningsCount; }
279    }
280
281    public void Error (int code, Location loc, string error)
282    {
283      if (reporting_disabled > 0)
284        return;
285
286      ErrorMessage msg = new ErrorMessage (code, loc, error, extra_information);
287      extra_information.Clear ();
288
289      printer.Print (msg, settings.ShowFullPaths);
290
291      if (settings.Stacktrace)
292        Console.WriteLine (FriendlyStackTrace (new StackTrace (true)));
293
294      if (printer.ErrorsCount == settings.FatalCounter)
295        throw new FatalException (msg.Text);
296    }
297
298    public void Error (int code, Location loc, string format, string arg)
299    {
300      Error (code, loc, String.Format (format, arg));
301    }
302
303    public void Error (int code, Location loc, string format, string arg1, string arg2)
304    {
305      Error (code, loc, String.Format (format, arg1, arg2));
306    }
307
308    public void Error (int code, Location loc, string format, params string[] args)
309    {
310      Error (code, loc, String.Format (format, args));
311    }
312
313    public void Error (int code, string error)
314    {
315      Error (code, Location.Null, error);
316    }
317
318    public void Error (int code, string format, string arg)
319    {
320      Error (code, Location.Null, format, arg);
321    }
322
323    public void Error (int code, string format, string arg1, string arg2)
324    {
325      Error (code, Location.Null, format, arg1, arg2);
326    }
327
328    public void Error (int code, string format, params string[] args)
329    {
330      Error (code, Location.Null, String.Format (format, args));
331    }
332
333    //
334    // Errors encountered so far
335    //
336    public int Errors {
337      get { return printer.ErrorsCount; }
338    }
339
340    public bool IsDisabled {
341      get {
342        return reporting_disabled > 0;
343      }
344    }
345
346    public ReportPrinter Printer {
347      get { return printer; }
348    }
349
350    public ReportPrinter SetPrinter (ReportPrinter printer)
351    {
352      ReportPrinter old = this.printer;
353      this.printer = printer;
354      return old;
355    }
356
357    [Conditional ("MCS_DEBUG")]
358    static public void Debug (string message, params object[] args)
359    {
360      Debug (4, message, args);
361    }
362     
363    [Conditional ("MCS_DEBUG")]
364    static public void Debug (int category, string message, params object[] args)
365    {
366//      if ((category & DebugFlags) == 0)
367//        return;
368
369      StringBuilder sb = new StringBuilder (message);
370
371      if ((args != null) && (args.Length > 0)) {
372        sb.Append (": ");
373
374        bool first = true;
375        foreach (object arg in args) {
376          if (first)
377            first = false;
378          else
379            sb.Append (", ");
380          if (arg == null)
381            sb.Append ("null");
382//          else if (arg is ICollection)
383//            sb.Append (PrintCollection ((ICollection) arg));
384          else
385            sb.Append (arg);
386        }
387      }
388
389      Console.WriteLine (sb.ToString ());
390    }
391/*
392    static public string PrintCollection (ICollection collection)
393    {
394      StringBuilder sb = new StringBuilder ();
395
396      sb.Append (collection.GetType ());
397      sb.Append ("(");
398
399      bool first = true;
400      foreach (object o in collection) {
401        if (first)
402          first = false;
403        else
404          sb.Append (", ");
405        sb.Append (o);
406      }
407
408      sb.Append (")");
409      return sb.ToString ();
410    }
411*/
412    static string FriendlyStackTrace (StackTrace t)
413    {
414      StringBuilder sb = new StringBuilder ();
415
416      bool foundUserCode = false;
417
418      for (int i = 0; i < t.FrameCount; i++) {
419        StackFrame f = t.GetFrame (i);
420        var mb = f.GetMethod ();
421
422        if (!foundUserCode && mb.ReflectedType == typeof (Report))
423          continue;
424
425        foundUserCode = true;
426
427        sb.Append ("\tin ");
428
429        if (f.GetFileLineNumber () > 0)
430          sb.AppendFormat ("(at {0}:{1}) ", f.GetFileName (), f.GetFileLineNumber ());
431
432        sb.AppendFormat ("{0}.{1} (", mb.ReflectedType.Name, mb.Name);
433
434        bool first = true;
435        foreach (var pi in mb.GetParameters ()) {
436          if (!first)
437            sb.Append (", ");
438          first = false;
439
440          sb.Append (pi.ParameterType.FullName);
441        }
442        sb.Append (")\n");
443      }
444
445      return sb.ToString ();
446    }
447  }
448
449  public abstract class AbstractMessage
450  {
451    readonly string[] extra_info;
452    protected readonly int code;
453    protected readonly Location location;
454    readonly string message;
455
456    protected AbstractMessage (int code, Location loc, string msg, List<string> extraInfo)
457    {
458      this.code = code;
459      if (code < 0)
460        this.code = 8000 - code;
461
462      this.location = loc;
463      this.message = msg;
464      if (extraInfo.Count != 0) {
465        this.extra_info = extraInfo.ToArray ();
466      }
467    }
468
469    protected AbstractMessage (AbstractMessage aMsg)
470    {
471      this.code = aMsg.code;
472      this.location = aMsg.location;
473      this.message = aMsg.message;
474      this.extra_info = aMsg.extra_info;
475    }
476
477    public int Code {
478      get { return code; }
479    }
480
481    public override bool Equals (object obj)
482    {
483      AbstractMessage msg = obj as AbstractMessage;
484      if (msg == null)
485        return false;
486
487      return code == msg.code && location.Equals (msg.location) && message == msg.message;
488    }
489
490    public override int GetHashCode ()
491    {
492      return code.GetHashCode ();
493    }
494
495    public abstract bool IsWarning { get; }
496
497    public Location Location {
498      get { return location; }
499    }
500
501    public abstract string MessageType { get; }
502
503    public string[] RelatedSymbols {
504      get { return extra_info; }
505    }
506
507    public string Text {
508      get { return message; }
509    }
510  }
511
512  sealed class WarningMessage : AbstractMessage
513  {
514    public WarningMessage (int code, Location loc, string message, List<string> extra_info)
515      : base (code, loc, message, extra_info)
516    {
517    }
518
519    public override bool IsWarning {
520      get { return true; }
521    }
522
523    public override string MessageType {
524      get {
525        return "warning";
526      }
527    }
528  }
529
530  sealed class ErrorMessage : AbstractMessage
531  {
532    public ErrorMessage (int code, Location loc, string message, List<string> extraInfo)
533      : base (code, loc, message, extraInfo)
534    {
535    }
536
537    public ErrorMessage (AbstractMessage aMsg)
538      : base (aMsg)
539    {
540    }
541
542    public override bool IsWarning {
543      get { return false; }
544    }
545
546    public override string MessageType {
547      get {
548        return "error";
549      }
550    }
551  }
552
553  //
554  // Generic base for any message writer
555  //
556  public abstract class ReportPrinter
557  {
558    protected HashSet<ITypeDefinition> reported_missing_definitions;
559
560    #region Properties
561
562    public int ErrorsCount { get; protected set; }
563   
564    public int WarningsCount { get; private set; }
565 
566    //
567    // When (symbols related to previous ...) can be used
568    //
569    public virtual bool HasRelatedSymbolSupport {
570      get { return true; }
571    }
572
573    #endregion
574
575
576    protected virtual string FormatText (string txt)
577    {
578      return txt;
579    }
580
581    public virtual void Print (AbstractMessage msg, bool showFullPath)
582    {
583      if (msg.IsWarning) {
584        ++WarningsCount;
585      } else {
586        ++ErrorsCount;
587      }
588    }
589
590    protected void Print (AbstractMessage msg, TextWriter output, bool showFullPath)
591    {
592      StringBuilder txt = new StringBuilder ();
593      if (!msg.Location.IsNull) {
594        if (showFullPath)
595          txt.Append (msg.Location.ToStringFullName ());
596        else
597          txt.Append (msg.Location.ToString ());
598
599        txt.Append (" ");
600      }
601
602      txt.AppendFormat ("{0} CS{1:0000}: {2}", msg.MessageType, msg.Code, msg.Text);
603
604      if (!msg.IsWarning)
605        output.WriteLine (FormatText (txt.ToString ()));
606      else
607        output.WriteLine (txt.ToString ());
608
609      if (msg.RelatedSymbols != null) {
610        foreach (string s in msg.RelatedSymbols)
611          output.WriteLine (s + msg.MessageType + ")");
612      }
613    }
614
615    //
616    // Tracks reported missing types. It needs to be session specific
617    // because we can run in probing mode
618    //
619    public bool MissingTypeReported (ITypeDefinition typeDefinition)
620    {
621      if (reported_missing_definitions == null)
622        reported_missing_definitions = new HashSet<ITypeDefinition> ();
623
624      if (reported_missing_definitions.Contains (typeDefinition))
625        return true;
626
627      reported_missing_definitions.Add (typeDefinition);
628      return false;
629    }
630
631    public void Reset ()
632    {
633      // HACK: Temporary hack for broken repl flow
634      ErrorsCount = WarningsCount = 0;
635    }
636  }
637
638  sealed class NullReportPrinter : ReportPrinter
639  {
640  }
641
642  //
643  // Default message recorder, it uses two types of message groups.
644  // Common messages: messages reported in all sessions.
645  // Merged messages: union of all messages in all sessions.
646  //
647  // Used by the Lambda expressions to compile the code with various
648  // parameter values, or by attribute resolver
649  //
650  class SessionReportPrinter : ReportPrinter
651  {
652    List<AbstractMessage> session_messages;
653    //
654    // A collection of exactly same messages reported in all sessions
655    //
656    List<AbstractMessage> common_messages;
657
658    //
659    // A collection of unique messages reported in all sessions
660    //
661    List<AbstractMessage> merged_messages;
662
663    bool showFullPaths;
664
665    public void ClearSession ()
666    {
667      session_messages = null;
668    }
669
670    public override void Print (AbstractMessage msg, bool showFullPath)
671    {
672      //
673      // This line is useful when debugging recorded messages
674      //
675      // Console.WriteLine ("RECORDING: {0}", msg.Text);
676
677      if (session_messages == null)
678        session_messages = new List<AbstractMessage> ();
679
680      session_messages.Add (msg);
681
682      this.showFullPaths = showFullPath;
683      base.Print (msg, showFullPath);
684    }
685
686    public void EndSession ()
687    {
688      if (session_messages == null)
689        return;
690
691      //
692      // Handles the first session
693      //
694      if (common_messages == null) {
695        common_messages = new List<AbstractMessage> (session_messages);
696        merged_messages = session_messages;
697        session_messages = null;
698        return;
699      }
700
701      //
702      // Store common messages if any
703      //
704      for (int i = 0; i < common_messages.Count; ++i) {
705        AbstractMessage cmsg = common_messages[i];
706        bool common_msg_found = false;
707        foreach (AbstractMessage msg in session_messages) {
708          if (cmsg.Equals (msg)) {
709            common_msg_found = true;
710            break;
711          }
712        }
713
714        if (!common_msg_found)
715          common_messages.RemoveAt (i);
716      }
717
718      //
719      // Merge session and previous messages
720      //
721      for (int i = 0; i < session_messages.Count; ++i) {
722        AbstractMessage msg = session_messages[i];
723        bool msg_found = false;
724        for (int ii = 0; ii < merged_messages.Count; ++ii) {
725          if (msg.Equals (merged_messages[ii])) {
726            msg_found = true;
727            break;
728          }
729        }
730
731        if (!msg_found)
732          merged_messages.Add (msg);
733      }
734    }
735
736    public bool IsEmpty {
737      get {
738        return merged_messages == null && common_messages == null;
739      }
740    }
741
742    //
743    // Prints collected messages, common messages have a priority
744    //
745    public bool Merge (ReportPrinter dest)
746    {
747      var messages_to_print = merged_messages;
748      if (common_messages != null && common_messages.Count > 0) {
749        messages_to_print = common_messages;
750      }
751
752      if (messages_to_print == null)
753        return false;
754
755      bool error_msg = false;
756      foreach (AbstractMessage msg in messages_to_print) {
757        dest.Print (msg, showFullPaths);
758        error_msg |= !msg.IsWarning;
759      }
760
761      if (reported_missing_definitions != null) {
762        foreach (var missing in reported_missing_definitions)
763          dest.MissingTypeReported (missing);
764      }
765
766      return error_msg;
767    }
768  }
769
770  public class StreamReportPrinter : ReportPrinter
771  {
772    readonly TextWriter writer;
773
774    public StreamReportPrinter (TextWriter writer)
775    {
776      this.writer = writer;
777    }
778
779    public override void Print (AbstractMessage msg, bool showFullPath)
780    {
781      Print (msg, writer, showFullPath);
782      base.Print (msg, showFullPath);
783    }
784  }
785
786  public class ConsoleReportPrinter : StreamReportPrinter
787  {
788    static readonly string prefix, postfix;
789
790    static ConsoleReportPrinter ()
791    {
792      string term = Environment.GetEnvironmentVariable ("TERM");
793      bool xterm_colors = false;
794     
795      switch (term){
796      case "xterm":
797      case "rxvt":
798      case "rxvt-unicode":
799        if (Environment.GetEnvironmentVariable ("COLORTERM") != null){
800          xterm_colors = true;
801        }
802        break;
803
804      case "xterm-color":
805      case "xterm-256color":
806        xterm_colors = true;
807        break;
808      }
809      if (!xterm_colors)
810        return;
811
812      if (!(UnixUtils.isatty (1) && UnixUtils.isatty (2)))
813        return;
814     
815      string config = Environment.GetEnvironmentVariable ("MCS_COLORS");
816      if (config == null){
817        config = "errors=red";
818        //config = "brightwhite,red";
819      }
820
821      if (config == "disable")
822        return;
823
824      if (!config.StartsWith ("errors="))
825        return;
826
827      config = config.Substring (7);
828     
829      int p = config.IndexOf (",");
830      if (p == -1)
831        prefix = GetForeground (config);
832      else
833        prefix = GetBackground (config.Substring (p+1)) + GetForeground (config.Substring (0, p));
834      postfix = "\x001b[0m";
835    }
836
837    public ConsoleReportPrinter ()
838      : base (Console.Error)
839    {
840    }
841
842    public ConsoleReportPrinter (TextWriter writer)
843      : base (writer)
844    {
845    }
846
847    static int NameToCode (string s)
848    {
849      switch (s) {
850      case "black":
851        return 0;
852      case "red":
853        return 1;
854      case "green":
855        return 2;
856      case "yellow":
857        return 3;
858      case "blue":
859        return 4;
860      case "magenta":
861        return 5;
862      case "cyan":
863        return 6;
864      case "grey":
865      case "white":
866        return 7;
867      }
868      return 7;
869    }
870
871    //
872    // maps a color name to its xterm color code
873    //
874    static string GetForeground (string s)
875    {
876      string highcode;
877
878      if (s.StartsWith ("bright")) {
879        highcode = "1;";
880        s = s.Substring (6);
881      } else
882        highcode = "";
883
884      return "\x001b[" + highcode + (30 + NameToCode (s)).ToString () + "m";
885    }
886
887    static string GetBackground (string s)
888    {
889      return "\x001b[" + (40 + NameToCode (s)).ToString () + "m";
890    }
891
892    protected override string FormatText (string txt)
893    {
894      if (prefix != null)
895        return prefix + txt + postfix;
896
897      return txt;
898    }
899  }
900
901  class TimeReporter
902  {
903    public enum TimerType
904    {
905      ParseTotal,
906      AssemblyBuilderSetup,
907      CreateTypeTotal,
908      ReferencesLoading,
909      ReferencesImporting,
910      PredefinedTypesInit,
911      ModuleDefinitionTotal,
912      EmitTotal,
913      CloseTypes,
914      Resouces,
915      OutputSave,
916      DebugSave,
917    }
918
919    readonly Stopwatch[] timers;
920    Stopwatch total;
921
922    public TimeReporter (bool enabled)
923    {
924      if (!enabled)
925        return;
926
927      timers = new Stopwatch[System.Enum.GetValues(typeof (TimerType)).Length];
928    }
929
930    public void Start (TimerType type)
931    {
932      if (timers != null) {
933        var sw = new Stopwatch ();
934        timers[(int) type] = sw;
935        sw.Start ();
936      }
937    }
938
939    public void StartTotal ()
940    {
941      total = new Stopwatch ();
942      total.Start ();
943    }
944
945    public void Stop (TimerType type)
946    {
947      if (timers != null) {
948        timers[(int) type].Stop ();
949      }
950    }
951
952    public void StopTotal ()
953    {
954      total.Stop ();
955    }
956
957    public void ShowStats ()
958    {
959      if (timers == null)
960        return;
961
962      Dictionary<TimerType, string> timer_names = new Dictionary<TimerType,string> {
963        { TimerType.ParseTotal, "Parsing source files" },
964        { TimerType.AssemblyBuilderSetup, "Assembly builder setup" },
965        { TimerType.CreateTypeTotal, "Compiled types created" },
966        { TimerType.ReferencesLoading, "Referenced assemblies loading" },
967        { TimerType.ReferencesImporting, "Referenced assemblies importing" },
968        { TimerType.PredefinedTypesInit, "Predefined types initialization" },
969        { TimerType.ModuleDefinitionTotal, "Module definition" },
970        { TimerType.EmitTotal, "Resolving and emitting members blocks" },
971        { TimerType.CloseTypes, "Module types closed" },
972        { TimerType.Resouces, "Embedding resources" },
973        { TimerType.OutputSave, "Writing output file" },
974        { TimerType.DebugSave, "Writing debug symbols file" },
975      };
976
977      int counter = 0;
978      double percentage = (double) total.ElapsedMilliseconds / 100;
979      long subtotal = total.ElapsedMilliseconds;
980      foreach (var timer in timers) {
981        string msg = timer_names[(TimerType) counter++];
982        var ms = timer == null ? 0 : timer.ElapsedMilliseconds;
983        Console.WriteLine ("{0,4:0.0}% {1,5}ms {2}", ms / percentage, ms, msg);
984        subtotal -= ms;
985      }
986
987      Console.WriteLine ("{0,4:0.0}% {1,5}ms Other tasks", subtotal / percentage, subtotal);
988      Console.WriteLine ();
989      Console.WriteLine ("Total elapsed time: {0}", total.Elapsed);
990    }
991  }
992
993  public class InternalErrorException : Exception {
994    public InternalErrorException (MemberCore mc, Exception e)
995      : base (mc.Location + " " + mc.GetSignatureForError (), e)
996    {
997    }
998
999    public InternalErrorException ()
1000      : base ("Internal error")
1001    {
1002    }
1003
1004    public InternalErrorException (string message)
1005      : base (message)
1006    {
1007    }
1008
1009    public InternalErrorException (string message, params object[] args)
1010      : base (String.Format (message, args))
1011    {
1012    }
1013
1014    public InternalErrorException (Exception exception, string message, params object[] args)
1015      : base (String.Format (message, args), exception)
1016    {
1017    }
1018   
1019    public InternalErrorException (Exception e, Location loc)
1020      : base (loc.ToString (), e)
1021    {
1022    }
1023  }
1024
1025  class FatalException : Exception
1026  {
1027    public FatalException (string message)
1028      : base (message)
1029    {
1030    }
1031  }
1032
1033  /// <summary>
1034  /// Handles #pragma warning
1035  /// </summary>
1036  public class WarningRegions {
1037
1038    abstract class PragmaCmd
1039    {
1040      public int Line;
1041
1042      protected PragmaCmd (int line)
1043      {
1044        Line = line;
1045      }
1046
1047      public abstract bool IsEnabled (int code, bool previous);
1048    }
1049   
1050    class Disable : PragmaCmd
1051    {
1052      int code;
1053      public Disable (int line, int code)
1054        : base (line)
1055      {
1056        this.code = code;
1057      }
1058
1059      public override bool IsEnabled (int code, bool previous)
1060      {
1061        return this.code != code && previous;
1062      }
1063    }
1064
1065    class DisableAll : PragmaCmd
1066    {
1067      public DisableAll (int line)
1068        : base (line) {}
1069
1070      public override bool IsEnabled(int code, bool previous)
1071      {
1072        return false;
1073      }
1074    }
1075
1076    class Enable : PragmaCmd
1077    {
1078      int code;
1079      public Enable (int line, int code)
1080        : base (line)
1081      {
1082        this.code = code;
1083      }
1084
1085      public override bool IsEnabled(int code, bool previous)
1086      {
1087        return this.code == code || previous;
1088      }
1089    }
1090
1091    class EnableAll : PragmaCmd
1092    {
1093      public EnableAll (int line)
1094        : base (line) {}
1095
1096      public override bool IsEnabled(int code, bool previous)
1097      {
1098        return true;
1099      }
1100    }
1101
1102
1103    List<PragmaCmd> regions = new List<PragmaCmd> ();
1104
1105    public void WarningDisable (int line)
1106    {
1107      regions.Add (new DisableAll (line));
1108    }
1109
1110    public void WarningDisable (Location location, int code, Report Report)
1111    {
1112      if (Report.CheckWarningCode (code, location))
1113        regions.Add (new Disable (location.Row, code));
1114    }
1115
1116    public void WarningEnable (int line)
1117    {
1118      regions.Add (new EnableAll (line));
1119    }
1120
1121    public void WarningEnable (Location location, int code, CompilerContext context)
1122    {
1123      if (!context.Report.CheckWarningCode (code, location))
1124        return;
1125
1126      if (context.Settings.IsWarningDisabledGlobally (code))
1127        context.Report.Warning (1635, 1, location, "Cannot restore warning `CS{0:0000}' because it was disabled globally", code);
1128
1129      regions.Add (new Enable (location.Row, code));
1130    }
1131
1132    public bool IsWarningEnabled (int code, int src_line)
1133    {
1134      bool result = true;
1135      foreach (PragmaCmd pragma in regions) {
1136        if (src_line < pragma.Line)
1137          break;
1138
1139        result = pragma.IsEnabled (code, result);
1140      }
1141      return result;
1142    }
1143  }
1144}
Note: See TracBrowser for help on using the repository browser.