~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

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